예제 #1
0
        public static bool Intersect(P2D a1, P2D b1, P2D a2, P2D b2)
        {
            int o1 = Orientation(a1, b1, a2);
            int o2 = Orientation(a1, b1, b2);
            int o3 = Orientation(a2, b2, a1);
            int o4 = Orientation(a2, b2, b1);

            if (o1 != o2 && o3 != o4)
            {
                return(true);
            }
            if (o1 == 0 && a2.X <= Math.Max(a1.X, b1.X) && a2.X >= Math.Min(a1.X, b1.X) && a2.Y <= Math.Max(a1.Y, b1.Y) && a2.Y >= Math.Min(a1.Y, b1.Y))
            {
                return(true);
            }
            if (o2 == 0 && b2.X <= Math.Max(a1.X, b1.X) && b2.X >= Math.Min(a1.X, b1.X) && b2.Y <= Math.Max(a1.Y, b1.Y) && b2.Y >= Math.Min(a1.Y, b1.Y))
            {
                return(true);
            }
            if (o3 == 0 && a1.X <= Math.Max(a2.X, b2.X) && a1.X >= Math.Min(a2.X, b2.X) && a1.Y <= Math.Max(a2.Y, b2.Y) && a1.Y >= Math.Min(a2.Y, b2.Y))
            {
                return(true);
            }
            if (o4 == 0 && b1.X <= Math.Max(a2.X, b2.X) && b1.X >= Math.Min(a2.X, b2.X) && b1.Y <= Math.Max(a2.Y, b2.Y) && b1.Y >= Math.Min(a2.Y, b2.Y))
            {
                return(true);
            }
            return(false);
        }
예제 #2
0
        // ----- Convex Hull ---------------------------------------------------
        //
        // -- find a convex hull (envelop) of a set of points [points]
        //
        // IEnumerable<P2D> GetConvexHull(IEnumerable<P2D> points)
        // ---------------------------------------------------------------------
        public static IEnumerable <P2D> GetConvexHull(IEnumerable <P2D> points)
        {
            List <P2D> plist = new List <P2D>(points);

            plist.Sort((a, b) => a.X == b.X ? a.Y.CompareTo(b.Y) : (a.X > b.X ? 1 : -1));
            List <P2D> hull = new List <P2D>();
            int        L = 0, U = 0;

            for (int i = plist.Count - 1; i >= 0; i--)
            {
                P2D p = plist[i], p1;
                while (L >= 2 && ((p1 = hull[hull.Count - 1]) - hull[hull.Count - 2]) % (p - p1) >= 0)
                {
                    hull.RemoveAt(hull.Count - 1);
                    L--;
                }
                hull.Add(p);
                L++;
                while (U >= 2 && ((p1 = hull[0]) - hull[1]) % (p - p1) <= 0)
                {
                    hull.RemoveAt(0);
                    U--;
                }
                if (U != 0)
                {
                    hull.Insert(0, p);
                }
                U++;
            }
            hull.RemoveAt(hull.Count - 1);
            return(hull);
        }
예제 #3
0
파일: P2D.cs 프로젝트: abundrew/algorithms
 public override bool Equals(object o)
 {
     if (o is P2D)
     {
         P2D c = (P2D)o; return(this == c);
     }
     return(false);
 }
예제 #4
0
        public bool Inside(P2D p)
        {
            P2D    ap   = p - A;
            double apab = ap * AB;
            double apad = ap * AD;

            return(le(0, apab) && le(apab, AB * AB) && le(0, apad) && le(apad, AD * AD));
        }
예제 #5
0
 public        P2D[] ToPolygon(int n)
 {
     P2D[] pgon = new P2D[n];
     for (int i = 0; i < n; i++)
     {
         pgon[i] = new P2D(C.X + Math.Cos(Math.PI * 2 * i / n), C.Y + Math.Sin(Math.PI * 2 * i / n));
     }
     return(pgon);
 }
예제 #6
0
        private static bool IsInside(Edge edge, P2D test)
        {
            bool?isLeft = IsLeftOf(edge, test);

            if (isLeft == null)
            {
                return(true);
            }
            return(!isLeft.Value);
        }
예제 #7
0
        // ----- Line Segment Intersection -------------------------------------
        //
        // -- a relative orientation of points [p1], [p2], [p3]
        //
        // -- 0: colinear
        // -- 1: clock wise
        // -- 2: counterclock wise
        //
        // int Orientation(P2D p1, P2D p2, P2D p3)
        //
        // -- do line segments [a1, b1] and [a2, b2] intersect
        //
        // bool Intersect(P2D a1, P2D b1, P2D a2, P2D b2)
        // ---------------------------------------------------------------------
        static int Orientation(P2D p1, P2D p2, P2D p3)
        {
            double val = (p2.Y - p1.Y) * (p3.X - p2.X) - (p2.X - p1.X) * (p3.Y - p2.Y);

            if (val == 0)
            {
                return(0);
            }
            return((val > 0) ? 1 : 2);
        }
