예제 #1
0
        public static Rect2D PolygonBoundary(IPolygonReader poly, ITransEngine2D mat)
        {
            if (poly == null)
            {
                throw (new ArgumentNullException("PolygonBoundary(poly)"));
            }
            Rect2D ret = Rect2D.Empty;
            Point  pt  = new Point();

            for (int i = 0; i < poly.Length; i++)
            {
                poly.GetRow(i, out double x, out double y);
                pt.X = x;
                pt.Y = y;
                if (mat != null)
                {
                    mat.TransTo(pt, ref pt);
                }
                if (ret.IsEmpty)
                {
                    ret = new Rect2D(pt, new Size(0, 0));
                }
                else
                {
                    ret.Union(pt);
                }
            }
            return(ret);
        }
예제 #2
0
        public PolygonOffset(IPolygonReader poly, bool isClosed = true, bool isOutline = true)
        {
            // testovani a vyhozeni vyjimek
            if (poly == null)
            {
                throw (new ArgumentNullException("PolygonOffset(poly,..)"));
            }
            if (poly.Length < (isClosed ? 3 : 2))
            {
                throw (new FormatException("PolygonOffset, small number of points"));
            }

            mySrc = new MyPoint[poly.Length];
            myRet = null;

            IsClosed  = isClosed;
            IsOutline = isOutline;

            // zjistim smer otaceni
            myIsReversed = Funcs2D.PolygonIsClockwise(poly) == IsOutline;
            for (int i = 0; i < poly.Length; i++)
            {
                poly.GetRow(i, out double x, out double y);
                mySrc[i].Pt.X   = x;
                mySrc[i].Pt.Y   = y;
                mySrc[i].Id     = i;
                mySrc[i].Offset = 0;
            }

            if (!IsClosed)
            {
                mySrc[poly.Length - 1].Id = 0;
            }
        }
예제 #3
0
        public static Point[,] PolygonParallelEdges(IPolygonReader poly, bool closed, Point pt1, Point pt2)
        {
            List <int> r = PolygonParallelEdges(poly, closed, pt2.Minus(pt1));

            Point[,] ret = new Point[r.Count, 2];
            int i = 0, k;

            foreach (int j in r)
            {
                poly.GetRow(j, out double x, out double y);
                ret[i, 0].X = x; ret[i, 0].Y = y;
                if (j == poly.Length - 1)
                {
                    k = 0;
                }
                else
                {
                    k = j + 1;
                }
                poly.GetRow(k, out x, out y);
                ret[i, 1].X = x; ret[i, 1].Y = y;
                i++;
            }
            return(ret);
        }
예제 #4
0
        public static Point PolygonCentre(IPolygonReader poly)
        {
            if (poly == null)
            {
                throw (new ArgumentNullException("PolygonCentre(poly)"));
            }
            Point ret = new Point();

            double[] v = new double[3] {
                0, 0, 0
            };
            double[,] p = poly.CopyTo();
            double dx, dy;
            int    b = p.GetLength(0) - 1;

            for (int e = 0; e < p.GetLength(0); e++)
            {
                dx = p[e, 0] - p[b, 0];
                dy = p[e, 1] - p[b, 1];

                v[2] += (p[b, 0] * dy - p[b, 1] * dx) / 2.0;
                v[0] += -dx * (3.0 * p[b, 1] * p[b, 1] + 3.0 * p[b, 1] * dy + dy * dy) / 6.0;
                v[1] += dy * (3.0 * p[b, 0] * p[b, 0] + 3.0 * p[b, 0] * dx + dx * dx) / 6.0;

                b = e;
            }
            ret.X = v[1] / v[2];
            ret.Y = v[0] / v[2];
            return(ret);
        }
예제 #5
0
 public SplitPoly(IPolygonReader poly, List <int> inx)
 {
     Poly   = poly;
     Inx    = inx;
     Area   = Funcs2D.PolygonArea(poly);
     IsClkw = Area <= 0;
     Area   = Math.Abs(Area);
 }
