Пример #1
0
        public void DoCircleClipping(Vector2 pos, float radius)
        {
            List<VertexPosition[]> shape_old = shape;
            bool isCleared = false;
            int sc = 0;
            for (sc = 0; sc < shape_old.Count; sc++)
            {
                ClippingPolygons subj = new ClippingPolygons(1);
                subj.Add(new ClippingPolygon(shape_old[sc].Length));
                foreach (VertexPosition point in shape_old[sc])
                {
                    subj[0].Add(new IntPoint((int)((point.Position.X) * accuracy), (int)((point.Position.Y) * accuracy)));
                }

                ClippingPolygons clip = new ClippingPolygons(1);
                clip.Add(new ClippingPolygon());
                for (int alpha = 0; alpha < 360; alpha += 10)
                {
                    clip[0].Add(new IntPoint((int)(((Math.Sin((alpha) * Math.PI / 180.0) * radius) + pos.X) * accuracy), (int)(((Math.Cos((alpha) * Math.PI / 180.0) * radius) + pos.Y) * accuracy)));
                    //log.Log(pos.ToString());
                }

                ClippingPolygons solution = new ClippingPolygons();

                Clipper c = new Clipper();
                c.AddPolygons(subj, PolyType.ptSubject);
                c.AddPolygons(clip, PolyType.ptClip);

                if (c.Execute(ClipType.ctDifference, solution, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd))
                {
                    if (!isCleared)
                    {
                        shape = new List<VertexPosition[]>();
                        drawer.Clear();
                        isCleared = true;
                    }

                    for (int f = 0; f < solution.Count; f++)
                    {

                        shape.Add(new VertexPosition[solution[f].Count]);
                        drawer.Add(new ChunkDrawer(ref log));

                        for (int i = 0; i < solution[f].Count; i++)
                        {

                            shape[shape.Count-1][i] = new VertexPosition(solution[f][i].X / accuracy, solution[f][i].Y / accuracy, 0);
                        }
                        drawer[shape.Count-1].BufferVertices(shape[shape.Count - 1]);
                    }

                }
            }
        }
Пример #2
0
        public void DoCircleClipping(Vector2 pos, float radius)
        {
            ClippingPolygons subj = new ClippingPolygons(1);
            subj.Add(new ClippingPolygon(shape.Length));
            foreach(VertexPosition point in shape){
                subj[0].Add(new IntPoint((int)((point.Position.X) * accuracy), (int)((point.Position.Y) * accuracy)));
            }

            ClippingPolygons clip = new ClippingPolygons(1);
            clip.Add(new ClippingPolygon());
            for (int alpha = 0; alpha < 360; alpha += 10)
            {
                clip[0].Add(new IntPoint((int)(((Math.Sin((alpha) * Math.PI / 180.0) * radius)+pos.X) * accuracy), (int)(((Math.Cos((alpha) * Math.PI / 180.0) * radius)+pos.Y) * accuracy)));
                //log.Log(pos.ToString());
            }

            ClippingPolygons solution = new ClippingPolygons();

            Clipper c = new Clipper();
            c.AddPolygons(subj, PolyType.ptSubject);
            c.AddPolygons(clip, PolyType.ptClip);

            if (c.Execute(ClipType.ctDifference, solution, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd))
            {

                for (int f = 0; f < solution.Count; f++)
                {
                    if (f == 0)
                    {
                        shape = new VertexPosition[solution[f].Count];
                        for (int i = 0; i < solution[f].Count; i++)
                        {

                            shape[i] = new VertexPosition(solution[f][i].X / accuracy, solution[f][i].Y / accuracy, 0);
                        }
                    }

                }
            }
            BufferVertices(ref shape);
        }
