//--------------------------------------------------------------------------- private void DrawBitmap(bool justClip = false) { Cursor.Current = Cursors.WaitCursor; try { if (!justClip) { if (rbTest2.Checked) { GenerateAustPlusRandomEllipses((int)nudCount.Value); } else { GenerateRandomPolygon((int)nudCount.Value); } } using (Graphics newgraphic = Graphics.FromImage(mybitmap)) using (GraphicsPath path = new GraphicsPath()) { newgraphic.SmoothingMode = SmoothingMode.AntiAlias; newgraphic.Clear(Color.White); if (rbNonZero.Checked) { path.FillMode = FillMode.Winding; } //draw subjects ... for (int i = 0; i < subjects.length; i++) { Polygon pg = (Polygon)subjects[i]; PointF[] pts = PolygonToPointFArray(pg, scale); path.AddPolygon(pts); pts = null; } using (Pen myPen = new Pen(Color.FromArgb(196, 0xC3, 0xC9, 0xCF), (float)0.6)) using (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; } for (int i = 0; i < clips.length; i++) { Polygon pg = (Polygon)clips[i]; 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.length > 0 || subjects.length > 0) && !rbNone.Checked) { Polygons solution2 = new Polygons(); Clipper c = new Clipper(new haxe.lang.Null <int>(0, false)); c.addPaths(subjects, PolyType.PT_SUBJECT, true); c.addPaths(clips, PolyType.PT_CLIP, true); InternalTools.clear(solution); #if UsePolyTree bool succeeded = c.executePolyTree(GetClipType(), solutionTree, GetPolyFillType(), GetPolyFillType()); //nb: we aren't doing anything useful here with solutionTree except to show //that it works. Convert PolyTree back to Polygons structure ... solution = Clipper.polyTreeToPaths(solutionTree); #else bool succeeded = c.executePaths(GetClipType(), solution, GetPolyFillType(), GetPolyFillType()); #endif if (succeeded) { //SaveToFile("solution", solution); 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) { ClipperOffset co = new ClipperOffset(new haxe.lang.Null <double>(0.0, false), new haxe.lang.Null <double>(0.0, false)); co.addPaths(solution, JoinType.JT_ROUND, EndType.ET_CLOSED_POLYGON); co.executePaths(solution2, (double)nudOffset.Value * scale); } else { solution2 = solution2.concat(solution);// Polygons(solution); } for (int i = 0; i < solution2.length; i++) { Polygon pg = (Polygon)solution2[i]; 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 ... using (Font f = new Font("Arial", 8)) using (SolidBrush b = new SolidBrush(Color.Navy)) { double subj_area = 0, clip_area = 0, int_area = 0, union_area = 0; c.clear(); c.addPaths(subjects, PolyType.PT_SUBJECT, true); c.executePaths(ClipType.CT_UNION, solution2, GetPolyFillType(), GetPolyFillType()); for (int i = 0; i < solution2.length; i++) { Polygon pg = (Polygon)solution2[i]; subj_area += Clipper.area(pg); } c.clear(); c.addPaths(clips, PolyType.PT_CLIP, true); c.executePaths(ClipType.CT_UNION, solution2, GetPolyFillType(), GetPolyFillType()); for (int i = 0; i < solution2.length; i++) { Polygon pg = (Polygon)solution2[i]; clip_area += Clipper.area(pg); } c.addPaths(subjects, PolyType.PT_SUBJECT, true); c.executePaths(ClipType.CT_INTERSECTION, solution2, GetPolyFillType(), GetPolyFillType()); for (int i = 0; i < solution2.length; i++) { Polygon pg = (Polygon)solution2[i]; int_area += Clipper.area(pg); } c.executePaths(ClipType.CT_UNION, solution2, GetPolyFillType(), GetPolyFillType()); for (int i = 0; i < solution2.length; i++) { Polygon pg = (Polygon)solution2[i]; union_area += Clipper.area(pg); } using (StringFormat lftStringFormat = new StringFormat()) using (StringFormat rtStringFormat = new StringFormat()) { lftStringFormat.Alignment = StringAlignment.Near; lftStringFormat.LineAlignment = StringAlignment.Near; 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; } } } finally { Cursor.Current = Cursors.Default; } }
//--------------------------------------------------------------------------- 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; }