예제 #6
0
        public static IPolygonReader[] PolygonsInterconnect(IPolygonReader[] polygons, Point pt, Vector v)
        {
            IPolygonReader[] ret = null;
            List <Tuple <double, int, int> > cr = new List <Tuple <double, int, int> >();

            bool[] bcr  = new bool[polygons.Length];
            Point  ptt  = new Point();
            Vector norm = Funcs2D.VectorNormal(v);

            for (int i = 0; i < polygons.Length; i++)
            {
                for (int j = 0; j < polygons[i].Length; j++)
                {
                    polygons[i].GetRow(j, out double x, out double y);
                    ptt.X = x; ptt.Y = y;
                    if (TwoLine2D.CrossRel(pt, v, ptt, norm, out Point pr))
                    {
                        if (Funcs2D.IsEqual(pr.Y, 0.0, Funcs2D.Epson))
                        {
                            cr.Add(new Tuple <double, int, int>(pr.X, i, j));
                            bcr[i] = true;
                        }
                    }
                }
            }
            if (cr.Count < 2)
            {
                return(null);
            }
            int k = 1;

            foreach (var b in bcr)
            {
                if (!b)
                {
                    k++;
                }
            }
            ret = new IPolygonReader[k];
            k   = 0;
            for (int i = 0; i < bcr.Length; i++)
            {
                if (!bcr[i])
                {
                    ret[k++] = polygons[i];
                }
            }

            // trideni
            cr.Sort((a, b) => a.Item1.CompareTo(b.Item1));

            List <Point> rpt = new List <Point>();

            f_InterconnectJoin(0, cr, polygons, rpt);

            ret[k] = new BoxListPoint(Funcs2D.PolygonPure(new BoxListPoint(rpt), true));
            return(ret);
        }
예제 #7
0
 private IPolygonReader[] f_MakeResults()
 {
     IPolygonReader[] ret = new IPolygonReader[myRet.Count];
     for (int i = 0; i < ret.Length; i++)
     {
         ret[i] = new BoxListPoint(myRet[i]);
     }
     return(ret);
 }
예제 #8
0
        public static bool PolygonIsPure(IPolygonReader poly, bool closed, double limit)
        {
            if (poly == null)
            {
                throw (new ArgumentNullException("f_PolygonPure(poly,..)"));
            }
            List <int> ret = null;

            return(f_PolygonPure(new BoxArrayPoint(poly).Value, closed, limit, ref ret));
        }
예제 #9
0
        // vrati absolutni souradnice pruseciku primky s polygonem
        public static List <Point> PolygonLineCrossing(IPolygonReader poly, bool closed, Point pt, Vector v)
        {
            List <double> r   = PolygonLineCrossingRel(poly, closed, pt, v);
            List <Point>  ret = new List <Point>();

            foreach (double rel in r)
            {
                ret.Add(PointOnLine(pt, v, rel));
            }
            return(ret);
        }
예제 #10
0
        public static List <int> PolygonPureIndexes(IPolygonReader poly, bool closed, double limit)
        {
            if (poly == null)
            {
                throw (new ArgumentNullException("PolygonPureIndexes(poly,..)"));
            }
            List <int> retInx = new List <int>(poly.Length);

            f_PolygonPure(new BoxArrayPoint(poly).Value, closed, limit, ref retInx);
            return(retInx);
        }
예제 #11
0
 // rozdeli polygon v bodech krizeni na jedntlive dilci polygony
 // pokud neni selfCrossing vraci null
 public IPolygonReader[] GetSplitPolygons()
 {
     if (!f_MakeSplits())
     {
         return(null);
     }
     IPolygonReader[] ret = new IPolygonReader[mySplits.Count];
     for (int i = 0; i < ret.Length; i++)
     {
         ret[i] = new BoxListPoint(mySplits[i]);
     }
     return(ret);
 }
예제 #12
0
 public BoxListPoint(IPolygonReader pr)
 {
     if (pr == null)
     {
         throw (new ArgumentNullException("pr"));
     }
     myValue = new List <Point>();
     for (int i = 0; i < pr.Length; i++)
     {
         pr.GetRow(i, out double x, out double y);
         myValue.Add(new Point(x, y));
     }
 }
예제 #13
0
 // zaridi transformaci polygonu pri cteni
 public BoxTrans(IPolygonReader polygon, TransMethod transfuncs)
 {
     if (polygon == null)
     {
         throw (new ArgumentNullException("BoxTrans(polygon,..)"));
     }
     if (transfuncs == null)
     {
         throw (new ArgumentNullException("BoxTrans(..,transfuncs)"));
     }
     myPoly  = polygon;
     d_Trans = transfuncs;
 }
예제 #14
0
 public BoxArrayPoint(IPolygonReader pr)
 {
     if (pr == null)
     {
         throw (new ArgumentNullException("pr"));
     }
     myValue = new Point[pr.Length];
     for (int i = 0; i < pr.Length; i++)
     {
         pr.GetRow(i, out double x, out double y);
         myValue[i].X = x;
         myValue[i].Y = y;
     }
 }
예제 #15
0
        // vrati polygon ktery je vycisten od
        // po sobe jdoucich shodnych bodu
        // a bodu ktere lezi na jende primce
        public static List <Point> PolygonPure(IPolygonReader poly, bool closed, double limit)
        {
            if (poly == null)
            {
                throw (new ArgumentNullException("PolygonPure(poly,..)"));
            }
            Point[]    pt     = new BoxArrayPoint(poly).Value;
            List <int> retInx = new List <int>(poly.Length);

            f_PolygonPure(pt, closed, limit, ref retInx);
            List <Point> ret = new List <Point>(retInx.Count);

            foreach (int i in retInx)
            {
                ret.Add(pt[i]);
            }
            return(ret);
        }