Пример #3
0
        //---------------------------------------------------------------------------
        private void DrawBitmap(bool justClip = false)
        {
            if (!justClip)
            {
                if (rbTest2.Checked)
                    GenerateAustPlusRandomEllipses((int)nudCount.Value);
                else
                    GenerateRandomPolygon((int)nudCount.Value);
            }

            Cursor.Current = Cursors.WaitCursor;
            Graphics newgraphic;
            newgraphic = Graphics.FromImage(mybitmap);
            newgraphic.SmoothingMode = SmoothingMode.AntiAlias;
            newgraphic.Clear(Color.White);

            GraphicsPath path = new GraphicsPath();
            if (rbNonZero.Checked) path.FillMode = FillMode.Winding;

            //draw subjects ...
            foreach (Polygon pg in subjects)
            {
                PointF[] pts = PolygonToPointFArray(pg, scale);
                path.AddPolygon(pts);
                pts = null;
            }
            Pen myPen = new Pen(Color.FromArgb(196, 0xC3, 0xC9, 0xCF), (float)0.6);
            SolidBrush myBrush = new SolidBrush(Color.FromArgb(127, 0xDD, 0xDD, 0xF0));
            newgraphic.FillPath(myBrush, path);
            newgraphic.DrawPath(myPen, path);
            path.Reset();

            //draw clips ...
            if (rbNonZero.Checked) path.FillMode = FillMode.Winding;
            foreach (Polygon pg in clips)
            {
                PointF[] pts = PolygonToPointFArray(pg, scale);
                path.AddPolygon(pts);
                pts = null;
            }
            myPen.Color = Color.FromArgb(196, 0xF9, 0xBE, 0xA6);
            myBrush.Color = Color.FromArgb(127, 0xFF, 0xE0, 0xE0);
            newgraphic.FillPath(myBrush, path);
            newgraphic.DrawPath(myPen, path);

            //do the clipping ...
            if ((clips.Count > 0 || subjects.Count > 0) && !rbNone.Checked)
            {
                Polygons solution2 = new Polygons();
                Clipper c = new Clipper();
                c.AddPolygons(subjects, PolyType.ptSubject);
                c.AddPolygons(clips, PolyType.ptClip);
                exSolution.Clear();
                solution.Clear();
                bool succeeded = c.Execute(GetClipType(), solution, GetPolyFillType(), GetPolyFillType());
                if (succeeded)
                {
                    myBrush.Color = Color.Black;
                    path.Reset();

                    //It really shouldn't matter what FillMode is used for solution
                    //polygons because none of the solution polygons overlap.
                    //However, FillMode.Winding will show any orientation errors where
                    //holes will be stroked (outlined) correctly but filled incorrectly  ...
                    path.FillMode = FillMode.Winding;

                    //or for something fancy ...
                    if (nudOffset.Value != 0)
                        solution2 = Clipper.OffsetPolygons(solution, (double)nudOffset.Value * scale, JoinType.jtMiter);
                    else
                        solution2 = new Polygons(solution);
                    foreach (Polygon pg in solution2)
                    {
                        PointF[] pts = PolygonToPointFArray(pg, scale);
                        if (pts.Count() > 2)
                            path.AddPolygon(pts);
                        pts = null;
                    }
                    myBrush.Color = Color.FromArgb(127, 0x66, 0xEF, 0x7F);
                    myPen.Color = Color.FromArgb(255, 0, 0x33, 0);
                    myPen.Width = 1.0f;
                    newgraphic.FillPath(myBrush, path);
                    newgraphic.DrawPath(myPen, path);

                    //now do some fancy testing ...
                    Font f = new Font("Arial", 8);
                    SolidBrush b = new SolidBrush(Color.Navy);
                    double subj_area = 0, clip_area = 0, int_area = 0, union_area = 0;
                    c.Clear();
                    c.AddPolygons(subjects, PolyType.ptSubject);
                    c.Execute(ClipType.ctUnion, solution2, GetPolyFillType(), GetPolyFillType());
                    foreach (Polygon pg in solution2) subj_area += Clipper.Area(pg);
                    c.Clear();
                    c.AddPolygons(clips, PolyType.ptClip);
                    c.Execute(ClipType.ctUnion, solution2, GetPolyFillType(), GetPolyFillType());
                    foreach (Polygon pg in solution2) clip_area += Clipper.Area(pg);
                    c.AddPolygons(subjects, PolyType.ptSubject);
                    c.Execute(ClipType.ctIntersection, solution2, GetPolyFillType(), GetPolyFillType());
                    foreach (Polygon pg in solution2) int_area += Clipper.Area(pg);
                    c.Execute(ClipType.ctUnion, solution2, GetPolyFillType(), GetPolyFillType());
                    foreach (Polygon pg in solution2) union_area += Clipper.Area(pg);

                    StringFormat lftStringFormat = new StringFormat();
                    lftStringFormat.Alignment = StringAlignment.Near;
                    lftStringFormat.LineAlignment = StringAlignment.Near;
                    StringFormat rtStringFormat = new StringFormat();
                    rtStringFormat.Alignment = StringAlignment.Far;
                    rtStringFormat.LineAlignment = StringAlignment.Near;
                    Rectangle rec = new Rectangle(pictureBox1.ClientSize.Width - 108,
                        pictureBox1.ClientSize.Height - 116, 104, 106);
                    newgraphic.FillRectangle(new SolidBrush(Color.FromArgb(196, Color.WhiteSmoke)), rec);
                    newgraphic.DrawRectangle(myPen, rec);
                    rec.Inflate(new Size(-2, 0));
                    newgraphic.DrawString("Areas", f, b, rec, rtStringFormat);
                    rec.Offset(new Point(0, 14));
                    newgraphic.DrawString("subj: ", f, b, rec, lftStringFormat);
                    newgraphic.DrawString((subj_area / 100000).ToString("0,0"), f, b, rec, rtStringFormat);
                    rec.Offset(new Point(0, 12));
                    newgraphic.DrawString("clip: ", f, b, rec, lftStringFormat);
                    newgraphic.DrawString((clip_area / 100000).ToString("0,0"), f, b, rec, rtStringFormat);
                    rec.Offset(new Point(0, 12));
                    newgraphic.DrawString("intersect: ", f, b, rec, lftStringFormat);
                    newgraphic.DrawString((int_area / 100000).ToString("0,0"), f, b, rec, rtStringFormat);
                    rec.Offset(new Point(0, 12));
                    newgraphic.DrawString("---------", f, b, rec, rtStringFormat);
                    rec.Offset(new Point(0, 10));
                    newgraphic.DrawString("s + c - i: ", f, b, rec, lftStringFormat);
                    newgraphic.DrawString(((subj_area + clip_area - int_area) / 100000).ToString("0,0"), f, b, rec, rtStringFormat);
                    rec.Offset(new Point(0, 10));
                    newgraphic.DrawString("---------", f, b, rec, rtStringFormat);
                    rec.Offset(new Point(0, 10));
                    newgraphic.DrawString("union: ", f, b, rec, lftStringFormat);
                    newgraphic.DrawString((union_area / 100000).ToString("0,0"), f, b, rec, rtStringFormat);
                    rec.Offset(new Point(0, 10));
                    newgraphic.DrawString("---------", f, b, rec, rtStringFormat);
                } //end if succeeded
            } //end if something to clip

            pictureBox1.Image = mybitmap;
            newgraphic.Dispose();
            Cursor.Current = Cursors.Default;
        }
 //------------------------------------------------------------------------------
 public static Polygons SimplifyPolygons(Polygons polys)
 {
     Polygons result = new Polygons();
     Clipper c = new Clipper();
     c.AddPolygons(polys, PolyType.ptSubject);
     c.Execute(ClipType.ctUnion, result);
     return result;
 }
            public PolyOffsetBuilder(Polygons pts, Polygons solution, double delta, JoinType jointype, double MiterLimit = 2)
            {
                //precondtion: solution != pts

                if (delta == 0)
                {
                    solution = pts;
                    return;
                }

                this.pts = pts;
                this.delta = delta;
                if (MiterLimit <= 1) MiterLimit = 1;
                double RMin = 2/(MiterLimit*MiterLimit);

                normals = new List<DoublePoint>();

                double deltaSq = delta*delta;
                solution.Clear();
                solution.Capacity = pts.Count;
                for (m_i = 0; m_i < pts.Count; m_i++)
                {
                    int len = pts[m_i].Count;
                    if (len > 1 && pts[m_i][0].X == pts[m_i][len - 1].X &&
                        pts[m_i][0].Y == pts[m_i][len - 1].Y) len--;

                    if (len == 0 || (len < 3 && delta <= 0))
                        continue;
                    else if (len == 1)
                    {
                        Polygon arc;
                        arc = BuildArc(pts[m_i][len - 1], 0, 2 * Math.PI, delta);
                        solution.Add(arc);
                        continue;
                    }

                    //build normals ...
                    normals.Clear();
                    normals.Capacity = len;
                    for (int j = 0; j < len -1; ++j)
                        normals.Add(GetUnitNormal(pts[m_i][j], pts[m_i][j+1]));
                    normals.Add(GetUnitNormal(pts[m_i][len - 1], pts[m_i][0]));

                    currentPoly = new Polygon();
                    m_k = len - 1;
                    for (m_j = 0; m_j < len; ++m_j)
                    {
                        switch (jointype)
                        {
                            case JoinType.jtMiter:
                            {
                                m_R = 1 + (normals[m_j].X*normals[m_k].X +
                                    normals[m_j].Y*normals[m_k].Y);
                                if (m_R >= RMin) DoMiter(); else DoSquare(MiterLimit);
                                break;
                            }
                            case JoinType.jtRound:
                                DoRound();
                                break;
                            case JoinType.jtSquare:
                                DoSquare(1);
                                break;
                        }
                        m_k = m_j;
                    }
                    solution.Add(currentPoly);
                }

                //finally, clean up untidy corners ...
                Clipper clpr = new Clipper();
                clpr.AddPolygons(solution, PolyType.ptSubject);
                if (delta > 0)
                {
                    clpr.Execute(ClipType.ctUnion, solution, PolyFillType.pftPositive, PolyFillType.pftPositive);
                }
                else
                {
                    IntRect r = clpr.GetBounds();
                    Polygon outer = new Polygon(4);

                    outer.Add(new IntPoint(r.left - 10, r.bottom + 10));
                    outer.Add(new IntPoint(r.right + 10, r.bottom + 10));
                    outer.Add(new IntPoint(r.right + 10, r.top - 10));
                    outer.Add(new IntPoint(r.left - 10, r.top - 10));

                    clpr.AddPolygon(outer, PolyType.ptSubject);
                    clpr.Execute(ClipType.ctUnion, solution, PolyFillType.pftNegative, PolyFillType.pftNegative);
                    if (solution.Count > 0)
                    {
                        solution.RemoveAt(0);
                        for (int i = 0; i < solution.Count; i++)
                            solution[i].Reverse();
                    }
                }
            }
        static public PolyTree FindDistictObjectBounds(ImageBuffer image)
        {
            MarchingSquaresByte marchingSquaresData = new MarchingSquaresByte(image, 5, 0);
            marchingSquaresData.CreateLineSegments();
            Polygons lineLoops = marchingSquaresData.CreateLineLoops(1);

            if (lineLoops.Count == 1)
            {
                return null;
            }

            // create a bounding polygon to clip against
            IntPoint min = new IntPoint(long.MaxValue, long.MaxValue);
            IntPoint max = new IntPoint(long.MinValue, long.MinValue);
            foreach (Polygon polygon in lineLoops)
            {
                foreach (IntPoint point in polygon)
                {
                    min.X = Math.Min(point.X - 10, min.X);
                    min.Y = Math.Min(point.Y - 10, min.Y);
                    max.X = Math.Max(point.X + 10, max.X);
                    max.Y = Math.Max(point.Y + 10, max.Y);
                }
            }

            Polygon boundingPoly = new Polygon();
            boundingPoly.Add(min);
            boundingPoly.Add(new IntPoint(min.X, max.Y));
            boundingPoly.Add(max);
            boundingPoly.Add(new IntPoint(max.X, min.Y));

            // now clip the polygons to get the inside and outside polys
            Clipper clipper = new Clipper();
            clipper.AddPolygons(lineLoops, PolyType.ptSubject);
            clipper.AddPolygon(boundingPoly, PolyType.ptClip);

            PolyTree polyTreeForPlate = new PolyTree();
            clipper.Execute(ClipType.ctIntersection, polyTreeForPlate);

            return polyTreeForPlate;
        }
