示例#1
0
        public static Vector2D GetPointLineIntersectLine(Pair2D lineA, Pair2D lineB)
        {
            double dx_cx = lineB.B.x - lineB.A.x;
            double dy_cy = lineB.B.y - lineB.A.y;
            double bx_ax = lineA.B.x - lineA.A.x;
            double by_ay = lineA.B.y - lineA.A.y;
            double de    = bx_ax * dy_cy - by_ay * dx_cx;

            if (System.Math.Abs(de) < 0.0001d)
            {
                return(null);
            }

            if (de > -tor && de < tor)
            {
                return(null);
            }

            double ax_cx = lineA.A.x - lineB.A.x;
            double ay_cy = lineA.A.y - lineB.A.y;

            double r = (ay_cy * dx_cx - ax_cx * dy_cy) / de;
            double s = (ay_cy * bx_ax - ax_cx * by_ay) / de;

            if ((r < 0) || (r > 1) || (s < 0) || (s > 1))
            {
                return(null);
            }

            return(new Vector2D(lineA.A.x + r * bx_ax, lineA.A.y + r * by_ay));
        }
示例#2
0
        public static bool GetBoolLineIntersectLine(Pair2D lineA, Pair2D lineB)
        {
            double dx_cx = lineB.B.x - lineB.A.x;
            double dy_cy = lineB.B.y - lineB.A.y;
            double bx_ax = lineA.B.x - lineA.A.x;
            double by_ay = lineA.B.y - lineA.A.y;
            double de    = bx_ax * dy_cy - by_ay * dx_cx;

            if (System.Math.Abs(de) < 0.0001d)
            {
                return(false);
            }

            if (de > -tor && de < tor)
            {
                return(false);
            }

            double ax_cx = lineA.A.x - lineB.A.x;
            double ay_cy = lineA.A.y - lineB.A.y;

            double r = (ay_cy * dx_cx - ax_cx * dy_cy) / de;
            double s = (ay_cy * bx_ax - ax_cx * by_ay) / de;

            if ((r < 0) || (r > 1) || (s < 0) || (s > 1))
            {
                return(false);
            }

            return(true);
        }
示例#3
0
        public static bool SliceIntersectPoly(List <Vector2D> slice, Polygon2D poly)
        {
            Pair2D pairA = new Pair2D(null, null);

            foreach (Vector2D pointA in slice)
            {
                pairA.B = pointA;

                if (pairA.A != null && pairA.B != null)
                {
                    Pair2D pairB = new Pair2D(new Vector2D(poly.pointsList.Last()), null);

                    foreach (Vector2D pointB in poly.pointsList)
                    {
                        pairB.B = pointB;

                        if (LineIntersectLine(pairA, pairB))
                        {
                            return(true);
                        }

                        pairB.A = pointB;
                    }
                }

                pairA.A = pointA;
            }

            return(false);
        }