예제 #8
0
        // Returns the intersection of the two lines (line segments are passed in, but they are treated like infinite lines)
        private static P2D GetIntersect(P2D line1From, P2D line1To, P2D line2From, P2D line2To)
        {
            P2D    direction1 = line1To - line1From;
            P2D    direction2 = line2To - line2From;
            double dotPerp    = (direction1.X * direction2.Y) - (direction1.Y * direction2.X);

            // If it's 0, it means the lines are parallel so have infinite intersection points
            if (IsNearZero(dotPerp))
            {
                return(new P2D(double.MaxValue, double.MaxValue));
            }
            P2D    c = line2From - line1From;
            double t = (c.X * direction2.Y - c.Y * direction2.X) / dotPerp;

            //	Return the intersection point
            return(line1From + (direction1 * t));
        }
예제 #9
0
        // Tells if the test point lies on the left side of the edge line
        private static bool?IsLeftOf(Edge edge, P2D test)
        {
            P2D tmp1 = edge.To - edge.From;
            P2D tmp2 = test - edge.To;
            //dot product of perpendicular?
            double x = (tmp1.X * tmp2.Y) - (tmp1.Y * tmp2.X);

            if (x < 0)
            {
                return(false);
            }
            else
            if (x > 0)
            {
                return(true);
            }
            else
            {
                //Colinear points;
                return(null);
            }
        }
예제 #10
0
파일: P2D.cs 프로젝트: abundrew/algorithms
 public P2D Rot(P2D O, double theta)
 {
     return(new P2D(Math.Cos(theta) * (X - O.X) - Math.Sin(theta) * (Y - O.Y) + O.X, Math.Sin(theta) * (X - O.X) + Math.Cos(theta) * (Y - O.Y) + O.Y));
 }
예제 #11
0
        // This clips the subject polygon against the clip polygon (gets the intersection of the two polygons)
        public static P2D[] GetIntersectedPolygon(P2D[] subjectPoly, P2D[] clipPoly)
        {
            List <P2D> outputList = subjectPoly.ToList();
            //	Make sure it's clockwise
            bool?cw = IsClockwise(subjectPoly);

            if (cw == false)
            {
                outputList.Reverse();
            }
            //	Walk around the clip polygon clockwise
            foreach (Edge clipEdge in IterateEdgesClockwise(clipPoly))
            {
                // clone it
                List <P2D> inputList = outputList.ToList();
                outputList.Clear();
                if (inputList.Count == 0)
                {
                    // Sometimes when the polygons don't intersect, this list goes to zero.  Jump out to avoid an index out of range exception
                    break;
                }
                P2D S = inputList[inputList.Count - 1];
                foreach (P2D E in inputList)
                {
                    if (IsInside(clipEdge, E))
                    {
                        if (!IsInside(clipEdge, S))
                        {
                            P2D point = GetIntersect(S, E, clipEdge.From, clipEdge.To);
                            if (point.X == double.MaxValue)
                            {
                                // may be colinear, or may be a bug
                                throw new ApplicationException("Line segments don't intersect");
                            }
                            else
                            {
                                outputList.Add(point);
                            }
                        }
                        outputList.Add(E);
                    }
                    else if (IsInside(clipEdge, S))
                    {
                        P2D point = GetIntersect(S, E, clipEdge.From, clipEdge.To);
                        if (point.X == double.MaxValue)
                        {
                            // may be colinear, or may be a bug
                            throw new ApplicationException("Line segments don't intersect");
                        }
                        else
                        {
                            outputList.Add(point);
                        }
                    }
                    S = E;
                }
            }
            int ix = 0;

            while (ix < outputList.Count - 1)
            {
                if (outputList[ix].X == outputList[ix + 1].X && outputList[ix].Y == outputList[ix + 1].Y)
                {
                    outputList.RemoveAt(ix + 1);
                }
                else
                {
                    ix++;
                }
            }
            return(outputList.ToArray());
        }
예제 #12
0
 public Edge(P2D from, P2D to)
 {
     From = from;
     To   = to;
 }
예제 #13
0
 public bool Inside(P2D p)
 {
     return(le((p - C).Abs(), R));
 }
예제 #14
0
 public C2D(P2D c, double r)
 {
     C = c; R = r;
 }
예제 #15
0
 public C2D(double x, double y, double r)
 {
     C = new P2D(x, y); R = r;
 }
예제 #16
0
 public R2D(double xa, double ya, double xb, double yb, double xd, double yd)
 {
     A = new P2D(xa, ya); AB = new P2D(xb, yb) - A; AD = new P2D(xd, yd) - A;
 }
예제 #17
0
 public R2D(P2D a, P2D b, P2D d)
 {
     A = a; AB = b - a; AD = d - a;
 }