Пример #7
0
        void calculateRegionPath(ClipType clipType)
        {
            Clipper c = new Clipper();

            var subjects = solution;
            //subjects.Add (solution);

            var clips = new Paths ();

            foreach (var path in regionList [regionList.Count - 1].regionPath)
                clips.Add (path);

            c.AddPolygons(subjects, PolyType.ptSubject);
            c.AddPolygons(clips, PolyType.ptClip);

            solution.Clear();

            bool succeeded = c.Execute(clipType, solution, SUBJ_FILL_TYPE, CLIP_FILL_TYPE);

            if (succeeded)
            {
                PathsToInternalPath (solution);

                // Not sure what this is returning
            //				var bounds = c.GetBounds ();
            //				regionBounds.X = bounds.left / scale;
            //				regionBounds.Y = bounds.top / scale;
            //				regionBounds.Width = (bounds.right - bounds.left) / scale;
            //				regionBounds.Height = (bounds.bottom - bounds.top) / scale;

                if (regionPath.IsEmpty)
                    regionBounds = RectangleF.Empty;
                else
                    regionBounds = regionPath.BoundingBox;

            }
        }
Пример #8
0
        //------------------------------------------------------------------------------

        public static Polygons SimplifyPolygons(Polygons polys,
            PolyFillType fillType = PolyFillType.pftEvenOdd)
        {
            Polygons result = new Polygons();
            Clipper c = new Clipper();
            c.AddPolygons(polys, PolyType.ptSubject);
            c.Execute(ClipType.ctUnion, result, fillType, fillType);
            return result;
        }
