11
22#include < cstdlib>
3+ #include < cstdint>
4+ #include < cmath>
5+ #include < string>
6+ #include < functional>
37#include " clipper2/clipper.h"
8+ #include " clipper2/clipper.core.h"
9+ #include " clipper2/clipper.engine.h"
10+ #include " clipper2/clipper.triangulation.h"
411#include " ../../Utils/clipper.svg.h"
512#include " ../../Utils/clipper.svg.utils.h"
613
@@ -9,8 +16,9 @@ using namespace Clipper2Lib;
916
1017
1118void System (const std::string &filename);
12- void TestingZ_Int64 ();
13- void TestingZ_Double ();
19+ void Test1_64 ();
20+ void Test1_Double ();
21+ void Test2_Double ();
1422
1523// use the Z callback to flag intersections by setting z = 1;
1624
@@ -34,11 +42,77 @@ class MyClass {
3442
3543int main (int argc, char * argv[])
3644{
37- // TestingZ_Int64();
38- TestingZ_Double ();
45+ Test1_64 ();
46+ Test1_Double ();
47+ Test2_Double ();
3948}
4049
41- void TestingZ_Int64 ()
50+ static uint32_t ByteToRainbowColor (uint8_t b)
51+ {
52+ uint8_t b2;
53+ switch (b / 43 )
54+ {
55+ // 0..42
56+ case 0 : b2 = (b - 0 ) * 6 ; return 0xFFFF0000 | (b2 << 8 ); // 0xFFFF0000 -> 0xFFFFFF00 (red..yellow)
57+ // 43..85
58+ case 1 : b2 = (85 - b) * 6 ; return 0xFF00FF00 | (b2 << 16 ); // 0xFFFFFF00 -> 0xFF00FF00 (yellow..lime)
59+ // 86..128
60+ case 2 : b2 = (b - 86 ) * 6 ; return 0xFF00FF00 | b2; // 0xFF00FF00 -> 0xFF00FFFF (lime..aqua)
61+ // 129..171
62+ case 3 : b2 = (171 - b) * 6 ; return 0xFF0000FF | (b2 << 8 ); // 0xFF00FFFF -> 0xFF0000FF (aqua..blue)
63+ // 172..214
64+ case 4 : b2 = (b - 172 ) * 6 ; return 0xFF0000FF | (b2 << 16 ); // 0xFF0000FF -> 0xFFFF00FF (blue..fuschia)
65+ // 215..255
66+ default : b2 = (255 - b) * 6 ; return 0xFFFF0000 | b2; // 0xFF0000FF -> 0xFFFF00FF (fuschia..red)
67+ }
68+ }
69+
70+ static void DisplayAsSvg (const string& filename,
71+ const Paths64* subject, const Paths64* clip, const Paths64* solution)
72+ {
73+ SvgWriter svg;
74+ if (subject)
75+ SvgAddSubject (svg, *subject, FillRule::NonZero);
76+ if (clip)
77+ SvgAddClip (svg, *clip, FillRule::NonZero);
78+ if (solution)
79+ SvgAddSolution (svg, *solution, FillRule::NonZero, false );
80+ SvgSaveToFile (svg, filename, 320 , 320 , 0 );
81+ System (filename);
82+ }
83+
84+ static void DisplayAsSvg (const string& filename,
85+ const PathsD* subject, const PathsD* clip, const PathsD* solution, bool multi_color = false )
86+ {
87+ SvgWriter svg;
88+ if (subject)
89+ SvgAddSubject (svg, *subject, FillRule::NonZero);
90+ if (clip)
91+ SvgAddClip (svg, *clip, FillRule::NonZero);
92+ if (solution)
93+ {
94+ if (multi_color)
95+ {
96+ #ifdef USINGZ
97+ for (const PathD& path : *solution)
98+ {
99+ // set color using the average 'z' for each triangle
100+ uint8_t d = (path.size () == 3 ) ? (path[0 ].z + path[1 ].z + path[2 ].z ) / 3.0 : 128 ;
101+ svg.AddPath (path, false , FillRule::NonZero, ByteToRainbowColor (d), 0x80808080 , 0.8 , false );
102+ }
103+ #else
104+ // just set a random color
105+ SvgAddRCSolution (svg, *solution, FillRule::NonZero, false );
106+ #endif
107+ }
108+ else
109+ SvgAddSolution (svg, *solution, FillRule::NonZero, false );
110+ }
111+ SvgSaveToFile (svg, filename, 320 , 320 , 0 );
112+ System (filename);
113+ }
114+
115+ void Test1_64 ()
42116{
43117
44118 Paths64 subject, solution;
@@ -53,24 +127,21 @@ void TestingZ_Int64()
53127 std::placeholders::_4, std::placeholders::_5));
54128 c64.Execute (ClipType::Union, FillRule::NonZero, solution);
55129
56- SvgWriter svg ;
57- SvgAddSolution (svg, solution, FillRule::NonZero, false );
58- if (solution. size () > 0 ) {
130+ Paths64 ellipses ;
131+ if ( solution. size () > 0 )
132+ {
59133 // draw circles around intersection points - flagged by z == 1
60- PathsD ellipses;
61134 double r = 3.0 ;
62135 for (const Point64& pt : solution[0 ])
63136 if (pt.z == 1 )
64137 {
65- ellipses.push_back (Ellipse (RectD (pt.x - r, pt.y - r, pt.x + r, pt.y + r), 11 ));
138+ ellipses.push_back (Ellipse (Rect64 (pt.x - r, pt.y - r, pt.x + r, pt.y + r), 11 ));
66139 }
67- SvgAddClip (svg, ellipses, FillRule::NonZero);
68140 }
69- SvgSaveToFile (svg, " usingz_int64.svg" , 800 , 600 , 20 );
70- System (" usingz_int64.svg" );
141+ DisplayAsSvg (" TestingZ1_64.svg" , &subject, &ellipses, &solution);
71142}
72143
73- void TestingZ_Double ()
144+ void Test1_Double ()
74145{
75146 PathsD subject, solution;
76147 MyClass mc;
@@ -84,22 +155,33 @@ void TestingZ_Double()
84155 std::placeholders::_4, std::placeholders::_5));
85156 c.Execute (ClipType::Union, FillRule::NonZero, solution);
86157
87- SvgWriter svg;
88- SvgAddSubject (svg, subject, FillRule::NonZero);
89- if (solution.size () > 0 )
158+ PathsD ellipses;
159+ if (solution.size () > 0 )
90160 {
91161 // draw circles around intersection points
92- PathsD ellipses;
93162 double r = 3.0 ;
94163 for (const PointD& pt : solution[0 ])
95164 if (pt.z == 1 )
96- ellipses.push_back (Ellipse (RectD (pt.x - r, pt.y - r,
165+ ellipses.push_back (Ellipse (RectD (pt.x - r, pt.y - r,
97166 pt.x + r, pt.y + r), 11 ));
98-
99- SvgAddSolution (svg, ellipses, FillRule::NonZero, false );
100167 }
101- SvgSaveToFile (svg, " usingz_double.svg" , 320 , 320 , 0 );
102- System (" usingz_double.svg" );
168+ DisplayAsSvg (" TestingZ1_D.svg" , &subject, &ellipses, &solution, false );
169+ }
170+
171+ void Test2_Double ()
172+ {
173+ SvgReader sr = SvgReader (" .\\ TriSamples\\ coral3.svg" );
174+ PathsD subject = sr.paths , sol;
175+ RectD r = GetBounds (subject);
176+ PointD mp = r.MidPoint ();
177+ double d = (mp.y - r.top ) / 255 ;
178+ // for each point in subject set, 'z' as the distance fron 'mp'
179+ // relative to 'd' and then scale to 255
180+ for (PathD& path : subject)
181+ for (PointD& pt : path)
182+ pt.z = std::sqrt (DistanceSqr (pt, mp)) / d;
183+ Triangulate (subject, 0 , sol, true );
184+ DisplayAsSvg (" coral3_t2.svg" , nullptr , nullptr , &sol, true );
103185}
104186
105187void System (const std::string &filename)
0 commit comments