示例#1
0
        /// <summary>
        /// See <see cref="IForce.ApplyToObject(TPhysicalObject)"/>.
        /// </summary>
        public void ApplyToObject(IBody <TShapeFigure> physicalObject)
        {
            ArgumentChecks.AssertNotNull(physicalObject, nameof(physicalObject));

            // TODO: make this class "more generic", so it could be used for particles as well. Add a strategy to determine the "point to apply the force to".
            var pointClosestToBlastCenter = this._supportFunctions.GetFigureOutlinePointClosestToPosition(
                physicalObject.Shape.Current,
                this._position);

            // Is the object within reach of the blast?
            var offset = pointClosestToBlastCenter.GetOffsetFrom(this._position);

            if (offset.Magnitude() > this._currentBlastRadius)
            {
                return;
            }

            var forceVector = offset.Norm().Multiply(this._currentForce);

            physicalObject.ApplyForceAtPointInSpace(forceVector, pointClosestToBlastCenter);
        }
示例#2
0
        /// <summary>
        /// See <see cref="IForce{TPhysicalObject}.ApplyToObject(TPhysicalObject)"/>.
        /// </summary>
        public void ApplyToObject(IBody <TShapeFigure> physicalObject)
        {
            ArgumentChecks.AssertNotNull(physicalObject, nameof(physicalObject));

            var velocity = physicalObject.CurrentState.Velocity;

            if (velocity.SquaredMagnitude() == 0)
            {
                return;
            }

            var forceDirection    = velocity.Invert();
            var supportPointLeft  = this._supportFunctions.GetSupportPoint(physicalObject.Shape.Current, forceDirection.Get90DegreesLeft());
            var supportPointRight = this._supportFunctions.GetSupportPoint(physicalObject.Shape.Current, forceDirection.Get90DegreesRight());

            var intersectionWithPerpendicular = this._lineCalculationHelper.GetIntersectionWithPerpendicularThroughPoint(
                new Line(physicalObject.CurrentState.Position, physicalObject.CurrentState.Position.AddVector(forceDirection)),
                supportPointLeft);

            var pointOppositeLeftSupportPoint = this._lineCalculationHelper.GetIntersectionWithPerpendicularThroughPoint(
                new Line(supportPointLeft, intersectionWithPerpendicular),
                supportPointRight);

            var offset = pointOppositeLeftSupportPoint.GetOffsetFrom(supportPointLeft);

            // Determine the exposed "area".
            var exposedArea = offset.SquaredMagnitude();

            // Determine force.
            var forceMagnitude = exposedArea * this._density * velocity.SquaredMagnitude() / 2;
            var forceVector    = forceDirection.Norm().Multiply(forceMagnitude);

            // Determine the point to apply force to.
            var pointToApplyForceTo = supportPointLeft.AddVector(offset.Divide(2));

            // Apply force.
            physicalObject.ApplyForceAtPointInSpace(forceVector, pointToApplyForceTo);
        }