Пример #9
0
            public PolyOffsetBuilder(Polygons pts, Polygons solution, double delta, 
                JoinType jointype, double MiterLimit = 2, bool AutoFix = true)
            {
                //precondtion: solution != pts

                if (delta == 0)
                {
                    solution = pts;
                    return;
                }

                this.pts = pts;
                this.delta = delta;

                //AutoFix - fixes polygon orientation if necessary and removes 
                //duplicate vertices. Can be set false when you're sure that polygon
                //orientation is correct and that there are no duplicate vertices.
                if (AutoFix)
                {
                    int Len = pts.Count, botI = 0;
                    while (botI < Len && pts[botI].Count == 0) botI++;
                    if (botI == Len) return;

                    //botPt: used to find the lowermost (in inverted Y-axis) & leftmost point
                    //This point (on pts[botI]) must be on an outer polygon ring and if 
                    //its orientation is false (counterclockwise) then assume all polygons 
                    //need reversing ...
                    IntPoint botPt = pts[botI][0];
                    for (int i = botI; i < Len; ++i)
                    {
                        if (pts[i].Count == 0) continue;
                        if (UpdateBotPt(pts[i][0], ref botPt)) botI = i;
                        for (int j = pts[i].Count -1; j > 0; j--)
                        {
                            if (PointsEqual(pts[i][j], pts[i][j -1]))
                                pts[i].RemoveAt(j);
                            else if (UpdateBotPt(pts[i][j], ref botPt))
                                botI = i;
                        }
                    }
                    if (!Orientation(pts[botI]))
                        ReversePolygons(pts);
                }

                if (MiterLimit <= 1) MiterLimit = 1;
                double RMin = 2.0 / (MiterLimit*MiterLimit);

                normals = new List<DoublePoint>();

                double deltaSq = delta*delta;
                solution.Clear();
                solution.Capacity = pts.Count;
                for (m_i = 0; m_i < pts.Count; m_i++)
                {
                    int len = pts[m_i].Count;
                    if (len > 1 && pts[m_i][0].X == pts[m_i][len - 1].X &&
                        pts[m_i][0].Y == pts[m_i][len - 1].Y) len--;

                    if (len == 0 || (len < 3 && delta <= 0)) 
                        continue;
                    else if (len == 1)
                    {
                        Polygon arc;
                        arc = BuildArc(pts[m_i][len - 1], 0, 2 * Math.PI, delta);
                        solution.Add(arc);
                        continue;
                    }

                    //build normals ...
                    normals.Clear();
                    normals.Capacity = len;
                    for (int j = 0; j < len -1; ++j)
                        normals.Add(GetUnitNormal(pts[m_i][j], pts[m_i][j+1]));
                    normals.Add(GetUnitNormal(pts[m_i][len - 1], pts[m_i][0]));

                    currentPoly = new Polygon();
                    m_k = len - 1;
                    for (m_j = 0; m_j < len; ++m_j)
                    {
                        switch (jointype)
                        {
                            case JoinType.jtMiter:
                            {
                                m_R = 1 + (normals[m_j].X*normals[m_k].X + 
                                    normals[m_j].Y*normals[m_k].Y);
                                if (m_R >= RMin) DoMiter(); else DoSquare(MiterLimit);
                                break;
                            }
                            case JoinType.jtRound: 
                                DoRound();
                                break;
                            case JoinType.jtSquare:
                                DoSquare(1);
                                break;
                        }
                        m_k = m_j;
                    }
                    solution.Add(currentPoly);
                }

                //finally, clean up untidy corners ...
                Clipper clpr = new Clipper();
                clpr.AddPolygons(solution, PolyType.ptSubject);
                if (delta > 0)
                {
                    clpr.Execute(ClipType.ctUnion, solution, PolyFillType.pftPositive, PolyFillType.pftPositive);
                }
                else
                {
                    IntRect r = clpr.GetBounds();
                    Polygon outer = new Polygon(4);

                    outer.Add(new IntPoint(r.left - 10, r.bottom + 10));
                    outer.Add(new IntPoint(r.right + 10, r.bottom + 10));
                    outer.Add(new IntPoint(r.right + 10, r.top - 10));
                    outer.Add(new IntPoint(r.left - 10, r.top - 10));

                    clpr.AddPolygon(outer, PolyType.ptSubject);
                    clpr.Execute(ClipType.ctUnion, solution, PolyFillType.pftNegative, PolyFillType.pftNegative);
                    if (solution.Count > 0)
                    {
                        solution.RemoveAt(0);
                        for (int i = 0; i < solution.Count; i++)
                            solution[i].Reverse();
                    }
                }
            }
Пример #10
0
            //------------------------------------------------------------------------------
            public PolyOffsetBuilder(Polygons pts, Polygons solution, bool isPolygon, double delta,
                JoinType jointype, EndType endtype, double limit = 0)
            {
                //precondition: solution != pts

                if (delta == 0) { solution = pts; return; }
                m_p = pts;
                m_delta = delta;
                m_rmin = 0.5;

                if (jointype == JoinType.jtMiter)
                {
                    if (limit > 2) m_rmin = 2.0 / (limit * limit);
                    limit = 0.25; //just in case endtype == etRound
                }
                else
                {
                    if (limit <= 0) limit = 0.25;
                    else if (limit > Math.Abs(delta)) limit = Math.Abs(delta);
                }

                double deltaSq = delta * delta;
                solution.Clear();
                solution.Capacity = pts.Count;
                for (m_i = 0; m_i < pts.Count; m_i++)
                {
                    int len = pts[m_i].Count;
                    if (len == 0 || (len < 3 && delta <= 0))
                        continue;
                    else if (len == 1)
                    {
                        currentPoly = new Polygon();
                        currentPoly = BuildArc(pts[m_i][0], 0, 2 * Math.PI, delta, limit);
                        solution.Add(currentPoly);
                        continue;
                    }

                    bool forceClose = PointsEqual(pts[m_i][0], pts[m_i][len - 1]);
                    if (forceClose) len--;

                    //build normals ...
                    normals.Clear();
                    normals.Capacity = len;
                    for (int j = 0; j < len - 1; ++j)
                        normals.Add(GetUnitNormal(pts[m_i][j], pts[m_i][j + 1]));
                    if (isPolygon || forceClose)
                        normals.Add(GetUnitNormal(pts[m_i][len - 1], pts[m_i][0]));
                    else
                        normals.Add(new DoublePoint(normals[len - 2]));

                    currentPoly = new Polygon();
                    if (isPolygon || forceClose)
                    {
                        m_k = len - 1;
                        for (m_j = 0; m_j < len; ++m_j)
                            OffsetPoint(jointype, limit);
                        solution.Add(currentPoly);
                        if (!isPolygon)
                        {
                            currentPoly = new Polygon();
                            m_delta = -m_delta;
                            m_k = len - 1;
                            for (m_j = 0; m_j < len; ++m_j)
                                OffsetPoint(jointype, limit);
                            m_delta = -m_delta;
                            currentPoly.Reverse();
                            solution.Add(currentPoly);
                        }
                    }
                    else
                    {
                        m_k = 0;
                        for (m_j = 1; m_j < len - 1; ++m_j)
                            OffsetPoint(jointype, limit);

                        IntPoint pt1;
                        if (endtype == EndType.etButt)
                        {
                            m_j = len - 1;
                            pt1 = new IntPoint((Int64)Round(pts[m_i][m_j].X + normals[m_j].X *
                              delta), (Int64)Round(pts[m_i][m_j].Y + normals[m_j].Y * delta));
                            AddPoint(pt1);
                            pt1 = new IntPoint((Int64)Round(pts[m_i][m_j].X - normals[m_j].X *
                              delta), (Int64)Round(pts[m_i][m_j].Y - normals[m_j].Y * delta));
                            AddPoint(pt1);
                        }
                        else
                        {
                            m_j = len - 1;
                            m_k = len - 2;
                            normals[m_j].X = -normals[m_j].X;
                            normals[m_j].Y = -normals[m_j].Y;
                            if (endtype == EndType.etSquare) DoSquare();
                            else DoRound(limit);
                        }

                        //re-build Normals ...
                        for (int j = len - 1; j > 0; j--)
                        {
                            normals[j].X = -normals[j - 1].X;
                            normals[j].Y = -normals[j - 1].Y;
                        }
                        normals[0].X = -normals[1].X;
                        normals[0].Y = -normals[1].Y;

                        m_k = len - 1;
                        for (m_j = m_k - 1; m_j > 0; --m_j)
                            OffsetPoint(jointype, limit);

                        if (endtype == EndType.etButt)
                        {
                            pt1 = new IntPoint((Int64)Round(pts[m_i][0].X - normals[0].X * delta),
                              (Int64)Round(pts[m_i][0].Y - normals[0].Y * delta));
                            AddPoint(pt1);
                            pt1 = new IntPoint((Int64)Round(pts[m_i][0].X + normals[0].X * delta),
                              (Int64)Round(pts[m_i][0].Y + normals[0].Y * delta));
                            AddPoint(pt1);
                        }
                        else
                        {
                            m_k = 1;
                            if (endtype == EndType.etSquare) DoSquare();
                            else DoRound(limit);
                        }
                        solution.Add(currentPoly);
                    }
                }

                //finally, clean up untidy corners ...
                Clipper clpr = new Clipper();
                clpr.AddPolygons(solution, PolyType.ptSubject);
                if (delta > 0)
                {
                    clpr.Execute(ClipType.ctUnion, solution, PolyFillType.pftPositive, PolyFillType.pftPositive);
                }
                else
                {
                    IntRect r = clpr.GetBounds();
                    Polygon outer = new Polygon(4);

                    outer.Add(new IntPoint(r.left - 10, r.bottom + 10));
                    outer.Add(new IntPoint(r.right + 10, r.bottom + 10));
                    outer.Add(new IntPoint(r.right + 10, r.top - 10));
                    outer.Add(new IntPoint(r.left - 10, r.top - 10));

                    clpr.AddPolygon(outer, PolyType.ptSubject);
                    clpr.ReverseSolution = true;
                    clpr.Execute(ClipType.ctUnion, solution, PolyFillType.pftNegative, PolyFillType.pftNegative);
                    if (solution.Count > 0) solution.RemoveAt(0);
                }
            }
