private static void BuildShape() { //each "shape" may contain more than one shape (e.g. a zig-zag on the southern hemisphere between two octahedral faces will have #zig + #zag + 1 shapes) edge_pattern = new Dictionary <QuadraticBezier, QuadraticBezier>(); BuildDictionary(); DiscontinuityLocations(); AugmentDictionary(); // add edges that are along the square (0,0) -> (1,0) -> (1,1) -> (0,1) while (edge_pattern.Count != 0) // make sure there are no more shapes left to process { Dictionary <QuadraticBezier, QuadraticBezier> .Enumerator iter = edge_pattern.GetEnumerator(); iter.MoveNext(); QuadraticBezier first_edge = iter.Current.Key; QuadraticBezier current_edge = first_edge; SVGBuilder.BeginShape(); do // process every edge in each shape { SVGBuilder.SetEdge(current_edge); QuadraticBezier temp_edge = current_edge; DebugUtility.Log("Cycling:", current_edge.end_UV, current_edge.begin_UV); current_edge = edge_pattern[current_edge]; edge_pattern.Remove(temp_edge); } while (current_edge != first_edge); SVGBuilder.EndShape(); } }
//--------------------------------------------------------------------- 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); } }
//--------------------------------------------------------------------- private void bSave_Click(object sender, EventArgs e) { //save to SVG ... if (saveFileDialog1.ShowDialog() == DialogResult.OK) { PolyFillType pft = GetPolyFillType(); 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); } }
//////////////////////////////////////////////// static void Main(string[] args) { ////quick test with random polygons ... //Paths ss = new Paths(1), cc = new Paths(1), sss = new Paths(); //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.AddPaths(ss, PolyType.ptSubject, true); //cpr.AddPaths(cc, PolyType.ptClip, true); //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.AddPaths(ss); //svg1.style.brushClr = Color.FromArgb(0x20, 0x9c, 0, 0); //svg1.style.penClr = Color.FromArgb(0xff, 0xa0, 0x7a); //svg1.AddPaths(cc); //svg1.style.brushClr = Color.FromArgb(0xAA, 0x80, 0xff, 0x9c); //svg1.style.penClr = Color.FromArgb(0, 0x33, 0); //svg1.AddPaths(sss); //svg1.SaveToFile("solution.svg", 1.0 / scale); //return; if (args.Length < 5) { string appname = System.Environment.GetCommandLineArgs()[0]; appname = System.IO.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; } } Paths subjs = new Paths(); Paths clips = new Paths(); 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.AddPaths(subjs, PolyType.ptSubject, true); cp.AddPaths(clips, PolyType.ptClip, true); Paths solution = new Paths(); //Paths solution = new Paths(); 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.AddPaths(subjs); svg.style.brushClr = Color.FromArgb(0x20, 0x9c, 0, 0); svg.style.penClr = Color.FromArgb(0xff, 0xa0, 0x7a); svg.AddPaths(clips); svg.style.brushClr = Color.FromArgb(0xAA, 0x80, 0xff, 0x9c); svg.style.penClr = Color.FromArgb(0, 0x33, 0); svg.AddPaths(solution); svg.SaveToFile("solution.svg", svg_scale); Console.WriteLine("finished!"); } else { Console.WriteLine("failed!"); } }
//////////////////////////////////////////////// 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!"); } }