Пример #1
0
        public static FP DistanceBetweenPointAndLineSegment(ref TSVector2 point, ref TSVector2 start, ref TSVector2 end)
        {
            if (start == end)
            {
                return(TSVector2.Distance(point, start));
            }

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

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

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

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

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

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

            return(TSVector2.Distance(point, pointOnLine));
        }
Пример #2
0
        /// <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>
        // TS - public Dictionary<Body, Vector2> Activate(Vector2 pos, FP radius, FP force, FP maxForce = FP.MaxValue)
        public Dictionary <Body, TSVector2> Activate(TSVector2 pos, FP radius, FP force, FP maxForce)
        {
            HashSet <Body> affectedBodies = new HashSet <Body>();

            AABB aabb;

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

            // Query the world for bodies within the radius.
            World.QueryAABB(fixture =>
            {
                if (TSVector2.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));
        }
Пример #3
0
        public List <TSVector> SubdivideEvenly(int divisions)
        {
            List <TSVector> verts = new List <TSVector>();

            FP length = GetLength();

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

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

            // increment t until we are at half the distance
            while (deltaLength * 0.5f >= TSVector2.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++)
            {
                TSVector2 normal = GetPositionNormal(t);
                FP        angle  = FP.Atan2(normal.y, normal.x);

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

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

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

                start = end;
            }
            return(verts);
        }
Пример #4
0
        public FP GetLength()
        {
            List <TSVector2> verts = GetVertices(ControlPoints.Count * 25);
            FP length = 0;

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

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

            return(length);
        }
Пример #5
0
        private Dictionary <Body, TSVector2> ApplyImpulse(TSVector2 pos, FP radius, FP force, FP maxForce, HashSet <Body> overlappingBodies)
        {
            Dictionary <Body, TSVector2> forces = new Dictionary <Body, TSVector2>(overlappingBodies.Count);

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

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

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

            return(forces);
        }
Пример #6
0
        private bool SplitPolygonEdge(Vertices polygon, TSVector2 coordInsideThePolygon, out int vertex1Index, out int vertex2Index)
        {
            int       num   = 0;
            int       index = 0;
            bool      flag  = false;
            FP        y     = FP.MaxValue;
            bool      flag2 = false;
            TSVector2 zero  = TSVector2.zero;
            List <FP> list  = this.SearchCrossingEdges(polygon, (int)((long)coordInsideThePolygon.y));

            vertex1Index = 0;
            vertex2Index = 0;
            zero.y       = coordInsideThePolygon.y;
            bool flag3 = list != null && list.Count > 1 && list.Count % 2 == 0;
            bool result;

            if (flag3)
            {
                for (int i = 0; i < list.Count; i++)
                {
                    bool flag4 = list[i] < coordInsideThePolygon.x;
                    if (flag4)
                    {
                        FP   fP    = coordInsideThePolygon.x - list[i];
                        bool flag5 = fP < y;
                        if (flag5)
                        {
                            y      = fP;
                            zero.x = list[i];
                            flag2  = true;
                        }
                    }
                }
                bool flag6 = flag2;
                if (flag6)
                {
                    y = FP.MaxValue;
                    int num2 = polygon.Count - 1;
                    for (int j = 0; j < polygon.Count; j++)
                    {
                        TSVector2 tSVector  = polygon[j];
                        TSVector2 tSVector2 = polygon[num2];
                        FP        fP        = LineTools.DistanceBetweenPointAndLineSegment(ref zero, ref tSVector, ref tSVector2);
                        bool      flag7     = fP < y;
                        if (flag7)
                        {
                            y     = fP;
                            num   = j;
                            index = num2;
                            flag  = true;
                        }
                        num2 = j;
                    }
                    bool flag8 = flag;
                    if (flag8)
                    {
                        TSVector2 value = polygon[index] - polygon[num];
                        value.Normalize();
                        TSVector2 value2 = polygon[num];
                        FP        fP     = TSVector2.Distance(value2, zero);
                        vertex1Index = num;
                        vertex2Index = num + 1;
                        polygon.Insert(num, fP * value + polygon[vertex1Index]);
                        polygon.Insert(num, fP * value + polygon[vertex2Index]);
                        result = true;
                        return(result);
                    }
                }
            }
            result = false;
            return(result);
        }
Пример #7
0
        private bool DistanceToHullAcceptable(Vertices polygon, TSVector2 point, bool higherDetail)
        {
            bool flag = polygon == null;

            if (flag)
            {
                throw new ArgumentNullException("polygon", "'polygon' can't be null.");
            }
            bool flag2 = polygon.Count < 3;

            if (flag2)
            {
                throw new ArgumentException("'polygon.Count' can't be less then 3.");
            }
            TSVector2 tSVector = polygon[polygon.Count - 1];
            bool      result;

            if (higherDetail)
            {
                for (int i = 0; i < polygon.Count; i++)
                {
                    TSVector2 value = polygon[i];
                    bool      flag3 = LineTools.DistanceBetweenPointAndLineSegment(ref point, ref value, ref tSVector) <= this._hullTolerance || TSVector2.Distance(point, value) <= this._hullTolerance;
                    if (flag3)
                    {
                        result = false;
                        return(result);
                    }
                    tSVector = polygon[i];
                }
                result = true;
            }
            else
            {
                for (int j = 0; j < polygon.Count; j++)
                {
                    TSVector2 value = polygon[j];
                    bool      flag4 = LineTools.DistanceBetweenPointAndLineSegment(ref point, ref value, ref tSVector) <= this._hullTolerance;
                    if (flag4)
                    {
                        result = false;
                        return(result);
                    }
                    tSVector = polygon[j];
                }
                result = true;
            }
            return(result);
        }
Пример #8
0
 public static FP SDCircle(TSVector2 x, TSVector2 c, FP radius)
 {
     return(TSVector2.Distance(x, c) - radius);
 }