Пример #11
0
        ////////////////////////////////////////////////
        
        static void Main(string[] args)
        {
            ////quick test with random polygons ...
            //Polygons ss = new Polygons(1), cc = new Polygons(1), sss = new Polygons();
            //Random r = new Random((int)DateTime.Now.Ticks);
            //int scale = 1000000000; //tests 128bit math
            //ss.Add(MakeRandomPolygon(r, 400, 350, 9, scale));
            //cc.Add(MakeRandomPolygon(r, 400, 350, 9, scale));
            //Clipper cpr = new Clipper();
            //cpr.AddPolygons(ss, PolyType.ptSubject);
            //cpr.AddPolygons(cc, PolyType.ptClip);
            //cpr.Execute(ClipType.ctUnion, sss, PolyFillType.pftNonZero, PolyFillType.pftNonZero);
            //sss = Clipper.OffsetPolygons(sss, -5.0*scale, JoinType.jtMiter, 4);
            //SVGBuilder svg1 = new SVGBuilder();
            //svg1.style.brushClr = Color.FromArgb(0x20, 0, 0, 0x9c);
            //svg1.style.penClr = Color.FromArgb(0xd3, 0xd3, 0xda);
            //svg1.AddPolygons(ss);
            //svg1.style.brushClr = Color.FromArgb(0x20, 0x9c, 0, 0);
            //svg1.style.penClr = Color.FromArgb(0xff, 0xa0, 0x7a);
            //svg1.AddPolygons(cc);
            //svg1.style.brushClr = Color.FromArgb(0xAA, 0x80, 0xff, 0x9c);
            //svg1.style.penClr = Color.FromArgb(0, 0x33, 0);
            //svg1.AddPolygons(sss);
            //svg1.SaveToFile("solution.svg", 1.0/scale);
            //return;

            if (args.Length < 5)
            {
                string appname = System.Environment.GetCommandLineArgs()[0];
                appname = Path.GetFileName(appname);
                Console.WriteLine("");
                Console.WriteLine("Usage:");
                Console.WriteLine("  {0} CLIPTYPE s_file c_file INPUT_DEC_PLACES SVG_SCALE [S_FILL, C_FILL]", appname);
                Console.WriteLine("  where ...");
                Console.WriteLine("  CLIPTYPE = INTERSECTION|UNION|DIFFERENCE|XOR");
                Console.WriteLine("  FILLMODE = NONZERO|EVENODD");
                Console.WriteLine("  INPUT_DEC_PLACES = signific. decimal places for subject & clip coords.");
                Console.WriteLine("  SVG_SCALE = scale of SVG image as power of 10. (Fractions are accepted.)");
                Console.WriteLine("  both S_FILL and C_FILL are optional. The default is EVENODD.");
                Console.WriteLine("Example:");
                Console.WriteLine("  Intersect polygons, rnd to 4 dec places, SVG is 1/100 normal size ...");
                Console.WriteLine("  {0} INTERSECTION subj.txt clip.txt 0 0 NONZERO NONZERO", appname);
                return;
            }

            ClipType ct;
            switch (args[0].ToUpper())
            {
                case "INTERSECTION": ct = ClipType.ctIntersection; break;
                case "UNION": ct = ClipType.ctUnion; break;
                case "DIFFERENCE": ct = ClipType.ctDifference; break;
                case "XOR": ct = ClipType.ctXor; break;
                default: Console.WriteLine("Error: invalid operation - {0}", args[0]); return;
            }

            string subjFilename = args[1];
            string clipFilename = args[2];
            if (!File.Exists(subjFilename))
            {
                Console.WriteLine("Error: file - {0} - does not exist.", subjFilename);
                return;
            }
            if (!File.Exists(clipFilename))
            {
                Console.WriteLine("Error: file - {0} - does not exist.", clipFilename);
                return;
            }

            int decimal_places = 0;
            if (!Int32.TryParse(args[3], out decimal_places))
            {
                Console.WriteLine("Error: invalid number of decimal places - {0}", args[3]);
                return;
            }
            if (decimal_places > 8) decimal_places = 8;
            else if (decimal_places < 0) decimal_places = 0;

            double svg_scale = 0;
            if (!double.TryParse(args[4], out svg_scale))
            {
                Console.WriteLine("Error: invalid value for SVG_SCALE - {0}", args[4]);
                return;
            }
            if (svg_scale < -18) svg_scale = -18;
            else if (svg_scale > 18) svg_scale = 18;
            svg_scale = Math.Pow(10, svg_scale - decimal_places);//nb: also compensate for decimal places


            PolyFillType pftSubj = PolyFillType.pftEvenOdd;
            PolyFillType pftClip = PolyFillType.pftEvenOdd;
            if (args.Length > 6)
            {
                switch (args[5].ToUpper())
                {
                    case "EVENODD": pftSubj = PolyFillType.pftEvenOdd; break;
                    case "NONZERO": pftSubj = PolyFillType.pftNonZero; break;
                    default: Console.WriteLine("Error: invalid cliptype - {0}", args[5]); return;
                }
                switch (args[6].ToUpper())
                {
                    case "EVENODD": pftClip = PolyFillType.pftEvenOdd; break;
                    case "NONZERO": pftClip = PolyFillType.pftNonZero; break;
                    default: Console.WriteLine("Error: invalid cliptype - {0}", args[6]); return;
                }
            }

            Polygons subjs = new Polygons();
            Polygons clips = new Polygons();
            if (!LoadFromFile(subjFilename, subjs, decimal_places))
            {
                Console.WriteLine("Error processing subject polygons file - {0} ", subjFilename);
                OutputFileFormat();
                return;
            }
            if (!LoadFromFile(clipFilename, clips, decimal_places))
            {
                Console.WriteLine("Error processing clip polygons file - {0} ", clipFilename);
                OutputFileFormat();
                return;
            }

            Console.WriteLine("wait ...");
            Clipper cp = new Clipper();
            cp.AddPolygons(subjs, PolyType.ptSubject);
            cp.AddPolygons(clips, PolyType.ptClip);

            Polygons solution = new Polygons();
            //Polygons solution = new Polygons();
            if (cp.Execute(ct, solution, pftSubj, pftClip))
            {
                SaveToFile("solution.txt", solution, decimal_places);

                //solution = Clipper.OffsetPolygons(solution, -4, JoinType.jtRound);

                SVGBuilder svg = new SVGBuilder();
                svg.style.brushClr = Color.FromArgb(0x20, 0, 0, 0x9c);
                svg.style.penClr = Color.FromArgb(0xd3, 0xd3, 0xda);
                svg.AddPolygons(subjs);
                svg.style.brushClr = Color.FromArgb(0x20, 0x9c, 0, 0);
                svg.style.penClr = Color.FromArgb(0xff, 0xa0, 0x7a);
                svg.AddPolygons(clips);
                svg.style.brushClr = Color.FromArgb(0xAA, 0x80, 0xff, 0x9c);
                svg.style.penClr = Color.FromArgb(0, 0x33, 0);
                svg.AddPolygons(solution);
                svg.SaveToFile("solution.svg", svg_scale);

                Console.WriteLine("finished!");
            }
            else
            {
                Console.WriteLine("failed!");
            }
        }
