Esempio n. 1
0
        public ConvexPolygon(Point[] points)
        {
            if (points.Length < 3)
            {
                throw new ArgumentException("Too few points (" + points.Length + "). There should be at least 3 points to make a polygon");
            }
            // Checking convexity
            double sign_value = Vector.CrossProduct(
                (Vector)points[0] - (Vector)points[points.Length - 1],
                (Vector)points[1] - (Vector)points[points.Length - 1]);

            double sign_value2 = Vector.CrossProduct(
                (Vector)points[points.Length - 1] - (Vector)points[points.Length - 2],
                (Vector)points[0] - (Vector)points[points.Length - 2]);
            if (Math.Sign(sign_value) * Math.Sign(sign_value2) < 0)
                throw new PolygonNotConvexException("Polygon isn't convex");

            for (int i = 0; i < points.Length - 2; i++)
            {
                double sign_value_i = Vector.CrossProduct(
                    (Vector)points[i + 1] - (Vector)points[i],
                    (Vector)points[i + 2] - (Vector)points[i]);
                if (Math.Sign(sign_value) * Math.Sign(sign_value_i) < 0)
                    throw new PolygonNotConvexException("Polygon isn't convex");
            }

            // Sorting points clockwise
            if (sign_value > 0)
                mVertex = points;
            else
            {
                mVertex = new Point[points.Length];
                for (int i = 0; i < points.Length; i++)
                {
                    mVertex[i] = points[points.Length - 1 - i];
                }
            }

            // Constructing sides
            mSides = new Segment[mVertex.Length];
            mSides[mVertex.Length - 1] = new Segment(mVertex[mVertex.Length - 1], mVertex[0]);
            for (int i = 0; i < mVertex.Length - 1; i++)
                mSides[i] = new Segment(mVertex[i], mVertex[i + 1]);

            // Calculating bounding box
            mXMin = mVertex[0].X; mXMax = mVertex[0].X;
            mYMin = mVertex[0].Y; mYMax = mVertex[0].Y;

            for (int i = 1; i < mVertex.Length; i++)
            {
                if (mXMin > mVertex[i].X) mXMin = mVertex[i].X;
                if (mYMin > mVertex[i].Y) mYMin = mVertex[i].Y;

                if (mXMax < mVertex[i].X) mXMax = mVertex[i].X;
                if (mYMax < mVertex[i].Y) mYMax = mVertex[i].Y;
            }
        }
Esempio n. 2
0
        public static Point GetCrossing(Segment s1, Segment s2)
        {
            // Algorithmic equality
            if (s1 == s2)
                throw new SelfCrossingException("Trying to find selfcrossing");

            // TODO: Add rough estimation here (i.e. rectangle estimation)

            if (s1._Crossings.ContainsKey(s2))
                return s1._Crossings[s2];
            // TODO: Check integrity

            // Parallelism and zero-length
            Vector AB1 = new Vector(s1._B.X - s1._A.X, s1._B.Y - s1._A.Y);
            Vector AB2 = new Vector(s2._B.X - s2._A.X, s2._B.Y - s2._A.Y);
            double D = Vector.CrossProduct(AB2, AB1);
            if (Math.Abs(D) == 0) return null;

            if (s1._A == s2._A || s1._A == s2._B) return s1._A;
            if (s1._B == s2._A || s1._B == s2._B) return s1._B;

            // Calculating crossing between lines
            double m = Vector.CrossProduct((Vector)s1._A, AB1);
            double n = Vector.CrossProduct((Vector)s2._A, AB2);

            double x = (m * AB2.X - n * AB1.X) / D;
            double y = (m * AB2.Y - n * AB1.Y) / D;

            // Checking if an endpoint of one segment is contained by other
            if (s1._A.X == x && s1._A.Y == y) return s1._A;
            if (s1._B.X == x && s1._B.Y == y) return s1._B;
            if (s2._A.X == x && s2._A.Y == y) return s2._A;
            if (s2._B.X == x && s2._B.Y == y) return s2._B;

            // Checking if the crossing point is in both segments
            Vector AC1 = new Vector(x - s1._A.X, y - s1._A.Y);
            Vector BC1 = new Vector(x - s1._B.X, y - s1._B.Y);
            if ((AB1 * AC1) * (-AB1 * BC1) < 0) return null;

            Vector AC2 = new Vector(x - s2._A.X, y - s2._A.Y);
            Vector BC2 = new Vector(x - s2._B.X, y - s2._B.Y);
            if ((AB2 * AC2) * (-AB2 * BC2) < 0) return null;

            // Adding the point to crossing dictionaries
            Point crs = new Point(x, y);
            s1._Crossings.Add(s2, crs);
            s2._Crossings.Add(s1, crs);

            return crs;
        }
Esempio n. 3
0
 public int IndexOfSide(Segment side)
 {
     for (int i = 0; i < mSides.Length; i++)
         if (mSides[i] == side) return i;
     return -1;
 }
Esempio n. 4
0
 public bool HasCrossing(Point crossing, out Segment mySide, out Segment other)
 {
     mySide = null; other = null;
     for (int i = 0; i < mSides.Length; i++)
     {
         Segment res = mSides[i].HasCrossing(crossing);
         if (res != null)
         {
             mySide = mSides[i];
             other = res;
             return true;
         }
     }
     return false;
 }