示例#4
0
        public static bool SliceIntersectItself(List <Vector2D> slice)
        {
            Pair2D pairA = new Pair2D(null, null);
            Pair2D pairB = new Pair2D(null, null);

            for (int i = 0; i < slice.Count - 1; i++)
            {
                pairA.A = slice[i];
                pairA.B = slice[i + 1];

                for (int x = 0; x < slice.Count - 1; x++)
                {
                    pairB.A = slice[x];
                    pairB.B = slice[x + 1];

                    if (GetBoolLineIntersectLine(pairA, pairB))
                    {
                        if (pairA.A != pairB.A && pairA.B != pairB.B && pairA.A != pairB.B && pairA.B != pairB.A)
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
示例#5
0
            static public bool IntersectLine(Pair2D line, Vector2D circle, float radius)
            {
                double sx = line.B.x - line.A.x;
                double sy = line.B.y - line.A.y;

                double q = ((circle.x - line.A.x) * (line.B.x - line.A.x) + (circle.y - line.A.y) * (line.B.y - line.A.y)) / (sx * sx + sy * sy);

                if (q < 0.0f)
                {
                    q = 0.0f;
                }
                else if (q > 1.0)
                {
                    q = 1.0f;
                }

                double dx = circle.x - ((1.0f - q) * line.A.x + q * line.B.x);
                double dy = circle.y - ((1.0f - q) * line.A.y + q * line.B.y);

                if (dx * dx + dy * dy < radius * radius)
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
        static public void RemoveClosePoints(List <Vector2D> list, float closePrecision = 0.005f)
        {
            List <Vector2D> points = new List <Vector2D>(list);
            Pair2D          pair   = new Pair2D(list.Last(), null);

            //Vector2D lastPos = null;

            for (int i = 0; i < points.Count; i++)
            {
                pair.B = points[i];

                if (points.Count < 4)
                {
                    break;
                }

                if (Vector2D.Distance(pair.A, pair.B) < closePrecision)
                {
                    //Debug.LogWarning("Smart Utility 2D: Polygon points are too close");
                    list.Remove(pair.A);
                }
                else
                {
                    pair.A = pair.B;
                }
            }
        }
示例#7
0
        public static bool LineIntersectLine(Pair2D lineA, Pair2D lineB)
        {
            if (GetBoolLineIntersectLine(lineA, lineB))
            {
                return(true);
            }

            return(false);
        }
示例#8
0
 static public bool IntersectSlice(List <Vector2D> points, Vector2D circle, float radius)
 {
     foreach (Pair2D id in Pair2D.GetList(points, false))                   // Remove GetList()
     {
         if (IntersectLine(id, circle, radius) == true)
         {
             return(true);
         }
     }
     return(false);
 }
示例#9
0
 static public bool IntersectPolygon(Polygon2D poly, Vector2D circle, float radius)
 {
     foreach (Pair2D id in Pair2D.GetList(poly.pointsList))                   // Remove GetList()
     {
         if (IntersectLine(id, circle, radius) == true)
         {
             return(true);
         }
     }
     return(false);
 }
示例#10
0
        /// <summary>
        /// Return a list which starts with first interesction with given line
        /// </summary>
        public static List <Vector2D> GetListStartingIntersectLine(List <Vector2D> pointsList, Pair2D line)
        {
            List <Vector2D> result = new List <Vector2D> ();
            bool            start  = false;

            Pair2D   id = pair2D;
            Vector2D r;

            id.B = pointsList.Last();

            for (int x = 0; x < pointsList.Count; x++)
            {
                id.A = pointsList[x];

                r = Math2D.GetPointLineIntersectLine(id, line);
                if (start == true)
                {
                    result.Add(id.B);
                }

                if (r != null)
                {
                    result.Add(r);
                    start = true;
                }

                id.B = id.A;
            }

            id.B = pointsList.Last();

            for (int x = 0; x < pointsList.Count; x++)
            {
                id.A = pointsList[x];

                r = Math2D.GetPointLineIntersectLine(id, line);
                if (start == true)
                {
                    result.Add(id.B);
                }

                if (r != null)
                {
                    result.Add(r);
                    start = false;
                }

                id.B = id.A;
            }
            return(result);
        }
示例#11
0
        public List <Vector2D> GetListLineIntersectPoly(Pair2D line)
        {
            List <Vector2D> intersections = Math2D.GetListLineIntersectPoly(line, this);

            foreach (Polygon2D poly in holesList)
            {
                foreach (Vector2D p in Math2D.GetListLineIntersectPoly(line, poly))
                {
                    intersections.Add(p);
                }
            }

            return(intersections);
        }
示例#12
0
        public List <Polygon2D> LineIntersectHoles(Pair2D pair)
        {
            List <Polygon2D> resultList = new List <Polygon2D>();

            foreach (Polygon2D poly in holesList)
            {
                if (Math2D.LineIntersectPoly(pair, poly) == true)
                {
                    resultList.Add(poly);
                }
            }

            return(resultList);
        }
示例#13
0
        public static bool PointInPoly(Vector2D point, Polygon2D poly)
        {
            if (poly.pointsList.Count < 3)
            {
                return(false);
            }

            int total = 0;
            int diff  = 0;

            Pair2D id = pair2D;

            id.A = poly.pointsList[poly.pointsList.Count - 1];

            for (int i = 0; i < poly.pointsList.Count; i++)
            {
                id.B = poly.pointsList[i];

                diff = (GetQuad(point, id.A) - GetQuad(point, id.B));

                switch (diff)
                {
                case -2:
                case 2:
                    if ((id.B.x - (((id.B.y - point.y) * (id.A.x - id.B.x)) / (id.A.y - id.B.y))) < point.x)
                    {
                        diff = -diff;
                    }

                    break;

                case 3:
                    diff = -1;
                    break;

                case -3:
                    diff = 1;
                    break;

                default:
                    break;
                }

                total += diff;

                id.A = id.B;
            }

            return(Mathf.Abs(total) == 4);
        }
示例#14
0
        public static bool LineIntersectSlice(Pair2D pairA, List <Vector2D> slice)
        {
            Pair2D pairB = new Pair2D(null, null);

            for (int i = 0; i < slice.Count - 1; i++)
            {
                pairB.A = slice[i];
                pairB.B = slice[i + 1];

                if (LineIntersectLine(pairA, pairB))
                {
                    return(true);
                }
            }

            return(false);
        }
示例#15
0
        public static List <Vector2D> GetListLineIntersectSlice(Pair2D pair, List <Vector2D> slice)
        {
            List <Vector2D> resultList = new List <Vector2D> ();

            Pair2D   id = new Pair2D(null, null);
            Vector2D result;

            for (int i = 0; i < slice.Count - 1; i++)
            {
                id.A = slice[i];
                id.B = slice[i + 1];

                result = GetPointLineIntersectLine(id, pair);
                if (result != null)
                {
                    resultList.Add(result);
                }
            }
            return(resultList);
        }
示例#16
0
            public static double PointToLine(Vector2D p, Pair2D pair)
            {
                double A = p.x - pair.A.x;
                double B = p.y - pair.A.y;
                double C = pair.B.x - pair.A.x;
                double D = pair.B.y - pair.A.y;

                double dot    = A * C + B * D;
                double len_sq = C * C + D * D;

                double param = -1;

                // in case of 0 length line
                if (len_sq != 0)
                {
                    param = dot / len_sq;
                }

                double xx, yy;

                if (param < 0)
                {
                    xx = pair.A.x;
                    yy = pair.A.y;
                }
                else if (param > 1)
                {
                    xx = pair.B.x;
                    yy = pair.B.y;
                }
                else
                {
                    xx = pair.A.x + param * C;
                    yy = pair.A.y + param * D;
                }

                double dx = p.x - xx;
                double dy = p.y - yy;

                return(System.Math.Sqrt(dx * dx + dy * dy));
            }
示例#17
0
        public static bool LineIntersectPoly(Pair2D line, Polygon2D poly)
        {
            Pair2D pair = line_intersect_poly;

            pair.A = new Vector2D(poly.pointsList.Last());
            pair.B = new Vector2D(Vector2.zero);

            for (int i = 0; i < poly.pointsList.Count; i++)
            {
                pair.B = poly.pointsList[i];

                if (LineIntersectLine(line, pair))
                {
                    return(true);
                }

                pair.A = pair.B;
            }

            return(false);
        }
示例#18
0
        public static Rect GetBounds(Pair2D pair)
        {
            double rMinX = 1e+10f;
            double rMinY = 1e+10f;
            double rMaxX = -1e+10f;
            double rMaxY = -1e+10f;

            Vector2D id = pair.A;

            rMinX = System.Math.Min(rMinX, id.x);
            rMinY = System.Math.Min(rMinY, id.y);
            rMaxX = System.Math.Max(rMaxX, id.x);
            rMaxY = System.Math.Max(rMaxY, id.y);

            id    = pair.B;
            rMinX = System.Math.Min(rMinX, id.x);
            rMinY = System.Math.Min(rMinY, id.y);
            rMaxX = System.Math.Max(rMaxX, id.x);
            rMaxY = System.Math.Max(rMaxY, id.y);

            return(new Rect((float)rMinX, (float)rMinY, (float)System.Math.Abs(rMinX - rMaxX), (float)System.Math.Abs(rMinY - rMaxY)));
        }
示例#19
0
        // Getting List is Slower
        public static List <Vector2D> GetListLineIntersectPoly(Pair2D line, Polygon2D poly)
        {
            List <Vector2D> result = new List <Vector2D>();

            Vector2D intersection;

            Pair2D pair = new Pair2D(new Vector2D(poly.pointsList.Last()), null);

            for (int i = 0; i < poly.pointsList.Count; i++)
            {
                pair.B = poly.pointsList[i];

                intersection = GetPointLineIntersectLine(line, pair);
                if (intersection != null)
                {
                    result.Add(intersection);
                }

                pair.A = pair.B;
            }
            return(result);
        }
示例#20
0
        // Might Break (Only for 2 collisions)
        /// <summary>
        /// Return a list which starts with first interesction with given slice
        /// </summary>
        public static List <Vector2D> GetListStartingIntersectSlice(List <Vector2D> pointsList, List <Vector2D> slice)
        {
            List <Vector2D> result = new List <Vector2D> ();
            bool            start  = false;

            List <Pair2D> pointsPairList = Pair2D.GetList(pointsList);

            foreach (Pair2D p in pointsPairList)
            {
                List <Vector2D> r = Math2D.GetListLineIntersectSlice(p, slice);
                if (start == true)
                {
                    result.Add(p.A);
                }

                if (r.Count > 0)
                {
                    result.Add(r.First());
                    start = true;
                }
            }

            foreach (Pair2D p in pointsPairList)
            {
                List <Vector2D> r = Math2D.GetListLineIntersectSlice(p, slice);
                if (start == true)
                {
                    result.Add(p.A);
                }

                if (r.Count > 0)
                {
                    result.Add(r.First());
                    start = false;
                }
            }
            return(result);
        }
示例#21
0
        // Lighting 2D

        public static List <Vector2D> GetConvexHull(List <Vector2D> points)
        {
            //If we have just 3 points, then they are the convex hull, so return those
            if (points.Count == 3)
            {
                //These might not be ccw, and they may also be colinear
                return(points);
            }

            //If fewer points, then we cant create a convex hull
            if (points.Count < 3)
            {
                return(null);
            }

            //The list with points on the convex hull
            List <Vector2D> convexHull = new List <Vector2D>();

            //Step 1. Find the vertex with the smallest x coordinate
            //If several have the same x coordinate, find the one with the smallest z
            Vector2D startVertex = points[0];

            Vector2 startPos = startVertex.ToVector2();

            for (int i = 1; i < points.Count; i++)
            {
                Vector2 testPos = points[i].ToVector2();

                //Because of precision issues, we use Mathf.Approximately to test if the x positions are the same
                if (testPos.x < startPos.x || (Mathf.Approximately(testPos.x, startPos.x) && testPos.y < startPos.y))
                {
                    startVertex = points[i];

                    startPos = startVertex.ToVector2();
                }
            }

            //This vertex is always on the convex hull
            convexHull.Add(startVertex);

            points.Remove(startVertex);

            //Step 2. Loop to generate the convex hull
            Vector2D currentPoint = convexHull[0];

            //Store colinear points here - better to create this list once than each loop
            List <Vector2D> colinearPoints = new List <Vector2D>();

            int counter = 0;

            while (true)
            {
                //After 2 iterations we have to add the start position again so we can terminate the algorithm
                //Cant use convexhull.count because of colinear points, so we need a counter
                if (counter == 2)
                {
                    points.Add(convexHull[0]);
                }

                //Pick next point randomly
                Vector2D nextPoint = points[Random.Range(0, points.Count)];

                //To 2d space so we can see if a point is to the left is the vector ab
                Vector2 a = currentPoint.ToVector2();

                Vector2 b = nextPoint.ToVector2();

                //Test if there's a point to the right of ab, if so then it's the new b
                for (int i = 0; i < points.Count; i++)
                {
                    //Dont test the point we picked randomly
                    if (points[i].Equals(nextPoint))
                    {
                        continue;
                    }

                    Vector2 c = points[i].ToVector2();

                    //Where is c in relation to a-b
                    // < 0 -> to the right
                    // = 0 -> on the line
                    // > 0 -> to the left
                    float relation = IsAPointLeftOfVectorOrOnTheLine(a, b, c);

                    //Colinear points
                    //Cant use exactly 0 because of floating point precision issues
                    //This accuracy is smallest possible, if smaller points will be missed if we are testing with a plane
                    float accuracy = 0.00001f;

                    if (relation < accuracy && relation > -accuracy)
                    {
                        colinearPoints.Add(points[i]);
                    }
                    //To the right = better point, so pick it as next point on the convex hull
                    else if (relation < 0f)
                    {
                        nextPoint = points[i];

                        b = nextPoint.ToVector2();

                        //Clear colinear points
                        colinearPoints.Clear();
                    }
                    //To the left = worse point so do nothing
                }



                //If we have colinear points
                if (colinearPoints.Count > 0)
                {
                    colinearPoints.Add(nextPoint);

                    //Sort this list, so we can add the colinear points in correct order
                    colinearPoints = colinearPoints.OrderBy(n => Vector3.SqrMagnitude(n.ToVector2() - currentPoint.ToVector2())).ToList();

                    convexHull.AddRange(colinearPoints);

                    currentPoint = colinearPoints[colinearPoints.Count - 1];

                    //Remove the points that are now on the convex hull
                    for (int i = 0; i < colinearPoints.Count; i++)
                    {
                        points.Remove(colinearPoints[i]);
                    }

                    colinearPoints.Clear();
                }
                else
                {
                    convexHull.Add(nextPoint);

                    points.Remove(nextPoint);

                    currentPoint = nextPoint;
                }

                //Have we found the first point on the hull? If so we have completed the hull
                if (currentPoint.Equals(convexHull[0]))
                {
                    //Then remove it because it is the same as the first point, and we want a convex hull with no duplicates
                    convexHull.RemoveAt(convexHull.Count - 1);

                    break;
                }

                counter += 1;
            }

            return(convexHull);
        }
示例#22
0
        public static Mesh Triangulate3D(Polygon2D polygon, float z, Vector2 UVScale, Vector2 UVOffset, float UVRotation, Triangulation triangulation)
        {
            polygon.Normalize();

            Mesh result = null;

            switch (triangulation)
            {
            case Triangulation.Advanced:
                List <Vector2> uvs           = new List <Vector2>();
                List <Vector3> sideVertices  = new List <Vector3>();
                List <int>     sideTriangles = new List <int>();

                Vector3 pointA = new Vector3(0, 0, 0);
                Vector3 pointB = new Vector3(0, 0, 0);
                Vector3 pointC = new Vector3(0, 0, z);
                Vector3 pointD = new Vector3(0, 0, z);

                Vector2 uv0 = new Vector2();
                Vector2 uv1 = new Vector2();

                float a, b;

                int vCount = 0;

                Pair2D pair = new Pair2D(new Vector2D(polygon.pointsList.Last()), null);
                foreach (Vector2D p in polygon.pointsList)
                {
                    pair.B = p;

                    pointA.x = (float)pair.A.x;
                    pointA.y = (float)pair.A.y;
                    pointB.x = (float)pair.B.x;
                    pointB.y = (float)pair.B.y;
                    pointC.x = (float)pair.B.x;
                    pointC.y = (float)pair.B.y;
                    pointD.x = (float)pair.A.x;
                    pointD.y = (float)pair.A.y;

                    sideVertices.Add(pointA);
                    sideVertices.Add(pointB);
                    sideVertices.Add(pointC);
                    sideVertices.Add(pointD);

                    a = ((float)pair.A.x + 25f) / 50 + UVOffset.x / 2;
                    b = ((float)pair.B.x + 25f) / 50 + UVOffset.x / 2;

                    uv0.x = a;
                    uv0.y = a;
                    uv1.x = b;
                    uv1.y = b;

                    uvs.Add(new Vector2(0, 0));
                    uvs.Add(new Vector2(0, 1));
                    uvs.Add(new Vector2(1, 1));
                    uvs.Add(new Vector2(1, 0));

                    sideTriangles.Add(vCount + 2);
                    sideTriangles.Add(vCount + 1);
                    sideTriangles.Add(vCount + 0);

                    sideTriangles.Add(vCount + 0);
                    sideTriangles.Add(vCount + 3);
                    sideTriangles.Add(vCount + 2);

                    vCount += 4;

                    pair.A = pair.B;
                }

                Mesh mainMesh = new Mesh();
                mainMesh.subMeshCount = 2;

                Mesh surfaceMesh = PerformTriangulationAdvanced(polygon, UVScale, UVOffset, UVRotation);

                ///// UVS  /////
                foreach (Vector2 p in surfaceMesh.uv)
                {
                    uvs.Add(p);
                }
                foreach (Vector2 p in surfaceMesh.uv)
                {
                    uvs.Add(p);
                }

                surfaceMesh.triangles = surfaceMesh.triangles.Reverse().ToArray();

                ///// VERTICES ////

                List <Vector3> vertices = new List <Vector3>();
                foreach (Vector3 v in sideVertices)
                {
                    vertices.Add(v);
                }

                foreach (Vector3 v in surfaceMesh.vertices)
                {
                    Vector3 nV = v;
                    nV.z = z;
                    vertices.Add(nV);
                }

                foreach (Vector3 v in surfaceMesh.vertices)
                {
                    vertices.Add(v);
                }

                mainMesh.SetVertices(vertices);

                ///// TRIANGLES /////

                List <int> triangles = new List <int>();
                foreach (int p in sideTriangles)
                {
                    triangles.Add(p);
                }
                mainMesh.SetTriangles(triangles, 0);

                triangles.Clear();
                int count = sideVertices.Count();
                foreach (int p in surfaceMesh.triangles)
                {
                    triangles.Add(p + count);
                }

                int   trisCount = surfaceMesh.triangles.Count() / 3;
                int[] tris      = surfaceMesh.triangles;

                for (var i = 0; i < trisCount; i++)
                {
                    var tmp = tris[i * 3];
                    tris[i * 3]     = tris[i * 3 + 1];
                    tris[i * 3 + 1] = tmp;
                }

                count += surfaceMesh.vertices.Count();
                foreach (int p in tris)
                {
                    triangles.Add(p + count);
                }

                mainMesh.SetTriangles(triangles, 1);

                ///// LEFTOVERS /////

                mainMesh.uv = uvs.ToArray();
                mainMesh.RecalculateNormals();
                mainMesh.RecalculateBounds();

                result = mainMesh;

                break;
            }

            return(result);
        }