Пример #12
0
        private void Slice(Plane p)
        {
            float epsilon = 0.01f; // TODO: compute proper epsilon value

            List<PolyLine> linePile = new List<PolyLine>(); // Pile of disconnected lines on the slice plane
            List<Vector3> all_points = new List<Vector3>();
            foreach (Face f in this.faces)
            {
                PolyLine newLine = TrianglePlaneIntersect(f, p);

                // Only add lines with exactly 2 points - others are a no match or error
                if (newLine.points.Count() == 2 && (newLine.points[0] - newLine.points[1]).Length> epsilon)
                {
                    linePile.Add(newLine);

                    // Add the vertices to the all_points list - only need to add the first one, the tail will be the head of another point
                    bool matched = false;
                    foreach (Vector3 point in all_points)
                    {
                        if ((point - newLine.points[0]).Length < epsilon)
                        {
                            matched = true;
                            break;
                        }
                    }
                    if (!matched)
                    {
                        all_points.Add(newLine.points[0]);
                    }
                }
            }

            // linePile is a unordered list of line segments.
            // If a line segment is oriented with point[0] on (0, 0, 0) and point[1]
            // somewhere on the positive Y axis, the solid object is in the direction of the positive x axis.
            //
            //              p[1]xxxxxxxxxxxxxxxxxxxxxxxx
            //               xx                       xx
            //               xx  <object over here>   xx
            //               xx                       xx
            //              p[0]xxxxxxxxxxxxxxxxxxxxxxxx
            //

            List<PolyLine> newPolyLines = new List<PolyLine>();
            for (int i = 0; i < linePile.Count(); i++)
            {
                int points = linePile[i].points.Count();

                Vector3 v1 = linePile[i].points[0];
                Vector3 v2 = linePile[i].points[1];

                //DrawCone1(v1, v2);

                List<Vector3> points_on_line = new List<Vector3>();
                foreach (Vector3 v in all_points)
                {
                    if ((v1 - v).Length >= epsilon && (v2 - v).Length >= epsilon && DistanceToCylinder(v1, v2, v) < epsilon)
                    {
                        points_on_line.Add(v);
                    }
                }

                points_on_line.Insert(0, v1);
                points_on_line.Add(v2);

                // Order from v1 to v2
                var sorted = points_on_line.OrderBy(order_vec => (order_vec - v1).Length);

                PolyLine newPolyLine = new PolyLine();
                foreach (Vector3 v in sorted)
                {
                    if (newPolyLine.points.Count() == 0 || (newPolyLine.points[newPolyLine.points.Count() - 1] - v).Length > epsilon)
                    {
                        newPolyLine.points.Add(v);
                    }
                }
                if (newPolyLine.points.Count() >= 2)
                {
                    newPolyLines.Add(newPolyLine);
                }
                if (newPolyLine.points.Count() >= 3)
                {
                    // Shouldn't get here!
                }
            }

            List<LinePointIndices> lpis = new List<LinePointIndices>();
            List<Vector3> vertices = new List<Vector3>();
            List<List<int>> v_lookup = new List<List<int>>();

            foreach (PolyLine l in newPolyLines)
            {
                int lastIndex = -1;
                foreach (Vector3 pointVec in l.points)
                {
                    int currentIndex = -1;
                    for (int i = 0; i < vertices.Count(); i++)
                    {
                        float length = (vertices[i] - pointVec).Length;
                        if (length < epsilon)
                        {
                            currentIndex = i;
                            continue;
                        }
                    }
                    if (currentIndex == -1)
                    {
                        vertices.Add(pointVec);
                        v_lookup.Add(new List<int>());
                        currentIndex = vertices.Count() - 1;
                    }

                    if (lastIndex != -1 && lastIndex != currentIndex)
                    {
                        LinePointIndices line = new LinePointIndices();

                        bool already_matched = false;
                        foreach (int line_index in v_lookup[lastIndex])
                        {
                            LinePointIndices l2 = lpis[line_index];
                            if (l2.indices[1] == currentIndex)
                            {
                                already_matched = true;
                            }
                        }
                        if (!already_matched)
                        {

                            line.indices.Add(lastIndex);
                            line.indices.Add(currentIndex);
                            lpis.Add(line);

                            v_lookup[lastIndex].Add(lpis.Count() - 1);
                            v_lookup[currentIndex].Add(lpis.Count() - 1);
                        }
                    }
                    lastIndex = currentIndex;
                }
            }

            //List<Vector3> scaled = new List<Vector3>();
            List<int> vector_indices_to_see = new List<int>();
            foreach (Vector3 v in vertices)
            {
                //scaled.Add(v / 125);
                vector_indices_to_see.Add(vector_indices_to_see.Count());
            }

            List<LinePointIndices> slices = new List<LinePointIndices>();

            GL.PushMatrix();
            GL.PointSize(10);
            List<int> seenVertices = new List<int>();
            while(vector_indices_to_see.Count() > 0)
            {
                List<int> line_indices = v_lookup [vector_indices_to_see[0]];
                vector_indices_to_see.RemoveAt(0);
                if (line_indices.Count() == 0)
                {
                    continue;
                }
                LinePointIndices line = lpis[line_indices[0]]; // Only need to look at one line with this vertex
                LinePointIndices start_line = new LinePointIndices();
                start_line.indices.Add(line.indices[0]);
                start_line.indices.Add(line.indices[1]);
                GL.Color3(Color.Green);
                DrawCone1(vertices[start_line.indices[0]], vertices[start_line.indices[1]]);
                LinePointIndices loop = FindLoop(seenVertices, p.normal, vertices, v_lookup, lpis, start_line);

                if (loop != null)
                {
                    slices.Add(loop);
                    GL.Color3(Color.LightBlue);
                    GL.Begin(BeginMode.LineLoop);
                    Vector3 add = new Vector3(0, 0, 0);
                    foreach (int i in loop.indices)
                    {
                        vector_indices_to_see.RemoveAll(value => value == i);
                        GL.Vertex3(vertices[i] + add);
                        seenVertices.Add(i);
                        //add += new Vector3(0, 0, 25);
                    }
                    GL.End();
                    //GL.Translate(new Vector3(0, 0, +100));
                }
                //break;
            }
            GL.PointSize(1);
            GL.PopMatrix();

            Vector3 normal = new Vector3(0, 0, 1);
            float toolRadius = 100;
            GL.LineWidth(1);

            List<IntPoint> boundingBox = new List<IntPoint>();
            boundingBox.Add(new IntPoint(-1000, -1000));
            boundingBox.Add(new IntPoint(3000, -1000));
            boundingBox.Add(new IntPoint(3000, 3000));
            boundingBox.Add(new IntPoint(-1000, 3000));

            List<LineLoop> loops = new List<LineLoop>();

            foreach (LinePointIndices l in slices)
            {
                LineStrip line = new LineStrip();
                for (int i = 0; i < l.indices.Count (); i++)
                {
                    line.Append(vertices[l.indices[i]]);
                }
                line.Append(vertices[l.indices[0]]);
                loops.Add(new LineLoop (line));
            }

            if (loops.Count() > 0)
            {
                Vector3 up = new Vector3(0, 0, 1);
                if (Math.Abs (normal.Z) > 0.8)
                {
                    up = new Vector3(1, 0, 0);
                }

                float distance = Vector3.Dot(loops[0].GetVertex(0), normal);

                Matrix4 transform = Matrix4.LookAt(normal * distance, normal * (distance - 1), up);
                Matrix4 inverseTransform = Matrix4.Invert(transform);

                Clipper c = new Clipper();
                c.Clear();

                try
                {
                    // These loops go clockwise
                    foreach (LineLoop loop in loops)
                    {
                        List<IntPoint> polygon = new List<IntPoint>();
                        foreach (Vector3 vertex in loop.Vertices)
                        {
                            Vector3 result = Vector3.Transform(vertex, transform);
                            polygon.Add(new IntPoint((long)result.X, (long)result.Y));
                        }
                        polygon.RemoveAt(0);
                        c.AddPolygon(polygon, PolyType.ptClip);
                        GL.PushMatrix();
                        GL.Translate(new Vector3(0, 0, 100));
                        //loop.Draw();
                        GL.PopMatrix();
                    }
                    List<List<IntPoint>> union = new List<List<IntPoint>>();
                    bool r = c.Execute(ClipType.ctUnion, union, PolyFillType.pftNonZero, PolyFillType.pftNonZero);

                    List<List<IntPoint>> with_offset = Clipper.OffsetPolygons(union, toolRadius, JoinType.jtSquare);
                    List<List<IntPoint>> whatsLeft = Clipper.OffsetPolygons(with_offset, -toolRadius, JoinType.jtRound);

                    List<LineStrip> strips = new List<LineStrip>();
                    foreach (List<IntPoint> polygon in with_offset)
                    {
                        LineStrip strip = new LineStrip();
                        foreach (IntPoint point in polygon)
                        {
                            strip.Append(Vector3.Transform(new Vector3(point.X, point.Y, 0.0f), inverseTransform));
                        }
                        strip.Append(Vector3.Transform(new Vector3(polygon[0].X, polygon[0].Y, 0.0f), inverseTransform));

                        strips.Add(strip);
                        //new LineLoop(strip).Draw();
                    }

                    List<List<IntPoint>> removeArea = new List<List<IntPoint>>();
                    c.Clear();
                    c.AddPolygons(with_offset, PolyType.ptClip);
                    c.AddPolygon(boundingBox, PolyType.ptSubject);
                    List<List<IntPoint>> resultingPolygon = new List<List<IntPoint>>();
                    c.Execute(ClipType.ctDifference, removeArea, PolyFillType.pftNonZero, PolyFillType.pftNonZero);
                    removeArea = Clipper.CleanPolygons(removeArea, toolRadius / 100);

                    c.Clear();
                    c.AddPolygons(removeArea, PolyType.ptClip);
                    PolyTree test = new PolyTree();
                    c.Execute(ClipType.ctUnion, test, PolyFillType.pftNonZero, PolyFillType.pftNonZero);

                    //PolyNode pn = test.GetFirst();
                    //while (pn != null)
                    //{
                    //    if (pn.IsHole)
                    //    {
                    //        LineLoop l = new LineLoop(pn.Contour, inverseTransform);
                    //        l.Draw();
                    //    }
                    //    pn = pn.GetNext();
                    //}
                    List<Polygons> polys = FlattenPolyTree(test);

                    //GL.PushMatrix();
                    foreach (Polygons polygons in polys)
                    {
                        //GL.Translate(new Vector3 (0, 0, 100));
                        //foreach (Polygon polygon in polygons)
                        //{
                        //    LineLoop l = new LineLoop(polygon, inverseTransform);
                        //    l.Draw();
                        //}
                        List<Polygons> paths = ReducePolygon(polygons, toolRadius, inverseTransform);
                        //IOrderedEnumerable<List<IntPoint>> ordered = paths.OrderBy(poly => Clipper.Area(poly));
                        GL.PushMatrix();
                        List<Polygons> paths2 = new List<Polygons>();
                        List<Polygons> paths3 = new List<Polygons>();
                        foreach (Polygons polygons2 in paths)
                        {
                            var newPolys = new Polygons();
                            foreach (Polygon poly in polygons2)
                            {
                                if (Clipper.Area(poly) > 0)
                                {
                                    newPolys.Add(poly);
                                }
                            }
                            paths2.Add(newPolys);

                            //GL.Translate(new Vector3(0, 0, 100));
                            var newInnerPolys = new Polygons();
                            foreach (Polygon poly in polygons2)
                            {

                                if (paths3.Count() == 0)
                                {
                                    //newInnerPoly
                                }
                                if (Clipper.Area(poly) < 0)
                                {
                                  LineLoop l = new LineLoop(poly, inverseTransform);
                                  l.Draw();
                                }
                            }

                        }
                        foreach (Polygons polygons2 in paths2)
                        {
                            GL.Translate(new Vector3(0, 0, 100));
                            foreach (Polygon poly in polygons2)
                            {
                                LineLoop l = new LineLoop(poly, inverseTransform);
                                l.Draw();
                            }
                        }
                        GL.PopMatrix();
                    }
                    //GL.PopMatrix();

                    double boundingBoxArea = Clipper.Area(boundingBox);
                    // Outer Polygon
                    // Inner Polygons
                    //ReducePolygon(boundingBox, with_offset, toolRadius, inverseTransform);

                    //strips = new List<LineStrip>();
                    //double area = 1;
                    //int loopTimes = 0;

                    //List<List<IntPoint>> cutPolygons = new List<List<IntPoint>>();
                    //List<Vector3> parentPoints = new List<Vector3>();
                    //GL.PushMatrix();
                    //while (removeArea.Count() > 0)
                    //{
                    //    List<Vector3> points = new List<Vector3>();
                    //    foreach (List<IntPoint> polygon in removeArea)
                    //    {
                    //        double area = Clipper.Area(polygon);
                    //
                    //        if (area > 0) // Bigger to Smaller
                    //        {
                    //        }
                    //        IntPoint[] newP = new IntPoint[polygon.Count()];
                    //        polygon.CopyTo(newP);
                    //        cutPolygons.Add(new List<IntPoint>(newP));
                    //
                    //
                    //        LineLoop l = new LineLoop(polygon, inverseTransform);
                    //        //l.Draw();
                    //        points.AddRange(l.Vertices);
                    //
                    //        //ReducePolygon(null, polygon, toolRadius, inverseTransform);
                    //        //area += Clipper.Area(polygon);
                    //        //LineStrip strip = new LineStrip();
                    //        //foreach (IntPoint point in polygon)
                    //        //{
                    //        //    strip.Append(Vector3.Transform(new Vector3(point.X, point.Y, 0.0f), inverseTransform));
                    //        //}
                    //        //strip.Append(Vector3.Transform(new Vector3(polygon[0].X, polygon[0].Y, 0.0f), inverseTransform));
                    //
                    //        //strips.Add(strip);
                    //        //new LineLoop(strip).Draw();
                    //    }
                    //
                    //    //GL.Color3(Color.Black);
                    //    //GL.Begin(BeginMode.Lines);
                    //    //foreach (Vector3 v in points)
                    //    //{
                    //    //    foreach (Vector3 v2 in parentPoints)
                    //    //    {
                    //    //        if ((v - v2).Length < toolRadius * 2)
                    //    //        {
                    //    //            GL.Vertex3(v);
                    //    //            GL.Vertex3(v2);
                    //    //        }
                    //    //    }
                    //    //}
                    //    //GL.End();
                    //
                    //    parentPoints = points;
                    //    removeArea = Clipper.OffsetPolygons(removeArea, -toolRadius, JoinType.jtRound);
                    //    removeArea = Clipper.CleanPolygons(removeArea, toolRadius / 100);
                    //}
                    //GL.PopMatrix();

                    //IOrderedEnumerable<List<IntPoint>> ordered = cutPolygons.OrderBy(poly => Clipper.Area(poly));
                    //
                    //GL.PushMatrix();
                    //foreach (List<IntPoint> poly in ordered)
                    //{
                    //    GL.Translate(new Vector3(0, 0, 100));
                    //    LineLoop l = new LineLoop(poly, inverseTransform);
                    //    l.Draw();
                    //}
                    //GL.PopMatrix();

                    ////strips = new List<LineStrip>();
                    //GL.Color3(Color.Red);
                    //GL.LineWidth(2);
                    //foreach (List<IntPoint> polygon in whatsLeft)
                    //{
                    //    LineStrip strip = new LineStrip();
                    //    foreach (IntPoint point in polygon)
                    //    {
                    //        strip.Append(Vector3.Transform(new Vector3(point.X, point.Y, 0.0f), inverseTransform));
                    //    }
                    //    strip.Append(Vector3.Transform(new Vector3(polygon[0].X, polygon[0].Y, 0.0f), inverseTransform));
                    //
                    //    strips.Add(strip);
                    //    new LineLoop(strip).Draw();
                    //}
                    //GL.LineWidth(1);

                }
                catch (Exception e)
                {
                }
            }
        }