/// <summary>
        /// Activate the explosion at the specified position.
        /// </summary>
        /// <param name="pos">The position (center) of the explosion.</param>
        /// <param name="radius">The radius of the explosion.</param>
        /// <param name="force">The force applied</param>
        /// <param name="maxForce">A maximum amount of force. When force gets over this value, it will be equal to maxForce</param>
        /// <returns>A list of bodies and the amount of force that was applied to them.</returns>
        // FP - public Dictionary<Body, Vector2> Activate(Vector2 pos, FP radius, FP force, FP maxForce = FP.MaxValue)
        public Dictionary <Body, FPVector2> Activate(FPVector2 pos, FP radius, FP force, FP maxForce)
        {
            HashSet <Body> affectedBodies = new HashSet <Body>();

            AABB aabb;

            aabb.LowerBound = pos - new FPVector2(radius);
            aabb.UpperBound = pos + new FPVector2(radius);

            // Query the world for bodies within the radius.
            World.QueryAABB(fixture =>
            {
                if (FPVector2.Distance(fixture.Body.Position, pos) <= radius)
                {
                    if (!affectedBodies.Contains(fixture.Body))
                    {
                        affectedBodies.Add(fixture.Body);
                    }
                }

                return(true);
            }, ref aabb);

            return(ApplyImpulse(pos, radius, force, maxForce, affectedBodies));
        }
Beispiel #2
0
        public static FP DistanceBetweenPointAndLineSegment(ref FPVector2 point, ref FPVector2 start, ref FPVector2 end)
        {
            if (start == end)
            {
                return(FPVector2.Distance(point, start));
            }

            FPVector2 v = FPVector2.Subtract(end, start);
            FPVector2 w = FPVector2.Subtract(point, start);

            FP c1 = FPVector2.Dot(w, v);

            if (c1 <= 0)
            {
                return(FPVector2.Distance(point, start));
            }

            FP c2 = FPVector2.Dot(v, v);

            if (c2 <= c1)
            {
                return(FPVector2.Distance(point, end));
            }

            FP        b           = c1 / c2;
            FPVector2 pointOnLine = FPVector2.Add(start, FPVector2.Multiply(v, b));

            return(FPVector2.Distance(point, pointOnLine));
        }
Beispiel #3
0
        public List <FPVector> SubdivideEvenly(int divisions)
        {
            List <FPVector> verts = new List <FPVector>();

            FP length = GetLength();

            FP deltaLength = length / divisions + 0.001f;
            FP t           = 0.000f;

            // we always start at the first control point
            FPVector2 start = ControlPoints[0];
            FPVector2 end   = GetPosition(t);

            // increment t until we are at half the distance
            while (deltaLength * 0.5f >= FPVector2.Distance(start, end))
            {
                end = GetPosition(t);
                t  += 0.0001f;

                if (t >= 1f)
                {
                    break;
                }
            }

            start = end;

            // for each box
            for (int i = 1; i < divisions; i++)
            {
                FPVector2 normal = GetPositionNormal(t);
                FP        angle  = FP.Atan2(normal.y, normal.x);

                verts.Add(new FPVector(end.x, end.y, angle));

                // until we reach the correct distance down the curve
                while (deltaLength >= FPVector2.Distance(start, end))
                {
                    end = GetPosition(t);
                    t  += 0.00001f;

                    if (t >= 1f)
                    {
                        break;
                    }
                }
                if (t >= 1f)
                {
                    break;
                }

                start = end;
            }
            return(verts);
        }
Beispiel #4
0
            public FP?IntersectsWithRay(FPVector2 origin, FPVector2 direction)
            {
                FP          largestDistance = FPMath.Max(A.Position.x - origin.x, B.Position.x - origin.x) * 2f;
                LineSegment raySegment      = new LineSegment(new Vertex(origin, 0), new Vertex(origin + (direction * largestDistance), 0));

                FPVector2?intersection = FindIntersection(this, raySegment);
                FP?       value        = null;

                if (intersection != null)
                {
                    value = FPVector2.Distance(origin, intersection.Value);
                }

                return(value);
            }
Beispiel #5
0
        public FP GetLength()
        {
            List <FPVector2> verts = GetVertices(ControlPoints.Count * 25);
            FP length = 0;

            for (int i = 1; i < verts.Count; i++)
            {
                length += FPVector2.Distance(verts[i - 1], verts[i]);
            }

            if (Closed)
            {
                length += FPVector2.Distance(verts[ControlPoints.Count - 1], verts[0]);
            }

            return(length);
        }
        private Dictionary <Body, FPVector2> ApplyImpulse(FPVector2 pos, FP radius, FP force, FP maxForce, HashSet <Body> overlappingBodies)
        {
            Dictionary <Body, FPVector2> forces = new Dictionary <Body, FPVector2>(overlappingBodies.Count);

            foreach (Body overlappingBody in overlappingBodies)
            {
                if (IsActiveOn(overlappingBody))
                {
                    FP distance     = FPVector2.Distance(pos, overlappingBody.Position);
                    FP forcePercent = GetPercent(distance, radius);

                    FPVector2 forceVector = pos - overlappingBody.Position;
                    forceVector *= 1f / FP.Sqrt(forceVector.x * forceVector.x + forceVector.y * forceVector.y);
                    forceVector *= FPMath.Min(force * forcePercent, maxForce);
                    forceVector *= -1;

                    overlappingBody.ApplyLinearImpulse(forceVector);
                    forces.Add(overlappingBody, forceVector);
                }
            }

            return(forces);
        }