예제 #16
0
        public PolygonSelfCrossing(IPolygonReader poly, bool isClosed = true)
        {
            IsClosed = isClosed;
            if (poly == null)
            {
                throw (new ArgumentNullException("PolygonSelfCrossing(poly)"));
            }
            myCrossId = null;
            mySplits  = null;

            myPoly = poly.CopyTo();
            int length = myPoly.GetLength(0);

            myData = new MyLine[length];
            for (int i = 0; i < myData.Length; i++)
            {
                myData[i] = new MyLine(i, i == (myData.Length - 1));
            }
            int begin = 0;

            if (!IsClosed)
            {
                length -= 2;
                begin   = 1;
            }
            for (int i = begin; i < length; i++)
            {
                for (int j = i + 2; j < length; j++)
                {
                    if (myData[i].TestCrossing(myData[j], myPoly))
                    {
                        if (myCrossId == null)
                        {
                            myCrossId = new List <int[]>();
                        }
                        myCrossId.Add(new int[] { i, j });
                    }
                }
            }
            for (int i = 0; i < myData.Length; i++)
            {
                myData[i].Sort();
            }
        }
예제 #17
0
        public static List <int> PolygonParallelEdges(IPolygonReader poly, bool closed, Vector v)
        {
            List <int> r = new List <int>();

            Point[] p = new BoxArrayPoint(poly).Value;
            for (int i = 0, j; i < p.Length; i++)
            {
                if (i == p.Length - 1)
                {
                    j = 0;
                }
                else
                {
                    j = i + 1;
                }
                if (Funcs2D.IsParallel(v, p[j].Minus(p[i])) != 0)
                {
                    r.Add(i);
                }
            }
            return(r);
        }
예제 #18
0
        // vrati relativni souradnice pruseciku primky s polygonem
        public static List <double> PolygonLineCrossingRel(IPolygonReader poly, bool closed, Point pt, Vector v)
        {
            if (poly == null)
            {
                throw (new ArgumentNullException("PolygonLineCrossing_rel(poly,..)"));
            }
            List <double> ret = new List <double>();
            int           b, e;

            double[,] p = poly.CopyTo();
            if (closed)
            {
                e = poly.Length - 1;
                b = 0;
            }
            else
            {
                e = 0;
                b = 1;
            }
            Point p1, p2;

            for (int i = b; i < poly.Length; i++)
            {
                b  = e; e = i;
                p1 = new Point(p[b, 0], p[b, 1]);
                p2 = new Point(p[e, 0], p[e, 1]);
                if (TwoLine2D.CrossRel(pt, v, p1, p2.Minus(p1), out Point pr))
                {
                    if (TwoLine2D.TestRelOnLine(TwoLine2D.CrossStatus.And, pr.Y))
                    {
                        ret.Add(pr.X);
                    }
                }
            }
            ret.Sort();
            return(ret);
        }
예제 #19
0
        // polygons

        private static double f_PolygonArea(IPolygonReader poly)
        {
            if (poly == null)
            {
                throw (new ArgumentNullException("f_PolygonArea(poly)"));
            }
            if (poly.Length < 3)
            {
                return(0);
            }
            double dx, dy, a = 0;

            double[,] p = poly.CopyTo();
            int b = p.GetLength(0) - 1;

            for (int e = 0; e < p.GetLength(0); e++)
            {
                dx = p[e, 0] - p[b, 0];
                dy = p[e, 1] - p[b, 1];
                a += (p[b, 0] * dy - p[b, 1] * dx) / 2.0;
                b  = e;
            }
            return(a);
        }
예제 #20
0
 public static bool PolygonIsClockwise(IPolygonReader poly)
 {
     return(f_PolygonArea(poly) <= 0.0);
 }
예제 #21
0
 public BoxTransFrom(IPolygonReader polygon, ITransEngine2D transformation) :
     base(polygon, new TransMethod(transformation.TransFrom))
 {
 }
예제 #22
0
 public static bool PolygonIsPure(IPolygonReader poly, bool closed)
 {
     return(PolygonIsPure(poly, closed, Epson));
 }
예제 #23
0
 public static double PolygonArea(IPolygonReader poly)
 {
     return(f_PolygonArea(poly));
 }
예제 #24
0
 public static List <Point> PolygonPure(IPolygonReader poly, bool closed)
 {
     return(PolygonPure(poly, closed, Epson));
 }