Created
February 7, 2014 20:31
-
-
Save nraynaud/8871172 to your computer and use it in GitHub Desktop.
clipper C# GUI demo main form cleanup
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //#define UsePolyTree | |
| using System; | |
| using System.Diagnostics; | |
| using System.Text; | |
| using System.Collections.Generic; | |
| using System.Drawing; | |
| using System.Drawing.Drawing2D; | |
| using System.Drawing.Imaging; | |
| using System.IO; | |
| using System.Reflection; | |
| using System.Linq; | |
| using System.Windows.Forms; | |
| using System.Globalization; | |
| using ClipperLib; | |
| namespace WindowsFormsApplication1 | |
| { | |
| using Polygon = List<IntPoint>; | |
| using Polygons = List<List<IntPoint>>; | |
| public partial class Form1 : Form | |
| { | |
| private Bitmap mybitmap; | |
| private Polygons subjects = new Polygons(); | |
| private Polygons clips = new Polygons(); | |
| private Polygons solution = new Polygons(); | |
| #if UsePolyTree | |
| private PolyTree solutionTree = new PolyTree(); | |
| #endif | |
| //Here we are scaling all coordinates up by 100 when they're passed to Clipper | |
| //via Polygon (or Polygons) objects because Clipper no longer accepts floating | |
| //point values. Likewise when Clipper returns a solution in a Polygons object, | |
| //we need to scale down these returned values by the same amount before displaying. | |
| private float scale = 100; //or 1 or 10 or 10000 etc for lesser or greater precision. | |
| //------------------------------------------------------------------------------ | |
| //--------------------------------------------------------------------- | |
| //a very simple class that builds an SVG file with any number of | |
| //polygons of the specified formats ... | |
| class SVGBuilder | |
| { | |
| public class StyleInfo | |
| { | |
| public PolyFillType pft; | |
| public Color brushClr; | |
| public Color penClr; | |
| public double penWidth; | |
| public int[] dashArray; | |
| public Boolean showCoords; | |
| public StyleInfo Clone() | |
| { | |
| StyleInfo si = new StyleInfo(); | |
| si.pft = this.pft; | |
| si.brushClr = this.brushClr; | |
| si.dashArray = this.dashArray; | |
| si.penClr = this.penClr; | |
| si.penWidth = this.penWidth; | |
| si.showCoords = this.showCoords; | |
| return si; | |
| } | |
| public StyleInfo() | |
| { | |
| pft = PolyFillType.pftNonZero; | |
| brushClr = Color.AntiqueWhite; | |
| dashArray = null; | |
| penClr = Color.Black; | |
| penWidth = 0.8; | |
| showCoords = false; | |
| } | |
| } | |
| public class PolyInfo | |
| { | |
| public Polygons polygons; | |
| public StyleInfo si; | |
| } | |
| public StyleInfo style; | |
| private List<PolyInfo> PolyInfoList; | |
| const string svg_header = "<?xml version=\"1.0\" standalone=\"no\"?>\n" + | |
| "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\"\n" + | |
| "\"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n\n" + | |
| "<svg width=\"{0}px\" height=\"{1}px\" viewBox=\"0 0 {2} {3}\" " + | |
| "version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n\n"; | |
| const string svg_path_format = "\"\n style=\"fill:{0};" + | |
| " fill-opacity:{1:f2}; fill-rule:{2}; stroke:{3};" + | |
| " stroke-opacity:{4:f2}; stroke-width:{5:f2};\"/>\n\n"; | |
| public SVGBuilder() | |
| { | |
| PolyInfoList = new List<PolyInfo>(); | |
| style = new StyleInfo(); | |
| } | |
| public void AddPolygons(Polygons poly) | |
| { | |
| if (poly.Count == 0) return; | |
| PolyInfo pi = new PolyInfo(); | |
| pi.polygons = poly; | |
| pi.si = style.Clone(); | |
| PolyInfoList.Add(pi); | |
| } | |
| public Boolean SaveToFile(string filename, double scale = 1.0, int margin = 10) | |
| { | |
| if (scale == 0) scale = 1.0; | |
| if (margin < 0) margin = 0; | |
| //calculate the bounding rect ... | |
| int i = 0, j = 0; | |
| while (i < PolyInfoList.Count) | |
| { | |
| j = 0; | |
| while (j < PolyInfoList[i].polygons.Count && | |
| PolyInfoList[i].polygons[j].Count == 0) j++; | |
| if (j < PolyInfoList[i].polygons.Count) break; | |
| i++; | |
| } | |
| if (i == PolyInfoList.Count) return false; | |
| IntRect rec = new IntRect(); | |
| rec.left = PolyInfoList[i].polygons[j][0].X; | |
| rec.right = rec.left; | |
| rec.top = PolyInfoList[0].polygons[j][0].Y; | |
| rec.bottom = rec.top; | |
| for (; i < PolyInfoList.Count; i++) | |
| { | |
| foreach (Polygon pg in PolyInfoList[i].polygons) | |
| foreach (IntPoint pt in pg) | |
| { | |
| if (pt.X < rec.left) rec.left = pt.X; | |
| else if (pt.X > rec.right) rec.right = pt.X; | |
| if (pt.Y < rec.top) rec.top = pt.Y; | |
| else if (pt.Y > rec.bottom) rec.bottom = pt.Y; | |
| } | |
| } | |
| rec.left = (Int64)(rec.left * scale); | |
| rec.top = (Int64)(rec.top * scale); | |
| rec.right = (Int64)(rec.right * scale); | |
| rec.bottom = (Int64)(rec.bottom * scale); | |
| Int64 offsetX = -rec.left + margin; | |
| Int64 offsetY = -rec.top + margin; | |
| using(StreamWriter writer = new StreamWriter(filename)) | |
| { | |
| writer.Write(svg_header, | |
| (rec.right - rec.left) + margin * 2, | |
| (rec.bottom - rec.top) + margin * 2, | |
| (rec.right - rec.left) + margin * 2, | |
| (rec.bottom - rec.top) + margin * 2); | |
| foreach (PolyInfo pi in PolyInfoList) | |
| { | |
| writer.Write(" <path d=\""); | |
| foreach (Polygon p in pi.polygons) | |
| { | |
| if (p.Count < 3) continue; | |
| writer.Write(String.Format(NumberFormatInfo.InvariantInfo, " M {0:f2} {1:f2}", | |
| (double)((double)p[0].X * scale + offsetX), | |
| (double)((double)p[0].Y * scale + offsetY))); | |
| for (int k = 1; k < p.Count; k++) | |
| { | |
| writer.Write(String.Format(NumberFormatInfo.InvariantInfo, " L {0:f2} {1:f2}", | |
| (double)((double)p[k].X * scale + offsetX), | |
| (double)((double)p[k].Y * scale + offsetY))); | |
| } | |
| writer.Write(" z"); | |
| } | |
| writer.Write(String.Format(NumberFormatInfo.InvariantInfo, svg_path_format, | |
| ColorTranslator.ToHtml(pi.si.brushClr), | |
| (float)pi.si.brushClr.A / 255, | |
| (pi.si.pft == PolyFillType.pftEvenOdd ? "evenodd" : "nonzero"), | |
| ColorTranslator.ToHtml(pi.si.penClr), | |
| (float)pi.si.penClr.A / 255, | |
| pi.si.penWidth)); | |
| if (pi.si.showCoords) | |
| { | |
| writer.Write("<g font-family=\"Verdana\" font-size=\"11\" fill=\"black\">\n\n"); | |
| foreach (Polygon p in pi.polygons) | |
| { | |
| foreach (IntPoint pt in p) | |
| { | |
| Int64 x = pt.X; | |
| Int64 y = pt.Y; | |
| writer.Write(String.Format( | |
| "<text x=\"{0}\" y=\"{1}\">{2},{3}</text>\n", | |
| (int)(x * scale + offsetX), (int)(y * scale + offsetY), x, y)); | |
| } | |
| writer.Write("\n"); | |
| } | |
| writer.Write("</g>\n"); | |
| } | |
| } | |
| writer.Write("</svg>\n"); | |
| } | |
| return true; | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| //------------------------------------------------------------------------------ | |
| static private PointF[] PolygonToPointFArray(Polygon pg, float scale) | |
| { | |
| PointF[] result = new PointF[pg.Count]; | |
| for (int i = 0; i < pg.Count; ++i) | |
| { | |
| result[i].X = (float)pg[i].X / scale; | |
| result[i].Y = (float)pg[i].Y / scale; | |
| } | |
| return result; | |
| } | |
| public Form1() | |
| { | |
| InitializeComponent(); | |
| this.MouseWheel += new MouseEventHandler(Form1_MouseWheel); | |
| mybitmap = new Bitmap( | |
| pictureBox1.ClientRectangle.Width, | |
| pictureBox1.ClientRectangle.Height, | |
| PixelFormat.Format32bppArgb); | |
| } | |
| //--------------------------------------------------------------------- | |
| private void Form1_MouseWheel(object sender, MouseEventArgs e) | |
| { | |
| if (e.Delta > 0 && nudOffset.Value < 10) nudOffset.Value += (decimal)0.5; | |
| else if (e.Delta < 0 && nudOffset.Value > -10) nudOffset.Value -= (decimal)0.5; | |
| } | |
| //--------------------------------------------------------------------- | |
| private void bRefresh_Click(object sender, EventArgs e) | |
| { | |
| DrawBitmap(); | |
| } | |
| //--------------------------------------------------------------------- | |
| private void GenerateAustPlusRandomEllipses(int count) | |
| { | |
| subjects.Clear(); | |
| //load map of Australia from resource ... | |
| Assembly _assembly = Assembly.GetExecutingAssembly(); | |
| using(BinaryReader polyStream = new BinaryReader(_assembly.GetManifestResourceStream("GuiDemo.aust.bin"))) | |
| { | |
| int polyCnt = polyStream.ReadInt32(); | |
| for (int i = 0; i < polyCnt; ++i) | |
| { | |
| int vertCnt = polyStream.ReadInt32(); | |
| Polygon pg = new Polygon(vertCnt); | |
| for (int j = 0; j < vertCnt; ++j) | |
| { | |
| float x = polyStream.ReadSingle() * scale; | |
| float y = polyStream.ReadSingle() * scale; | |
| pg.Add(new IntPoint((int)x, (int)y)); | |
| } | |
| subjects.Add(pg); | |
| } | |
| } | |
| clips.Clear(); | |
| Random rand = new Random(); | |
| using (GraphicsPath path = new GraphicsPath ()) { | |
| const int ellipse_size = 100 , margin= 10; | |
| for (int i = 0; i < count; ++i) { | |
| int w = pictureBox1.ClientRectangle.Width - ellipse_size - margin * 2; | |
| int h = pictureBox1.ClientRectangle.Height - ellipse_size - margin * 2 - statusStrip1.Height; | |
| int x = rand.Next (w) + margin; | |
| int y = rand.Next (h) + margin; | |
| int size = rand.Next (ellipse_size - 20) + 20; | |
| path.Reset (); | |
| path.AddEllipse (x, y, size, size); | |
| path.Flatten (); | |
| Polygon clip = new Polygon (path.PathPoints.Count ()); | |
| foreach (PointF p in path.PathPoints) | |
| clip.Add (new IntPoint ((int)(p.X * scale), (int)(p.Y * scale))); | |
| clips.Add (clip); | |
| } | |
| } | |
| } | |
| //--------------------------------------------------------------------- | |
| private IntPoint GenerateRandomPoint(int l, int t, int r, int b, Random rand) | |
| { | |
| int Q = 10; | |
| return new IntPoint( | |
| Convert.ToInt64((rand.Next(r / Q) * Q + l + 10) * scale), | |
| Convert.ToInt64((rand.Next(b / Q) * Q + t + 10) * scale)); | |
| } | |
| //--------------------------------------------------------------------- | |
| private void GenerateRandomPolygon(int count) | |
| { | |
| int Q = 10; | |
| Random rand = new Random(); | |
| int l = 10; | |
| int t = 10; | |
| int r = (pictureBox1.ClientRectangle.Width - 20) / Q * Q; | |
| int b = (pictureBox1.ClientRectangle.Height - 20) / Q * Q; | |
| subjects.Clear(); | |
| clips.Clear(); | |
| Polygon subj = new Polygon(count); | |
| for (int i = 0; i < count; ++i) | |
| subj.Add(GenerateRandomPoint(l, t, r, b, rand)); | |
| subjects.Add(subj); | |
| Polygon clip = new Polygon(count); | |
| for (int i = 0; i < count; ++i) | |
| clip.Add(GenerateRandomPoint(l, t, r, b, rand)); | |
| clips.Add(clip); | |
| } | |
| //--------------------------------------------------------------------- | |
| ClipType GetClipType() | |
| { | |
| if (rbIntersect.Checked) return ClipType.ctIntersection; | |
| if (rbUnion.Checked) return ClipType.ctUnion; | |
| if (rbDifference.Checked) return ClipType.ctDifference; | |
| else return ClipType.ctXor; | |
| } | |
| //--------------------------------------------------------------------- | |
| PolyFillType GetPolyFillType() | |
| { | |
| if (rbNonZero.Checked) return PolyFillType.pftNonZero; | |
| else return PolyFillType.pftEvenOdd; | |
| } | |
| //--------------------------------------------------------------------- | |
| bool LoadFromFile(string filename, Polygons ppg, double scale = 0, | |
| int xOffset = 0, int yOffset = 0) | |
| { | |
| double scaling = Math.Pow(10, scale); | |
| ppg.Clear(); | |
| if (!File.Exists(filename)) return false; | |
| using (StreamReader sr = new StreamReader (filename)) | |
| { | |
| string line; | |
| if ((line = sr.ReadLine ()) == null) | |
| return false; | |
| int polyCnt, vertCnt; | |
| if (!Int32.TryParse (line, out polyCnt) || polyCnt < 0) | |
| return false; | |
| ppg.Capacity = polyCnt; | |
| for (int i = 0; i < polyCnt; i++) | |
| { | |
| if ((line = sr.ReadLine ()) == null) | |
| return false; | |
| if (!Int32.TryParse (line, out vertCnt) || vertCnt < 0) | |
| return false; | |
| Polygon pg = new Polygon (vertCnt); | |
| ppg.Add (pg); | |
| for (int j = 0; j < vertCnt; j++) | |
| { | |
| double x, y; | |
| if ((line = sr.ReadLine ()) == null) | |
| return false; | |
| char[] delimiters = new char[] { ',', ' ' }; | |
| string[] vals = line.Split (delimiters); | |
| if (vals.Length < 2) | |
| return false; | |
| if (!double.TryParse (vals [0], out x)) | |
| return false; | |
| if (!double.TryParse (vals [1], out y)) | |
| if (vals.Length < 2 || !double.TryParse (vals [2], out y)) | |
| return false; | |
| x = x * scaling + xOffset; | |
| y = y * scaling + yOffset; | |
| pg.Add (new IntPoint ((int)Math.Round (x), (int)Math.Round (y))); | |
| } | |
| } | |
| } | |
| return true; | |
| } | |
| //------------------------------------------------------------------------------ | |
| void SaveToFile(string filename, Polygons ppg, int scale = 0) | |
| { | |
| double scaling = Math.Pow(10, scale); | |
| using (StreamWriter writer = new StreamWriter (filename)) { | |
| writer.Write ("{0}\n", ppg.Count); | |
| foreach (Polygon pg in ppg) { | |
| writer.Write ("{0}\n", pg.Count); | |
| foreach (IntPoint ip in pg) | |
| writer.Write ("{0:0.0000}, {1:0.0000}\n", ip.X / scaling, ip.Y / scaling); | |
| } | |
| } | |
| } | |
| //--------------------------------------------------------------------------- | |
| 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 ... | |
| foreach (Polygon pg in subjects) { | |
| 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; | |
| 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.AddPaths (subjects, PolyType.ptSubject, true); | |
| c.AddPaths (clips, PolyType.ptClip, true); | |
| solution.Clear (); | |
| #if UsePolyTree | |
| bool succeeded = c.Execute(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 ... | |
| Clipper.PolyTreeToPolygons(solutionTree, solution); | |
| #else | |
| bool succeeded = c.Execute (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 (); | |
| co.AddPaths (solution, JoinType.jtRound, EndType.etClosedPolygon); | |
| co.Execute (ref solution2, (double)nudOffset.Value * scale); | |
| } 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 ... | |
| 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.ptSubject, true); | |
| c.Execute (ClipType.ctUnion, solution2, GetPolyFillType (), GetPolyFillType ()); | |
| foreach (Polygon pg in solution2) | |
| subj_area += Clipper.Area (pg); | |
| c.Clear (); | |
| c.AddPaths (clips, PolyType.ptClip, true); | |
| c.Execute (ClipType.ctUnion, solution2, GetPolyFillType (), GetPolyFillType ()); | |
| foreach (Polygon pg in solution2) | |
| clip_area += Clipper.Area (pg); | |
| c.AddPaths (subjects, PolyType.ptSubject, true); | |
| 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); | |
| 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 Form1_Load(object sender, EventArgs e) | |
| { | |
| toolStripStatusLabel1.Text = | |
| "Tip: Use the mouse-wheel (or +,-,0) to adjust the offset of the solution polygons."; | |
| DrawBitmap(); | |
| } | |
| //--------------------------------------------------------------------- | |
| private void bClose_Click(object sender, EventArgs e) | |
| { | |
| Close(); | |
| } | |
| //--------------------------------------------------------------------- | |
| private void Form1_Resize(object sender, EventArgs e) | |
| { | |
| if (pictureBox1.ClientRectangle.Width == 0 || | |
| pictureBox1.ClientRectangle.Height == 0) return; | |
| if (mybitmap != null) | |
| mybitmap.Dispose(); | |
| mybitmap = new Bitmap( | |
| pictureBox1.ClientRectangle.Width, | |
| pictureBox1.ClientRectangle.Height, | |
| PixelFormat.Format32bppArgb); | |
| pictureBox1.Image = mybitmap; | |
| DrawBitmap(); | |
| } | |
| //--------------------------------------------------------------------- | |
| private void rbNonZero_Click(object sender, EventArgs e) | |
| { | |
| DrawBitmap(true); | |
| } | |
| //--------------------------------------------------------------------- | |
| private void Form1_KeyDown(object sender, KeyEventArgs e) | |
| { | |
| switch (e.KeyCode) | |
| { | |
| case Keys.Escape: | |
| this.Close(); | |
| return; | |
| case Keys.F1: | |
| MessageBox.Show(this.Text + "\nby Angus Johnson\nCopyright © 2010, 2011", | |
| this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information); | |
| e.Handled = true; | |
| return; | |
| case Keys.Oemplus: | |
| case Keys.Add: | |
| if (nudOffset.Value == 10) return; | |
| nudOffset.Value += (decimal)0.5; | |
| e.Handled = true; | |
| break; | |
| case Keys.OemMinus: | |
| case Keys.Subtract: | |
| if (nudOffset.Value == -10) return; | |
| nudOffset.Value -= (decimal)0.5; | |
| e.Handled = true; | |
| break; | |
| case Keys.NumPad0: | |
| case Keys.D0: | |
| if (nudOffset.Value == 0) return; | |
| nudOffset.Value = (decimal)0; | |
| e.Handled = true; | |
| break; | |
| default: return; | |
| } | |
| } | |
| //--------------------------------------------------------------------- | |
| private void nudCount_ValueChanged(object sender, EventArgs e) | |
| { | |
| DrawBitmap(true); | |
| } | |
| //--------------------------------------------------------------------- | |
| private void rbTest1_Click(object sender, EventArgs e) | |
| { | |
| if (rbTest1.Checked) | |
| lblCount.Text = "Vertex &Count:"; | |
| else | |
| lblCount.Text = "Ellipse &Count:"; | |
| DrawBitmap(); | |
| } | |
| //--------------------------------------------------------------------- | |
| private void bSave_Click(object sender, EventArgs e) | |
| { | |
| //save to SVG ... | |
| if (saveFileDialog1.ShowDialog() == DialogResult.OK) | |
| { | |
| SVGBuilder svg = new SVGBuilder(); | |
| svg.style.brushClr = Color.FromArgb(0x10, 0, 0, 0x9c); | |
| svg.style.penClr = Color.FromArgb(0xd3, 0xd3, 0xda); | |
| svg.AddPolygons(subjects); | |
| svg.style.brushClr = Color.FromArgb(0x10, 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(saveFileDialog1.FileName, 1.0 / scale); | |
| } | |
| } | |
| //--------------------------------------------------------------------- | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment