blob: 5026ac5344f8892b4427739df74a8199b6ee82d0 [file] [log] [blame]
caryclarkdac1d172014-06-17 05:15:38 -07001<html>
2<head>
3<div height="0" hidden="true">
caryclarkdac1d172014-06-17 05:15:38 -07004
caryclarkbca19f72015-05-13 08:23:48 -07005<div id="loops63i">
6seg=1 {{{0, 1}, {0.490384609f, 1.73557687f}, {0.499815077f, 2.00021958f}, {0.382070184f, 1.94870627f}}}
7seg=2 {{{0.382070184f, 1.94870627f}, {0.0196006298f, 1.79012585f}, {-1.54807687f, -1.36458325f}, {6, -3}}}
8seg=3 {{{6, -3}, {0, 1}}}
9op sect
10seg=4 {{{2, 4}, {-1.72877336f, 0.996266127f}, {0.721898317f, -0.977560639f}, {1.6714313f, -1.08141601f}}}
11seg=5 {{{1.6714313f, -1.08141601f}, {2.24979973f, -1.14467525f}, {2.27122664f, -0.514151096f}, {0, 1}}}
12seg=6 {{{0, 1}, {2, 4}}}
13debugShowCubicIntersection wtTs[0]=0.000769248274 {{{0,1}, {0.490384609,1.73557687}, {0.499815077,2.00021958}, {0.382070184,1.94870627}}} {{0.00113082887,1.00169671}} wtTs[1]=1 {{0.382070184,1.94870627}} wnTs[0]=0.324591 {{{0.382070184,1.94870627}, {0.0196006298,1.79012585}, {-1.54807687,-1.36458325}, {6,-3}}} wnTs[1]=0
14addT insert t=0.000769248274 segID=1 spanID=13
15addT insert t=0.324590897 segID=2 spanID=14
16debugShowCubicLineIntersection wtTs[0]=0 {{{0,1}, {0.490384609,1.73557687}, {0.499815077,2.00021958}, {0.382070184,1.94870627}}} {{0,1}} wnTs[0]=1 {{{6,-3}, {0,1}}}
17debugShowCubicLineIntersection wtTs[0]=0.325081142 {{{0.382070184,1.94870627}, {0.0196006298,1.79012585}, {-1.54807687,-1.36458325}, {6,-3}}} {{0.00104786863,0.999301434}} wtTs[1]=1 {{6,-3}} wnTs[0]=0.999825 {{{6,-3}, {0,1}}} wnTs[1]=0
18addT insert t=0.325081142 segID=2 spanID=15
19addT insert t=0.999825355 segID=3 spanID=16
20debugShowCubicIntersection wtTs[0]=0.000874182828 {{{0,1}, {0.490384609,1.73557687}, {0.499815077,2.00021958}, {0.382070184,1.94870627}}} {{0.00128495507,1.00192797}} wnTs[0]=0.39056 {{{2,4}, {-1.72877336,0.996266127}, {0.721898317,-0.977560639}, {1.6714313,-1.08141601}}}
21addT insert t=0.000874182828 segID=1 spanID=17
22addT insert t=0.390560161 segID=4 spanID=18
23debugShowCubicIntersection wtTs[0]=0 {{{0,1}, {0.490384609,1.73557687}, {0.499815077,2.00021958}, {0.382070184,1.94870627}}} {{0,1}} wnTs[0]=1 {{{1.6714313,-1.08141601}, {2.24979973,-1.14467525}, {2.27122664,-0.514151096}, {0,1}}}
24debugShowCubicLineIntersection wtTs[0]=0 {{{0,1}, {0.490384609,1.73557687}, {0.499815077,2.00021958}, {0.382070184,1.94870627}}} {{0,1}} wnTs[0]=0 {{{0,1}, {2,4}}}
25debugShowCubicIntersection wtTs[0]=0.311178311 {{{0.382070184,1.94870627}, {0.0196006298,1.79012585}, {-1.54807687,-1.36458325}, {6,-3}}} {{0.00457555428,1.06636167}} wtTs[1]=0.33834339 {{4.02102705e-06,0.93367821}} wtTs[2]=0.515074123 {{0.273102283,-0.0639350563}} wnTs[0]=0.380259 {{{2,4}, {-1.72877336,0.996266127}, {0.721898317,-0.977560639}, {1.6714313,-1.08141601}}} wnTs[1]=0.401625031 wnTs[2]=0.588973826
26addT insert t=0.311178311 segID=2 spanID=19
27addT insert t=0.380259358 segID=4 spanID=20
28addT insert t=0.33834339 segID=2 spanID=21
29addT insert t=0.401625031 segID=4 spanID=22
30addT insert t=0.515074123 segID=2 spanID=23
31addT insert t=0.588973826 segID=4 spanID=24
32debugShowCubicIntersection wtTs[0]=0.325081151 {{{0.382070184,1.94870627}, {0.0196006298,1.79012585}, {-1.54807687,-1.36458325}, {6,-3}}} {{0.00104786712,0.999301374}} wnTs[0]=0.999846 {{{1.6714313,-1.08141601}, {2.24979973,-1.14467525}, {2.27122664,-0.514151096}, {0,1}}}
33addT alias t=0.325081151 segID=2 spanID=15
34addT insert t=0.999846187 segID=5 spanID=25
35debugShowCubicLineIntersection wtTs[0]=0.324590993 {{{0.382070184,1.94870627}, {0.0196006298,1.79012585}, {-1.54807687,-1.36458325}, {6,-3}}} {{0.00113081234,1.00169623}} wnTs[0]=0.000565406 {{{0,1}, {2,4}}}
36addT alias t=0.324590993 segID=2 spanID=14
37addT insert t=0.000565406168 segID=6 spanID=26
38debugShowCubicLineIntersection wtTs[0]=0.390998296 {{{2,4}, {-1.72877336,0.996266127}, {0.721898317,-0.977560639}, {1.6714313,-1.08141601}}} {{0.00119023165,0.999206483}} wnTs[0]=0.999802 {{{6,-3}, {0,1}}}
39addT insert t=0.999801628 segID=3 spanID=27
40addT insert t=0.390998296 segID=4 spanID=28
41debugShowCubicLineIntersection wtTs[0]=1 {{{1.6714313,-1.08141601}, {2.24979973,-1.14467525}, {2.27122664,-0.514151096}, {0,1}}} {{0,1}} wnTs[0]=1 {{{6,-3}, {0,1}}}
42debugShowLineIntersection wtTs[0]=1 {{{6,-3}, {0,1}}} {{0,1}} wnTs[0]=0 {{{0,1}, {2,4}}}
43debugShowCubicIntersection wtTs[0]=0.390998305 {{{2,4}, {-1.72877336,0.996266127}, {0.721898317,-0.977560639}, {1.6714313,-1.08141601}}} {{0.00119022967,0.999206483}} wtTs[1]=1 {{1.6714313,-1.08141601}} wnTs[0]=0.999825 {{{1.6714313,-1.08141601}, {2.24979973,-1.14467525}, {2.27122664,-0.514151096}, {0,1}}} wnTs[1]=0
44addT alias t=0.390998305 segID=4 spanID=28
45addT insert t=0.999825287 segID=5 spanID=29
46debugShowCubicLineIntersection wtTs[0]=0 {{{2,4}, {-1.72877336,0.996266127}, {0.721898317,-0.977560639}, {1.6714313,-1.08141601}}} {{2,4}} wtTs[1]=0.390560259 {{0.00128493353,1.00192738}} wnTs[0]=1 {{{0,1}, {2,4}}} wnTs[1]=0.00064246676
47addT alias t=0.390560259 segID=4 spanID=18
48addT insert t=0.00064246676 segID=6 spanID=30
49debugShowCubicLineIntersection wtTs[0]=1 {{{1.6714313,-1.08141601}, {2.24979973,-1.14467525}, {2.27122664,-0.514151096}, {0,1}}} {{0,1}} wnTs[0]=0 {{{0,1}, {2,4}}}
50markDone id=6 (0,1 2,4) t=0 [11] (0,1) tEnd=0.000565406168 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
51markDone id=3 (6,-3 0,1) t=0.999825355 [16] (0.00104786863,0.999301434) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
52markDone id=3 (6,-3 0,1) t=0.999801628 [27] (0.00119023165,0.999206483) tEnd=0.999825355 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
53sortAngles [1] tStart=0 [1]
54sortAngles [1] tStart=0.000769248274 [13]
55after [1/2] 9/9 tStart=0.000769248274 tEnd=0 < [2/8] 25/25 tStart=0.324590897 tEnd=0.311178311 < [1/3] 25/25 tStart=0.000769248274 tEnd=0.000874182828 T 11
56afterPart {{{0.00113082887,1.00169671}, {0.000754170394,1.00113142}, {0.000377227514,1.00056584}, {0,1}}} id=1
57afterPart {{{0.00113082887,1.00169671}, {0.0019015128,1.02353067}, {0.00305805582,1.04508925}, {0.00457555428,1.06636167}}} id=2
58afterPart {{{0.00113082887,1.00169671}, {0.00118220953,1.00177382}, {0.00123358499,1.00185087}, {0.00128495507,1.00192797}}} id=1
59after [1/2] 9/9 tStart=0.000769248274 tEnd=0 < [2/9] 9/9 tStart=0.324590897 tEnd=0.325081142 < [2/8] 25/25 tStart=0.324590897 tEnd=0.311178311 F 12
60afterPart {{{0.00113082887,1.00169671}, {0.000754170394,1.00113142}, {0.000377227514,1.00056584}, {0,1}}} id=1
61afterPart {{{0.00113082887,1.00169671}, {0.00110265955,1.00089865}, {0.00107500573,1.00010022}, {0.00104786863,0.999301434}}} id=2
62afterPart {{{0.00113082887,1.00169671}, {0.0019015128,1.02353067}, {0.00305805582,1.04508925}, {0.00457555428,1.06636167}}} id=2
63after [2/8] 25/25 tStart=0.324590897 tEnd=0.311178311 < [2/9] 9/9 tStart=0.324590897 tEnd=0.325081142 < [1/3] 25/25 tStart=0.000769248274 tEnd=0.000874182828 F 5
64afterPart {{{0.00113082887,1.00169671}, {0.0019015128,1.02353067}, {0.00305805582,1.04508925}, {0.00457555428,1.06636167}}} id=2
65afterPart {{{0.00113082887,1.00169671}, {0.00110265955,1.00089865}, {0.00107500573,1.00010022}, {0.00104786863,0.999301434}}} id=2
66afterPart {{{0.00113082887,1.00169671}, {0.00118220953,1.00177382}, {0.00123358499,1.00185087}, {0.00128495507,1.00192797}}} id=1
67after [1/3] 25/25 tStart=0.000769248274 tEnd=0.000874182828 < [2/9] 9/9 tStart=0.324590897 tEnd=0.325081142 < [1/2] 9/9 tStart=0.000769248274 tEnd=0 T 11
68afterPart {{{0.00113082887,1.00169671}, {0.00118220953,1.00177382}, {0.00123358499,1.00185087}, {0.00128495507,1.00192797}}} id=1
69afterPart {{{0.00113082887,1.00169671}, {0.00110265955,1.00089865}, {0.00107500573,1.00010022}, {0.00104786863,0.999301434}}} id=2
70afterPart {{{0.00113082887,1.00169671}, {0.000754170394,1.00113142}, {0.000377227514,1.00056584}, {0,1}}} id=1
71after [1/2] 9/9 tStart=0.000769248274 tEnd=0 < [6/32] 25/25 tStart=0.000565406168 tEnd=0.00064246676 < [2/8] 25/25 tStart=0.324590897 tEnd=0.311178311 F 11
72afterPart {{{0.00113082887,1.00169671}, {0.000754170394,1.00113142}, {0.000377227514,1.00056584}, {0,1}}} id=1
73afterPart {{{0.00113082887,1.00169671}, {0.00128495507,1.00192797}}} id=6
74afterPart {{{0.00113082887,1.00169671}, {0.0019015128,1.02353067}, {0.00305805582,1.04508925}, {0.00457555428,1.06636167}}} id=2
75after [2/8] 25/25 tStart=0.324590897 tEnd=0.311178311 < [6/32] 25/25 tStart=0.000565406168 tEnd=0.00064246676 < [1/3] 25/25 tStart=0.000769248274 tEnd=0.000874182828 F 7
76afterPart {{{0.00113082887,1.00169671}, {0.0019015128,1.02353067}, {0.00305805582,1.04508925}, {0.00457555428,1.06636167}}} id=2
77afterPart {{{0.00113082887,1.00169671}, {0.00128495507,1.00192797}}} id=6
78afterPart {{{0.00113082887,1.00169671}, {0.00118220953,1.00177382}, {0.00123358499,1.00185087}, {0.00128495507,1.00192797}}} id=1
79after [1/3] 25/25 tStart=0.000769248274 tEnd=0.000874182828 < [6/32] 25/25 tStart=0.000565406168 tEnd=0.00064246676 < [2/9] 9/9 tStart=0.324590897 tEnd=0.325081142 T 12
80afterPart {{{0.00113082887,1.00169671}, {0.00118220953,1.00177382}, {0.00123358499,1.00185087}, {0.00128495507,1.00192797}}} id=1
81afterPart {{{0.00113082887,1.00169671}, {0.00128495507,1.00192797}}} id=6
82afterPart {{{0.00113082887,1.00169671}, {0.00110265955,1.00089865}, {0.00107500573,1.00010022}, {0.00104786863,0.999301434}}} id=2
83sortAngles [1] tStart=0.000874182828 [17]
84after [1/4] 9/9 tStart=0.000874182828 tEnd=0.000769248274 < [4/19] 25/25 tStart=0.390560161 tEnd=0.380259358 < [1/5] 25/25 tStart=0.000874182828 tEnd=1 T 11
85afterPart {{{0.00128495507,1.00192797}, {0.00123358499,1.00185087}, {0.00118220953,1.00177382}, {0.00113082887,1.00169671}}} id=1
86afterPart {{{0.00128495507,1.00192797}, {0.00204163459,1.02326208}, {0.00313570279,1.04474029}, {0.00457555428,1.06636167}}} id=4
87afterPart {{{0.00128495507,1.00192797}, {0.490400999,1.73603928}, {0.499712146,2.00017455}, {0.382070184,1.94870627}}} id=1
88after [1/4] 9/9 tStart=0.000874182828 tEnd=0.000769248274 < [4/20] 9/9 tStart=0.390560161 tEnd=0.390998296 < [4/19] 25/25 tStart=0.390560161 tEnd=0.380259358 F 12
89afterPart {{{0.00128495507,1.00192797}, {0.00123358499,1.00185087}, {0.00118220953,1.00177382}, {0.00113082887,1.00169671}}} id=1
90afterPart {{{0.00128495507,1.00192797}, {0.00125277045,1.00102055}, {0.00122119614,1.00011339}, {0.00119023165,0.999206483}}} id=4
91afterPart {{{0.00128495507,1.00192797}, {0.00204163459,1.02326208}, {0.00313570279,1.04474029}, {0.00457555428,1.06636167}}} id=4
92after [4/19] 25/25 tStart=0.390560161 tEnd=0.380259358 < [4/20] 9/9 tStart=0.390560161 tEnd=0.390998296 < [1/5] 25/25 tStart=0.000874182828 tEnd=1 F 5
93afterPart {{{0.00128495507,1.00192797}, {0.00204163459,1.02326208}, {0.00313570279,1.04474029}, {0.00457555428,1.06636167}}} id=4
94afterPart {{{0.00128495507,1.00192797}, {0.00125277045,1.00102055}, {0.00122119614,1.00011339}, {0.00119023165,0.999206483}}} id=4
95afterPart {{{0.00128495507,1.00192797}, {0.490400999,1.73603928}, {0.499712146,2.00017455}, {0.382070184,1.94870627}}} id=1
96after [1/5] 25/25 tStart=0.000874182828 tEnd=1 < [4/20] 9/9 tStart=0.390560161 tEnd=0.390998296 < [1/4] 9/9 tStart=0.000874182828 tEnd=0.000769248274 T 11
97afterPart {{{0.00128495507,1.00192797}, {0.490400999,1.73603928}, {0.499712146,2.00017455}, {0.382070184,1.94870627}}} id=1
98afterPart {{{0.00128495507,1.00192797}, {0.00125277045,1.00102055}, {0.00122119614,1.00011339}, {0.00119023165,0.999206483}}} id=4
99afterPart {{{0.00128495507,1.00192797}, {0.00123358499,1.00185087}, {0.00118220953,1.00177382}, {0.00113082887,1.00169671}}} id=1
100after [1/4] 9/9 tStart=0.000874182828 tEnd=0.000769248274 < [6/33] 9/9 tStart=0.00064246676 tEnd=0.000565406168 < [4/19] 25/25 tStart=0.390560161 tEnd=0.380259358 T 12
101afterPart {{{0.00128495507,1.00192797}, {0.00123358499,1.00185087}, {0.00118220953,1.00177382}, {0.00113082887,1.00169671}}} id=1
102afterPart {{{0.00128495507,1.00192797}, {0.00113082887,1.00169671}}} id=6
103afterPart {{{0.00128495507,1.00192797}, {0.00204163459,1.02326208}, {0.00313570279,1.04474029}, {0.00457555428,1.06636167}}} id=4
104after [1/4] 9/9 tStart=0.000874182828 tEnd=0.000769248274 < [6/34] 25/25 tStart=0.00064246676 tEnd=1 < [6/33] 9/9 tStart=0.00064246676 tEnd=0.000565406168 F 5
105afterPart {{{0.00128495507,1.00192797}, {0.00123358499,1.00185087}, {0.00118220953,1.00177382}, {0.00113082887,1.00169671}}} id=1
106afterPart {{{0.00128495507,1.00192797}, {2,4}}} id=6
107afterPart {{{0.00128495507,1.00192797}, {0.00113082887,1.00169671}}} id=6
108after [6/33] 9/9 tStart=0.00064246676 tEnd=0.000565406168 < [6/34] 25/25 tStart=0.00064246676 tEnd=1 < [4/19] 25/25 tStart=0.390560161 tEnd=0.380259358 F 11
109afterPart {{{0.00128495507,1.00192797}, {0.00113082887,1.00169671}}} id=6
110afterPart {{{0.00128495507,1.00192797}, {2,4}}} id=6
111afterPart {{{0.00128495507,1.00192797}, {0.00204163459,1.02326208}, {0.00313570279,1.04474029}, {0.00457555428,1.06636167}}} id=4
112after [4/19] 25/25 tStart=0.390560161 tEnd=0.380259358 < [6/34] 25/25 tStart=0.00064246676 tEnd=1 < [1/5] 25/25 tStart=0.000874182828 tEnd=1 F 7
113afterPart {{{0.00128495507,1.00192797}, {0.00204163459,1.02326208}, {0.00313570279,1.04474029}, {0.00457555428,1.06636167}}} id=4
114afterPart {{{0.00128495507,1.00192797}, {2,4}}} id=6
115afterPart {{{0.00128495507,1.00192797}, {0.490400999,1.73603928}, {0.499712146,2.00017455}, {0.382070184,1.94870627}}} id=1
116after [1/5] 25/25 tStart=0.000874182828 tEnd=1 < [6/34] 25/25 tStart=0.00064246676 tEnd=1 < [4/20] 9/9 tStart=0.390560161 tEnd=0.390998296 T 12
117afterPart {{{0.00128495507,1.00192797}, {0.490400999,1.73603928}, {0.499712146,2.00017455}, {0.382070184,1.94870627}}} id=1
118afterPart {{{0.00128495507,1.00192797}, {2,4}}} id=6
119afterPart {{{0.00128495507,1.00192797}, {0.00125277045,1.00102055}, {0.00122119614,1.00011339}, {0.00119023165,0.999206483}}} id=4
120sortAngles [2] tStart=0.311178311 [19]
121after [2/6] 25/25 tStart=0.311178311 tEnd=0 < [4/17] 25/25 tStart=0.380259358 tEnd=0 < [2/7] 9/9 tStart=0.311178311 tEnd=0.324590897 F 12
122afterPart {{{0.00457555428,1.06636167}, {0.039782232,1.5598917}, {0.26927752,1.89935948}, {0.382070184,1.94870627}}} id=2
123afterPart {{{0.00457555428,1.06636167}, {0.0577283974,1.8645258}, {0.582099039,2.85780209}, {2,4}}} id=4
124afterPart {{{0.00457555428,1.06636167}, {0.00305805582,1.04508925}, {0.0019015128,1.02353067}, {0.00113082887,1.00169671}}} id=2
125after [2/6] 25/25 tStart=0.311178311 tEnd=0 < [4/18] 9/9 tStart=0.380259358 tEnd=0.390560161 < [2/7] 9/9 tStart=0.311178311 tEnd=0.324590897 T 11
126afterPart {{{0.00457555428,1.06636167}, {0.039782232,1.5598917}, {0.26927752,1.89935948}, {0.382070184,1.94870627}}} id=2
127afterPart {{{0.00457555428,1.06636167}, {0.00313570279,1.04474029}, {0.00204163459,1.02326208}, {0.00128495507,1.00192797}}} id=4
128afterPart {{{0.00457555428,1.06636167}, {0.00305805582,1.04508925}, {0.0019015128,1.02353067}, {0.00113082887,1.00169671}}} id=2
129sortAngles [2] tStart=0.324590897 [14]
130sortAngles [2] tStart=0.325081142 [15]
131after [2/10] 25/25 tStart=0.325081142 tEnd=0.324590897 < [5/29] 1/1 tStart=0.999846187 tEnd=0.999825287 < [2/11] 9/9 tStart=0.325081142 tEnd=0.33834339 T 4
132afterPart {{{0.00104786863,0.999301434}, {0.00107500573,1.00010022}, {0.00110265955,1.00089865}, {0.00113082887,1.00169671}}} id=2
133afterPart {{{0.00104786863,0.999301434}, {0.00109532382,0.999269793}, {0.00114277846,0.999238124}, {0.00119023165,0.999206483}}} id=5
134afterPart {{{0.00104786863,0.999301434}, {0.00031374693,0.977692314}, {-4.22273526e-05,0.955814396}, {4.02102705e-06,0.93367821}}} id=2
135after [2/10] 25/25 tStart=0.325081142 tEnd=0.324590897 < [5/30] 17/17 tStart=0.999846187 tEnd=1 < [5/29] 1/1 tStart=0.999846187 tEnd=0.999825287 F 4
136afterPart {{{0.00104786863,0.999301434}, {0.00107500573,1.00010022}, {0.00110265955,1.00089865}, {0.00113082887,1.00169671}}} id=2
137afterPart {{{0.00104786863,0.999301434}, {0.000698633821,0.999534287}, {0.000349343284,0.999767104}, {0,1}}} id=5
138afterPart {{{0.00104786863,0.999301434}, {0.00109532382,0.999269793}, {0.00114277846,0.999238124}, {0.00119023165,0.999206483}}} id=5
139after [5/29] 1/1 tStart=0.999846187 tEnd=0.999825287 < [5/30] 17/17 tStart=0.999846187 tEnd=1 < [2/11] 9/9 tStart=0.325081142 tEnd=0.33834339 F 4
140afterPart {{{0.00104786863,0.999301434}, {0.00109532382,0.999269793}, {0.00114277846,0.999238124}, {0.00119023165,0.999206483}}} id=5
141afterPart {{{0.00104786863,0.999301434}, {0.000698633821,0.999534287}, {0.000349343284,0.999767104}, {0,1}}} id=5
142afterPart {{{0.00104786863,0.999301434}, {0.00031374693,0.977692314}, {-4.22273526e-05,0.955814396}, {4.02102705e-06,0.93367821}}} id=2
143after [2/11] 9/9 tStart=0.325081142 tEnd=0.33834339 < [5/30] 17/17 tStart=0.999846187 tEnd=1 < [2/10] 25/25 tStart=0.325081142 tEnd=0.324590897 T 4
144afterPart {{{0.00104786863,0.999301434}, {0.00031374693,0.977692314}, {-4.22273526e-05,0.955814396}, {4.02102705e-06,0.93367821}}} id=2
145afterPart {{{0.00104786863,0.999301434}, {0.000698633821,0.999534287}, {0.000349343284,0.999767104}, {0,1}}} id=5
146afterPart {{{0.00104786863,0.999301434}, {0.00107500573,1.00010022}, {0.00110265955,1.00089865}, {0.00113082887,1.00169671}}} id=2
147sortAngles [2] tStart=0.33834339 [21]
148after [2/12] 21/25 tStart=0.33834339 tEnd=0.325081142 < [4/23] 25/25 tStart=0.401625031 tEnd=0.390998296 < [2/13] 5/5 tStart=0.33834339 tEnd=0.515074123 T 12
149afterPart {{{4.02102705e-06,0.93367821}, {-4.22273526e-05,0.955814396}, {0.00031374693,0.977692314}, {0.00104786863,0.999301434}}} id=2
150afterPart {{{4.02102705e-06,0.93367821}, {4.68720371e-05,0.955366912}, {0.000439203198,0.977209978}, {0.00119023165,0.999206483}}} id=4
151afterPart {{{4.02102705e-06,0.93367821}, {0.000620320001,0.638694712}, {0.0726626179,0.297848628}, {0.273102283,-0.0639350563}}} id=2
152after [2/12] 21/25 tStart=0.33834339 tEnd=0.325081142 < [4/24] 9/5 tStart=0.401625031 tEnd=0.588973826 < [4/23] 25/25 tStart=0.401625031 tEnd=0.390998296 F 5
153afterPart {{{4.02102705e-06,0.93367821}, {-4.22273526e-05,0.955814396}, {0.00031374693,0.977692314}, {0.00104786863,0.999301434}}} id=2
154afterPart {{{4.02102705e-06,0.93367821}, {-0.000751440063,0.551307505}, {0.107116791,0.216928359}, {0.273102283,-0.0639350563}}} id=4
155afterPart {{{4.02102705e-06,0.93367821}, {4.68720371e-05,0.955366912}, {0.000439203198,0.977209978}, {0.00119023165,0.999206483}}} id=4
156after [4/23] 25/25 tStart=0.401625031 tEnd=0.390998296 < [4/24] 9/5 tStart=0.401625031 tEnd=0.588973826 < [2/13] 5/5 tStart=0.33834339 tEnd=0.515074123 F 11
157afterPart {{{4.02102705e-06,0.93367821}, {4.68720371e-05,0.955366912}, {0.000439203198,0.977209978}, {0.00119023165,0.999206483}}} id=4
158afterPart {{{4.02102705e-06,0.93367821}, {-0.000751440063,0.551307505}, {0.107116791,0.216928359}, {0.273102283,-0.0639350563}}} id=4
159afterPart {{{4.02102705e-06,0.93367821}, {0.000620320001,0.638694712}, {0.0726626179,0.297848628}, {0.273102283,-0.0639350563}}} id=2
160after [2/13] 5/5 tStart=0.33834339 tEnd=0.515074123 < [4/24] 9/5 tStart=0.401625031 tEnd=0.588973826 < [2/12] 21/25 tStart=0.33834339 tEnd=0.325081142 T 12
161afterPart {{{4.02102705e-06,0.93367821}, {0.000620320001,0.638694712}, {0.0726626179,0.297848628}, {0.273102283,-0.0639350563}}} id=2
162afterPart {{{4.02102705e-06,0.93367821}, {-0.000751440063,0.551307505}, {0.107116791,0.216928359}, {0.273102283,-0.0639350563}}} id=4
163afterPart {{{4.02102705e-06,0.93367821}, {-4.22273526e-05,0.955814396}, {0.00031374693,0.977692314}, {0.00104786863,0.999301434}}} id=2
164sortAngles [2] tStart=0.515074123 [23]
165after [2/14] 21/21 tStart=0.515074123 tEnd=0.33834339 < [4/25] 21/21 tStart=0.588973826 tEnd=0.401625031 < [2/15] 5/1 tStart=0.515074123 tEnd=1 F 12
166afterPart {{{0.273102283,-0.0639350563}, {0.0726626179,0.297848628}, {0.000620320001,0.638694712}, {4.02102705e-06,0.93367821}}} id=2
167afterPart {{{0.273102283,-0.0639350563}, {0.107116791,0.216928359}, {-0.000751440063,0.551307505}, {4.02102705e-06,0.93367821}}} id=4
168afterPart {{{0.273102283,-0.0639350563}, {0.823082351,-1.05662188}, {2.33974221,-2.2069441}, {6,-3}}} id=2
169after [2/14] 21/21 tStart=0.515074123 tEnd=0.33834339 < [4/26] 5/1 tStart=0.588973826 tEnd=1 < [2/15] 5/1 tStart=0.515074123 tEnd=1 T 11
170afterPart {{{0.273102283,-0.0639350563}, {0.0726626179,0.297848628}, {0.000620320001,0.638694712}, {4.02102705e-06,0.93367821}}} id=2
171afterPart {{{0.273102283,-0.0639350563}, {0.637259321,-0.680123784}, {1.28114839,-1.03872873}, {1.6714313,-1.08141601}}} id=4
172afterPart {{{0.273102283,-0.0639350563}, {0.823082351,-1.05662188}, {2.33974221,-2.2069441}, {6,-3}}} id=2
173sortAngles [3] tStart=0.999801628 [27]
174after [3/16] 1/1 tStart=0.999801628 tEnd=0 < [4/22] 9/9 tStart=0.390998296 tEnd=0.401625031 < [4/21] 25/25 tStart=0.390998296 tEnd=0.390560161 T 4
175afterPart {{{0.00119023165,0.999206483}, {6,-3}}} id=3
176afterPart {{{0.00119023165,0.999206483}, {0.000439203198,0.977209978}, {4.68720371e-05,0.955366912}, {4.02102705e-06,0.93367821}}} id=4
177afterPart {{{0.00119023165,0.999206483}, {0.00122119614,1.00011339}, {0.00125277045,1.00102055}, {0.00128495507,1.00192797}}} id=4
178after [3/16] 1/1 tStart=0.999801628 tEnd=0 < [5/27] 1/5 tStart=0.999825287 tEnd=0 < [4/22] 9/9 tStart=0.390998296 tEnd=0.401625031 T 7
179afterPart {{{0.00119023165,0.999206483}, {6,-3}}} id=3
180afterPart {{{0.00119023165,0.999206483}, {2.27121914,-0.514371368}, {2.24969868,-1.1446642}, {1.6714313,-1.08141601}}} id=5
181afterPart {{{0.00119023165,0.999206483}, {0.000439203198,0.977209978}, {4.68720371e-05,0.955366912}, {4.02102705e-06,0.93367821}}} id=4
182after [3/16] 1/1 tStart=0.999801628 tEnd=0 < [5/28] 17/17 tStart=0.999825287 tEnd=0.999846187 < [5/27] 1/5 tStart=0.999825287 tEnd=0 F 5
183afterPart {{{0.00119023165,0.999206483}, {6,-3}}} id=3
184afterPart {{{0.00119023165,0.999206483}, {0.00114277846,0.999238124}, {0.00109532382,0.999269793}, {0.00104786863,0.999301434}}} id=5
185afterPart {{{0.00119023165,0.999206483}, {2.27121914,-0.514371368}, {2.24969868,-1.1446642}, {1.6714313,-1.08141601}}} id=5
186after [5/27] 1/5 tStart=0.999825287 tEnd=0 < [5/28] 17/17 tStart=0.999825287 tEnd=0.999846187 < [4/22] 9/9 tStart=0.390998296 tEnd=0.401625031 F 4
187afterPart {{{0.00119023165,0.999206483}, {2.27121914,-0.514371368}, {2.24969868,-1.1446642}, {1.6714313,-1.08141601}}} id=5
188afterPart {{{0.00119023165,0.999206483}, {0.00114277846,0.999238124}, {0.00109532382,0.999269793}, {0.00104786863,0.999301434}}} id=5
189afterPart {{{0.00119023165,0.999206483}, {0.000439203198,0.977209978}, {4.68720371e-05,0.955366912}, {4.02102705e-06,0.93367821}}} id=4
190after [4/22] 9/9 tStart=0.390998296 tEnd=0.401625031 < [5/28] 17/17 tStart=0.999825287 tEnd=0.999846187 < [4/21] 25/25 tStart=0.390998296 tEnd=0.390560161 T 4
191afterPart {{{0.00119023165,0.999206483}, {0.000439203198,0.977209978}, {4.68720371e-05,0.955366912}, {4.02102705e-06,0.93367821}}} id=4
192afterPart {{{0.00119023165,0.999206483}, {0.00114277846,0.999238124}, {0.00109532382,0.999269793}, {0.00104786863,0.999301434}}} id=5
193afterPart {{{0.00119023165,0.999206483}, {0.00122119614,1.00011339}, {0.00125277045,1.00102055}, {0.00128495507,1.00192797}}} id=4
194sortAngles [4] tStart=0.380259358 [20]
195sortAngles [4] tStart=0.390560161 [18]
196sortAngles [4] tStart=0.390998296 [28]
197sortAngles [4] tStart=0.401625031 [22]
198sortAngles [4] tStart=0.588973826 [24]
199sortAngles [5] tStart=0.999825287 [29]
200sortAngles [5] tStart=0.999846187 [25]
201sortAngles [5] tStart=1 [10]
202sortAngles [6] tStart=0.000565406168 [26]
203sortAngles [6] tStart=0.00064246676 [30]
204debugShowCoincidence - id=1 t=0 tEnd=0.000769248274
205debugShowCoincidence + id=6 t=0 tEnd=0.000565406168
206debugShowCoincidence - id=5 t=0.999846187 tEnd=1
207debugShowCoincidence + id=3 t=0.999825355 tEnd=1
208debugShowCoincidence - id=5 t=0.999825287 tEnd=0.999846187
209debugShowCoincidence + id=3 t=0.999801628 tEnd=0.999825355
210debugShowActiveSpans id=1 (0,1 0.490384609,1.73557687 0.499815077,2.00021958 0.382070184,1.94870627) t=0 (0,1) tEnd=0.000769248274 windSum=? oppSum=? windValue=1 oppValue=1
211debugShowActiveSpans id=1 (0,1 0.490384609,1.73557687 0.499815077,2.00021958 0.382070184,1.94870627) t=0.000769248274 (0.00113082887,1.00169671) tEnd=0.000874182828 windSum=? windValue=1
212debugShowActiveSpans id=1 (0,1 0.490384609,1.73557687 0.499815077,2.00021958 0.382070184,1.94870627) t=0.000874182828 (0.00128495507,1.00192797) tEnd=1 windSum=? windValue=1
213debugShowActiveSpans id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0 (0.382070184,1.94870627) tEnd=0.311178311 windSum=? windValue=1
214debugShowActiveSpans id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0.311178311 (0.00457555428,1.06636167) tEnd=0.324590897 windSum=? windValue=1
215debugShowActiveSpans id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0.324590897 (0.00113082887,1.00169671) tEnd=0.325081142 windSum=? windValue=1
216debugShowActiveSpans id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0.325081142 (0.00104786863,0.999301434) tEnd=0.33834339 windSum=? windValue=1
217debugShowActiveSpans id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0.33834339 (4.02102705e-06,0.93367821) tEnd=0.515074123 windSum=? windValue=1
218debugShowActiveSpans id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0.515074123 (0.273102283,-0.0639350563) tEnd=1 windSum=? windValue=1
219debugShowActiveSpans id=3 (6,-3 0,1) t=0 (6,-3) tEnd=0.999801628 windSum=? windValue=1
220debugShowActiveSpans id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0 (2,4) tEnd=0.380259358 windSum=? windValue=1
221debugShowActiveSpans id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.380259358 (0.00457555428,1.06636167) tEnd=0.390560161 windSum=? windValue=1
222debugShowActiveSpans id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.390560161 (0.00128495507,1.00192797) tEnd=0.390998296 windSum=? windValue=1
223debugShowActiveSpans id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.390998296 (0.00119023165,0.999206483) tEnd=0.401625031 windSum=? windValue=1
224debugShowActiveSpans id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.401625031 (4.02102705e-06,0.93367821) tEnd=0.588973826 windSum=? windValue=1
225debugShowActiveSpans id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.588973826 (0.273102283,-0.0639350563) tEnd=1 windSum=? windValue=1
226debugShowActiveSpans id=5 (1.6714313,-1.08141601 2.24979973,-1.14467525 2.27122664,-0.514151096 0,1) t=0 (1.6714313,-1.08141601) tEnd=0.999825287 windSum=? windValue=1
227debugShowActiveSpans id=5 (1.6714313,-1.08141601 2.24979973,-1.14467525 2.27122664,-0.514151096 0,1) t=0.999825287 (0.00119023165,0.999206483) tEnd=0.999846187 windSum=? oppSum=? windValue=1 oppValue=1
228debugShowActiveSpans id=5 (1.6714313,-1.08141601 2.24979973,-1.14467525 2.27122664,-0.514151096 0,1) t=0.999846187 (0.00104786863,0.999301434) tEnd=1 windSum=? oppSum=? windValue=1 oppValue=1
229debugShowActiveSpans id=6 (0,1 2,4) t=0.000565406168 (0.00113082887,1.00169671) tEnd=0.00064246676 windSum=? windValue=1
230debugShowActiveSpans id=6 (0,1 2,4) t=0.00064246676 (0.00128495507,1.00192797) tEnd=1 windSum=? windValue=1
231sortableTop dir=kLeft seg=1 t=0.000384624137 pt=(0.000565627823,1.00084853)
232sortableTop [0] valid=1 operand=0 span=1 ccw=0 seg=1 {{{0, 1}, {0.490384609f, 1.73557687f}, {0.499815077f, 2.00021958f}, {0.382070184f, 1.94870627f}}} t=0.000384624137 pt=(0.000565627823,1.00084853) slope=(1.47004406,2.20564388)
233markWinding id=1 (0,1 0.490384609,1.73557687 0.499815077,2.00021958 0.382070184,1.94870627) t=0 [1] (0,1) tEnd=0.000769248274 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=1
234markWinding id=1 (0,1 0.490384609,1.73557687 0.499815077,2.00021958 0.382070184,1.94870627) t=0 [1] (0,1) tEnd=0.000769248274 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=1
235nextChase mismatched signs
236markWinding id=5 (1.6714313,-1.08141601 2.24979973,-1.14467525 2.27122664,-0.514151096 0,1) t=0.999846187 [25] (0.00104786863,0.999301434) tEnd=1 newWindSum=1 newOppSum=1 oppSum=? windSum=? windValue=1 oppValue=1
237activeOp id=1 t=0.000769248274 tEnd=0 op=sect miFrom=1 miTo=0 suFrom=1 suTo=0 result=1
238nextChase mismatched signs
239findNextOp simple
240markDone id=1 (0,1 0.490384609,1.73557687 0.499815077,2.00021958 0.382070184,1.94870627) t=0 [1] (0,1) tEnd=0.000769248274 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=1
241bridgeOp current id=1 from=(0.00113082887,1.00169671) to=(0,1)
242path.moveTo(0.00113082887,1.00169671);
243path.cubicTo(0.000754170411,1.00113142, 0.000377227523,1.00056589, 0,1);
244markWinding id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0.324590897 [14] (0.00113082887,1.00169671) tEnd=0.325081142 newWindSum=1 newOppSum=1 oppSum=? windSum=? windValue=1 oppValue=0
245markAngle last segment=2 span=14 windSum=1
246markWinding id=5 (1.6714313,-1.08141601 2.24979973,-1.14467525 2.27122664,-0.514151096 0,1) t=0.999825287 [29] (0.00119023165,0.999206483) tEnd=0.999846187 newWindSum=1 newOppSum=-1 oppSum=? windSum=? windValue=1 oppValue=1
247markAngle last segment=5 span=29 windSum=1
248markWinding id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0.325081142 [15] (0.00104786863,0.999301434) tEnd=0.33834339 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
249markAngle last segment=2 span=21 windSum=?
250findNextOp
251dumpOne [5/30] next=2/10 sect=17/17 s=0.999846187 [25] e=1 [10] sgn=-1 windVal=1 windSum=1 oppVal=1 oppSum=1 operand
252dumpOne [2/10] next=5/29 sect=25/25 s=0.325081142 [15] e=0.324590897 [14] sgn=1 windVal=1 windSum=1 oppVal=0 oppSum=1
253dumpOne [5/29] next=2/11 sect=1/1 s=0.999846187 [25] e=0.999825287 [29] sgn=1 windVal=1 windSum=1 oppVal=1 oppSum=-1 operand
254dumpOne [2/11] next=5/30 sect=9/9 s=0.325081142 [15] e=0.33834339 [21] sgn=-1 windVal=1 windSum=-1 oppVal=0 oppSum=0
255activeOp id=2 t=0.325081142 tEnd=0.324590897 op=sect miFrom=1 miTo=0 suFrom=1 suTo=1 result=1
256findNextOp chase.append segment=2 span=14 windSum=1
257activeOp id=5 t=0.999846187 tEnd=0.999825287 op=sect miFrom=0 miTo=1 suFrom=1 suTo=0 result=0
258markDone id=5 (1.6714313,-1.08141601 2.24979973,-1.14467525 2.27122664,-0.514151096 0,1) t=0.999825287 [29] (0.00119023165,0.999206483) tEnd=0.999846187 newWindSum=1 newOppSum=-1 oppSum=-1 windSum=1 windValue=1 oppValue=1
259findNextOp chase.append segment=5 span=29 windSum=1
260activeOp id=2 t=0.325081142 tEnd=0.33834339 op=sect miFrom=1 miTo=0 suFrom=0 suTo=0 result=0
261markDone id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0.325081142 [15] (0.00104786863,0.999301434) tEnd=0.33834339 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
262findNextOp chase.append segment=2 span=21 windSum=-2147483647
263markDone id=5 (1.6714313,-1.08141601 2.24979973,-1.14467525 2.27122664,-0.514151096 0,1) t=0.999846187 [25] (0.00104786863,0.999301434) tEnd=1 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=1
264findNextOp from:[5] to:[2] start=25208280 end=25208144
265bridgeOp current id=5 from=(0,1) to=(0.00104786863,0.999301434)
266path.cubicTo(0.000349343289,0.999767125, 0.000698633841,0.999534309, 0.00104786863,0.999301434);
267markWinding id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0.311178311 [19] (0.00457555428,1.06636167) tEnd=0.324590897 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
268markAngle last segment=2 span=19 windSum=-1
269markWinding id=1 (0,1 0.490384609,1.73557687 0.499815077,2.00021958 0.382070184,1.94870627) t=0.000769248274 [13] (0.00113082887,1.00169671) tEnd=0.000874182828 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
270markAngle last segment=1 span=17 windSum=?
271markWinding id=6 (0,1 2,4) t=0.000565406168 [26] (0.00113082887,1.00169671) tEnd=0.00064246676 newWindSum=1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
272markAngle last segment=6 span=30 windSum=?
273findNextOp
274dumpOne [2/9] next=1/2 sect=9/9 s=0.324590897 [14] e=0.325081142 [15] sgn=-1 windVal=1 windSum=1 oppVal=0 oppSum=1
275dumpOne [1/2] next=2/8 sect=9/9 s=0.000769248274 [13] e=0 [1] sgn=1 windVal=1 windSum=1 oppVal=1 oppSum=1 done
276dumpOne [2/8] next=1/3 sect=25/25 s=0.324590897 [14] e=0.311178311 [19] sgn=1 windVal=1 windSum=-1 oppVal=0 oppSum=0
277dumpOne [1/3] next=6/32 sect=25/25 s=0.000769248274 [13] e=0.000874182828 [17] sgn=-1 windVal=1 windSum=-1 oppVal=0 oppSum=0
278dumpOne [6/32] next=2/9 sect=25/25 s=0.000565406168 [26] e=0.00064246676 [30] sgn=-1 windVal=1 windSum=1 oppVal=0 oppSum=0 operand
279activeOp id=1 t=0.000769248274 tEnd=0 op=sect miFrom=1 miTo=0 suFrom=1 suTo=0 result=1
280activeOp id=2 t=0.324590897 tEnd=0.311178311 op=sect miFrom=0 miTo=1 suFrom=0 suTo=0 result=0
281markDone id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0.311178311 [19] (0.00457555428,1.06636167) tEnd=0.324590897 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
282findNextOp chase.append segment=2 span=19 windSum=-1
283activeOp id=1 t=0.000769248274 tEnd=0.000874182828 op=sect miFrom=1 miTo=0 suFrom=0 suTo=0 result=0
284markDone id=1 (0,1 0.490384609,1.73557687 0.499815077,2.00021958 0.382070184,1.94870627) t=0.000769248274 [13] (0.00113082887,1.00169671) tEnd=0.000874182828 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
285findNextOp chase.append segment=1 span=17 windSum=-2147483647
286activeOp id=6 t=0.000565406168 tEnd=0.00064246676 op=sect miFrom=0 miTo=0 suFrom=0 suTo=1 result=0
287markDone id=6 (0,1 2,4) t=0.000565406168 [26] (0.00113082887,1.00169671) tEnd=0.00064246676 newWindSum=1 newOppSum=0 oppSum=0 windSum=1 windValue=1 oppValue=0
288findNextOp chase.append segment=6 span=30 windSum=-2147483647
289markDone id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0.324590897 [14] (0.00113082887,1.00169671) tEnd=0.325081142 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=0
290findNextOp from:[2] to:[1] start=25208008 end=1606414720
291bridgeOp current id=2 from=(0.00104786863,0.999301434) to=(0.00113082887,1.00169671)
292path.cubicTo(0.00107500574,1.00010026, 0.0011026595,1.0008986, 0.00113082887,1.00169671);
caryclark624637c2015-05-11 07:21:27 -0700293path.close();
caryclarkbca19f72015-05-13 08:23:48 -0700294markWinding id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.380259358 [20] (0.00457555428,1.06636167) tEnd=0.390560161 newWindSum=-2 newOppSum=-1 oppSum=? windSum=? windValue=1 oppValue=0
295markAngle last segment=4 span=20 windSum=-2
296markWinding id=1 (0,1 0.490384609,1.73557687 0.499815077,2.00021958 0.382070184,1.94870627) t=0.000874182828 [17] (0.00128495507,1.00192797) tEnd=1 newWindSum=-1 newOppSum=-2 oppSum=? windSum=? windValue=1 oppValue=0
297markWinding id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0 [3] (0.382070184,1.94870627) tEnd=0.311178311 newWindSum=-1 newOppSum=-2 oppSum=? windSum=? windValue=1 oppValue=0
298markAngle last segment=2 span=19 windSum=-1
299markWinding id=6 (0,1 2,4) t=0.00064246676 [30] (0.00128495507,1.00192797) tEnd=1 newWindSum=-2 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
300markWinding id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0 [7] (2,4) tEnd=0.380259358 newWindSum=-2 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
301markAngle last segment=4 span=20 windSum=-2
302markWinding id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.390560161 [18] (0.00128495507,1.00192797) tEnd=0.390998296 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
303markAngle last segment=4 span=28 windSum=?
304debugShowActiveSpans id=1 (0,1 0.490384609,1.73557687 0.499815077,2.00021958 0.382070184,1.94870627) t=0.000874182828 (0.00128495507,1.00192797) tEnd=1 windSum=-1 oppSum=-2 windValue=1 oppValue=0
305debugShowActiveSpans id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0 (0.382070184,1.94870627) tEnd=0.311178311 windSum=-1 oppSum=-2 windValue=1 oppValue=0
306debugShowActiveSpans id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0.33834339 (4.02102705e-06,0.93367821) tEnd=0.515074123 windSum=? windValue=1
307debugShowActiveSpans id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0.515074123 (0.273102283,-0.0639350563) tEnd=1 windSum=? windValue=1
308debugShowActiveSpans id=3 (6,-3 0,1) t=0 (6,-3) tEnd=0.999801628 windSum=? windValue=1
309debugShowActiveSpans id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0 (2,4) tEnd=0.380259358 windSum=-2 oppSum=0 windValue=1 oppValue=0
310debugShowActiveSpans id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.380259358 (0.00457555428,1.06636167) tEnd=0.390560161 windSum=-2 oppSum=-1 windValue=1 oppValue=0
311debugShowActiveSpans id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.390560161 (0.00128495507,1.00192797) tEnd=0.390998296 windSum=-1 oppSum=0 windValue=1 oppValue=0
312debugShowActiveSpans id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.390998296 (0.00119023165,0.999206483) tEnd=0.401625031 windSum=? windValue=1
313debugShowActiveSpans id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.401625031 (4.02102705e-06,0.93367821) tEnd=0.588973826 windSum=? windValue=1
314debugShowActiveSpans id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.588973826 (0.273102283,-0.0639350563) tEnd=1 windSum=? windValue=1
315debugShowActiveSpans id=5 (1.6714313,-1.08141601 2.24979973,-1.14467525 2.27122664,-0.514151096 0,1) t=0 (1.6714313,-1.08141601) tEnd=0.999825287 windSum=? windValue=1
316debugShowActiveSpans id=6 (0,1 2,4) t=0.00064246676 (0.00128495507,1.00192797) tEnd=1 windSum=-2 oppSum=0 windValue=1 oppValue=0
317activeOp id=4 t=0.390560161 tEnd=0.380259358 op=sect miFrom=1 miTo=1 suFrom=1 suTo=1 result=0
318markDone id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.380259358 [20] (0.00457555428,1.06636167) tEnd=0.390560161 newWindSum=-2 newOppSum=-1 oppSum=-1 windSum=-2 windValue=1 oppValue=0
319bridgeOp chase.append id=4 windSum=-2
320debugShowActiveSpans id=1 (0,1 0.490384609,1.73557687 0.499815077,2.00021958 0.382070184,1.94870627) t=0.000874182828 (0.00128495507,1.00192797) tEnd=1 windSum=-1 oppSum=-2 windValue=1 oppValue=0
321debugShowActiveSpans id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0 (0.382070184,1.94870627) tEnd=0.311178311 windSum=-1 oppSum=-2 windValue=1 oppValue=0
322debugShowActiveSpans id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0.33834339 (4.02102705e-06,0.93367821) tEnd=0.515074123 windSum=? windValue=1
323debugShowActiveSpans id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0.515074123 (0.273102283,-0.0639350563) tEnd=1 windSum=? windValue=1
324debugShowActiveSpans id=3 (6,-3 0,1) t=0 (6,-3) tEnd=0.999801628 windSum=? windValue=1
325debugShowActiveSpans id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0 (2,4) tEnd=0.380259358 windSum=-2 oppSum=0 windValue=1 oppValue=0
326debugShowActiveSpans id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.390560161 (0.00128495507,1.00192797) tEnd=0.390998296 windSum=-1 oppSum=0 windValue=1 oppValue=0
327debugShowActiveSpans id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.390998296 (0.00119023165,0.999206483) tEnd=0.401625031 windSum=? windValue=1
328debugShowActiveSpans id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.401625031 (4.02102705e-06,0.93367821) tEnd=0.588973826 windSum=? windValue=1
329debugShowActiveSpans id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.588973826 (0.273102283,-0.0639350563) tEnd=1 windSum=? windValue=1
330debugShowActiveSpans id=5 (1.6714313,-1.08141601 2.24979973,-1.14467525 2.27122664,-0.514151096 0,1) t=0 (1.6714313,-1.08141601) tEnd=0.999825287 windSum=? windValue=1
331debugShowActiveSpans id=6 (0,1 2,4) t=0.00064246676 (0.00128495507,1.00192797) tEnd=1 windSum=-2 oppSum=0 windValue=1 oppValue=0
332activeOp id=2 t=0.311178311 tEnd=0 op=sect miFrom=0 miTo=1 suFrom=1 suTo=1 result=1
333findNextOp simple
334markDone id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0 [3] (0.382070184,1.94870627) tEnd=0.311178311 newWindSum=-1 newOppSum=-2 oppSum=-2 windSum=-1 windValue=1 oppValue=0
335bridgeOp current id=2 from=(0.00457555428,1.06636167) to=(0.382070184,1.94870627)
336path.moveTo(0.00457555428,1.06636167);
337path.cubicTo(0.0397822335,1.5598917, 0.269277513,1.89935946, 0.382070184,1.94870627);
338findNextOp
339dumpOne [1/5] next=6/34 sect=25/25 s=0.000874182828 [17] e=1 [2] sgn=-1 windVal=1 windSum=-1 oppVal=0 oppSum=-2
340dumpOne [6/34] next=4/20 sect=25/25 s=0.00064246676 [30] e=1 [12] sgn=-1 windVal=1 windSum=-2 oppVal=0 oppSum=0 operand
341dumpOne [4/20] next=1/4 sect=9/9 s=0.390560161 [18] e=0.390998296 [28] sgn=-1 windVal=1 windSum=-1 oppVal=0 oppSum=0 operand
342dumpOne [1/4] next=6/33 sect=9/9 s=0.000874182828 [17] e=0.000769248274 [13] sgn=1 windVal=1 windSum=-1 oppVal=0 oppSum=0 done
343dumpOne [6/33] next=4/19 sect=9/9 s=0.00064246676 [30] e=0.000565406168 [26] sgn=1 windVal=1 windSum=1 oppVal=0 oppSum=0 done operand
344dumpOne [4/19] next=1/5 sect=25/25 s=0.390560161 [18] e=0.380259358 [20] sgn=1 windVal=1 windSum=-2 oppVal=0 oppSum=-1 done operand
345activeOp id=6 t=0.00064246676 tEnd=1 op=sect miFrom=0 miTo=0 suFrom=1 suTo=1 result=0
346markDone id=6 (0,1 2,4) t=0.00064246676 [30] (0.00128495507,1.00192797) tEnd=1 newWindSum=-2 newOppSum=0 oppSum=0 windSum=-2 windValue=1 oppValue=0
347markDone id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0 [7] (2,4) tEnd=0.380259358 newWindSum=-2 newOppSum=0 oppSum=0 windSum=-2 windValue=1 oppValue=0
348activeOp id=4 t=0.390560161 tEnd=0.390998296 op=sect miFrom=0 miTo=0 suFrom=1 suTo=0 result=0
349markDone id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.390560161 [18] (0.00128495507,1.00192797) tEnd=0.390998296 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
350activeOp id=1 t=0.000874182828 tEnd=0.000769248274 op=sect miFrom=0 miTo=1 suFrom=0 suTo=0 result=0
351activeOp id=6 t=0.00064246676 tEnd=0.000565406168 op=sect miFrom=1 miTo=1 suFrom=0 suTo=1 result=1
352activeOp id=4 t=0.390560161 tEnd=0.380259358 op=sect miFrom=1 miTo=1 suFrom=1 suTo=1 result=0
353markDone id=1 (0,1 0.490384609,1.73557687 0.499815077,2.00021958 0.382070184,1.94870627) t=0.000874182828 [17] (0.00128495507,1.00192797) tEnd=1 newWindSum=-1 newOppSum=-2 oppSum=-2 windSum=-1 windValue=1 oppValue=0
354findNextOp from:[1] to:[6] start=41944776 end=25209856
355bridgeOp current id=1 from=(0.382070184,1.94870627) to=(0.00128495507,1.00192797)
356path.cubicTo(0.499712139,2.00017452, 0.490401,1.73603928, 0.00128495507,1.00192797);
357markWinding id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.390998296 [28] (0.00119023165,0.999206483) tEnd=0.401625031 newWindSum=-1 newOppSum=-1 oppSum=? windSum=? windValue=1 oppValue=0
358markAngle last segment=4 span=28 windSum=-1
359markWinding id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0.33834339 [21] (4.02102705e-06,0.93367821) tEnd=0.515074123 newWindSum=-1 newOppSum=-1 oppSum=? windSum=? windValue=1 oppValue=0
360markAngle last segment=2 span=23 windSum=?
361markWinding id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.401625031 [22] (4.02102705e-06,0.93367821) tEnd=0.588973826 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
362markAngle last segment=4 span=24 windSum=?
363debugShowActiveSpans id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0.33834339 (4.02102705e-06,0.93367821) tEnd=0.515074123 windSum=-1 oppSum=-1 windValue=1 oppValue=0
364debugShowActiveSpans id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0.515074123 (0.273102283,-0.0639350563) tEnd=1 windSum=? windValue=1
365debugShowActiveSpans id=3 (6,-3 0,1) t=0 (6,-3) tEnd=0.999801628 windSum=? windValue=1
366debugShowActiveSpans id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.390998296 (0.00119023165,0.999206483) tEnd=0.401625031 windSum=-1 oppSum=-1 windValue=1 oppValue=0
367debugShowActiveSpans id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.401625031 (4.02102705e-06,0.93367821) tEnd=0.588973826 windSum=-1 oppSum=0 windValue=1 oppValue=0
368debugShowActiveSpans id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.588973826 (0.273102283,-0.0639350563) tEnd=1 windSum=? windValue=1
369debugShowActiveSpans id=5 (1.6714313,-1.08141601 2.24979973,-1.14467525 2.27122664,-0.514151096 0,1) t=0 (1.6714313,-1.08141601) tEnd=0.999825287 windSum=? windValue=1
370activeOp id=4 t=0.401625031 tEnd=0.390998296 op=sect miFrom=1 miTo=1 suFrom=0 suTo=1 result=1
371markWinding id=3 (6,-3 0,1) t=0 [5] (6,-3) tEnd=0.999801628 newWindSum=-1 newOppSum=-1 oppSum=? windSum=? windValue=1 oppValue=0
372markWinding id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0.515074123 [23] (0.273102283,-0.0639350563) tEnd=1 newWindSum=-1 newOppSum=-1 oppSum=? windSum=? windValue=1 oppValue=0
373markAngle last segment=2 span=23 windSum=-1
374markWinding id=5 (1.6714313,-1.08141601 2.24979973,-1.14467525 2.27122664,-0.514151096 0,1) t=0 [9] (1.6714313,-1.08141601) tEnd=0.999825287 newWindSum=-2 newOppSum=-1 oppSum=? windSum=? windValue=1 oppValue=0
375markWinding id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.588973826 [24] (0.273102283,-0.0639350563) tEnd=1 newWindSum=-2 newOppSum=-1 oppSum=? windSum=? windValue=1 oppValue=0
376markAngle last segment=4 span=24 windSum=-2
377findNextOp
378dumpOne [4/22] next=5/28 sect=9/9 s=0.390998296 [28] e=0.401625031 [22] sgn=-1 windVal=1 windSum=-1 oppVal=0 oppSum=-1 operand
379dumpOne [5/28] next=4/21 sect=17/17 s=0.999825287 [29] e=0.999846187 [25] sgn=-1 windVal=1 windSum=1 oppVal=1 oppSum=-1 done operand
380dumpOne [4/21] next=3/16 sect=25/25 s=0.390998296 [28] e=0.390560161 [18] sgn=1 windVal=1 windSum=-1 oppVal=0 oppSum=0 done operand
381dumpOne [3/16] next=5/27 sect=1/1 s=0.999801628 [27] e=0 [5] sgn=1 windVal=1 windSum=-1 oppVal=0 oppSum=-1
382dumpOne [5/27] next=4/22 sect=1/5 s=0.999825287 [29] e=0 [9] sgn=1 windVal=1 windSum=-2 oppVal=0 oppSum=-1 operand
383activeOp id=5 t=0.999825287 tEnd=0.999846187 op=sect miFrom=1 miTo=0 suFrom=0 suTo=1 result=0
384activeOp id=4 t=0.390998296 tEnd=0.390560161 op=sect miFrom=0 miTo=0 suFrom=1 suTo=0 result=0
385activeOp id=3 t=0.999801628 tEnd=0 op=sect miFrom=0 miTo=1 suFrom=0 suTo=0 result=0
386markDone id=3 (6,-3 0,1) t=0 [5] (6,-3) tEnd=0.999801628 newWindSum=-1 newOppSum=-1 oppSum=-1 windSum=-1 windValue=1 oppValue=0
387markDone id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0.515074123 [23] (0.273102283,-0.0639350563) tEnd=1 newWindSum=-1 newOppSum=-1 oppSum=-1 windSum=-1 windValue=1 oppValue=0
388findNextOp chase.append segment=2 span=23 windSum=-1
389activeOp id=5 t=0.999825287 tEnd=0 op=sect miFrom=1 miTo=1 suFrom=0 suTo=1 result=1
390findNextOp chase.append segment=4 span=24 windSum=-2
391markDone id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.390998296 [28] (0.00119023165,0.999206483) tEnd=0.401625031 newWindSum=-1 newOppSum=-1 oppSum=-1 windSum=-1 windValue=1 oppValue=0
392findNextOp from:[4] to:[5] start=41944600 end=25207400
393bridgeOp current id=4 from=(4.02102705e-06,0.93367821) to=(0.00119023165,0.999206483)
394path.moveTo(4.02102705e-06,0.93367821);
395path.cubicTo(4.68720355e-05,0.95536691, 0.000439203199,0.977209985, 0.00119023165,0.999206483);
396findNextOp simple
397markDone id=5 (1.6714313,-1.08141601 2.24979973,-1.14467525 2.27122664,-0.514151096 0,1) t=0 [9] (1.6714313,-1.08141601) tEnd=0.999825287 newWindSum=-2 newOppSum=-1 oppSum=-1 windSum=-2 windValue=1 oppValue=0
398bridgeOp current id=5 from=(0.00119023165,0.999206483) to=(1.6714313,-1.08141601)
399path.cubicTo(2.27121925,-0.514371395, 2.24969864,-1.14466417, 1.6714313,-1.08141601);
400findNextOp
401dumpOne [4/26] next=2/15 sect=5/1 s=0.588973826 [24] e=1 [8] sgn=-1 windVal=1 windSum=-2 oppVal=0 oppSum=-1 operand
402dumpOne [2/15] next=4/25 sect=5/1 s=0.515074123 [23] e=1 [4] sgn=-1 windVal=1 windSum=-1 oppVal=0 oppSum=-1 done
403dumpOne [4/25] next=2/14 sect=21/21 s=0.588973826 [24] e=0.401625031 [22] sgn=1 windVal=1 windSum=-1 oppVal=0 oppSum=0 operand
404dumpOne [2/14] next=4/26 sect=21/21 s=0.515074123 [23] e=0.33834339 [21] sgn=1 windVal=1 windSum=-1 oppVal=0 oppSum=-1
405activeOp id=2 t=0.515074123 tEnd=1 op=sect miFrom=1 miTo=0 suFrom=1 suTo=1 result=1
406activeOp id=4 t=0.588973826 tEnd=0.401625031 op=sect miFrom=0 miTo=0 suFrom=1 suTo=1 result=0
407markDone id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.401625031 [22] (4.02102705e-06,0.93367821) tEnd=0.588973826 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
408activeOp id=2 t=0.515074123 tEnd=0.33834339 op=sect miFrom=0 miTo=1 suFrom=1 suTo=1 result=1
409markDone id=4 (2,4 -1.72877336,0.996266127 0.721898317,-0.977560639 1.6714313,-1.08141601) t=0.588973826 [24] (0.273102283,-0.0639350563) tEnd=1 newWindSum=-2 newOppSum=-1 oppSum=-1 windSum=-2 windValue=1 oppValue=0
410findNextOp from:[4] to:[2] start=25209368 end=25206496
411bridgeOp current id=4 from=(1.6714313,-1.08141601) to=(0.273102283,-0.0639350563)
412path.cubicTo(1.28114843,-1.03872871, 0.637259305,-0.680123806, 0.273102283,-0.0639350563);
413findNextOp simple
414path.cubicTo(0.823082328,-1.05662191, 2.33974218,-2.20694399, 6,-3);
415debugShowActiveSpans id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0.33834339 (4.02102705e-06,0.93367821) tEnd=0.515074123 windSum=-1 oppSum=-1 windValue=1 oppValue=0
416debugShowActiveSpans id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0.33834339 (4.02102705e-06,0.93367821) tEnd=0.515074123 windSum=-1 oppSum=-1 windValue=1 oppValue=0
417activeOp id=2 t=0.515074123 tEnd=0.33834339 op=sect miFrom=0 miTo=1 suFrom=1 suTo=1 result=1
418findNextOp
419dumpOne [2/13] next=4/24 sect=5/5 s=0.33834339 [21] e=0.515074123 [23] sgn=-1 windVal=1 windSum=-1 oppVal=0 oppSum=-1
420dumpOne [4/24] next=2/12 sect=9/5 s=0.401625031 [22] e=0.588973826 [24] sgn=-1 windVal=1 windSum=-1 oppVal=0 oppSum=0 done operand
421dumpOne [2/12] next=4/23 sect=21/25 s=0.33834339 [21] e=0.325081142 [15] sgn=1 windVal=1 windSum=-1 oppVal=0 oppSum=0 done
422dumpOne [4/23] next=2/13 sect=25/25 s=0.401625031 [22] e=0.390998296 [28] sgn=1 windVal=1 windSum=-1 oppVal=0 oppSum=-1 done operand
423activeOp id=4 t=0.401625031 tEnd=0.588973826 op=sect miFrom=0 miTo=0 suFrom=1 suTo=0 result=0
424activeOp id=2 t=0.33834339 tEnd=0.325081142 op=sect miFrom=0 miTo=1 suFrom=0 suTo=0 result=0
425activeOp id=4 t=0.401625031 tEnd=0.390998296 op=sect miFrom=1 miTo=1 suFrom=0 suTo=1 result=1
426markDone id=2 (0.382070184,1.94870627 0.0196006298,1.79012585 -1.54807687,-1.36458325 6,-3) t=0.33834339 [21] (4.02102705e-06,0.93367821) tEnd=0.515074123 newWindSum=-1 newOppSum=-1 oppSum=-1 windSum=-1 windValue=1 oppValue=0
427findNextOp from:[2] to:[4] start=25209232 end=25210128
428bridgeOp current id=2 from=(0.273102283,-0.0639350563) to=(4.02102705e-06,0.93367821)
429path.moveTo(0.273102283,-0.0639350563);
430path.cubicTo(0.0726626143,0.297848642, 0.000620319974,0.638694704, 4.02102705e-06,0.93367821);
caryclarkdac1d172014-06-17 05:15:38 -0700431</div>
caryclark54359292015-03-26 07:52:43 -0700432
caryclarkdac1d172014-06-17 05:15:38 -0700433</div>
434
435<script type="text/javascript">
436
437var testDivs = [
caryclarkbca19f72015-05-13 08:23:48 -0700438 loops63i,
439
caryclarkdac1d172014-06-17 05:15:38 -0700440];
441
442var decimal_places = 3; // make this 3 to show more precision
443
444var tests = [];
445var testLines = [];
446var testTitles = [];
447var testIndex = 0;
448var ctx;
449
450var xmin, xmax, focusXmin, focusXmax;
451var ymin, ymax, focusYmin, focusYmax;
452var scale;
453var mouseX, mouseY;
454var srcLeft, srcTop;
455var screenWidth, screenHeight;
caryclark1049f122015-04-20 08:31:59 -0700456var drawnPts, drawnLines, drawnQuads, drawnConics, drawnCubics;
caryclarkdac1d172014-06-17 05:15:38 -0700457var curveT = 0;
458
459var pt_labels = 2;
460var collect_bounds = false;
461var control_lines = 0;
462var curve_t = false;
463var debug_xy = 1;
464var focus_enabled = false;
465var focus_on_selection = false;
466var step_limit = 0;
467var draw_active = false;
468var draw_add = false;
469var draw_angle = 0;
caryclark624637c2015-05-11 07:21:27 -0700470var draw_coincidence = false;
caryclarkdac1d172014-06-17 05:15:38 -0700471var draw_deriviatives = 0;
472var draw_hints = false;
caryclarkdac1d172014-06-17 05:15:38 -0700473var draw_id = false;
474var draw_intersection = 0;
475var draw_intersectT = false;
476var draw_legend = true;
477var draw_log = false;
478var draw_mark = false;
479var draw_midpoint = false;
480var draw_op = 0;
481var draw_sequence = false;
482var draw_sort = 0;
caryclark03b03ca2015-04-23 09:13:37 -0700483var draw_top = false;
caryclarkdac1d172014-06-17 05:15:38 -0700484var draw_path = 3;
485var draw_computed = 0;
486var retina_scale = !!window.devicePixelRatio;
487
488var activeCount = 0;
489var addCount = 0;
490var angleCount = 0;
caryclark624637c2015-05-11 07:21:27 -0700491var coinCount = 0;
caryclarkdac1d172014-06-17 05:15:38 -0700492var opCount = 0;
493var sectCount = 0;
494var sortCount = 0;
caryclark03b03ca2015-04-23 09:13:37 -0700495var topCount = 0;
caryclarkdac1d172014-06-17 05:15:38 -0700496var markCount = 0;
497var activeMax = 0;
498var addMax = 0;
499var angleMax = 0;
caryclark624637c2015-05-11 07:21:27 -0700500var coinMax = 0;
caryclarkdac1d172014-06-17 05:15:38 -0700501var sectMax = 0;
502var sectMax2 = 0;
503var sortMax = 0;
caryclark03b03ca2015-04-23 09:13:37 -0700504var topMax = 0;
caryclarkdac1d172014-06-17 05:15:38 -0700505var markMax = 0;
506var opMax = 0;
507var stepMax = 0;
508var lastIndex = 0;
509var hasPath = false;
510var hasComputedPath = false;
caryclark54359292015-03-26 07:52:43 -0700511var angleBetween = false;
512var afterIndex = 0;
caryclarkdac1d172014-06-17 05:15:38 -0700513
514var firstActiveSpan = -1;
515var logStart = -1;
516var logRange = 0;
517
518var SPAN_ID = 0;
519var SPAN_X1 = SPAN_ID + 1;
520var SPAN_Y1 = SPAN_X1 + 1;
521var SPAN_X2 = SPAN_Y1 + 1;
522var SPAN_Y2 = SPAN_X2 + 1;
caryclark1049f122015-04-20 08:31:59 -0700523
caryclarkdac1d172014-06-17 05:15:38 -0700524var SPAN_L_T = SPAN_Y2 + 1;
525var SPAN_L_TX = SPAN_L_T + 1;
526var SPAN_L_TY = SPAN_L_TX + 1;
527var SPAN_L_TEND = SPAN_L_TY + 1;
528var SPAN_L_OTHER = SPAN_L_TEND + 1;
529var SPAN_L_OTHERT = SPAN_L_OTHER + 1;
530var SPAN_L_OTHERI = SPAN_L_OTHERT + 1;
531var SPAN_L_SUM = SPAN_L_OTHERI + 1;
532var SPAN_L_VAL = SPAN_L_SUM + 1;
533var SPAN_L_OPP = SPAN_L_VAL + 1;
534
535var SPAN_X3 = SPAN_Y2 + 1;
536var SPAN_Y3 = SPAN_X3 + 1;
caryclark1049f122015-04-20 08:31:59 -0700537
caryclarkdac1d172014-06-17 05:15:38 -0700538var SPAN_Q_T = SPAN_Y3 + 1;
539var SPAN_Q_TX = SPAN_Q_T + 1;
540var SPAN_Q_TY = SPAN_Q_TX + 1;
541var SPAN_Q_TEND = SPAN_Q_TY + 1;
542var SPAN_Q_OTHER = SPAN_Q_TEND + 1;
543var SPAN_Q_OTHERT = SPAN_Q_OTHER + 1;
544var SPAN_Q_OTHERI = SPAN_Q_OTHERT + 1;
545var SPAN_Q_SUM = SPAN_Q_OTHERI + 1;
546var SPAN_Q_VAL = SPAN_Q_SUM + 1;
547var SPAN_Q_OPP = SPAN_Q_VAL + 1;
548
caryclark1049f122015-04-20 08:31:59 -0700549var SPAN_K_W = SPAN_Y3 + 1;
550var SPAN_K_T = SPAN_K_W + 1;
551var SPAN_K_TX = SPAN_K_T + 1;
552var SPAN_K_TY = SPAN_K_TX + 1;
553var SPAN_K_TEND = SPAN_K_TY + 1;
554var SPAN_K_OTHER = SPAN_K_TEND + 1;
555var SPAN_K_OTHERT = SPAN_K_OTHER + 1;
556var SPAN_K_OTHERI = SPAN_K_OTHERT + 1;
557var SPAN_K_SUM = SPAN_K_OTHERI + 1;
558var SPAN_K_VAL = SPAN_K_SUM + 1;
559var SPAN_K_OPP = SPAN_K_VAL + 1;
560
caryclarkdac1d172014-06-17 05:15:38 -0700561var SPAN_X4 = SPAN_Y3 + 1;
562var SPAN_Y4 = SPAN_X4 + 1;
caryclark1049f122015-04-20 08:31:59 -0700563
caryclarkdac1d172014-06-17 05:15:38 -0700564var SPAN_C_T = SPAN_Y4 + 1;
565var SPAN_C_TX = SPAN_C_T + 1;
566var SPAN_C_TY = SPAN_C_TX + 1;
567var SPAN_C_TEND = SPAN_C_TY + 1;
568var SPAN_C_OTHER = SPAN_C_TEND + 1;
569var SPAN_C_OTHERT = SPAN_C_OTHER + 1;
570var SPAN_C_OTHERI = SPAN_C_OTHERT + 1;
571var SPAN_C_SUM = SPAN_C_OTHERI + 1;
572var SPAN_C_VAL = SPAN_C_SUM + 1;
573var SPAN_C_OPP = SPAN_C_VAL + 1;
574
575var ACTIVE_LINE_SPAN = 1;
576var ACTIVE_QUAD_SPAN = ACTIVE_LINE_SPAN + 1;
caryclark1049f122015-04-20 08:31:59 -0700577var ACTIVE_CONIC_SPAN = ACTIVE_QUAD_SPAN + 1;
578var ACTIVE_CUBIC_SPAN = ACTIVE_CONIC_SPAN + 1;
caryclarkdac1d172014-06-17 05:15:38 -0700579
580var ADD_MOVETO = ACTIVE_CUBIC_SPAN + 1;
581var ADD_LINETO = ADD_MOVETO + 1;
582var ADD_QUADTO = ADD_LINETO + 1;
caryclark1049f122015-04-20 08:31:59 -0700583var ADD_CONICTO = ADD_QUADTO + 1;
584var ADD_CUBICTO = ADD_CONICTO + 1;
caryclarkdac1d172014-06-17 05:15:38 -0700585var ADD_CLOSE = ADD_CUBICTO + 1;
586var ADD_FILL = ADD_CLOSE + 1;
587
588var PATH_LINE = ADD_FILL + 1;
589var PATH_QUAD = PATH_LINE + 1;
caryclark1049f122015-04-20 08:31:59 -0700590var PATH_CONIC = PATH_QUAD + 1;
591var PATH_CUBIC = PATH_CONIC + 1;
caryclarkdac1d172014-06-17 05:15:38 -0700592
593var INTERSECT_LINE = PATH_CUBIC + 1;
594var INTERSECT_LINE_2 = INTERSECT_LINE + 1;
595var INTERSECT_LINE_NO = INTERSECT_LINE_2 + 1;
596var INTERSECT_QUAD_LINE = INTERSECT_LINE_NO + 1;
597var INTERSECT_QUAD_LINE_2 = INTERSECT_QUAD_LINE + 1;
598var INTERSECT_QUAD_LINE_NO = INTERSECT_QUAD_LINE_2 + 1;
599var INTERSECT_QUAD = INTERSECT_QUAD_LINE_NO + 1;
600var INTERSECT_QUAD_2 = INTERSECT_QUAD + 1;
601var INTERSECT_QUAD_NO = INTERSECT_QUAD_2 + 1;
caryclark1049f122015-04-20 08:31:59 -0700602var INTERSECT_CONIC_LINE = INTERSECT_QUAD_NO + 1;
603var INTERSECT_CONIC_LINE_2 = INTERSECT_CONIC_LINE + 1;
604var INTERSECT_CONIC_LINE_NO = INTERSECT_CONIC_LINE_2 + 1;
605var INTERSECT_CONIC = INTERSECT_CONIC_LINE_NO + 1;
606var INTERSECT_CONIC_2 = INTERSECT_CONIC + 1;
607var INTERSECT_CONIC_NO = INTERSECT_CONIC_2 + 1;
608var INTERSECT_SELF_CUBIC = INTERSECT_CONIC_NO + 1;
caryclarkdac1d172014-06-17 05:15:38 -0700609var INTERSECT_SELF_CUBIC_NO = INTERSECT_SELF_CUBIC + 1;
610var INTERSECT_CUBIC_LINE = INTERSECT_SELF_CUBIC_NO + 1;
611var INTERSECT_CUBIC_LINE_2 = INTERSECT_CUBIC_LINE + 1;
612var INTERSECT_CUBIC_LINE_3 = INTERSECT_CUBIC_LINE_2 + 1;
613var INTERSECT_CUBIC_LINE_NO = INTERSECT_CUBIC_LINE_3 + 1;
614var INTERSECT_CUBIC_QUAD = INTERSECT_CUBIC_LINE_NO + 1;
615var INTERSECT_CUBIC_QUAD_2 = INTERSECT_CUBIC_QUAD + 1;
616var INTERSECT_CUBIC_QUAD_3 = INTERSECT_CUBIC_QUAD_2 + 1;
617var INTERSECT_CUBIC_QUAD_4 = INTERSECT_CUBIC_QUAD_3 + 1;
618var INTERSECT_CUBIC_QUAD_NO = INTERSECT_CUBIC_QUAD_4 + 1;
619var INTERSECT_CUBIC = INTERSECT_CUBIC_QUAD_NO + 1;
620var INTERSECT_CUBIC_2 = INTERSECT_CUBIC + 1;
621var INTERSECT_CUBIC_3 = INTERSECT_CUBIC_2 + 1;
622var INTERSECT_CUBIC_4 = INTERSECT_CUBIC_3 + 1;
623// FIXME: add cubic 5- 9
624var INTERSECT_CUBIC_NO = INTERSECT_CUBIC_4 + 1;
625
626var SORT_UNARY = INTERSECT_CUBIC_NO + 1;
627var SORT_BINARY = SORT_UNARY + 1;
628
629var OP_DIFFERENCE = SORT_BINARY + 1;
630var OP_INTERSECT = OP_DIFFERENCE + 1;
631var OP_UNION = OP_INTERSECT + 1;
632var OP_XOR = OP_UNION + 1;
633
634var MARK_LINE = OP_XOR + 1;
635var MARK_QUAD = MARK_LINE + 1;
caryclark1049f122015-04-20 08:31:59 -0700636var MARK_CONIC = MARK_QUAD + 1;
637var MARK_CUBIC = MARK_CONIC + 1;
caryclarkdac1d172014-06-17 05:15:38 -0700638var MARK_DONE_LINE = MARK_CUBIC + 1;
639var MARK_DONE_QUAD = MARK_DONE_LINE + 1;
caryclark1049f122015-04-20 08:31:59 -0700640var MARK_DONE_CONIC = MARK_DONE_QUAD + 1;
641var MARK_DONE_CUBIC = MARK_DONE_CONIC + 1;
caryclarkdac1d172014-06-17 05:15:38 -0700642var MARK_UNSORTABLE_LINE = MARK_DONE_CUBIC + 1;
643var MARK_UNSORTABLE_QUAD = MARK_UNSORTABLE_LINE + 1;
caryclark1049f122015-04-20 08:31:59 -0700644var MARK_UNSORTABLE_CONIC = MARK_UNSORTABLE_QUAD + 1;
645var MARK_UNSORTABLE_CUBIC = MARK_UNSORTABLE_CONIC + 1;
caryclarkdac1d172014-06-17 05:15:38 -0700646var MARK_SIMPLE_LINE = MARK_UNSORTABLE_CUBIC + 1;
647var MARK_SIMPLE_QUAD = MARK_SIMPLE_LINE + 1;
caryclark1049f122015-04-20 08:31:59 -0700648var MARK_SIMPLE_CONIC = MARK_SIMPLE_QUAD + 1;
649var MARK_SIMPLE_CUBIC = MARK_SIMPLE_CONIC + 1;
caryclarkdac1d172014-06-17 05:15:38 -0700650var MARK_SIMPLE_DONE_LINE = MARK_SIMPLE_CUBIC + 1;
651var MARK_SIMPLE_DONE_QUAD = MARK_SIMPLE_DONE_LINE + 1;
caryclark1049f122015-04-20 08:31:59 -0700652var MARK_SIMPLE_DONE_CONIC = MARK_SIMPLE_DONE_QUAD + 1;
653var MARK_SIMPLE_DONE_CUBIC = MARK_SIMPLE_DONE_CONIC + 1;
caryclarkdac1d172014-06-17 05:15:38 -0700654var MARK_DONE_UNARY_LINE = MARK_SIMPLE_DONE_CUBIC + 1;
655var MARK_DONE_UNARY_QUAD = MARK_DONE_UNARY_LINE + 1;
caryclark1049f122015-04-20 08:31:59 -0700656var MARK_DONE_UNARY_CONIC = MARK_DONE_UNARY_QUAD + 1;
657var MARK_DONE_UNARY_CUBIC = MARK_DONE_UNARY_CONIC + 1;
caryclarkdac1d172014-06-17 05:15:38 -0700658var MARK_ANGLE_LAST = MARK_DONE_UNARY_CUBIC + 1;
659
660var COMPUTED_SET_1 = MARK_ANGLE_LAST + 1;
661var COMPUTED_SET_2 = COMPUTED_SET_1 + 1;
662
caryclark624637c2015-05-11 07:21:27 -0700663var ANGLE_AFTER = COMPUTED_SET_2 + 1;
caryclark54359292015-03-26 07:52:43 -0700664var ANGLE_AFTERPART = ANGLE_AFTER + 1;
caryclarkdac1d172014-06-17 05:15:38 -0700665
caryclark54359292015-03-26 07:52:43 -0700666var ACTIVE_OP = ANGLE_AFTERPART + 1;
caryclarkdac1d172014-06-17 05:15:38 -0700667
caryclark624637c2015-05-11 07:21:27 -0700668var COIN_MAIN_SPAN = ACTIVE_OP + 1;
669var COIN_OPP_SPAN = COIN_MAIN_SPAN + 1;
670
671var FRAG_TYPE_LAST = COIN_OPP_SPAN;
caryclarkdac1d172014-06-17 05:15:38 -0700672
673var REC_TYPE_UNKNOWN = -1;
674var REC_TYPE_PATH = 0;
caryclark54359292015-03-26 07:52:43 -0700675var REC_TYPE_PATH2 = 1;
676var REC_TYPE_SECT = 2;
677var REC_TYPE_ACTIVE = 3;
678var REC_TYPE_ADD = 4;
679var REC_TYPE_SORT = 5;
680var REC_TYPE_OP = 6;
681var REC_TYPE_MARK = 7;
682var REC_TYPE_COMPUTED = 8;
683var REC_TYPE_COIN = 9;
684var REC_TYPE_ANGLE = 10;
685var REC_TYPE_ACTIVE_OP = 11;
686var REC_TYPE_AFTERPART = 12;
caryclark03b03ca2015-04-23 09:13:37 -0700687var REC_TYPE_TOP = 13;
caryclark624637c2015-05-11 07:21:27 -0700688var REC_TYPE_COINCIDENCE = 14;
689var REC_TYPE_LAST = REC_TYPE_COINCIDENCE;
caryclarkdac1d172014-06-17 05:15:38 -0700690
691function strs_to_nums(strs) {
692 var result = [];
693 for (var idx = 1; idx < strs.length; ++idx) {
694 var str = strs[idx];
695 var num = parseFloat(str);
696 if (isNaN(num)) {
697 result.push(str);
698 } else {
699 result.push(num);
700 }
701 }
702 return result;
703}
704
705function filter_str_by(id, str, regex, array) {
706 if (regex.test(str)) {
707 var strs = regex.exec(str);
708 var result = strs_to_nums(strs);
709 array.push(id);
710 array.push(result);
711 return true;
712 }
713 return false;
714}
715
716function construct_regexp2(pattern) {
717 var escape = pattern.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
718 escape = escape.replace(/UNSORTABLE/g, "\\*\\*\\* UNSORTABLE \\*\\*\\*");
719 escape = escape.replace(/CUBIC_VAL/g, "\\(P_VAL P_VAL P_VAL P_VAL\\)");
caryclark1049f122015-04-20 08:31:59 -0700720 escape = escape.replace(/CONIC_VAL/g, "\\(P_VAL P_VAL P_VAL W_VAL\\)");
caryclarkdac1d172014-06-17 05:15:38 -0700721 escape = escape.replace(/QUAD_VAL/g, "\\(P_VAL P_VAL P_VAL\\)");
722 escape = escape.replace(/LINE_VAL/g, "\\(P_VAL P_VAL\\)");
723 escape = escape.replace(/FILL_TYPE/g, "SkPath::k[a-zA-Z]+_FillType");
caryclark54359292015-03-26 07:52:43 -0700724 escape = escape.replace(/PTR_VAL/g, "0x[0-9A-F]+");
caryclarkdac1d172014-06-17 05:15:38 -0700725 escape = escape.replace(/PT_VAL/g, "\\(P_VAL\\)");
726 escape = escape.replace(/P_VAL/g, "(-?\\d+\\.?\\d*(?:e-?\\d+)?)[Ff]?, ?(-?\\d+\\.?\\d*(?:e-?\\d+)?)[Ff]?");
727 escape = escape.replace(/T_VAL/g, "(-?\\d+\\.?\\d*(?:e-?\\d+)?)");
caryclark1049f122015-04-20 08:31:59 -0700728 escape = escape.replace(/W_VAL/g, "(-?\\d+\\.?\\d*(?:e-?\\d+)?)[Ff]?");
caryclarkdac1d172014-06-17 05:15:38 -0700729 escape = escape.replace(/PATH/g, "pathB?");
caryclark1049f122015-04-20 08:31:59 -0700730 escape = escape.replace(/IDX/g, "(-?\\d+)");
caryclarkdac1d172014-06-17 05:15:38 -0700731 escape = escape.replace(/NUM/g, "(-?\\d+)");
732 escape = escape.replace(/OPT/g, "(\\?|-?\\d+)");
733 return new RegExp(escape, 'i');
734}
735
736function construct_regexp2c(pattern) {
737 var escape = pattern.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
738 escape = escape.replace(/UNSORTABLE/g, "\\*\\*\\* UNSORTABLE \\*\\*\\*");
caryclark54359292015-03-26 07:52:43 -0700739 escape = escape.replace(/CUBIC_VAL/g, "(?:\\$\\d = )?\\{\\{\\{P_VAL\\}, \\{P_VAL\\}, \\{P_VAL\\}, \\{P_VAL\\}\\}\\}");
caryclark1049f122015-04-20 08:31:59 -0700740 escape = escape.replace(/CONIC_VAL/g, "(?:\\$\\d = )?\\{\\{\\{\\{P_VAL\\}, \\{P_VAL\\}, \\{P_VAL\\}\\}\\}, W_VAL\\}");
caryclark54359292015-03-26 07:52:43 -0700741 escape = escape.replace(/QUAD_VAL/g, "(?:\\$\\d = )?\\{\\{\\{P_VAL\\}, \\{P_VAL\\}, \\{P_VAL\\}\\}\\}");
742 escape = escape.replace(/LINE_VAL/g, "(?:\\$\\d = )?\\{\\{\\{P_VAL\\}, \\{P_VAL\\}\\}\\}");
caryclarkdac1d172014-06-17 05:15:38 -0700743 escape = escape.replace(/FILL_TYPE/g, "SkPath::k[a-zA-Z]+_FillType");
caryclark54359292015-03-26 07:52:43 -0700744 escape = escape.replace(/PTR_VAL/g, "0x[0-9A-F]+");
caryclarkdac1d172014-06-17 05:15:38 -0700745 escape = escape.replace(/PT_VAL/g, "\\{\\{P_VAL\\}\\}");
caryclark54359292015-03-26 07:52:43 -0700746 escape = escape.replace(/P_VAL/g, "(?:f?[xX] = )?(-?\\d+\\.?\\d*(?:e-?\\d+)?)[Ff]?, *(?: f?[yY] = )?(-?\\d+\\.?\\d*(?:e-?\\d+)?)[Ff]?");
caryclarkdac1d172014-06-17 05:15:38 -0700747 escape = escape.replace(/T_VAL/g, "(-?\\d+\\.?\\d*(?:e-?\\d+)?)");
caryclark1049f122015-04-20 08:31:59 -0700748 escape = escape.replace(/W_VAL/g, "(-?\\d+\\.?\\d*(?:e-?\\d+)?)[Ff]?");
caryclarkdac1d172014-06-17 05:15:38 -0700749 escape = escape.replace(/OPER/g, "[a-z]+");
750 escape = escape.replace(/PATH/g, "pathB?");
751 escape = escape.replace(/T_F/g, "([TF])");
caryclark1049f122015-04-20 08:31:59 -0700752 escape = escape.replace(/IDX/g, "(-?\\d+)");
caryclarkdac1d172014-06-17 05:15:38 -0700753 escape = escape.replace(/NUM/g, "(-?\\d+)");
754 escape = escape.replace(/OPT/g, "(\\?|-?\\d+)");
755 return new RegExp(escape, 'i');
756}
757
758function match_regexp(str, lineNo, array, id, pattern) {
759 var regex = construct_regexp2(pattern);
760 if (filter_str_by(id, str, regex, array)) {
761 return true;
762 }
763 regex = construct_regexp2c(pattern);
764 return filter_str_by(id, str, regex, array);
765}
766
767function endsWith(str, suffix) {
768 return str.indexOf(suffix, str.length - suffix.length) !== -1;
769}
770
771function parse_all(test) {
772 var lines = test.match(/[^\r\n]+/g);
773 var records = []; // a rec can be the original paths, a set of intersections, a set of active spans, a sort, or a path add
774 var record = [];
775 var recType = REC_TYPE_UNKNOWN;
776 var lastLineNo;
777 var moveX, moveY;
778 for (var lineNo = 0; lineNo < lines.length; ++lineNo) {
779 var line = lines[lineNo];
780 if (line.length == 0) {
781 continue;
782 }
783 var opStart = "SkOpSegment::";
784 if (line.lastIndexOf(opStart, 0) === 0) {
785 line = line.substr(opStart.length);
786 }
787 var angleStart = "SkOpAngle::";
788 if (line.lastIndexOf(angleStart, 0) === 0) {
789 line = line.substr(angleStart.length);
790 }
caryclark624637c2015-05-11 07:21:27 -0700791 var coinStart = "SkOpCoincidence::";
792 if (line.lastIndexOf(coinStart, 0) === 0) {
793 line = line.substr(coinStart.length);
794 }
caryclark54359292015-03-26 07:52:43 -0700795 var type = line.lastIndexOf("debugShowActiveSpans", 0) === 0 ? REC_TYPE_ACTIVE
caryclark624637c2015-05-11 07:21:27 -0700796 : line.lastIndexOf("debugShowCoincidence", 0) === 0 ? REC_TYPE_COINCIDENCE
caryclark54359292015-03-26 07:52:43 -0700797 : line.lastIndexOf("((SkOpSegment*)", 0) === 0 ? REC_TYPE_PATH2
caryclarkdac1d172014-06-17 05:15:38 -0700798 : line.lastIndexOf("debugShowTs", 0) === 0 ? REC_TYPE_COIN
caryclark54359292015-03-26 07:52:43 -0700799 : line.lastIndexOf("afterPart", 0) === 0 ? REC_TYPE_AFTERPART
caryclarkdac1d172014-06-17 05:15:38 -0700800 : line.lastIndexOf("debugShow", 0) === 0 ? REC_TYPE_SECT
801 : line.lastIndexOf("activeOp", 0) === 0 ? REC_TYPE_ACTIVE_OP
802 : line.lastIndexOf("computed", 0) === 0 ? REC_TYPE_COMPUTED
803 : line.lastIndexOf("debugOne", 0) === 0 ? REC_TYPE_SORT
804 : line.lastIndexOf("dumpOne", 0) === 0 ? REC_TYPE_SORT
caryclark03b03ca2015-04-23 09:13:37 -0700805 : line.lastIndexOf("findTop", 0) === 0 ? REC_TYPE_TOP
caryclarkdac1d172014-06-17 05:15:38 -0700806 : line.lastIndexOf("pathB.", 0) === 0 ? REC_TYPE_ADD
807 : line.lastIndexOf("path.", 0) === 0 ? REC_TYPE_ADD
808 : line.lastIndexOf("after", 0) === 0 ? REC_TYPE_ANGLE
809 : line.lastIndexOf("mark", 0) === 0 ? REC_TYPE_MARK
810 : line.lastIndexOf(" {{", 0) === 0 ? REC_TYPE_COMPUTED
caryclark54359292015-03-26 07:52:43 -0700811 : line.lastIndexOf("seg=", 0) === 0 ? REC_TYPE_PATH
caryclarkdac1d172014-06-17 05:15:38 -0700812 : line.lastIndexOf("op", 0) === 0 ? REC_TYPE_OP
813 : line.lastIndexOf("$", 0) === 0 ? REC_TYPE_PATH
814 : REC_TYPE_UNKNOWN;
815 if (recType != type || recType == REC_TYPE_ADD || recType == REC_TYPE_SECT
816 || recType == REC_TYPE_ACTIVE_OP || recType == REC_TYPE_ANGLE) {
817 if (recType != REC_TYPE_UNKNOWN) {
818 records.push(recType);
819 records.push(lastLineNo);
820 records.push(record);
821 }
822 record = [];
823 recType = type;
824 lastLineNo = lineNo;
825 }
826 var found = false;
827 switch (recType) {
828 case REC_TYPE_ACTIVE:
829 found = match_regexp(line, lineNo, record, ACTIVE_LINE_SPAN, "debugShowActiveSpans" +
caryclark624637c2015-05-11 07:21:27 -0700830" id=IDX LINE_VAL t=T_VAL PT_VAL tEnd=T_VAL windSum=OPT windValue=IDX"
caryclarkdac1d172014-06-17 05:15:38 -0700831 ) || match_regexp(line, lineNo, record, ACTIVE_QUAD_SPAN, "debugShowActiveSpans" +
caryclark624637c2015-05-11 07:21:27 -0700832" id=IDX QUAD_VAL t=T_VAL PT_VAL tEnd=T_VAL windSum=OPT windValue=IDX"
caryclark1049f122015-04-20 08:31:59 -0700833 ) || match_regexp(line, lineNo, record, ACTIVE_CONIC_SPAN, "debugShowActiveSpans" +
caryclark624637c2015-05-11 07:21:27 -0700834" id=IDX CONIC_VAL t=T_VAL PT_VAL tEnd=T_VAL windSum=OPT windValue=IDX"
caryclarkdac1d172014-06-17 05:15:38 -0700835 ) || match_regexp(line, lineNo, record, ACTIVE_CUBIC_SPAN, "debugShowActiveSpans" +
caryclark624637c2015-05-11 07:21:27 -0700836" id=IDX CUBIC_VAL t=T_VAL PT_VAL tEnd=T_VAL windSum=OPT windValue=IDX"
837 ) || match_regexp(line, lineNo, record, ACTIVE_LINE_SPAN, "debugShowActiveSpans" +
838" id=IDX LINE_VAL t=T_VAL PT_VAL tEnd=T_VAL windSum=OPT oppSum=OPT windValue=IDX oppValue=NUM"
839 ) || match_regexp(line, lineNo, record, ACTIVE_QUAD_SPAN, "debugShowActiveSpans" +
840" id=IDX QUAD_VAL t=T_VAL PT_VAL tEnd=T_VAL windSum=OPT oppSum=OPT windValue=IDX oppValue=NUM"
841 ) || match_regexp(line, lineNo, record, ACTIVE_CONIC_SPAN, "debugShowActiveSpans" +
842" id=IDX CONIC_VAL t=T_VAL PT_VAL tEnd=T_VAL windSum=OPT oppSum=OPT windValue=IDX oppValue=NUM"
843 ) || match_regexp(line, lineNo, record, ACTIVE_CUBIC_SPAN, "debugShowActiveSpans" +
844" id=IDX CUBIC_VAL t=T_VAL PT_VAL tEnd=T_VAL windSum=OPT oppSum=OPT windValue=IDX oppValue=NUM"
caryclarkdac1d172014-06-17 05:15:38 -0700845 );
846 break;
847 case REC_TYPE_ACTIVE_OP:
848 found = match_regexp(line, lineNo, record, ACTIVE_OP, "activeOp" +
849" id=IDX t=T_VAL tEnd=T_VAL op=OPER miFrom=NUM miTo=NUM suFrom=NUM suTo=NUM result=IDX"
850 );
851 break;
852 case REC_TYPE_ADD:
853 if (match_regexp(line, lineNo, record, ADD_MOVETO, "PATH.moveTo(P_VAL);")) {
854 moveX = record[1][0];
855 moveY = record[1][1];
856 found = true;
857 } else if (match_regexp(line, lineNo, record, ADD_LINETO, "PATH.lineTo(P_VAL);")) {
858 record[1].unshift(moveY);
859 record[1].unshift(moveX);
860 moveX = record[1][2];
861 moveY = record[1][3];
862 found = true;
863 } else if (match_regexp(line, lineNo, record, ADD_QUADTO, "PATH.quadTo(P_VAL, P_VAL);")) {
864 record[1].unshift(moveY);
865 record[1].unshift(moveX);
866 moveX = record[1][4];
867 moveY = record[1][5];
868 found = true;
caryclark1049f122015-04-20 08:31:59 -0700869 } else if (match_regexp(line, lineNo, record, ADD_CONICTO, "PATH.conicTo(P_VAL, P_VAL, T_VAL);")) {
870 record[1].unshift(moveY);
871 record[1].unshift(moveX);
872 moveX = record[1][4];
873 moveY = record[1][5];
874 found = true;
caryclarkdac1d172014-06-17 05:15:38 -0700875 } else if (match_regexp(line, lineNo, record, ADD_CUBICTO, "PATH.cubicTo(P_VAL, P_VAL, P_VAL);")) {
876 record[1].unshift(moveY);
877 record[1].unshift(moveX);
878 moveX = record[1][6];
879 moveY = record[1][7];
880 found = true;
881 } else if (match_regexp(line, lineNo, record, ADD_FILL, "PATH.setFillType(FILL_TYPE);")) {
882 found = true;
883 } else {
884 found = match_regexp(line, lineNo, record, ADD_CLOSE, "PATH.close();");
885 }
886 break;
caryclark54359292015-03-26 07:52:43 -0700887 case REC_TYPE_AFTERPART:
888 found = match_regexp(line, lineNo, record, PATH_LINE, "afterPart LINE_VAL")
889 || match_regexp(line, lineNo, record, PATH_QUAD, "afterPart QUAD_VAL")
caryclark1049f122015-04-20 08:31:59 -0700890 || match_regexp(line, lineNo, record, PATH_CONIC, "afterPart CONIC_VAL")
caryclark54359292015-03-26 07:52:43 -0700891 || match_regexp(line, lineNo, record, PATH_CUBIC, "afterPart CUBIC_VAL")
892 break;
caryclarkdac1d172014-06-17 05:15:38 -0700893 case REC_TYPE_ANGLE:
894 found = match_regexp(line, lineNo, record, ANGLE_AFTER, "after " +
caryclarkdac1d172014-06-17 05:15:38 -0700895"[IDX/IDX] NUM/NUM tStart=T_VAL tEnd=T_VAL < [IDX/IDX] NUM/NUM tStart=T_VAL tEnd=T_VAL < [IDX/IDX] NUM/NUM tStart=T_VAL tEnd=T_VAL T_F IDX");
896 break;
897 case REC_TYPE_COIN:
898 found = true;
899 break;
caryclark624637c2015-05-11 07:21:27 -0700900 case REC_TYPE_COINCIDENCE:
901 found = match_regexp(line, lineNo, record, COIN_MAIN_SPAN, "debugShowCoincidence" +
902" + id=IDX t=T_VAL tEnd=T_VAL"
903 ) || match_regexp(line, lineNo, record, COIN_OPP_SPAN, "debugShowCoincidence" +
904" - id=IDX t=T_VAL tEnd=T_VAL"
905 );
906 break;
caryclarkdac1d172014-06-17 05:15:38 -0700907 case REC_TYPE_COMPUTED:
908 found = line == "computed quadratics given"
909 || match_regexp(line, lineNo, record, COMPUTED_SET_1, "computed quadratics set 1"
910 ) || match_regexp(line, lineNo, record, COMPUTED_SET_2, "computed quadratics set 2"
911 ) || match_regexp(line, lineNo, record, PATH_QUAD, " QUAD_VAL,"
caryclark1049f122015-04-20 08:31:59 -0700912 ) || match_regexp(line, lineNo, record, PATH_CONIC, " CONIC_VAL,"
caryclarkdac1d172014-06-17 05:15:38 -0700913 ) || match_regexp(line, lineNo, record, PATH_CUBIC, " CUBIC_VAL,"
914 );
915 break;
916 case REC_TYPE_PATH:
caryclark54359292015-03-26 07:52:43 -0700917 found = match_regexp(line, lineNo, record, PATH_LINE, "seg=IDX LINE_VAL"
918 ) || match_regexp(line, lineNo, record, PATH_QUAD, "seg=IDX QUAD_VAL"
caryclark1049f122015-04-20 08:31:59 -0700919 ) || match_regexp(line, lineNo, record, PATH_CONIC, "seg=IDX CONIC_VAL"
caryclark54359292015-03-26 07:52:43 -0700920 ) || match_regexp(line, lineNo, record, PATH_CUBIC, "seg=IDX CUBIC_VAL"
921 );
922 break;
923 case REC_TYPE_PATH2:
924 found = match_regexp(line, lineNo, record, PATH_LINE, "((SkOpSegment*) PTR_VAL) [IDX] {LINE_VAL}"
925 ) || match_regexp(line, lineNo, record, PATH_QUAD, "((SkOpSegment*) PTR_VAL) [IDX] {QUAD_VAL}"
caryclark1049f122015-04-20 08:31:59 -0700926 ) || match_regexp(line, lineNo, record, PATH_CONIC, "((SkOpSegment*) PTR_VAL) [IDX] {CONIC_VAL}"
caryclark54359292015-03-26 07:52:43 -0700927 ) || match_regexp(line, lineNo, record, PATH_CUBIC, "((SkOpSegment*) PTR_VAL) [IDX] {CUBIC_VAL}"
caryclarkdac1d172014-06-17 05:15:38 -0700928 );
929 break;
930 case REC_TYPE_SECT:
931 found = match_regexp(line, lineNo, record, INTERSECT_LINE, "debugShowLineIntersection" +
932" wtTs[0]=T_VAL LINE_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL"
933 ) || match_regexp(line, lineNo, record, INTERSECT_LINE_2, "debugShowLineIntersection" +
934" wtTs[0]=T_VAL LINE_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL wnTs[1]=T_VAL"
935 ) || match_regexp(line, lineNo, record, INTERSECT_LINE_NO, "debugShowLineIntersection" +
936" no intersect LINE_VAL LINE_VAL"
937 ) || match_regexp(line, lineNo, record, INTERSECT_QUAD_LINE, "debugShowQuadLineIntersection" +
938" wtTs[0]=T_VAL QUAD_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL"
939 ) || match_regexp(line, lineNo, record, INTERSECT_QUAD_LINE_2, "debugShowQuadLineIntersection" +
940" wtTs[0]=T_VAL QUAD_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL wnTs[1]=T_VAL"
941 ) || match_regexp(line, lineNo, record, INTERSECT_QUAD_LINE_NO, "debugShowQuadLineIntersection" +
942" no intersect QUAD_VAL LINE_VAL"
943 ) || match_regexp(line, lineNo, record, INTERSECT_QUAD, "debugShowQuadIntersection" +
944" wtTs[0]=T_VAL QUAD_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL"
945 ) || match_regexp(line, lineNo, record, INTERSECT_QUAD_2, "debugShowQuadIntersection" +
946" wtTs[0]=T_VAL QUAD_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL wnTs[1]=T_VAL"
947 ) || match_regexp(line, lineNo, record, INTERSECT_QUAD_NO, "debugShowQuadIntersection" +
948" no intersect QUAD_VAL QUAD_VAL"
caryclark1049f122015-04-20 08:31:59 -0700949 ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_LINE, "debugShowConicLineIntersection" +
950" wtTs[0]=T_VAL CONIC_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL"
951 ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_LINE_2, "debugShowConicLineIntersection" +
952" wtTs[0]=T_VAL CONIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL wnTs[1]=T_VAL"
953 ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_LINE_NO, "debugShowConicLineIntersection" +
954" no intersect CONIC_VAL LINE_VAL"
955 ) || match_regexp(line, lineNo, record, INTERSECT_CONIC, "debugShowConicIntersection" +
956" wtTs[0]=T_VAL CONIC_VAL PT_VAL wnTs[0]=T_VAL CONIC_VAL"
957 ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_2, "debugShowConicIntersection" +
958" wtTs[0]=T_VAL CONIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL CONIC_VAL wnTs[1]=T_VAL"
959 ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_NO, "debugShowConicIntersection" +
960" no intersect CONIC_VAL CONIC_VAL"
caryclarkdac1d172014-06-17 05:15:38 -0700961 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_LINE, "debugShowCubicLineIntersection" +
962" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL"
963 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_LINE_2, "debugShowCubicLineIntersection" +
964" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL wnTs[1]=T_VAL"
965 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_LINE_3, "debugShowCubicLineIntersection" +
966" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wtTs[2]=T_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL wnTs[1]=T_VAL wnTs[2]=T_VAL"
967 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_LINE_NO, "debugShowCubicLineIntersection" +
968" no intersect CUBIC_VAL LINE_VAL"
969 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_QUAD, "debugShowCubicQuadIntersection" +
970" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL"
971 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_QUAD_2, "debugShowCubicQuadIntersection" +
972" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL wnTs[1]=T_VAL"
973 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_QUAD_3, "debugShowCubicQuadIntersection" +
974" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wtTs[2]=T_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL wnTs[1]=T_VAL wnTs[2]=T_VAL"
975 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_QUAD_4, "debugShowCubicQuadIntersection" +
976" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wtTs[2]=T_VAL wtTs[3]=T_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL wnTs[1]=T_VAL wnTs[2]=T_VAL wnTs[3]=T_VAL"
977 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_QUAD_NO, "debugShowCubicQuadIntersection" +
978" no intersect CUBIC_VAL QUAD_VAL"
979 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC, "debugShowCubicIntersection" +
980" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wnTs[0]=T_VAL CUBIC_VAL"
981 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_2, "debugShowCubicIntersection" +
982" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL CUBIC_VAL wnTs[1]=T_VAL"
983 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_3, "debugShowCubicIntersection" +
984" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wtTs[2]=T_VAL PT_VAL wnTs[0]=T_VAL CUBIC_VAL wnTs[1]=T_VAL wnTs[2]=T_VAL"
985 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_4, "debugShowCubicIntersection" +
986" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wtTs[2]=T_VAL PT_VAL wtTs[3]=T_VAL PT_VAL wnTs[0]=T_VAL CUBIC_VAL wnTs[1]=T_VAL wnTs[2]=T_VAL wnTs[3]=T_VAL"
987 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_NO, "debugShowCubicIntersection" +
988" no intersect CUBIC_VAL CUBIC_VAL"
989 ) || match_regexp(line, lineNo, record, INTERSECT_SELF_CUBIC, "debugShowCubicIntersection" +
990" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL"
991 ) || match_regexp(line, lineNo, record, INTERSECT_SELF_CUBIC_NO, "debugShowCubicIntersection" +
992" no self intersect CUBIC_VAL"
993 );
994 break;
995 case REC_TYPE_SORT:
996 var hasDone = / done/.test(line);
997 var hasUnorderable = / unorderable/.test(line);
998 var hasSmall = / small/.test(line);
999 var hasTiny = / tiny/.test(line);
1000 var hasOperand = / operand/.test(line);
1001 var hasStop = / stop/.test(line);
1002 line.replace(/[ a-z]+$/, "");
1003 found = match_regexp(line, lineNo, record, SORT_UNARY, "debugOne" +
1004" [IDX/IDX] next=IDX/IDX sect=IDX/IDX s=T_VAL [IDX] e=T_VAL [IDX] sgn=NUM windVal=IDX windSum=OPT"
1005 ) || match_regexp(line, lineNo, record, SORT_BINARY, "debugOne" +
1006" [IDX/IDX] next=IDX/IDX sect=IDX/IDX s=T_VAL [IDX] e=T_VAL [IDX] sgn=NUM windVal=IDX windSum=OPT oppVal=IDX oppSum=OPT"
1007 ) || match_regexp(line, lineNo, record, SORT_UNARY, "dumpOne" +
1008" [IDX/IDX] next=IDX/IDX sect=NUM/NUM s=T_VAL [IDX] e=T_VAL [IDX] sgn=NUM windVal=IDX windSum=OPT"
1009 ) || match_regexp(line, lineNo, record, SORT_BINARY, "dumpOne" +
1010" [IDX/IDX] next=IDX/IDX sect=NUM/NUM s=T_VAL [IDX] e=T_VAL [IDX] sgn=NUM windVal=IDX windSum=OPT oppVal=IDX oppSum=OPT"
1011 );
1012 if (found) {
1013 record[1].push(hasDone);
1014 record[1].push(hasUnorderable);
1015 record[1].push(hasSmall);
1016 record[1].push(hasTiny);
1017 record[1].push(hasOperand);
1018 record[1].push(hasStop);
1019 }
1020 break;
caryclark03b03ca2015-04-23 09:13:37 -07001021 case REC_TYPE_TOP:
1022 found = match_regexp(line, lineNo, record, ACTIVE_OP, "findTop" +
1023" id=IDX s=T_VAL e=T_VAL cw=NUM swap=NUM inflections=NUM monotonic=NUM"
1024 ) || match_regexp(line, lineNo, record, ACTIVE_OP, "findTop" +
1025" id=IDX s=T_VAL e=T_VAL (-) cw=NUM swap=NUM inflections=NUM monotonic=NUM"
1026 ) || match_regexp(line, lineNo, record, ACTIVE_OP, "findTop" +
1027" id=IDX s=T_VAL e=T_VAL (+) cw=NUM swap=NUM inflections=NUM monotonic=NUM"
1028 );
1029 break;
caryclarkdac1d172014-06-17 05:15:38 -07001030 case REC_TYPE_MARK:
1031 found = match_regexp(line, lineNo, record, MARK_LINE, "markWinding" +
caryclark54359292015-03-26 07:52:43 -07001032" id=IDX LINE_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX"
caryclarkdac1d172014-06-17 05:15:38 -07001033 ) || match_regexp(line, lineNo, record, MARK_QUAD, "markWinding" +
caryclark54359292015-03-26 07:52:43 -07001034" id=IDX QUAD_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX"
caryclark1049f122015-04-20 08:31:59 -07001035 ) || match_regexp(line, lineNo, record, MARK_CONIC, "markWinding" +
1036" id=IDX CONIC_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX"
caryclarkdac1d172014-06-17 05:15:38 -07001037 ) || match_regexp(line, lineNo, record, MARK_CUBIC, "markWinding" +
caryclark54359292015-03-26 07:52:43 -07001038" id=IDX CUBIC_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX"
1039 ) || match_regexp(line, lineNo, record, MARK_DONE_LINE, "markDone" +
1040" id=IDX LINE_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=OPT newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX oppValue=OPT"
1041 ) || match_regexp(line, lineNo, record, MARK_DONE_QUAD, "markDone" +
1042" id=IDX QUAD_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=OPT newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX oppValue=OPT"
caryclark1049f122015-04-20 08:31:59 -07001043 ) || match_regexp(line, lineNo, record, MARK_DONE_CONIC, "markDone" +
1044" id=IDX CONIC_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=OPT newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX oppValue=OPT"
caryclark54359292015-03-26 07:52:43 -07001045 ) || match_regexp(line, lineNo, record, MARK_DONE_CUBIC, "markDone" +
1046" id=IDX CUBIC_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=OPT newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX oppValue=OPT"
caryclarkdac1d172014-06-17 05:15:38 -07001047 ) || match_regexp(line, lineNo, record, MARK_SIMPLE_LINE, "markWinding" +
1048" id=IDX LINE_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM windSum=OPT windValue=IDX"
1049 ) || match_regexp(line, lineNo, record, MARK_SIMPLE_QUAD, "markWinding" +
1050" id=IDX QUAD_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM windSum=OPT windValue=IDX"
caryclark1049f122015-04-20 08:31:59 -07001051 ) || match_regexp(line, lineNo, record, MARK_SIMPLE_CONIC, "markWinding" +
1052" id=IDX CONIC_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM windSum=OPT windValue=IDX"
caryclarkdac1d172014-06-17 05:15:38 -07001053 ) || match_regexp(line, lineNo, record, MARK_SIMPLE_CUBIC, "markWinding" +
1054" id=IDX CUBIC_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM windSum=OPT windValue=IDX"
caryclarkdac1d172014-06-17 05:15:38 -07001055 ) || match_regexp(line, lineNo, record, MARK_ANGLE_LAST, "markAngle" +
caryclark1049f122015-04-20 08:31:59 -07001056" last segment=IDX span=IDX"
caryclark54359292015-03-26 07:52:43 -07001057 ) || match_regexp(line, lineNo, record, MARK_ANGLE_LAST, "markAngle" +
1058" last segment=IDX span=IDX windSum=OPT");
caryclarkdac1d172014-06-17 05:15:38 -07001059 break;
1060 case REC_TYPE_OP:
1061 if (line.lastIndexOf("oppSign oppSign=", 0) === 0
1062 || line.lastIndexOf("operator<", 0) === 0) {
1063 found = true;
1064 break;
1065 }
caryclark54359292015-03-26 07:52:43 -07001066 found = match_regexp(line, lineNo, record, OP_DIFFERENCE, "op diff"
caryclarkdac1d172014-06-17 05:15:38 -07001067 ) || match_regexp(line, lineNo, record, OP_INTERSECT, "op intersect"
caryclark54359292015-03-26 07:52:43 -07001068 ) || match_regexp(line, lineNo, record, OP_INTERSECT, "op sect"
caryclarkdac1d172014-06-17 05:15:38 -07001069 ) || match_regexp(line, lineNo, record, OP_UNION, "op union"
1070 ) || match_regexp(line, lineNo, record, OP_XOR, "op xor"
1071 );
1072 break;
1073 case REC_TYPE_UNKNOWN:
1074 found = true;
1075 break;
1076 }
1077 if (!found) {
1078 console.log(line + " [" + lineNo + "] of type " + type + " not found");
1079 }
1080 }
1081 if (recType != REC_TYPE_UNKNOWN) {
1082 records.push(recType);
1083 records.push(lastLineNo);
1084 records.push(record);
1085 }
1086 if (records.length >= 1) {
1087 tests[testIndex] = records;
1088 testLines[testIndex] = lines;
1089 }
1090}
1091
1092function init(test) {
1093 var canvas = document.getElementById('canvas');
1094 if (!canvas.getContext) return;
1095 ctx = canvas.getContext('2d');
1096 var resScale = retina_scale && window.devicePixelRatio ? window.devicePixelRatio : 1;
1097 var unscaledWidth = window.innerWidth - 20;
1098 var unscaledHeight = window.innerHeight - 20;
1099 screenWidth = unscaledWidth;
1100 screenHeight = unscaledHeight;
1101 canvas.width = unscaledWidth * resScale;
1102 canvas.height = unscaledHeight * resScale;
1103 canvas.style.width = unscaledWidth + 'px';
1104 canvas.style.height = unscaledHeight + 'px';
1105 if (resScale != 1) {
1106 ctx.scale(resScale, resScale);
1107 }
1108 xmin = Infinity;
1109 xmax = -Infinity;
1110 ymin = Infinity;
1111 ymax = -Infinity;
1112 hasPath = hasComputedPath = false;
1113 firstActiveSpan = -1;
1114 for (var tIndex = 0; tIndex < test.length; tIndex += 3) {
1115 var recType = test[tIndex];
1116 if (!typeof recType == 'number' || recType < REC_TYPE_UNKNOWN || recType > REC_TYPE_LAST) {
1117 console.log("unknown rec type: " + recType);
1118 throw "stop execution";
1119 }
1120 var records = test[tIndex + 2];
1121 for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
1122 var fragType = records[recordIndex];
1123 if (!typeof fragType == 'number' || fragType < 1 || fragType > FRAG_TYPE_LAST) {
1124 console.log("unknown in range frag type: " + fragType);
1125 throw "stop execution";
1126 }
1127 var frags = records[recordIndex + 1];
1128 var first = 0;
1129 var last = -1;
1130 var first2 = 0;
1131 var last2 = 0;
1132 switch (recType) {
1133 case REC_TYPE_COMPUTED:
1134 if (fragType == COMPUTED_SET_1 || fragType == COMPUTED_SET_2) {
1135 break;
1136 }
1137 hasComputedPath = true;
1138 case REC_TYPE_PATH:
caryclark54359292015-03-26 07:52:43 -07001139 first = 1;
caryclarkdac1d172014-06-17 05:15:38 -07001140 switch (fragType) {
1141 case PATH_LINE:
caryclark54359292015-03-26 07:52:43 -07001142 last = 5;
caryclarkdac1d172014-06-17 05:15:38 -07001143 break;
caryclark1049f122015-04-20 08:31:59 -07001144 case PATH_CONIC:
caryclarkdac1d172014-06-17 05:15:38 -07001145 case PATH_QUAD:
caryclark54359292015-03-26 07:52:43 -07001146 last = 7;
caryclarkdac1d172014-06-17 05:15:38 -07001147 break;
1148 case PATH_CUBIC:
caryclark54359292015-03-26 07:52:43 -07001149 last = 9;
caryclarkdac1d172014-06-17 05:15:38 -07001150 break;
1151 default:
1152 console.log("unknown " + (recType == REC_TYPE_PATH ? "REC_TYPE_PATH"
1153 : "REC_TYPE_COMPUTED") + " frag type:" + fragType);
1154 throw "stop execution";
1155 }
1156 if (recType == REC_TYPE_PATH) {
1157 hasPath = true;
1158 }
1159 break;
caryclark54359292015-03-26 07:52:43 -07001160 case REC_TYPE_PATH2:
1161 first = 1;
1162 switch (fragType) {
1163 case PATH_LINE:
1164 last = 5;
1165 break;
caryclark1049f122015-04-20 08:31:59 -07001166 case PATH_CONIC:
caryclark54359292015-03-26 07:52:43 -07001167 case PATH_QUAD:
1168 last = 7;
1169 break;
1170 case PATH_CUBIC:
1171 last = 9;
1172 break;
1173 default:
1174 console.log("unknown " + (recType == REC_TYPE_PATH2 ? "REC_TYPE_PATH2"
1175 : "REC_TYPE_COMPUTED") + " frag type:" + fragType);
1176 throw "stop execution";
1177 }
1178 if (recType == REC_TYPE_PATH2) {
1179 hasPath = true;
1180 }
1181 break;
caryclarkdac1d172014-06-17 05:15:38 -07001182 case REC_TYPE_ACTIVE:
1183 if (firstActiveSpan < 0) {
1184 firstActiveSpan = tIndex;
1185 }
1186 first = 1;
1187 switch (fragType) {
1188 case ACTIVE_LINE_SPAN:
1189 last = 5;
1190 break;
caryclark1049f122015-04-20 08:31:59 -07001191 case ACTIVE_CONIC_SPAN:
caryclarkdac1d172014-06-17 05:15:38 -07001192 case ACTIVE_QUAD_SPAN:
1193 last = 7;
1194 break;
1195 case ACTIVE_CUBIC_SPAN:
1196 last = 9;
1197 break;
1198 default:
1199 console.log("unknown REC_TYPE_ACTIVE frag type: " + fragType);
1200 throw "stop execution";
1201 }
1202 break;
1203 case REC_TYPE_ADD:
1204 switch (fragType) {
1205 case ADD_MOVETO:
1206 break;
1207 case ADD_LINETO:
1208 last = 4;
1209 break;
caryclark1049f122015-04-20 08:31:59 -07001210 case ADD_CONICTO:
caryclarkdac1d172014-06-17 05:15:38 -07001211 case ADD_QUADTO:
1212 last = 6;
1213 break;
1214 case ADD_CUBICTO:
1215 last = 8;
1216 break;
1217 case ADD_CLOSE:
1218 case ADD_FILL:
1219 break;
1220 default:
1221 console.log("unknown REC_TYPE_ADD frag type: " + fragType);
1222 throw "stop execution";
1223 }
1224 break;
caryclark54359292015-03-26 07:52:43 -07001225 case REC_TYPE_AFTERPART:
1226 switch (fragType) {
1227 case PATH_LINE:
1228 last = 4;
1229 break;
caryclark1049f122015-04-20 08:31:59 -07001230 case PATH_CONIC:
caryclark54359292015-03-26 07:52:43 -07001231 case PATH_QUAD:
1232 last = 6;
1233 break;
1234 case PATH_CUBIC:
1235 last = 8;
1236 break;
1237 default:
1238 console.log("unknown REC_TYPE_ACTIVEPART frag type: " + fragType);
1239 throw "stop execution";
1240 }
1241 break;
caryclarkdac1d172014-06-17 05:15:38 -07001242 case REC_TYPE_SECT:
1243 switch (fragType) {
1244 case INTERSECT_LINE:
1245 first = 1; last = 5; first2 = 8; last2 = 12;
1246 break;
1247 case INTERSECT_LINE_2:
1248 first = 1; last = 5; first2 = 11; last2 = 15;
1249 break;
1250 case INTERSECT_LINE_NO:
1251 first = 0; last = 4; first2 = 4; last2 = 8;
1252 break;
caryclark1049f122015-04-20 08:31:59 -07001253 case INTERSECT_CONIC_LINE:
1254 first = 1; last = 7; first2 = 11; last2 = 15;
1255 break;
caryclarkdac1d172014-06-17 05:15:38 -07001256 case INTERSECT_QUAD_LINE:
1257 first = 1; last = 7; first2 = 10; last2 = 14;
1258 break;
caryclark1049f122015-04-20 08:31:59 -07001259 case INTERSECT_CONIC_LINE_2:
1260 first = 1; last = 7; first2 = 14; last2 = 18;
1261 break;
caryclarkdac1d172014-06-17 05:15:38 -07001262 case INTERSECT_QUAD_LINE_2:
1263 first = 1; last = 7; first2 = 13; last2 = 17;
1264 break;
caryclark1049f122015-04-20 08:31:59 -07001265 case INTERSECT_CONIC_LINE_NO:
1266 first = 0; last = 6; first2 = 7; last2 = 11;
1267 break;
caryclarkdac1d172014-06-17 05:15:38 -07001268 case INTERSECT_QUAD_LINE_NO:
1269 first = 0; last = 6; first2 = 6; last2 = 10;
1270 break;
caryclark1049f122015-04-20 08:31:59 -07001271 case INTERSECT_CONIC:
1272 first = 1; last = 7; first2 = 11; last2 = 17;
1273 break;
caryclarkdac1d172014-06-17 05:15:38 -07001274 case INTERSECT_QUAD:
1275 first = 1; last = 7; first2 = 10; last2 = 16;
1276 break;
caryclark1049f122015-04-20 08:31:59 -07001277 case INTERSECT_CONIC_2:
1278 first = 1; last = 7; first2 = 14; last2 = 20;
1279 break;
caryclarkdac1d172014-06-17 05:15:38 -07001280 case INTERSECT_QUAD_2:
1281 first = 1; last = 7; first2 = 13; last2 = 19;
1282 break;
caryclark1049f122015-04-20 08:31:59 -07001283 case INTERSECT_CONIC_NO:
1284 first = 0; last = 6; first2 = 7; last2 = 13;
1285 break;
caryclarkdac1d172014-06-17 05:15:38 -07001286 case INTERSECT_QUAD_NO:
1287 first = 0; last = 6; first2 = 6; last2 = 12;
1288 break;
1289 case INTERSECT_SELF_CUBIC:
1290 first = 1; last = 9;
1291 break;
1292 case INTERSECT_SELF_CUBIC_NO:
1293 first = 0; last = 8;
1294 break;
1295 case INTERSECT_CUBIC_LINE:
1296 first = 1; last = 9; first2 = 12; last2 = 16;
1297 break;
1298 case INTERSECT_CUBIC_LINE_2:
1299 first = 1; last = 9; first2 = 15; last2 = 19;
1300 break;
1301 case INTERSECT_CUBIC_LINE_3:
1302 first = 1; last = 9; first2 = 18; last2 = 22;
1303 break;
1304 case INTERSECT_CUBIC_LINE_NO:
1305 first = 0; last = 8; first2 = 8; last2 = 12;
1306 break;
1307 case INTERSECT_CUBIC_QUAD:
1308 first = 1; last = 9; first2 = 12; last2 = 18;
1309 break;
1310 case INTERSECT_CUBIC_QUAD_2:
1311 first = 1; last = 9; first2 = 15; last2 = 21;
1312 break;
1313 case INTERSECT_CUBIC_QUAD_3:
1314 first = 1; last = 9; first2 = 18; last2 = 24;
1315 break;
1316 case INTERSECT_CUBIC_QUAD_4:
1317 first = 1; last = 9; first2 = 21; last2 = 27;
1318 break;
1319 case INTERSECT_CUBIC_QUAD_NO:
1320 first = 0; last = 8; first2 = 8; last2 = 14;
1321 break;
1322 case INTERSECT_CUBIC:
1323 first = 1; last = 9; first2 = 12; last2 = 20;
1324 break;
1325 case INTERSECT_CUBIC_2:
1326 first = 1; last = 9; first2 = 15; last2 = 23;
1327 break;
1328 case INTERSECT_CUBIC_3:
1329 first = 1; last = 9; first2 = 18; last2 = 26;
1330 break;
1331 case INTERSECT_CUBIC_4:
1332 first = 1; last = 9; first2 = 21; last2 = 29;
1333 break;
1334 case INTERSECT_CUBIC_NO:
1335 first = 0; last = 8; first2 = 8; last2 = 16;
1336 break;
1337 default:
1338 console.log("unknown REC_TYPE_SECT frag type: " + fragType);
1339 throw "stop execution";
1340 }
1341 break;
1342 default:
1343 continue;
1344 }
1345 for (var idx = first; idx < last; idx += 2) {
1346 xmin = Math.min(xmin, frags[idx]);
1347 xmax = Math.max(xmax, frags[idx]);
1348 ymin = Math.min(ymin, frags[idx + 1]);
1349 ymax = Math.max(ymax, frags[idx + 1]);
1350 }
1351 for (var idx = first2; idx < last2; idx += 2) {
1352 xmin = Math.min(xmin, frags[idx]);
1353 xmax = Math.max(xmax, frags[idx]);
1354 ymin = Math.min(ymin, frags[idx + 1]);
1355 ymax = Math.max(ymax, frags[idx + 1]);
1356 }
1357 }
1358 }
1359 var angleBounds = [Infinity, Infinity, -Infinity, -Infinity];
1360 for (var tIndex = 0; tIndex < test.length; tIndex += 3) {
1361 var recType = test[tIndex];
1362 var records = test[tIndex + 2];
1363 for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
1364 var fragType = records[recordIndex];
1365 var frags = records[recordIndex + 1];
1366 switch (recType) {
1367 case REC_TYPE_ACTIVE_OP:
1368 if (!draw_op) {
1369 break;
1370 }
1371 {
1372 var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
1373 curve_extremes(curve, angleBounds);
1374 }
1375 break;
1376 case REC_TYPE_ANGLE:
1377 if (!draw_angle) {
1378 break;
1379 }
caryclark54359292015-03-26 07:52:43 -07001380 {
caryclarkdac1d172014-06-17 05:15:38 -07001381 var curve = curvePartialByID(test, frags[0], frags[4], frags[5]);
1382 curve_extremes(curve, angleBounds);
1383 curve = curvePartialByID(test, frags[6], frags[10], frags[11]);
1384 curve_extremes(curve, angleBounds);
1385 curve = curvePartialByID(test, frags[12], frags[16], frags[17]);
1386 }
1387 break;
caryclark624637c2015-05-11 07:21:27 -07001388 case REC_TYPE_COINCIDENCE:
1389 if (!draw_coincidence) {
1390 break;
1391 }
1392 {
1393 var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
1394 curve_extremes(curve, angleBounds);
1395 }
1396 break;
caryclarkdac1d172014-06-17 05:15:38 -07001397 case REC_TYPE_SORT:
1398 if (!draw_sort) {
1399 break;
1400 }
1401 if (fragType == SORT_UNARY || fragType == SORT_BINARY) {
1402 var curve = curvePartialByID(test, frags[0], frags[6], frags[8]);
1403 curve_extremes(curve, angleBounds);
1404 }
1405 break;
caryclark03b03ca2015-04-23 09:13:37 -07001406 case REC_TYPE_TOP:
1407 if (!draw_top) {
1408 break;
1409 }
1410 {
1411 var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
1412 curve_extremes(curve, angleBounds);
1413 }
1414 break;
caryclarkdac1d172014-06-17 05:15:38 -07001415 }
1416 }
1417 }
1418 xmin = Math.min(xmin, angleBounds[0]);
1419 ymin = Math.min(ymin, angleBounds[1]);
1420 xmax = Math.max(xmax, angleBounds[2]);
1421 ymax = Math.max(ymax, angleBounds[3]);
1422 setScale(xmin, xmax, ymin, ymax);
1423 if (hasPath == false && hasComputedPath == true && !draw_computed) {
caryclark1049f122015-04-20 08:31:59 -07001424 draw_computed = 7; // show quadratics, conics, and cubics
caryclarkdac1d172014-06-17 05:15:38 -07001425 }
1426 if (hasPath == true && hasComputedPath == false && draw_computed) {
1427 draw_computed = 0;
1428 }
1429}
1430
1431function curveByID(test, id) {
caryclark54359292015-03-26 07:52:43 -07001432 var tIndex = -3;
1433 while ((tIndex += 3) < test.length) {
caryclarkdac1d172014-06-17 05:15:38 -07001434 var recType = test[tIndex];
caryclark54359292015-03-26 07:52:43 -07001435 if (recType == REC_TYPE_OP) {
1436 continue;
1437 }
1438 if (recType != REC_TYPE_PATH) {
caryclarkdac1d172014-06-17 05:15:38 -07001439 return [];
1440 }
1441 var records = test[tIndex + 2];
1442 for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
1443 var fragType = records[recordIndex];
1444 var frags = records[recordIndex + 1];
1445 if (frags[0] == id) {
1446 switch (fragType) {
caryclark54359292015-03-26 07:52:43 -07001447 case PATH_LINE:
caryclarkdac1d172014-06-17 05:15:38 -07001448 return [frags[1], frags[2], frags[3], frags[4]];
caryclark54359292015-03-26 07:52:43 -07001449 case PATH_QUAD:
caryclarkdac1d172014-06-17 05:15:38 -07001450 return [frags[1], frags[2], frags[3], frags[4],
1451 frags[5], frags[6]];
caryclark1049f122015-04-20 08:31:59 -07001452 case PATH_CONIC:
1453 return [frags[1], frags[2], frags[3], frags[4],
1454 frags[5], frags[6], frags[7]];
caryclark54359292015-03-26 07:52:43 -07001455 case PATH_CUBIC:
caryclarkdac1d172014-06-17 05:15:38 -07001456 return [frags[1], frags[2], frags[3], frags[4],
1457 frags[5], frags[6], frags[7], frags[8]];
1458 }
1459 }
1460 }
caryclarkdac1d172014-06-17 05:15:38 -07001461 }
1462 return [];
1463}
1464
1465function curvePartialByID(test, id, t0, t1) {
caryclark54359292015-03-26 07:52:43 -07001466 var tIndex = -3;
1467 while ((tIndex += 3) < test.length) {
caryclarkdac1d172014-06-17 05:15:38 -07001468 var recType = test[tIndex];
caryclark54359292015-03-26 07:52:43 -07001469 if (recType == REC_TYPE_OP) {
1470 continue;
1471 }
1472 if (recType != REC_TYPE_PATH) {
caryclarkdac1d172014-06-17 05:15:38 -07001473 return [];
1474 }
1475 var records = test[tIndex + 2];
1476 for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
1477 var fragType = records[recordIndex];
1478 var frags = records[recordIndex + 1];
1479 if (frags[0] == id) {
1480 switch (fragType) {
caryclark54359292015-03-26 07:52:43 -07001481 case PATH_LINE:
caryclarkdac1d172014-06-17 05:15:38 -07001482 return linePartial(frags[1], frags[2], frags[3], frags[4], t0, t1);
caryclark54359292015-03-26 07:52:43 -07001483 case PATH_QUAD:
caryclarkdac1d172014-06-17 05:15:38 -07001484 return quadPartial(frags[1], frags[2], frags[3], frags[4],
1485 frags[5], frags[6], t0, t1);
caryclark1049f122015-04-20 08:31:59 -07001486 case PATH_CONIC:
1487 return conicPartial(frags[1], frags[2], frags[3], frags[4],
1488 frags[5], frags[6], frags[7], t0, t1);
caryclark54359292015-03-26 07:52:43 -07001489 case PATH_CUBIC:
caryclarkdac1d172014-06-17 05:15:38 -07001490 return cubicPartial(frags[1], frags[2], frags[3], frags[4],
1491 frags[5], frags[6], frags[7], frags[8], t0, t1);
1492 }
1493 }
1494 }
caryclarkdac1d172014-06-17 05:15:38 -07001495 }
1496 return [];
1497}
1498
1499function idByCurve(test, frag, type) {
caryclark54359292015-03-26 07:52:43 -07001500 var tIndex = 0;
caryclarkdac1d172014-06-17 05:15:38 -07001501 while (tIndex < test.length) {
1502 var recType = test[tIndex];
caryclark54359292015-03-26 07:52:43 -07001503 if (recType != REC_TYPE_PATH) {
1504 ++tIndex;
1505 continue;
caryclarkdac1d172014-06-17 05:15:38 -07001506 }
1507 var records = test[tIndex + 2];
1508 for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
1509 var fragType = records[recordIndex];
1510 var frags = records[recordIndex + 1];
caryclark54359292015-03-26 07:52:43 -07001511 if (frag.length != frags.length - 1) {
1512 continue;
1513 }
caryclarkdac1d172014-06-17 05:15:38 -07001514 switch (fragType) {
caryclark54359292015-03-26 07:52:43 -07001515 case PATH_LINE:
caryclarkdac1d172014-06-17 05:15:38 -07001516 if (frag[0] != frags[1] || frag[1] != frags[2]
1517 || frag[2] != frags[3] || frag[3] != frags[4]) {
1518 continue;
1519 }
1520 return frags[0];
caryclark54359292015-03-26 07:52:43 -07001521 case PATH_QUAD:
caryclarkdac1d172014-06-17 05:15:38 -07001522 if (frag[0] != frags[1] || frag[1] != frags[2]
1523 || frag[2] != frags[3] || frag[3] != frags[4]
1524 || frag[4] != frags[5] || frag[5] != frags[6]) {
1525 continue;
1526 }
1527 return frags[0];
caryclark1049f122015-04-20 08:31:59 -07001528 case PATH_CONIC:
1529 if (frag[0] != frags[1] || frag[1] != frags[2]
1530 || frag[2] != frags[3] || frag[3] != frags[4]
1531 || frag[4] != frags[5] || frag[5] != frags[6]
1532 || frag[6] != frags[7]) {
1533 continue;
1534 }
1535 return frags[0];
caryclark54359292015-03-26 07:52:43 -07001536 case PATH_CUBIC:
caryclarkdac1d172014-06-17 05:15:38 -07001537 if (frag[0] != frags[1] || frag[1] != frags[2]
1538 || frag[2] != frags[3] || frag[3] != frags[4]
1539 || frag[4] != frags[5] || frag[5] != frags[6]
1540 || frag[6] != frags[7] || frag[7] != frags[8]) {
1541 continue;
1542 }
1543 return frags[0];
1544 }
1545 }
1546 ++tIndex;
1547 }
1548 return -1;
1549}
1550
1551function curve_extremes(curve, bounds) {
caryclark1049f122015-04-20 08:31:59 -07001552 var length = curve.length == 7 ? 6 : curve.length;
caryclarkdac1d172014-06-17 05:15:38 -07001553 for (var index = 0; index < curve.length; index += 2) {
1554 var x = curve[index];
1555 var y = curve[index + 1];
1556 bounds[0] = Math.min(bounds[0], x);
1557 bounds[1] = Math.min(bounds[1], y);
1558 bounds[2] = Math.max(bounds[2], x);
1559 bounds[3] = Math.max(bounds[3], y);
1560 }
1561}
1562
1563function setScale(x0, x1, y0, y1) {
1564 var srcWidth = x1 - x0;
1565 var srcHeight = y1 - y0;
1566 var usableWidth = screenWidth;
1567 var xDigits = Math.ceil(Math.log(Math.abs(xmax)) / Math.log(10));
1568 var yDigits = Math.ceil(Math.log(Math.abs(ymax)) / Math.log(10));
1569 usableWidth -= (xDigits + yDigits) * 10;
1570 usableWidth -= decimal_places * 10;
1571 if (draw_legend) {
1572 usableWidth -= 40;
1573 }
1574 var hscale = usableWidth / srcWidth;
1575 var vscale = screenHeight / srcHeight;
1576 scale = Math.min(hscale, vscale);
1577 var invScale = 1 / scale;
1578 var sxmin = x0 - invScale * 5;
1579 var symin = y0 - invScale * 10;
1580 var sxmax = x1 + invScale * (6 * decimal_places + 10);
1581 var symax = y1 + invScale * 10;
1582 srcWidth = sxmax - sxmin;
1583 srcHeight = symax - symin;
1584 hscale = usableWidth / srcWidth;
1585 vscale = screenHeight / srcHeight;
1586 scale = Math.min(hscale, vscale);
1587 srcLeft = sxmin;
1588 srcTop = symin;
1589}
1590
1591function drawArc(curve, op, from, to) {
1592 var type = PATH_LINE + (curve.length / 2 - 2);
1593 var pt = pointAtT(curve, type, op ? 0.4 : 0.6);
1594 var dy = pt.y - curve[1];
1595 var dx = pt.x - curve[0];
1596 var dist = Math.sqrt(dy * dy + dx * dx);
1597 var _dist = dist * scale;
1598 var angle = Math.atan2(dy, dx);
1599 var _px = (curve[0] - srcLeft) * scale;
1600 var _py = (curve[1] - srcTop) * scale;
1601 var divisor = 4;
1602 var endDist;
1603 do {
1604 var ends = [];
1605 for (var index = -1; index <= 1; index += 2) {
1606 var px = Math.cos(index * Math.PI / divisor);
1607 var py = Math.sin(index * Math.PI / divisor);
1608 ends.push(px);
1609 ends.push(py);
1610 }
1611 var endDx = (ends[2] - ends[0]) * scale * dist;
1612 var endDy = (ends[3] - ends[1]) * scale * dist;
1613 endDist = Math.sqrt(endDx * endDx + endDy * endDy);
1614 if (endDist < 100) {
1615 break;
1616 }
1617 divisor *= 2;
1618 } while (true);
1619 if (endDist < 30) {
1620 return;
1621 }
1622 if (op) {
1623 divisor *= 2;
1624 }
1625 ctx.strokeStyle = op ? "rgba(210,0,45, 0.4)" : "rgba(90,90,90, 0.5)";
1626 ctx.beginPath();
1627 ctx.arc(_px, _py, _dist, angle - Math.PI / divisor, angle + Math.PI / divisor, false);
1628 ctx.stroke();
1629 var saveAlign = ctx.textAlign;
1630 var saveStyle = ctx.fillStyle;
1631 var saveFont = ctx.font;
1632 ctx.textAlign = "center";
1633 ctx.fillStyle = "black";
1634 ctx.font = "normal 24px Arial";
1635 divisor *= 0.8;
1636 for (var index = -1; index <= 1; index += 2) {
1637 var px = curve[0] + Math.cos(angle + index * Math.PI / divisor) * dist;
1638 var py = curve[1] + Math.sin(angle + index * Math.PI / divisor) * dist;
1639 var _px = (px - srcLeft) * scale;
1640 var _py = (py - srcTop) * scale;
1641 ctx.fillText(index < 0 ? to.toString() : from.toString(), _px, _py + 8);
1642 }
1643 ctx.textAlign = saveAlign;
1644 ctx.fillStyle = saveStyle;
1645 ctx.font = saveFont;
1646}
1647
1648function drawPoint(px, py, end) {
caryclark1049f122015-04-20 08:31:59 -07001649 var length = drawnPts.length == 7 ? 6 : drawnPts.length;
1650 for (var pts = 0; pts < length; pts += 2) {
caryclarkdac1d172014-06-17 05:15:38 -07001651 var x = drawnPts[pts];
1652 var y = drawnPts[pts + 1];
1653 if (px == x && py == y) {
1654 return;
1655 }
1656 }
1657 drawnPts.push(px);
1658 drawnPts.push(py);
1659 var label = px.toFixed(decimal_places) + ", " + py.toFixed(decimal_places);
1660 var _px = (px - srcLeft) * scale;
1661 var _py = (py - srcTop) * scale;
1662 ctx.beginPath();
1663 ctx.arc(_px, _py, 3, 0, Math.PI*2, true);
1664 ctx.closePath();
1665 if (end) {
1666 ctx.fill();
1667 } else {
1668 ctx.stroke();
1669 }
1670 if (debug_xy) {
1671 ctx.textAlign = "left";
1672 ctx.fillText(label, _px + 5, _py);
1673 }
1674}
1675
caryclark1049f122015-04-20 08:31:59 -07001676function coordCount(curveType) {
1677 switch (curveType) {
1678 case PATH_LINE:
1679 return 4;
1680 case PATH_QUAD:
1681 return 6;
1682 case PATH_CONIC:
1683 return 6;
1684 case PATH_CUBIC:
1685 return 8;
1686 }
1687 return -1;
1688}
1689
caryclarkdac1d172014-06-17 05:15:38 -07001690function drawPoints(ptArray, curveType, drawControls) {
caryclark1049f122015-04-20 08:31:59 -07001691 var count = coordCount(curveType);
caryclarkdac1d172014-06-17 05:15:38 -07001692 for (var idx = 0; idx < count; idx += 2) {
1693 if (!drawControls && idx != 0 && idx != count - 2) {
1694 continue;
1695 }
1696 drawPoint(ptArray[idx], ptArray[idx + 1], idx == 0 || idx == count - 2);
1697 }
1698}
1699
1700function drawControlLines(curve, curveType, drawEnd) {
1701 if (curveType == PATH_LINE) {
1702 return;
1703 }
1704 ctx.strokeStyle = "rgba(0,0,0, 0.3)";
1705 drawLine(curve[0], curve[1], curve[2], curve[3]);
1706 drawLine(curve[2], curve[3], curve[4], curve[5]);
1707 if (curveType == PATH_CUBIC) {
1708 drawLine(curve[4], curve[5], curve[6], curve[7]);
1709 if (drawEnd > 1) {
1710 drawLine(curve[6], curve[7], curve[0], curve[1]);
1711 if (drawEnd > 2) {
1712 drawLine(curve[0], curve[1], curve[4], curve[5]);
1713 drawLine(curve[6], curve[7], curve[2], curve[3]);
1714 }
1715 }
1716 } else if (drawEnd > 1) {
1717 drawLine(curve[4], curve[5], curve[0], curve[1]);
1718 }
1719}
1720
1721function pointAtT(curve, curveType, t) {
1722 var xy = {};
1723 switch (curveType) {
1724 case PATH_LINE:
1725 var a = 1 - t;
1726 var b = t;
1727 xy.x = a * curve[0] + b * curve[2];
1728 xy.y = a * curve[1] + b * curve[3];
1729 break;
1730 case PATH_QUAD:
1731 var one_t = 1 - t;
1732 var a = one_t * one_t;
1733 var b = 2 * one_t * t;
1734 var c = t * t;
1735 xy.x = a * curve[0] + b * curve[2] + c * curve[4];
1736 xy.y = a * curve[1] + b * curve[3] + c * curve[5];
1737 break;
caryclark1049f122015-04-20 08:31:59 -07001738 case PATH_CONIC:
1739 var one_t = 1 - t;
1740 var a = one_t * one_t;
1741 var b = 2 * one_t * t;
1742 var c = t * t;
1743 xy.x = a * curve[0] + b * curve[2] * curve[6] + c * curve[4];
1744 xy.y = a * curve[1] + b * curve[3] * curve[6] + c * curve[5];
1745 var d = a + b * curve[6] + c;
1746 xy.x /= d;
1747 xy.y /= d;
1748 break;
caryclarkdac1d172014-06-17 05:15:38 -07001749 case PATH_CUBIC:
1750 var one_t = 1 - t;
1751 var one_t2 = one_t * one_t;
1752 var a = one_t2 * one_t;
1753 var b = 3 * one_t2 * t;
1754 var t2 = t * t;
1755 var c = 3 * one_t * t2;
1756 var d = t2 * t;
1757 xy.x = a * curve[0] + b * curve[2] + c * curve[4] + d * curve[6];
1758 xy.y = a * curve[1] + b * curve[3] + c * curve[5] + d * curve[7];
1759 break;
1760 }
1761 return xy;
1762}
1763
1764function drawPointAtT(curve, curveType) {
1765 var x, y;
1766 var xy = pointAtT(curve, curveType, curveT);
1767 drawPoint(xy.x, xy.y, true);
1768 if (!draw_intersectT) {
1769 return;
1770 }
1771 ctx.fillStyle = "red";
1772 drawTAtPointUp(xy.x, xy.y, curveT);
1773}
1774
1775function drawTAtPointUp(px, py, t) {
1776 var label = t.toFixed(decimal_places);
1777 var _px = (px - srcLeft)* scale;
1778 var _py = (py - srcTop) * scale;
1779 ctx.fillText(label, _px + 5, _py - 10);
1780}
1781
1782function drawTAtPointDown(px, py, t) {
1783 var label = t.toFixed(decimal_places);
1784 var _px = (px - srcLeft)* scale;
1785 var _py = (py - srcTop) * scale;
1786 ctx.fillText(label, _px + 5, _py + 10);
1787}
1788
1789function alreadyDrawnLine(x1, y1, x2, y2) {
1790 if (collect_bounds) {
1791 if (focus_enabled) {
1792 focusXmin = Math.min(focusXmin, x1, x2);
1793 focusYmin = Math.min(focusYmin, y1, y2);
1794 focusXmax = Math.max(focusXmax, x1, x2);
1795 focusYmax = Math.max(focusYmax, y1, y2);
1796 }
1797 return true;
1798 }
1799 for (var pts = 0; pts < drawnLines.length; pts += 4) {
1800 if (x1 == drawnLines[pts] && y1 == drawnLines[pts + 1]
1801 && x2 == drawnLines[pts + 2] && y2 == drawnLines[pts + 3]) {
1802 return true;
1803 }
1804 }
1805 drawnLines.push(x1);
1806 drawnLines.push(y1);
1807 drawnLines.push(x2);
1808 drawnLines.push(y2);
1809 return false;
1810}
1811
1812function drawLine(x1, y1, x2, y2) {
1813 if (alreadyDrawnLine(x1, y1, x2, y2)) {
1814 return;
1815 }
1816 ctx.beginPath();
1817 ctx.moveTo((x1 - srcLeft) * scale,
1818 (y1 - srcTop) * scale);
1819 ctx.lineTo((x2 - srcLeft) * scale,
1820 (y2 - srcTop) * scale);
1821 ctx.stroke();
1822}
1823
1824function linePartial(x1, y1, x2, y2, t1, t2) {
1825 var dx = x1 - x2;
1826 var dy = y1 - y2;
1827 var array = [
1828 x1 - t1 * dx,
1829 y1 - t1 * dy,
1830 x1 - t2 * dx,
1831 y1 - t2 * dy
1832 ];
1833 return array;
1834}
1835
1836function drawLinePartial(x1, y1, x2, y2, t1, t2) {
1837 var a = linePartial(x1, y1, x2, y2, t1, t2);
1838 var ax = a[0];
1839 var ay = a[1];
1840 var bx = a[2];
1841 var by = a[3];
1842 if (alreadyDrawnLine(ax, ay, bx, by)) {
1843 return;
1844 }
1845 ctx.beginPath();
1846 ctx.moveTo((ax - srcLeft) * scale,
1847 (ay - srcTop) * scale);
1848 ctx.lineTo((bx - srcLeft) * scale,
1849 (by - srcTop) * scale);
1850 ctx.stroke();
1851}
1852
1853function alreadyDrawnQuad(x1, y1, x2, y2, x3, y3) {
1854 if (collect_bounds) {
1855 if (focus_enabled) {
1856 focusXmin = Math.min(focusXmin, x1, x2, x3);
1857 focusYmin = Math.min(focusYmin, y1, y2, y3);
1858 focusXmax = Math.max(focusXmax, x1, x2, x3);
1859 focusYmax = Math.max(focusYmax, y1, y2, y3);
1860 }
1861 return true;
1862 }
1863 for (var pts = 0; pts < drawnQuads.length; pts += 6) {
1864 if (x1 == drawnQuads[pts] && y1 == drawnQuads[pts + 1]
1865 && x2 == drawnQuads[pts + 2] && y2 == drawnQuads[pts + 3]
1866 && x3 == drawnQuads[pts + 4] && y3 == drawnQuads[pts + 5]) {
1867 return true;
1868 }
1869 }
1870 drawnQuads.push(x1);
1871 drawnQuads.push(y1);
1872 drawnQuads.push(x2);
1873 drawnQuads.push(y2);
1874 drawnQuads.push(x3);
1875 drawnQuads.push(y3);
1876 return false;
1877}
1878
1879function drawQuad(x1, y1, x2, y2, x3, y3) {
1880 if (alreadyDrawnQuad(x1, y1, x2, y2, x3, y3)) {
1881 return;
1882 }
1883 ctx.beginPath();
1884 ctx.moveTo((x1 - srcLeft) * scale,
1885 (y1 - srcTop) * scale);
1886 ctx.quadraticCurveTo((x2 - srcLeft) * scale,
1887 (y2 - srcTop) * scale,
1888 (x3 - srcLeft) * scale,
1889 (y3 - srcTop) * scale);
1890 ctx.stroke();
1891}
1892
1893function interp(A, B, t) {
1894 return A + (B - A) * t;
1895}
1896
1897function interp_quad_coords(x1, x2, x3, t)
1898{
1899 var ab = interp(x1, x2, t);
1900 var bc = interp(x2, x3, t);
1901 var abc = interp(ab, bc, t);
1902 return abc;
1903}
1904
1905function quadPartial(x1, y1, x2, y2, x3, y3, t1, t2) {
1906 var ax = interp_quad_coords(x1, x2, x3, t1);
1907 var ay = interp_quad_coords(y1, y2, y3, t1);
1908 var dx = interp_quad_coords(x1, x2, x3, (t1 + t2) / 2);
1909 var dy = interp_quad_coords(y1, y2, y3, (t1 + t2) / 2);
1910 var cx = interp_quad_coords(x1, x2, x3, t2);
1911 var cy = interp_quad_coords(y1, y2, y3, t2);
1912 var bx = 2*dx - (ax + cx)/2;
1913 var by = 2*dy - (ay + cy)/2;
1914 var array = [
1915 ax, ay, bx, by, cx, cy
1916 ];
1917 return array;
1918}
1919
1920function drawQuadPartial(x1, y1, x2, y2, x3, y3, t1, t2) {
1921 var a = quadPartial(x1, y1, x2, y2, x3, y3, t1, t2);
1922 var ax = a[0];
1923 var ay = a[1];
1924 var bx = a[2];
1925 var by = a[3];
1926 var cx = a[4];
1927 var cy = a[5];
1928 if (alreadyDrawnQuad(ax, ay, bx, by, cx, cy)) {
1929 return;
1930 }
1931 ctx.beginPath();
1932 ctx.moveTo((ax - srcLeft) * scale,
1933 (ay - srcTop) * scale);
1934 ctx.quadraticCurveTo((bx - srcLeft) * scale,
1935 (by - srcTop) * scale,
1936 (cx - srcLeft) * scale,
1937 (cy - srcTop) * scale);
1938 ctx.stroke();
1939}
1940
caryclark1049f122015-04-20 08:31:59 -07001941function alreadyDrawnConic(x1, y1, x2, y2, x3, y3, w) {
1942 if (collect_bounds) {
1943 if (focus_enabled) {
1944 focusXmin = Math.min(focusXmin, x1, x2, x3);
1945 focusYmin = Math.min(focusYmin, y1, y2, y3);
1946 focusXmax = Math.max(focusXmax, x1, x2, x3);
1947 focusYmax = Math.max(focusYmax, y1, y2, y3);
1948 }
1949 return true;
1950 }
1951 for (var pts = 0; pts < drawnConics.length; pts += 8) {
1952 if (x1 == drawnConics[pts] && y1 == drawnCubics[pts + 1]
1953 && x2 == drawnCubics[pts + 2] && y2 == drawnCubics[pts + 3]
1954 && x3 == drawnCubics[pts + 4] && y3 == drawnCubics[pts + 5]
1955 && w == drawnCubics[pts + 6]) {
1956 return true;
1957 }
1958 }
1959 drawnConics.push(x1);
1960 drawnConics.push(y1);
1961 drawnConics.push(x2);
1962 drawnConics.push(y2);
1963 drawnConics.push(x3);
1964 drawnConics.push(y3);
1965 drawnCubics.push(w);
1966 return false;
1967}
1968
1969var kMaxConicToQuadPOW2 = 5;
1970
1971function computeQuadPOW2(curve, tol) {
1972 var a = curve[6] - 1;
1973 var k = a / (4 * (2 + a));
1974 var x = k * (curve[0] - 2 * curve[2] + curve[4]);
1975 var y = k * (curve[1] - 2 * curve[3] + curve[5]);
1976
1977 var error = Math.sqrt(x * x + y * y);
1978 var pow2;
1979 for (pow2 = 0; pow2 < kMaxConicToQuadPOW2; ++pow2) {
1980 if (error <= tol) {
1981 break;
1982 }
1983 error *= 0.25;
1984 }
1985 return pow2;
1986}
1987
1988function subdivide_w_value(w) {
1989 return Math.sqrt(0.5 + w * 0.5);
1990}
1991
1992function chop(curve, part1, part2) {
1993 var w = curve[6];
1994 var scale = 1 / (1 + w);
1995 part1[0] = curve[0];
1996 part1[1] = curve[1];
1997 part1[2] = (curve[0] + curve[2] * w) * scale;
1998 part1[3] = (curve[1] + curve[3] * w) * scale;
1999 part1[4] = part2[0] = (curve[0] + (curve[2] * w) * 2 + curve[4]) * scale * 0.5;
2000 part1[5] = part2[1] = (curve[1] + (curve[3] * w) * 2 + curve[5]) * scale * 0.5;
2001 part2[2] = (curve[2] * w + curve[4]) * scale;
2002 part2[3] = (curve[3] * w + curve[5]) * scale;
2003 part2[4] = curve[4];
2004 part2[5] = curve[5];
2005 part1[6] = part2[6] = subdivide_w_value(w);
2006}
2007
2008function subdivide(curve, level, pts) {
2009 if (0 == level) {
2010 pts.push(curve[2]);
2011 pts.push(curve[3]);
2012 pts.push(curve[4]);
2013 pts.push(curve[5]);
2014 } else {
2015 var part1 = [], part2 = [];
2016 chop(curve, part1, part2);
2017 --level;
2018 subdivide(part1, level, pts);
2019 subdivide(part2, level, pts);
2020 }
2021}
2022
2023function chopIntoQuadsPOW2(curve, pow2, pts) {
2024 subdivide(curve, pow2, pts);
2025 return 1 << pow2;
2026}
2027
2028function drawConicWithQuads(x1, y1, x2, y2, x3, y3, w) {
2029 if (alreadyDrawnConic(x1, y1, x2, y2, x3, y3, w)) {
2030 return;
2031 }
2032 ctx.beginPath();
2033 ctx.moveTo((x1 - srcLeft) * scale,
2034 (y1 - srcTop) * scale);
2035 var tol = 1 / scale;
2036 var curve = [x1, y1, x2, y2, x3, y3, w];
2037 var pow2 = computeQuadPOW2(curve, tol);
2038 var pts = [];
2039 chopIntoQuadsPOW2(curve, pow2, pts);
2040 for (var i = 0; i < pts.length; i += 4) {
2041 ctx.quadraticCurveTo(
2042 (pts[i + 0] - srcLeft) * scale, (pts[i + 1] - srcTop) * scale,
2043 (pts[i + 2] - srcLeft) * scale, (pts[i + 3] - srcTop) * scale);
2044 }
2045 ctx.stroke();
2046}
2047
2048function conic_eval_numerator(x1, x2, x3, w, t) {
2049 var src2w = x2 * w;
2050 var C = x1;
2051 var A = x3 - 2 * src2w + C;
2052 var B = 2 * (src2w - C);
2053 return (A * t + B) * t + C;
2054}
2055
2056
2057function conic_eval_denominator(w, t) {
2058 var B = 2 * (w - 1);
2059 var C = 1;
2060 var A = -B;
2061 return (A * t + B) * t + C;
2062}
2063
2064function conicPartial(x1, y1, x2, y2, x3, y3, w, t1, t2) {
2065 var ax = conic_eval_numerator(x1, x2, x3, w, t1);
2066 var ay = conic_eval_numerator(y1, y2, y3, w, t1);
2067 var az = conic_eval_denominator(w, t1);
2068 var midT = (t1 + t2) / 2;
2069 var dx = conic_eval_numerator(x1, x2, x3, w, midT);
2070 var dy = conic_eval_numerator(y1, y2, y3, w, midT);
2071 var dz = conic_eval_denominator(w, midT);
2072 var cx = conic_eval_numerator(x1, x2, x3, w, t2);
2073 var cy = conic_eval_numerator(y1, y2, y3, w, t2);
2074 var cz = conic_eval_denominator(w, t2);
2075 var bx = 2 * dx - (ax + cx) / 2;
2076 var by = 2 * dy - (ay + cy) / 2;
2077 var bz = 2 * dz - (az + cz) / 2;
2078 var dt = t2 - t1;
2079 var dt_1 = 1 - dt;
2080 var partW = (1 + dt * (w - 1)) / Math.sqrt(dt * dt + 2 * dt * dt_1 * w + dt_1 * dt_1);
2081 var array = [
2082 ax / az, ay / az, bx / bz, by / bz, cx / cz, cy / cz, partW
2083 ];
2084 return array;
2085}
2086
2087function drawConicPartial(x1, y1, x2, y2, x3, y3, w, t1, t2) {
2088 var a = conicPartial(x1, y1, x2, y2, x3, y3, w, t1, t2);
2089 var ax = a[0];
2090 var ay = a[1];
2091 var bx = a[2];
2092 var by = a[3];
2093 var cx = a[4];
2094 var cy = a[5];
2095 var w_ = a[6];
2096 drawConicWithQuads(ax, ay, bx, by, cx, cy, w_);
2097}
2098
caryclarkdac1d172014-06-17 05:15:38 -07002099function alreadyDrawnCubic(x1, y1, x2, y2, x3, y3, x4, y4) {
2100 if (collect_bounds) {
2101 if (focus_enabled) {
2102 focusXmin = Math.min(focusXmin, x1, x2, x3, x4);
2103 focusYmin = Math.min(focusYmin, y1, y2, y3, y4);
2104 focusXmax = Math.max(focusXmax, x1, x2, x3, x4);
2105 focusYmax = Math.max(focusYmax, y1, y2, y3, y4);
2106 }
2107 return true;
2108 }
2109 for (var pts = 0; pts < drawnCubics.length; pts += 8) {
2110 if (x1 == drawnCubics[pts] && y1 == drawnCubics[pts + 1]
2111 && x2 == drawnCubics[pts + 2] && y2 == drawnCubics[pts + 3]
2112 && x3 == drawnCubics[pts + 4] && y3 == drawnCubics[pts + 5]
2113 && x4 == drawnCubics[pts + 6] && y4 == drawnCubics[pts + 7]) {
2114 return true;
2115 }
2116 }
2117 drawnCubics.push(x1);
2118 drawnCubics.push(y1);
2119 drawnCubics.push(x2);
2120 drawnCubics.push(y2);
2121 drawnCubics.push(x3);
2122 drawnCubics.push(y3);
2123 drawnCubics.push(x4);
2124 drawnCubics.push(y4);
2125 return false;
2126}
2127
2128function drawCubic(x1, y1, x2, y2, x3, y3, x4, y4) {
2129 if (alreadyDrawnCubic(x1, y1, x2, y2, x3, y3, x4, y4)) {
2130 return;
2131 }
2132 ctx.beginPath();
2133 ctx.moveTo((x1 - srcLeft) * scale,
2134 (y1 - srcTop) * scale);
2135 ctx.bezierCurveTo((x2 - srcLeft) * scale,
2136 (y2 - srcTop) * scale,
2137 (x3 - srcLeft) * scale,
2138 (y3 - srcTop) * scale,
2139 (x4 - srcLeft) * scale,
2140 (y4 - srcTop) * scale);
2141 ctx.stroke();
2142}
2143
2144function interp_cubic_coords(x1, x2, x3, x4, t)
2145{
2146 var ab = interp(x1, x2, t);
2147 var bc = interp(x2, x3, t);
2148 var cd = interp(x3, x4, t);
2149 var abc = interp(ab, bc, t);
2150 var bcd = interp(bc, cd, t);
2151 var abcd = interp(abc, bcd, t);
2152 return abcd;
2153}
2154
2155function cubicPartial(x1, y1, x2, y2, x3, y3, x4, y4, t1, t2) {
2156 var ax = interp_cubic_coords(x1, x2, x3, x4, t1);
2157 var ay = interp_cubic_coords(y1, y2, y3, y4, t1);
2158 var ex = interp_cubic_coords(x1, x2, x3, x4, (t1*2+t2)/3);
2159 var ey = interp_cubic_coords(y1, y2, y3, y4, (t1*2+t2)/3);
2160 var fx = interp_cubic_coords(x1, x2, x3, x4, (t1+t2*2)/3);
2161 var fy = interp_cubic_coords(y1, y2, y3, y4, (t1+t2*2)/3);
2162 var dx = interp_cubic_coords(x1, x2, x3, x4, t2);
2163 var dy = interp_cubic_coords(y1, y2, y3, y4, t2);
2164 var mx = ex * 27 - ax * 8 - dx;
2165 var my = ey * 27 - ay * 8 - dy;
2166 var nx = fx * 27 - ax - dx * 8;
2167 var ny = fy * 27 - ay - dy * 8;
2168 var bx = (mx * 2 - nx) / 18;
2169 var by = (my * 2 - ny) / 18;
2170 var cx = (nx * 2 - mx) / 18;
2171 var cy = (ny * 2 - my) / 18;
2172 var array = [
2173 ax, ay, bx, by, cx, cy, dx, dy
2174 ];
2175 return array;
2176}
2177
2178function drawCubicPartial(x1, y1, x2, y2, x3, y3, x4, y4, t1, t2) {
2179 var a = cubicPartial(x1, y1, x2, y2, x3, y3, x4, y4, t1, t2);
2180 var ax = a[0];
2181 var ay = a[1];
2182 var bx = a[2];
2183 var by = a[3];
2184 var cx = a[4];
2185 var cy = a[5];
2186 var dx = a[6];
2187 var dy = a[7];
2188 if (alreadyDrawnCubic(ax, ay, bx, by, cx, cy, dx, dy)) {
2189 return;
2190 }
2191 ctx.beginPath();
2192 ctx.moveTo((ax - srcLeft) * scale,
2193 (ay - srcTop) * scale);
2194 ctx.bezierCurveTo((bx - srcLeft) * scale,
2195 (by - srcTop) * scale,
2196 (cx - srcLeft) * scale,
2197 (cy - srcTop) * scale,
2198 (dx - srcLeft) * scale,
2199 (dy - srcTop) * scale);
2200 ctx.stroke();
2201}
2202
2203function drawCurve(c) {
2204 switch (c.length) {
2205 case 4:
2206 drawLine(c[0], c[1], c[2], c[3]);
2207 break;
2208 case 6:
2209 drawQuad(c[0], c[1], c[2], c[3], c[4], c[5]);
2210 break;
caryclark1049f122015-04-20 08:31:59 -07002211 case 7:
2212 drawConicWithQuads(c[0], c[1], c[2], c[3], c[4], c[5], c[6]);
2213 break;
caryclarkdac1d172014-06-17 05:15:38 -07002214 case 8:
2215 drawCubic(c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]);
2216 break;
2217 }
2218}
2219
2220function boundsWidth(pts) {
2221 var min = pts[0];
2222 var max = pts[0];
caryclark1049f122015-04-20 08:31:59 -07002223 var length = pts.length == 7 ? 6 : pts.length;
2224 for (var idx = 2; idx < length; idx += 2) {
caryclarkdac1d172014-06-17 05:15:38 -07002225 min = Math.min(min, pts[idx]);
2226 max = Math.max(max, pts[idx]);
2227 }
2228 return max - min;
2229}
2230
2231function boundsHeight(pts) {
2232 var min = pts[1];
2233 var max = pts[1];
caryclark1049f122015-04-20 08:31:59 -07002234 var length = pts.length == 7 ? 6 : pts.length;
2235 for (var idx = 3; idx < length; idx += 2) {
caryclarkdac1d172014-06-17 05:15:38 -07002236 min = Math.min(min, pts[idx]);
2237 max = Math.max(max, pts[idx]);
2238 }
2239 return max - min;
2240}
2241
2242function tangent(pts) {
2243 var dx = pts[2] - pts[0];
2244 var dy = pts[3] - pts[1];
2245 if (dx == 0 && dy == 0 && pts.length > 4) {
2246 dx = pts[4] - pts[0];
2247 dy = pts[5] - pts[1];
caryclark1049f122015-04-20 08:31:59 -07002248 if (dx == 0 && dy == 0 && pts.length == 8) {
caryclarkdac1d172014-06-17 05:15:38 -07002249 dx = pts[6] - pts[0];
2250 dy = pts[7] - pts[1];
2251 }
2252 }
2253 return Math.atan2(-dy, dx);
2254}
2255
2256function hodograph(cubic) {
2257 var hodo = [];
2258 hodo[0] = 3 * (cubic[2] - cubic[0]);
2259 hodo[1] = 3 * (cubic[3] - cubic[1]);
2260 hodo[2] = 3 * (cubic[4] - cubic[2]);
2261 hodo[3] = 3 * (cubic[5] - cubic[3]);
2262 hodo[4] = 3 * (cubic[6] - cubic[4]);
2263 hodo[5] = 3 * (cubic[7] - cubic[5]);
2264 return hodo;
2265}
2266
2267function hodograph2(cubic) {
2268 var quad = hodograph(cubic);
2269 var hodo = [];
2270 hodo[0] = 2 * (quad[2] - quad[0]);
2271 hodo[1] = 2 * (quad[3] - quad[1]);
2272 hodo[2] = 2 * (quad[4] - quad[2]);
2273 hodo[3] = 2 * (quad[5] - quad[3]);
2274 return hodo;
2275}
2276
2277function quadraticRootsReal(A, B, C, s) {
2278 if (A == 0) {
2279 if (B == 0) {
2280 s[0] = 0;
2281 return C == 0;
2282 }
2283 s[0] = -C / B;
2284 return 1;
2285 }
2286 /* normal form: x^2 + px + q = 0 */
2287 var p = B / (2 * A);
2288 var q = C / A;
2289 var p2 = p * p;
2290 if (p2 < q) {
2291 return 0;
2292 }
2293 var sqrt_D = 0;
2294 if (p2 > q) {
2295 sqrt_D = sqrt(p2 - q);
2296 }
2297 s[0] = sqrt_D - p;
2298 s[1] = -sqrt_D - p;
2299 return 1 + s[0] != s[1];
2300}
2301
2302function add_valid_ts(s, realRoots, t) {
2303 var foundRoots = 0;
2304 for (var index = 0; index < realRoots; ++index) {
2305 var tValue = s[index];
2306 if (tValue >= 0 && tValue <= 1) {
2307 for (var idx2 = 0; idx2 < foundRoots; ++idx2) {
2308 if (t[idx2] != tValue) {
2309 t[foundRoots++] = tValue;
2310 }
2311 }
2312 }
2313 }
2314 return foundRoots;
2315}
2316
2317function quadraticRootsValidT(a, b, c, t) {
2318 var s = [];
2319 var realRoots = quadraticRootsReal(A, B, C, s);
2320 var foundRoots = add_valid_ts(s, realRoots, t);
2321 return foundRoots != 0;
2322}
2323
2324function find_cubic_inflections(cubic, tValues) {
2325 var Ax = src[2] - src[0];
2326 var Ay = src[3] - src[1];
2327 var Bx = src[4] - 2 * src[2] + src[0];
2328 var By = src[5] - 2 * src[3] + src[1];
2329 var Cx = src[6] + 3 * (src[2] - src[4]) - src[0];
2330 var Cy = src[7] + 3 * (src[3] - src[5]) - src[1];
2331 return quadraticRootsValidT(Bx * Cy - By * Cx, (Ax * Cy - Ay * Cx),
2332 Ax * By - Ay * Bx, tValues);
2333}
2334
2335function dxy_at_t(curve, type, t) {
2336 var dxy = {};
2337 if (type == PATH_QUAD) {
2338 var a = t - 1;
2339 var b = 1 - 2 * t;
2340 var c = t;
2341 dxy.x = a * curve[0] + b * curve[2] + c * curve[4];
2342 dxy.y = a * curve[1] + b * curve[3] + c * curve[5];
caryclark1049f122015-04-20 08:31:59 -07002343 } else if (type == PATH_CONIC) {
2344 var p20x = curve[4] - curve[0];
2345 var p20y = curve[5] - curve[1];
2346 var p10xw = (curve[2] - curve[0]) * curve[6];
2347 var p10yw = (curve[3] - curve[1]) * curve[6];
2348 var coeff0x = curve[6] * p20x - p20x;
2349 var coeff0y = curve[6] * p20y - p20y;
2350 var coeff1x = p20x - 2 * p10xw;
2351 var coeff1y = p20y - 2 * p10yw;
2352 dxy.x = t * (t * coeff0x + coeff1x) + p10xw;
2353 dxy.y = t * (t * coeff0y + coeff1y) + p10yw;
caryclarkdac1d172014-06-17 05:15:38 -07002354 } else if (type == PATH_CUBIC) {
2355 var one_t = 1 - t;
2356 var a = curve[0];
2357 var b = curve[2];
2358 var c = curve[4];
2359 var d = curve[6];
2360 dxy.x = 3 * ((b - a) * one_t * one_t + 2 * (c - b) * t * one_t + (d - c) * t * t);
2361 a = curve[1];
2362 b = curve[3];
2363 c = curve[5];
2364 d = curve[7];
2365 dxy.y = 3 * ((b - a) * one_t * one_t + 2 * (c - b) * t * one_t + (d - c) * t * t);
2366 }
2367 return dxy;
2368}
2369
2370function drawLabel(num, px, py) {
2371 ctx.beginPath();
2372 ctx.arc(px, py, 8, 0, Math.PI*2, true);
2373 ctx.closePath();
2374 ctx.strokeStyle = "rgba(0,0,0, 0.4)";
2375 ctx.lineWidth = num == 0 || num == 3 ? 2 : 1;
2376 ctx.stroke();
2377 ctx.fillStyle = "black";
2378 ctx.font = "normal 10px Arial";
2379 // ctx.rotate(0.001);
2380 ctx.fillText(num, px - 2, py + 3);
2381 // ctx.rotate(-0.001);
2382}
2383
2384function drawLabelX(ymin, num, loc) {
2385 var px = (loc - srcLeft) * scale;
2386 var py = (ymin - srcTop) * scale - 20;
2387 drawLabel(num, px, py);
2388}
2389
2390function drawLabelY(xmin, num, loc) {
2391 var px = (xmin - srcLeft) * scale - 20;
2392 var py = (loc - srcTop) * scale;
2393 drawLabel(num, px, py);
2394}
2395
2396function drawHodoOrigin(hx, hy, hMinX, hMinY, hMaxX, hMaxY) {
2397 ctx.beginPath();
2398 ctx.moveTo(hx, hy - 100);
2399 ctx.lineTo(hx, hy);
2400 ctx.strokeStyle = hMinY < 0 ? "green" : "blue";
2401 ctx.stroke();
2402 ctx.beginPath();
2403 ctx.moveTo(hx, hy);
2404 ctx.lineTo(hx, hy + 100);
2405 ctx.strokeStyle = hMaxY > 0 ? "green" : "blue";
2406 ctx.stroke();
2407 ctx.beginPath();
2408 ctx.moveTo(hx - 100, hy);
2409 ctx.lineTo(hx, hy);
2410 ctx.strokeStyle = hMinX < 0 ? "green" : "blue";
2411 ctx.stroke();
2412 ctx.beginPath();
2413 ctx.moveTo(hx, hy);
2414 ctx.lineTo(hx + 100, hy);
2415 ctx.strokeStyle = hMaxX > 0 ? "green" : "blue";
2416 ctx.stroke();
2417}
2418
2419function scalexy(x, y, mag) {
2420 var length = Math.sqrt(x * x + y * y);
2421 return mag / length;
2422}
2423
caryclark03b03ca2015-04-23 09:13:37 -07002424function drawArrow(x, y, dx, dy, s) {
2425 var dscale = scalexy(dx, dy, 1 / scale * 100 * s);
caryclarkdac1d172014-06-17 05:15:38 -07002426 dx *= dscale;
2427 dy *= dscale;
2428 ctx.beginPath();
2429 ctx.moveTo((x - srcLeft) * scale, (y - srcTop) * scale);
2430 x += dx;
2431 y += dy;
2432 ctx.lineTo((x - srcLeft) * scale, (y - srcTop) * scale);
2433 dx /= 10;
2434 dy /= 10;
2435 ctx.lineTo((x - dy - srcLeft) * scale, (y + dx - srcTop) * scale);
2436 ctx.lineTo((x + dx * 2 - srcLeft) * scale, (y + dy * 2 - srcTop) * scale);
2437 ctx.lineTo((x + dy - srcLeft) * scale, (y - dx - srcTop) * scale);
2438 ctx.lineTo((x - srcLeft) * scale, (y - srcTop) * scale);
2439 ctx.strokeStyle = "rgba(0,75,0, 0.4)";
2440 ctx.stroke();
2441}
2442
2443function x_at_t(curve, t) {
2444 var one_t = 1 - t;
2445 if (curve.length == 4) {
2446 return one_t * curve[0] + t * curve[2];
2447 }
2448 var one_t2 = one_t * one_t;
2449 var t2 = t * t;
2450 if (curve.length == 6) {
2451 return one_t2 * curve[0] + 2 * one_t * t * curve[2] + t2 * curve[4];
2452 }
caryclark1049f122015-04-20 08:31:59 -07002453 if (curve.length == 7) {
2454 return (one_t2 * curve[0] + 2 * one_t * t * curve[2] * curve[6] + t2 * curve[4])
2455 / (one_t2 +2 * one_t * t * curve[6] + t2);
2456 }
caryclarkdac1d172014-06-17 05:15:38 -07002457 var a = one_t2 * one_t;
2458 var b = 3 * one_t2 * t;
2459 var c = 3 * one_t * t2;
2460 var d = t2 * t;
2461 return a * curve[0] + b * curve[2] + c * curve[4] + d * curve[6];
2462}
2463
2464function y_at_t(curve, t) {
2465 var one_t = 1 - t;
2466 if (curve.length == 4) {
2467 return one_t * curve[1] + t * curve[3];
2468 }
2469 var one_t2 = one_t * one_t;
2470 var t2 = t * t;
2471 if (curve.length == 6) {
2472 return one_t2 * curve[1] + 2 * one_t * t * curve[3] + t2 * curve[5];
2473 }
caryclark1049f122015-04-20 08:31:59 -07002474 if (curve.length == 7) {
2475 return (one_t2 * curve[1] + 2 * one_t * t * curve[3] * curve[6] + t2 * curve[5])
2476 / (one_t2 +2 * one_t * t * curve[6] + t2);
2477 }
caryclarkdac1d172014-06-17 05:15:38 -07002478 var a = one_t2 * one_t;
2479 var b = 3 * one_t2 * t;
2480 var c = 3 * one_t * t2;
2481 var d = t2 * t;
2482 return a * curve[1] + b * curve[3] + c * curve[5] + d * curve[7];
2483}
2484
2485function drawOrder(curve, label) {
2486 var px = x_at_t(curve, 0.75);
2487 var py = y_at_t(curve, 0.75);
2488 var _px = (px - srcLeft) * scale;
2489 var _py = (py - srcTop) * scale;
2490 ctx.beginPath();
2491 ctx.arc(_px, _py, 15, 0, Math.PI * 2, true);
2492 ctx.closePath();
2493 ctx.fillStyle = "white";
2494 ctx.fill();
2495 if (label == 'L') {
2496 ctx.strokeStyle = "rgba(255,0,0, 1)";
2497 ctx.fillStyle = "rgba(255,0,0, 1)";
2498 } else {
2499 ctx.strokeStyle = "rgba(0,0,255, 1)";
2500 ctx.fillStyle = "rgba(0,0,255, 1)";
2501 }
2502 ctx.stroke();
2503 ctx.font = "normal 16px Arial";
2504 ctx.textAlign = "center";
2505 ctx.fillText(label, _px, _py + 5);
2506 ctx.font = "normal 10px Arial";
2507}
2508
2509function drawID(curve, id) {
2510 var px = x_at_t(curve, 0.5);
2511 var py = y_at_t(curve, 0.5);
2512 var _px = (px - srcLeft) * scale;
2513 var _py = (py - srcTop) * scale;
2514 draw_id_at(id, _px, _py);
2515}
2516
2517function draw_id_at(id, _px, _py) {
2518 ctx.beginPath();
2519 ctx.arc(_px, _py, 15, 0, Math.PI * 2, true);
2520 ctx.closePath();
2521 ctx.fillStyle = "white";
2522 ctx.fill();
2523 ctx.strokeStyle = "rgba(127,127,0, 1)";
2524 ctx.fillStyle = "rgba(127,127,0, 1)";
2525 ctx.stroke();
2526 ctx.font = "normal 16px Arial";
2527 ctx.textAlign = "center";
2528 ctx.fillText(id, _px, _py + 5);
2529 ctx.font = "normal 10px Arial";
2530}
2531
2532function drawLinePartialID(id, x1, y1, x2, y2, t1, t2) {
2533 var curve = [x1, y1, x2, y2];
2534 drawCurvePartialID(id, curve, t1, t2);
2535}
2536
2537function drawQuadPartialID(id, x1, y1, x2, y2, x3, y3, t1, t2) {
2538 var curve = [x1, y1, x2, y2, x3, y3];
2539 drawCurvePartialID(id, curve, t1, t2);
2540}
2541
caryclark1049f122015-04-20 08:31:59 -07002542function drawConicPartialID(id, x1, y1, x2, y2, x3, y3, w, t1, t2) {
2543 var curve = [x1, y1, x2, y2, x3, y3, w];
2544 drawCurvePartialID(id, curve, t1, t2);
2545}
2546
caryclarkdac1d172014-06-17 05:15:38 -07002547function drawCubicPartialID(id, x1, y1, x2, y2, x3, y3, x4, y4, t1, t2) {
2548 var curve = [x1, y1, x2, y2, x3, y3, x4, y4];
2549 drawCurvePartialID(id, curve, t1, t2);
2550}
2551
2552function drawCurvePartialID(id, curve, t1, t2) {
2553 var px = x_at_t(curve, (t1 + t2) / 2);
2554 var py = y_at_t(curve, (t1 + t2) / 2);
2555 var _px = (px - srcLeft) * scale;
2556 var _py = (py - srcTop) * scale;
2557 draw_id_at(id, _px, _py);
2558}
2559
2560function drawCurveSpecials(test, curve, type) {
2561 if (pt_labels) {
2562 drawPoints(curve, type, pt_labels == 2);
2563 }
2564 if (control_lines != 0) {
2565 drawControlLines(curve, type, control_lines);
2566 }
2567 if (curve_t) {
2568 drawPointAtT(curve, type);
2569 }
2570 if (draw_midpoint) {
2571 var mid = pointAtT(curve, type, 0.5);
2572 drawPoint(mid.x, mid.y, true);
2573 }
2574 if (draw_id) {
2575 var id = idByCurve(test, curve, type);
2576 if (id >= 0) {
2577 drawID(curve, id);
2578 }
2579 }
2580 if (type == PATH_LINE) {
2581 return;
2582 }
2583 if (draw_deriviatives > 0) {
2584 var d = dxy_at_t(curve, type, 0);
caryclark03b03ca2015-04-23 09:13:37 -07002585 drawArrow(curve[0], curve[1], d.x, d.y, 1);
caryclarkdac1d172014-06-17 05:15:38 -07002586 if (draw_deriviatives == 2) {
2587 d = dxy_at_t(curve, type, 1);
2588 if (type == PATH_CUBIC) {
caryclark03b03ca2015-04-23 09:13:37 -07002589 drawArrow(curve[6], curve[7], d.x, d.y, 1);
caryclarkdac1d172014-06-17 05:15:38 -07002590 } else {
caryclark03b03ca2015-04-23 09:13:37 -07002591 drawArrow(curve[4], curve[5], d.x, d.y, 1);
caryclarkdac1d172014-06-17 05:15:38 -07002592 }
2593 }
2594 if (draw_midpoint) {
2595 var mid = pointAtT(curve, type, 0.5);
2596 d = dxy_at_t(curve, type, 0.5);
caryclark03b03ca2015-04-23 09:13:37 -07002597 drawArrow(mid.x, mid.y, d.x, d.y, 1);
caryclarkdac1d172014-06-17 05:15:38 -07002598 }
2599 }
2600 if (type != PATH_CUBIC) {
2601 return;
2602 }
caryclarkdac1d172014-06-17 05:15:38 -07002603 if (draw_sequence) {
2604 var ymin = Math.min(curve[1], curve[3], curve[5], curve[7]);
2605 for (var i = 0; i < 8; i+= 2) {
2606 drawLabelX(ymin, i >> 1, curve[i]);
2607 }
2608 var xmin = Math.min(curve[0], curve[2], curve[4], curve[6]);
2609 for (var i = 1; i < 8; i+= 2) {
2610 drawLabelY(xmin, i >> 1, curve[i]);
2611 }
2612 }
2613}
2614
2615function logCurves(test) {
2616 for (curves in test) {
2617 var curve = test[curves];
2618 dumpCurve(curve);
2619 }
2620}
2621
2622function curveToString(curve) {
2623 var str = "{{";
caryclark1049f122015-04-20 08:31:59 -07002624 var length = curve.length == 7 ? 6 : curve.length;
2625 if (curve.length == 7) {
2626 str += "{";
2627 }
2628 for (i = 0; i < length; i += 2) {
caryclarkdac1d172014-06-17 05:15:38 -07002629 str += curve[i].toFixed(decimal_places) + "," + curve[i + 1].toFixed(decimal_places);
2630 if (i < curve.length - 2) {
2631 str += "}, {";
2632 }
2633 }
caryclark1049f122015-04-20 08:31:59 -07002634 str += "}";
2635 if (curve.length == 7) {
2636 str += "}, " + curve[6].toFixed(decimal_places);
2637 }
2638 str += "}";
caryclarkdac1d172014-06-17 05:15:38 -07002639 return str;
2640}
2641
2642function dumpCurve(curve) {
2643 console.log(curveToString(curve));
2644}
2645
2646function draw(test, lines, title) {
2647 ctx.fillStyle = "rgba(0,0,0, 0.1)";
2648 ctx.font = "normal 50px Arial";
2649 ctx.textAlign = "left";
2650 ctx.fillText(title, 50, 50);
2651 ctx.font = "normal 10px Arial";
2652 ctx.lineWidth = "1.001"; "0.999";
2653 var secondPath = test.length;
2654 var closeCount = 0;
2655 logStart = -1;
2656 logRange = 0;
2657 // find last active rec type at this step
2658 var curType = test[0];
2659 var curStep = 0;
2660 var hasOp = false;
2661 var lastActive = 0;
2662 var lastAdd = 0;
caryclark624637c2015-05-11 07:21:27 -07002663 var lastCoin = 0;
caryclarkdac1d172014-06-17 05:15:38 -07002664 var lastSect = 0;
2665 var lastSort = 0;
2666 var lastMark = 0;
caryclark03b03ca2015-04-23 09:13:37 -07002667 var lastTop = 0;
caryclarkdac1d172014-06-17 05:15:38 -07002668 activeCount = 0;
2669 addCount = 0;
2670 angleCount = 0;
2671 opCount = 0;
2672 sectCount = 0;
2673 sortCount = 0;
caryclark03b03ca2015-04-23 09:13:37 -07002674 topCount = 0;
caryclarkdac1d172014-06-17 05:15:38 -07002675 markCount = 0;
2676 activeMax = 0;
2677 addMax = 0;
2678 angleMax = 0;
caryclark624637c2015-05-11 07:21:27 -07002679 coinMax = 0;
caryclarkdac1d172014-06-17 05:15:38 -07002680 opMax = 0;
2681 sectMax = 0;
2682 sectMax2 = 0;
2683 sortMax = 0;
caryclark03b03ca2015-04-23 09:13:37 -07002684 topMax = 0;
caryclarkdac1d172014-06-17 05:15:38 -07002685 markMax = 0;
2686 lastIndex = test.length - 3;
2687 for (var tIndex = 0; tIndex < test.length; tIndex += 3) {
2688 var recType = test[tIndex];
2689 if (!typeof recType == 'number' || recType < REC_TYPE_UNKNOWN || recType > REC_TYPE_LAST) {
2690 console.log("unknown rec type: " + recType);
2691 throw "stop execution";
2692 }
2693 // if (curType == recType && curType != REC_TYPE_ADD) {
2694 // continue;
2695 // }
2696 var inStepRange = step_limit == 0 || curStep < step_limit;
2697 curType = recType;
2698 if (recType == REC_TYPE_OP) {
2699 hasOp = true;
2700 continue;
2701 }
2702 if (recType == REC_TYPE_UNKNOWN) {
2703 // these types do not advance step
2704 continue;
2705 }
2706 var bumpStep = false;
2707 var records = test[tIndex + 2];
2708 var fragType = records[0];
2709 if (recType == REC_TYPE_ADD) {
2710 if (records.length != 2) {
2711 console.log("expect only two elements: " + records.length);
2712 throw "stop execution";
2713 }
2714 if (fragType == ADD_MOVETO || fragType == ADD_CLOSE) {
2715 continue;
2716 }
2717 ++addMax;
2718 if (!draw_add || !inStepRange) {
2719 continue;
2720 }
2721 lastAdd = tIndex;
2722 ++addCount;
2723 bumpStep = true;
2724 }
2725 if (recType == REC_TYPE_PATH && hasOp) {
2726 secondPath = tIndex;
2727 }
caryclark54359292015-03-26 07:52:43 -07002728 if (recType == REC_TYPE_PATH2 && hasOp) {
2729 secondPath = tIndex;
2730 }
caryclarkdac1d172014-06-17 05:15:38 -07002731 if (recType == REC_TYPE_ACTIVE) {
2732 ++activeMax;
2733 if (!draw_active || !inStepRange) {
2734 continue;
2735 }
2736 lastActive = tIndex;
2737 ++activeCount;
2738 bumpStep = true;
2739 }
2740 if (recType == REC_TYPE_ACTIVE_OP) {
2741 ++opMax;
2742 if (!draw_op || !inStepRange) {
2743 continue;
2744 }
2745 lastOp = tIndex;
2746 ++opCount;
2747 bumpStep = true;
2748 }
caryclark54359292015-03-26 07:52:43 -07002749 if (recType == REC_TYPE_AFTERPART) {
2750 if (draw_angle != 3 || !inStepRange) {
2751 continue;
2752 }
2753 lastAngle = tIndex;
2754 ++angleCount;
2755 bumpStep = true;
2756 }
caryclarkdac1d172014-06-17 05:15:38 -07002757 if (recType == REC_TYPE_ANGLE) {
2758 ++angleMax;
caryclark54359292015-03-26 07:52:43 -07002759 if (draw_angle == 0 || draw_angle == 3 || !inStepRange) {
caryclarkdac1d172014-06-17 05:15:38 -07002760 continue;
2761 }
2762 lastAngle = tIndex;
2763 ++angleCount;
2764 bumpStep = true;
2765 }
caryclark624637c2015-05-11 07:21:27 -07002766 if (recType == REC_TYPE_COINCIDENCE) {
2767 ++coinMax;
2768 if (!draw_coincidence || !inStepRange) {
2769 continue;
2770 }
2771 lastCoin = tIndex;
2772 ++coinCount;
2773 bumpStep = true;
2774 }
caryclarkdac1d172014-06-17 05:15:38 -07002775 if (recType == REC_TYPE_SECT) {
2776 if (records.length != 2) {
2777 console.log("expect only two elements: " + records.length);
2778 throw "stop execution";
2779 }
2780 ++sectMax;
2781 var sectBump = 1;
2782 switch (fragType) {
2783 case INTERSECT_LINE:
2784 case INTERSECT_QUAD_LINE:
2785 case INTERSECT_QUAD:
caryclark1049f122015-04-20 08:31:59 -07002786 case INTERSECT_CONIC_LINE:
2787 case INTERSECT_CONIC:
caryclarkdac1d172014-06-17 05:15:38 -07002788 case INTERSECT_SELF_CUBIC:
2789 case INTERSECT_CUBIC_LINE:
2790 case INTERSECT_CUBIC_QUAD:
2791 case INTERSECT_CUBIC:
2792 sectBump = 1;
2793 break;
2794 case INTERSECT_LINE_2:
2795 case INTERSECT_QUAD_LINE_2:
2796 case INTERSECT_QUAD_2:
caryclark1049f122015-04-20 08:31:59 -07002797 case INTERSECT_CONIC_LINE_2:
2798 case INTERSECT_CONIC_2:
caryclarkdac1d172014-06-17 05:15:38 -07002799 case INTERSECT_CUBIC_LINE_2:
2800 case INTERSECT_CUBIC_QUAD_2:
2801 case INTERSECT_CUBIC_2:
2802 sectBump = 2;
2803 break;
2804 case INTERSECT_LINE_NO:
2805 case INTERSECT_QUAD_LINE_NO:
2806 case INTERSECT_QUAD_NO:
caryclark1049f122015-04-20 08:31:59 -07002807 case INTERSECT_CONIC_LINE_NO:
2808 case INTERSECT_CONIC_NO:
caryclarkdac1d172014-06-17 05:15:38 -07002809 case INTERSECT_SELF_CUBIC_NO:
2810 case INTERSECT_CUBIC_LINE_NO:
2811 case INTERSECT_CUBIC_QUAD_NO:
2812 case INTERSECT_CUBIC_NO:
2813 sectBump = 0;
2814 break;
2815 case INTERSECT_CUBIC_LINE_3:
2816 case INTERSECT_CUBIC_QUAD_3:
2817 case INTERSECT_CUBIC_3:
2818 sectBump = 3;
2819 break;
2820 case INTERSECT_CUBIC_QUAD_4:
2821 case INTERSECT_CUBIC_4:
2822 sectBump = 4;
2823 break;
2824 default:
2825 console.log("missing case " + records.length);
2826 throw "stop execution";
2827 }
2828 sectMax2 += sectBump;
2829 if (draw_intersection <= 1 || !inStepRange) {
2830 continue;
2831 }
2832 lastSect = tIndex;
2833 sectCount += sectBump;
2834 bumpStep = true;
2835 }
2836 if (recType == REC_TYPE_SORT) {
2837 ++sortMax;
2838 if (!draw_sort || !inStepRange) {
2839 continue;
2840 }
2841 lastSort = tIndex;
2842 ++sortCount;
2843 bumpStep = true;
2844 }
caryclark03b03ca2015-04-23 09:13:37 -07002845 if (recType == REC_TYPE_TOP) {
2846 ++topMax;
2847 if (!draw_top || !inStepRange) {
2848 continue;
2849 }
2850 lastTop = tIndex;
2851 ++topCount;
2852 bumpStep = true;
2853 }
caryclarkdac1d172014-06-17 05:15:38 -07002854 if (recType == REC_TYPE_MARK) {
2855 ++markMax;
2856 if (!draw_mark || !inStepRange) {
2857 continue;
2858 }
2859 lastMark = tIndex;
2860 ++markCount;
2861 bumpStep = true;
2862 }
2863 if (bumpStep) {
2864 lastIndex = tIndex;
2865 logStart = test[tIndex + 1];
2866 logRange = records.length / 2;
2867 ++curStep;
2868 }
2869 }
2870 stepMax = (draw_add ? addMax : 0)
2871 + (draw_active ? activeMax : 0)
reed0dc4dd62015-03-24 13:55:33 -07002872 + (draw_angle ? angleMax : 0)
caryclark624637c2015-05-11 07:21:27 -07002873 + (draw_coincidence ? coinMax : 0)
caryclark54359292015-03-26 07:52:43 -07002874 + (draw_op ? opMax : 0)
caryclarkdac1d172014-06-17 05:15:38 -07002875 + (draw_sort ? sortMax : 0)
caryclark03b03ca2015-04-23 09:13:37 -07002876 + (draw_top ? topMax : 0)
caryclarkdac1d172014-06-17 05:15:38 -07002877 + (draw_mark ? markMax : 0)
2878 + (draw_intersection == 2 ? sectMax : draw_intersection == 3 ? sectMax2 : 0);
2879 if (stepMax == 0) {
caryclark624637c2015-05-11 07:21:27 -07002880 stepMax = addMax + activeMax + angleMax + coinMax + opMax + sortMax + topMax + markMax;
caryclarkdac1d172014-06-17 05:15:38 -07002881 }
2882 drawnPts = [];
2883 drawnLines = [];
2884 drawnQuads = [];
caryclark1049f122015-04-20 08:31:59 -07002885 drawnConics = [];
caryclarkdac1d172014-06-17 05:15:38 -07002886 drawnCubics = [];
2887 focusXmin = focusYmin = Infinity;
2888 focusXmax = focusYmax = -Infinity;
2889 var pathIndex = 0;
2890 var opLetter = 'S';
2891 for (var tIndex = lastIndex; tIndex >= 0; tIndex -= 3) {
2892 var recType = test[tIndex];
2893 var records = test[tIndex + 2];
2894 for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
2895 var fragType = records[recordIndex];
2896 if (!typeof fragType == 'number' || fragType < 1 || fragType > FRAG_TYPE_LAST) {
2897 console.log("unknown in range frag type: " + fragType);
2898 throw "stop execution";
2899 }
2900 var frags = records[recordIndex + 1];
2901 focus_enabled = false;
2902 switch (recType) {
2903 case REC_TYPE_COMPUTED:
2904 if (draw_computed == 0) {
2905 continue;
2906 }
2907 ctx.lineWidth = 1;
2908 ctx.strokeStyle = pathIndex == 0 ? "black" : "red";
2909 ctx.fillStyle = "blue";
2910 var drawThis = false;
2911 switch (fragType) {
2912 case PATH_QUAD:
caryclark1049f122015-04-20 08:31:59 -07002913 if ((draw_computed & 0x9) == 1 || ((draw_computed & 8) != 0
2914 && (draw_computed & 7) == pathIndex)) {
caryclarkdac1d172014-06-17 05:15:38 -07002915 drawQuad(frags[0], frags[1], frags[2], frags[3],
2916 frags[4], frags[5]);
2917 drawThis = true;
2918 }
2919 break;
caryclark1049f122015-04-20 08:31:59 -07002920 case PATH_CONIC:
2921 if ((draw_computed & 0xA) == 2 || ((draw_computed & 8) != 0
2922 && (draw_computed & 7) == pathIndex)) {
2923 drawConicWithQuads(frags[0], frags[1], frags[2], frags[3],
2924 frags[4], frags[5], frags[6]);
2925 drawThis = true;
2926 }
2927 break;
caryclarkdac1d172014-06-17 05:15:38 -07002928 case PATH_CUBIC:
caryclark1049f122015-04-20 08:31:59 -07002929 if ((draw_computed & 0xC) == 4 || ((draw_computed & 8) != 0
2930 && (draw_computed & 7) == pathIndex)) {
caryclarkdac1d172014-06-17 05:15:38 -07002931 drawCubic(frags[0], frags[1], frags[2], frags[3],
2932 frags[4], frags[5], frags[6], frags[7]);
2933 drawThis = true;
2934 }
2935 ++pathIndex;
2936 break;
2937 case COMPUTED_SET_1:
2938 pathIndex = 0;
2939 break;
2940 case COMPUTED_SET_2:
2941 pathIndex = 1;
2942 break;
2943 default:
2944 console.log("unknown REC_TYPE_COMPUTED frag type: " + fragType);
2945 throw "stop execution";
2946 }
2947 if (!drawThis || collect_bounds) {
2948 break;
2949 }
2950 drawCurveSpecials(test, frags, fragType);
2951 break;
2952 case REC_TYPE_PATH:
caryclark54359292015-03-26 07:52:43 -07002953 case REC_TYPE_PATH2:
caryclarkdac1d172014-06-17 05:15:38 -07002954 if (!draw_path) {
2955 continue;
2956 }
2957 var firstPath = tIndex < secondPath;
2958 if ((draw_path & (firstPath ? 1 : 2)) == 0) {
2959 continue;
2960 }
2961 ctx.lineWidth = 1;
2962 ctx.strokeStyle = firstPath ? "black" : "red";
2963 ctx.fillStyle = "blue";
caryclark54359292015-03-26 07:52:43 -07002964 var frags2 = [];
caryclarkdac1d172014-06-17 05:15:38 -07002965 switch (fragType) {
2966 case PATH_LINE:
caryclark54359292015-03-26 07:52:43 -07002967 for (var i = 0; i < 4; ++ i) { frags2[i] = frags[i + 1]; }
2968 drawLine(frags2[0], frags2[1], frags2[2], frags2[3]);
caryclarkdac1d172014-06-17 05:15:38 -07002969 break;
2970 case PATH_QUAD:
caryclark54359292015-03-26 07:52:43 -07002971 for (var i = 0; i < 6; ++ i) { frags2[i] = frags[i + 1]; }
2972 drawQuad(frags2[0], frags2[1], frags2[2], frags2[3],
2973 frags2[4], frags2[5]);
caryclarkdac1d172014-06-17 05:15:38 -07002974 break;
caryclark1049f122015-04-20 08:31:59 -07002975 case PATH_CONIC:
2976 for (var i = 0; i < 7; ++ i) { frags2[i] = frags[i + 1]; }
2977 drawConicWithQuads(frags2[0], frags2[1], frags2[2], frags2[3],
2978 frags2[4], frags2[5], frags2[6]);
2979 break;
caryclarkdac1d172014-06-17 05:15:38 -07002980 case PATH_CUBIC:
caryclark54359292015-03-26 07:52:43 -07002981 for (var i = 0; i < 8; ++ i) { frags2[i] = frags[i + 1]; }
2982 drawCubic(frags2[0], frags2[1], frags2[2], frags2[3],
2983 frags2[4], frags2[5], frags2[6], frags2[7]);
caryclarkdac1d172014-06-17 05:15:38 -07002984 break;
2985 default:
caryclark54359292015-03-26 07:52:43 -07002986 console.log("unknown REC_TYPE_PATH2 frag type: " + fragType);
caryclarkdac1d172014-06-17 05:15:38 -07002987 throw "stop execution";
2988 }
2989 if (collect_bounds) {
2990 break;
2991 }
caryclark54359292015-03-26 07:52:43 -07002992 drawCurveSpecials(test, frags2, fragType);
caryclarkdac1d172014-06-17 05:15:38 -07002993 break;
2994 case REC_TYPE_OP:
2995 switch (fragType) {
2996 case OP_INTERSECT: opLetter = 'I'; break;
2997 case OP_DIFFERENCE: opLetter = 'D'; break;
2998 case OP_UNION: opLetter = 'U'; break;
2999 case OP_XOR: opLetter = 'X'; break;
3000 default:
3001 console.log("unknown REC_TYPE_OP frag type: " + fragType);
3002 throw "stop execution";
3003 }
3004 break;
3005 case REC_TYPE_ACTIVE:
3006 if (!draw_active || (step_limit > 0 && tIndex < lastActive)) {
3007 continue;
3008 }
3009 var x1 = frags[SPAN_X1];
3010 var y1 = frags[SPAN_Y1];
3011 var x2 = frags[SPAN_X2];
3012 var y2 = frags[SPAN_Y2];
caryclark1049f122015-04-20 08:31:59 -07003013 var x3, y3, x3, y4, t1, t2, w;
caryclarkdac1d172014-06-17 05:15:38 -07003014 ctx.lineWidth = 3;
3015 ctx.strokeStyle = "rgba(0,0,255, 0.3)";
3016 focus_enabled = true;
3017 switch (fragType) {
3018 case ACTIVE_LINE_SPAN:
3019 t1 = frags[SPAN_L_T];
3020 t2 = frags[SPAN_L_TEND];
3021 drawLinePartial(x1, y1, x2, y2, t1, t2);
3022 if (draw_id) {
3023 drawLinePartialID(frags[0], x1, y1, x2, y2, t1, t2);
3024 }
3025 break;
3026 case ACTIVE_QUAD_SPAN:
3027 x3 = frags[SPAN_X3];
3028 y3 = frags[SPAN_Y3];
3029 t1 = frags[SPAN_Q_T];
3030 t2 = frags[SPAN_Q_TEND];
3031 drawQuadPartial(x1, y1, x2, y2, x3, y3, t1, t2);
3032 if (draw_id) {
3033 drawQuadPartialID(frags[0], x1, y1, x2, y2, x3, y3, t1, t2);
3034 }
3035 break;
caryclark1049f122015-04-20 08:31:59 -07003036 case ACTIVE_CONIC_SPAN:
3037 x3 = frags[SPAN_X3];
3038 y3 = frags[SPAN_Y3];
3039 t1 = frags[SPAN_K_T];
3040 t2 = frags[SPAN_K_TEND];
3041 w = frags[SPAN_K_W];
3042 drawConicPartial(x1, y1, x2, y2, x3, y3, w, t1, t2);
3043 if (draw_id) {
3044 drawConicPartialID(frags[0], x1, y1, x2, y2, x3, y3, w, t1, t2);
3045 }
3046 break;
caryclarkdac1d172014-06-17 05:15:38 -07003047 case ACTIVE_CUBIC_SPAN:
3048 x3 = frags[SPAN_X3];
3049 y3 = frags[SPAN_Y3];
3050 x4 = frags[SPAN_X4];
3051 y4 = frags[SPAN_Y4];
3052 t1 = frags[SPAN_C_T];
3053 t2 = frags[SPAN_C_TEND];
3054 drawCubicPartial(x1, y1, x2, y2, x3, y3, x4, y4, t1, t2);
3055 if (draw_id) {
3056 drawCubicPartialID(frags[0], x1, y1, x2, y2, x3, y3, x4, y4, t1, t2);
3057 }
3058 break;
3059 default:
3060 console.log("unknown REC_TYPE_ACTIVE frag type: " + fragType);
3061 throw "stop execution";
3062 }
3063 break;
3064 case REC_TYPE_ACTIVE_OP:
3065 if (!draw_op || (step_limit > 0 && tIndex < lastOp)) {
3066 continue;
3067 }
3068 focus_enabled = true;
3069 ctx.lineWidth = 3;
3070 var activeSpan = frags[7] == "1";
3071 ctx.strokeStyle = activeSpan ? "rgba(45,160,0, 0.3)" : "rgba(255,45,0, 0.5)";
3072 var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
3073 drawCurve(curve);
3074 if (draw_op > 1) {
3075 drawArc(curve, false, frags[3], frags[4]);
3076 drawArc(curve, true, frags[5], frags[6]);
3077 }
3078 break;
3079 case REC_TYPE_ADD:
3080 if (!draw_add) {
3081 continue;
3082 }
3083 ctx.lineWidth = 3;
3084 ctx.strokeStyle = closeCount == 0 ? "rgba(0,0,255, 0.3)"
3085 : closeCount == 1 ? "rgba(0,127,0, 0.3)"
3086 : closeCount == 2 ? "rgba(0,127,127, 0.3)"
3087 : closeCount == 3 ? "rgba(127,127,0, 0.3)"
3088 : "rgba(127,0,127, 0.3)";
3089 focus_enabled = true;
3090 switch (fragType) {
3091 case ADD_MOVETO:
3092 break;
3093 case ADD_LINETO:
3094 if (step_limit == 0 || tIndex >= lastAdd) {
3095 drawLine(frags[0], frags[1], frags[2], frags[3]);
3096 }
3097 break;
3098 case ADD_QUADTO:
3099 if (step_limit == 0 || tIndex >= lastAdd) {
3100 drawQuad(frags[0], frags[1], frags[2], frags[3], frags[4], frags[5]);
3101 }
3102 break;
caryclark1049f122015-04-20 08:31:59 -07003103 case ADD_CONICTO:
3104 if (step_limit == 0 || tIndex >= lastAdd) {
3105 drawConicWithQuads(frags[0], frags[1], frags[2], frags[3],
3106 frags[4], frags[5], frags[6]);
3107 }
3108 break;
caryclarkdac1d172014-06-17 05:15:38 -07003109 case ADD_CUBICTO:
3110 if (step_limit == 0 || tIndex >= lastAdd) {
3111 drawCubic(frags[0], frags[1], frags[2], frags[3],
3112 frags[4], frags[5], frags[6], frags[7]);
3113 }
3114 break;
3115 case ADD_CLOSE:
3116 ++closeCount;
3117 break;
3118 case ADD_FILL:
3119 break;
3120 default:
3121 console.log("unknown REC_TYPE_ADD frag type: " + fragType);
3122 throw "stop execution";
3123 }
3124 break;
3125 case REC_TYPE_ANGLE:
caryclark54359292015-03-26 07:52:43 -07003126 angleBetween = frags[18] == "T";
3127 afterIndex = 0;
3128 if (draw_angle == 0 || draw_angle == 3 || (step_limit > 0 && tIndex < lastAngle)) {
caryclarkdac1d172014-06-17 05:15:38 -07003129 continue;
3130 }
3131 focus_enabled = true;
3132 ctx.lineWidth = 3;
3133 ctx.strokeStyle = "rgba(127,45,127, 0.3)";
caryclark54359292015-03-26 07:52:43 -07003134 var leftCurve = curvePartialByID(test, frags[0], frags[4], frags[5]);
3135 var midCurve = curvePartialByID(test, frags[6], frags[10], frags[11]);
3136 var rightCurve = curvePartialByID(test, frags[12], frags[16], frags[17]);
caryclarkdac1d172014-06-17 05:15:38 -07003137 drawCurve(leftCurve);
3138 drawCurve(rightCurve);
caryclark54359292015-03-26 07:52:43 -07003139 ctx.strokeStyle = angleBetween ? "rgba(0,160,45, 0.3)" : "rgba(255,0,45, 0.5)";
caryclarkdac1d172014-06-17 05:15:38 -07003140 drawCurve(midCurve);
3141 if (draw_angle > 1) {
3142 drawOrder(leftCurve, 'L');
3143 drawOrder(rightCurve, 'R');
3144 }
3145 break;
caryclark54359292015-03-26 07:52:43 -07003146 case REC_TYPE_AFTERPART:
3147 if (draw_angle != 3 || (step_limit > 0 && tIndex < lastAngle)) {
3148 continue;
3149 }
3150 ctx.strokeStyle = afterIndex == 0 ? "rgba(255,0,0, 1.0)"
3151 : (afterIndex == 1) == angleBetween ? "rgba(0,128,0, 1.0)"
3152 : "rgba(0,0,255, 1.0)";
3153 switch (fragType) {
3154 case PATH_LINE:
3155 drawLine(frags[0], frags[1], frags[2], frags[3]);
3156 break;
3157 case PATH_QUAD:
3158 drawQuad(frags[0], frags[1], frags[2], frags[3],
3159 frags[4], frags[5]);
3160 break;
caryclark1049f122015-04-20 08:31:59 -07003161 case PATH_CONIC:
3162 drawConicWithQuads(frags[0], frags[1], frags[2], frags[3],
3163 frags[4], frags[5], frags[6]);
3164 break;
caryclark54359292015-03-26 07:52:43 -07003165 case PATH_CUBIC:
3166 drawCubic(frags[0], frags[1], frags[2], frags[3],
caryclark1049f122015-04-20 08:31:59 -07003167 frags[4], frags[5], frags[6], frags[7]);
caryclark54359292015-03-26 07:52:43 -07003168 break;
3169 default:
3170 console.log("unknown REC_TYPE_AFTERPART frag type: " + fragType);
3171 throw "stop execution";
3172 }
3173 ++afterIndex;
3174 break;
caryclark624637c2015-05-11 07:21:27 -07003175 case REC_TYPE_COINCIDENCE:
3176 if (!draw_coincidence || (step_limit > 0 && tIndex < lastCoin)) {
3177 continue;
3178 }
3179 focus_enabled = true;
3180 ctx.lineWidth = 3;
3181 ctx.strokeStyle = "rgba(127,45,63, 0.3)";
3182 var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
3183 drawCurve(curve);
3184 break;
caryclarkdac1d172014-06-17 05:15:38 -07003185 case REC_TYPE_SECT:
3186 if (!draw_intersection) {
3187 continue;
3188 }
3189 if (draw_intersection != 1 && (step_limit > 0 && tIndex < lastSect)) {
3190 continue;
3191 }
3192 // draw_intersection == 1 : show all
3193 // draw_intersection == 2 : step == 0 ? show all : show intersection line #step
3194 // draw_intersection == 3 : step == 0 ? show all : show intersection #step
3195 ctx.lineWidth = 1;
3196 ctx.strokeStyle = "rgba(0,0,255, 0.3)";
3197 ctx.fillStyle = "blue";
3198 focus_enabled = true;
3199 var f = [];
3200 var c1s;
3201 var c1l;
3202 var c2s;
3203 var c2l;
3204 switch (fragType) {
3205 case INTERSECT_LINE:
3206 f.push(5, 6, 0, 7);
3207 c1s = 1; c1l = 4; c2s = 8; c2l = 4;
3208 break;
3209 case INTERSECT_LINE_2:
3210 f.push(5, 6, 0, 10);
3211 f.push(8, 9, 7, 15);
3212 c1s = 1; c1l = 4; c2s = 11; c2l = 4;
3213 break;
3214 case INTERSECT_LINE_NO:
3215 c1s = 0; c1l = 4; c2s = 4; c2l = 4;
3216 break;
3217 case INTERSECT_QUAD_LINE:
3218 f.push(7, 8, 0, 9);
3219 c1s = 1; c1l = 6; c2s = 10; c2l = 4;
3220 break;
3221 case INTERSECT_QUAD_LINE_2:
3222 f.push(7, 8, 0, 12);
3223 f.push(10, 11, 9, 17);
3224 c1s = 1; c1l = 6; c2s = 13; c2l = 4;
3225 break;
3226 case INTERSECT_QUAD_LINE_NO:
3227 c1s = 0; c1l = 6; c2s = 6; c2l = 4;
3228 break;
3229 case INTERSECT_QUAD:
3230 f.push(7, 8, 0, 9);
3231 c1s = 1; c1l = 6; c2s = 10; c2l = 6;
3232 break;
3233 case INTERSECT_QUAD_2:
3234 f.push(7, 8, 0, 12);
3235 f.push(10, 11, 9, 19);
3236 c1s = 1; c1l = 6; c2s = 13; c2l = 6;
3237 break;
3238 case INTERSECT_QUAD_NO:
3239 c1s = 0; c1l = 6; c2s = 6; c2l = 6;
3240 break;
caryclark1049f122015-04-20 08:31:59 -07003241 case INTERSECT_CONIC_LINE:
3242 f.push(8, 9, 0, 10);
3243 c1s = 1; c1l = 7; c2s = 11; c2l = 4;
3244 break;
3245 case INTERSECT_CONIC_LINE_2:
3246 f.push(8, 9, 0, 12);
3247 f.push(11, 12, 10, 18);
3248 c1s = 1; c1l = 7; c2s = 14; c2l = 4;
3249 break;
3250 case INTERSECT_CONIC_LINE_NO:
3251 c1s = 0; c1l = 7; c2s = 7; c2l = 4;
3252 break;
3253 case INTERSECT_CONIC:
3254 f.push(8, 9, 0, 10);
3255 c1s = 1; c1l = 7; c2s = 11; c2l = 7;
3256 break;
3257 case INTERSECT_CONIC_2:
3258 f.push(8, 9, 0, 13);
3259 f.push(11, 12, 10, 21);
3260 c1s = 1; c1l = 7; c2s = 14; c2l = 7;
3261 break;
3262 case INTERSECT_CONIC_NO:
3263 c1s = 0; c1l = 7; c2s = 7; c2l = 7;
3264 break;
caryclarkdac1d172014-06-17 05:15:38 -07003265 case INTERSECT_SELF_CUBIC:
3266 f.push(9, 10, 0, 11);
3267 c1s = 1; c1l = 8; c2s = 0; c2l = 0;
3268 break;
3269 case INTERSECT_SELF_CUBIC_NO:
3270 c1s = 0; c1l = 8; c2s = 0; c2l = 0;
3271 break;
3272 case INTERSECT_CUBIC_LINE:
3273 f.push(9, 10, 0, 11);
3274 c1s = 1; c1l = 8; c2s = 12; c2l = 4;
3275 break;
3276 case INTERSECT_CUBIC_LINE_2:
3277 f.push(9, 10, 0, 14);
3278 f.push(12, 13, 11, 19);
3279 c1s = 1; c1l = 8; c2s = 15; c2l = 4;
3280 break;
3281 case INTERSECT_CUBIC_LINE_3:
3282 f.push(9, 10, 0, 17);
3283 f.push(12, 13, 11, 22);
3284 f.push(15, 16, 14, 23);
3285 c1s = 1; c1l = 8; c2s = 18; c2l = 4;
3286 break;
3287 case INTERSECT_CUBIC_QUAD_NO:
3288 c1s = 0; c1l = 8; c2s = 8; c2l = 6;
3289 break;
3290 case INTERSECT_CUBIC_QUAD:
3291 f.push(9, 10, 0, 11);
3292 c1s = 1; c1l = 8; c2s = 12; c2l = 6;
3293 break;
3294 case INTERSECT_CUBIC_QUAD_2:
3295 f.push(9, 10, 0, 14);
3296 f.push(12, 13, 11, 21);
3297 c1s = 1; c1l = 8; c2s = 15; c2l = 6;
3298 break;
3299 case INTERSECT_CUBIC_QUAD_3:
3300 f.push(9, 10, 0, 17);
3301 f.push(12, 13, 11, 24);
3302 f.push(15, 16, 14, 25);
3303 c1s = 1; c1l = 8; c2s = 18; c2l = 6;
3304 break;
3305 case INTERSECT_CUBIC_QUAD_4:
3306 f.push(9, 10, 0, 20);
3307 f.push(12, 13, 11, 27);
3308 f.push(15, 16, 14, 28);
3309 f.push(18, 19, 17, 29);
3310 c1s = 1; c1l = 8; c2s = 21; c2l = 6;
3311 break;
3312 case INTERSECT_CUBIC_LINE_NO:
3313 c1s = 0; c1l = 8; c2s = 8; c2l = 4;
3314 break;
3315 case INTERSECT_CUBIC:
3316 f.push(9, 10, 0, 11);
3317 c1s = 1; c1l = 8; c2s = 12; c2l = 8;
3318 break;
3319 case INTERSECT_CUBIC_2:
3320 f.push(9, 10, 0, 14);
3321 f.push(12, 13, 11, 23);
3322 c1s = 1; c1l = 8; c2s = 15; c2l = 8;
3323 break;
3324 case INTERSECT_CUBIC_3:
3325 f.push(9, 10, 0, 17);
3326 f.push(12, 13, 11, 26);
3327 f.push(15, 16, 14, 27);
3328 c1s = 1; c1l = 8; c2s = 18; c2l = 8;
3329 break;
3330 case INTERSECT_CUBIC_4:
3331 f.push(9, 10, 0, 20);
3332 f.push(12, 13, 11, 29);
3333 f.push(15, 16, 14, 30);
3334 f.push(18, 19, 17, 31);
3335 c1s = 1; c1l = 8; c2s = 21; c2l = 8;
3336 break;
3337 case INTERSECT_CUBIC_NO:
3338 c1s = 0; c1l = 8; c2s = 8; c2l = 8;
3339 break;
3340 default:
3341 console.log("unknown REC_TYPE_SECT frag type: " + fragType);
3342 throw "stop execution";
3343 }
3344 if (draw_intersection != 1) {
3345 var id = -1;
3346 var curve;
3347 switch (c1l) {
3348 case 4:
3349 drawLine(frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3]);
3350 if (draw_id) {
3351 curve = [frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3]];
3352 id = idByCurve(test, curve, PATH_LINE);
3353 }
3354 break;
3355 case 6:
3356 drawQuad(frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
3357 frags[c1s + 4], frags[c1s + 5]);
3358 if (draw_id) {
3359 curve = [frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
3360 frags[c1s + 4], frags[c1s + 5]];
3361 id = idByCurve(test, curve, PATH_QUAD);
3362 }
3363 break;
caryclark1049f122015-04-20 08:31:59 -07003364 case 7:
3365 drawConicWithQuads(frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
3366 frags[c1s + 4], frags[c1s + 5], frags[c1s + 6]);
3367 if (draw_id) {
3368 curve = [frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
3369 frags[c1s + 4], frags[c1s + 5], frags[c1s + 6]];
3370 id = idByCurve(test, curve, PATH_CONIC);
3371 }
3372 break;
caryclarkdac1d172014-06-17 05:15:38 -07003373 case 8:
3374 drawCubic(frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
3375 frags[c1s + 4], frags[c1s + 5], frags[c1s + 6], frags[c1s + 7]);
3376 if (draw_id) {
3377 curve = [frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
3378 frags[c1s + 4], frags[c1s + 5], frags[c1s + 6], frags[c1s + 7]];
3379 id = idByCurve(test, curve, PATH_CUBIC);
3380 }
3381 break;
3382 }
3383 if (id >= 0) {
3384 drawID(curve, id);
3385 }
3386 id = -1;
3387 switch (c2l) {
3388 case 0:
3389 break;
3390 case 4:
3391 drawLine(frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3]);
3392 if (draw_id) {
3393 curve = [frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3]];
3394 id = idByCurve(test, curve, PATH_LINE);
3395 }
3396 break;
3397 case 6:
3398 drawQuad(frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
3399 frags[c2s + 4], frags[c2s + 5]);
3400 if (draw_id) {
3401 curve = [frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
3402 frags[c2s + 4], frags[c2s + 5]];
3403 id = idByCurve(test, curve, PATH_QUAD);
3404 }
3405 break;
caryclark1049f122015-04-20 08:31:59 -07003406 case 7:
3407 drawConicWithQuads(frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
3408 frags[c2s + 4], frags[c2s + 5], frags[c2s + 6]);
3409 if (draw_id) {
3410 curve = [frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
3411 frags[c2s + 4], frags[c2s + 5], frags[c2s + 6]];
3412 id = idByCurve(test, curve, PATH_CONIC);
3413 }
3414 break;
caryclarkdac1d172014-06-17 05:15:38 -07003415 case 8:
3416 drawCubic(frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
3417 frags[c2s + 4], frags[c2s + 5], frags[c2s + 6], frags[c2s + 7]);
3418 if (draw_id) {
3419 curve = [frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
3420 frags[c2s + 4], frags[c2s + 5], frags[c2s + 6], frags[c2s + 7]];
3421 id = idByCurve(test, curve, PATH_CUBIC);
3422 }
3423 break;
3424 }
3425 if (id >= 0) {
3426 drawID(curve, id);
3427 }
3428 }
3429 if (collect_bounds) {
3430 break;
3431 }
caryclark54359292015-03-26 07:52:43 -07003432 if (draw_intersection != 3 || step_limit == 0 || tIndex >= lastSect) {
3433 for (var idx = 0; idx < f.length; idx += 4) {
caryclarkdac1d172014-06-17 05:15:38 -07003434 drawPoint(frags[f[idx]], frags[f[idx + 1]], true);
3435 }
3436 }
3437 if (!draw_intersectT) {
3438 break;
3439 }
3440 ctx.fillStyle = "red";
caryclark54359292015-03-26 07:52:43 -07003441 if (draw_intersection != 3 || step_limit == 0 || tIndex >= lastSect) {
3442 for (var idx = 0; idx < f.length; idx += 4) {
caryclarkdac1d172014-06-17 05:15:38 -07003443 drawTAtPointUp(frags[f[idx]], frags[f[idx + 1]], frags[f[idx + 2]]);
3444 drawTAtPointDown(frags[f[idx]], frags[f[idx + 1]], frags[f[idx + 3]]);
3445 }
3446 }
3447 break;
3448 case REC_TYPE_SORT:
3449 if (!draw_sort || (step_limit > 0 && tIndex < lastSort)) {
3450 continue;
3451 }
3452 ctx.lineWidth = 3;
3453 ctx.strokeStyle = "rgba(127,127,0, 0.5)";
3454 focus_enabled = true;
3455 switch (fragType) {
3456 case SORT_UNARY:
3457 case SORT_BINARY:
3458 var curve = curvePartialByID(test, frags[0], frags[6], frags[8]);
3459 drawCurve(curve);
3460 break;
3461 default:
3462 console.log("unknown REC_TYPE_SORT frag type: " + fragType);
3463 throw "stop execution";
3464 }
3465 break;
caryclark03b03ca2015-04-23 09:13:37 -07003466 case REC_TYPE_TOP:
3467 if (!draw_top || (step_limit > 0 && tIndex < lastTop)) {
3468 continue;
3469 }
3470 ctx.lineWidth = 3;
3471 ctx.strokeStyle = "rgba(127,127,0, 0.5)";
3472 focus_enabled = true;
3473 {
3474 var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
3475 drawCurve(curve);
3476 var type = PATH_LINE + (curve.length / 2 - 2);
3477 var mid = pointAtT(curve, type, 0.5);
3478 var d = dxy_at_t(curve, type, 0.5);
3479 drawArrow(mid.x, mid.y, d.x, d.y, 0.3);
3480 }
3481 break;
caryclarkdac1d172014-06-17 05:15:38 -07003482 case REC_TYPE_MARK:
3483 if (!draw_mark || (step_limit > 0 && tIndex < lastMark)) {
3484 continue;
3485 }
3486 ctx.lineWidth = 3;
3487 ctx.strokeStyle = fragType >= MARK_DONE_LINE ?
3488 "rgba(127,0,127, 0.5)" : "rgba(127,127,0, 0.5)";
3489 focus_enabled = true;
3490 switch (fragType) {
3491 case MARK_LINE:
3492 case MARK_DONE_LINE:
3493 case MARK_UNSORTABLE_LINE:
3494 case MARK_SIMPLE_LINE:
3495 case MARK_SIMPLE_DONE_LINE:
3496 case MARK_DONE_UNARY_LINE:
3497 drawLinePartial(frags[1], frags[2], frags[3], frags[4],
3498 frags[5], frags[9]);
3499 if (draw_id) {
3500 drawLinePartialID(frags[0], frags[1], frags[2], frags[3], frags[4],
3501 frags[5], frags[9]);
3502 }
3503 break;
3504 case MARK_QUAD:
3505 case MARK_DONE_QUAD:
3506 case MARK_UNSORTABLE_QUAD:
3507 case MARK_SIMPLE_QUAD:
3508 case MARK_SIMPLE_DONE_QUAD:
3509 case MARK_DONE_UNARY_QUAD:
3510 drawQuadPartial(frags[1], frags[2], frags[3], frags[4],
3511 frags[5], frags[6], frags[7], frags[11]);
3512 if (draw_id) {
3513 drawQuadPartialID(frags[0], frags[1], frags[2], frags[3], frags[4],
3514 frags[5], frags[6], frags[7], frags[11]);
3515 }
3516 break;
3517 case MARK_CUBIC:
3518 case MARK_DONE_CUBIC:
3519 case MARK_UNSORTABLE_CUBIC:
3520 case MARK_SIMPLE_CUBIC:
3521 case MARK_SIMPLE_DONE_CUBIC:
3522 case MARK_DONE_UNARY_CUBIC:
3523 drawCubicPartial(frags[1], frags[2], frags[3], frags[4],
3524 frags[5], frags[6], frags[7], frags[8], frags[9], frags[13]);
3525 if (draw_id) {
3526 drawCubicPartialID(frags[0], frags[1], frags[2], frags[3], frags[4],
3527 frags[5], frags[6], frags[7], frags[8], frags[9], frags[13]);
3528 }
3529 break;
3530 case MARK_ANGLE_LAST:
3531 // FIXME: ignored for now
3532 break;
3533 default:
3534 console.log("unknown REC_TYPE_MARK frag type: " + fragType);
3535 throw "stop execution";
3536 }
3537 break;
3538 default:
3539 continue;
3540 }
3541 }
3542 switch (recType) {
3543 case REC_TYPE_SORT:
3544 if (!draw_sort || (step_limit > 0 && tIndex < lastSort)) {
3545 break;
3546 }
3547 var angles = []; // use tangent lines to describe arcs
3548 var windFrom = [];
3549 var windTo = [];
3550 var opp = [];
3551 var minXY = Number.MAX_VALUE;
3552 var partial;
3553 focus_enabled = true;
3554 var someUnsortable = false;
3555 for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
3556 var fragType = records[recordIndex];
3557 var frags = records[recordIndex + 1];
3558 var unsortable = (fragType == SORT_UNARY && frags[14]) ||
3559 (fragType == SORT_BINARY && frags[16]);
3560 someUnsortable |= unsortable;
3561 switch (fragType) {
3562 case SORT_UNARY:
3563 case SORT_BINARY:
3564 partial = curvePartialByID(test, frags[0], frags[6], frags[8]);
3565 break;
3566 default:
3567 console.log("unknown REC_TYPE_SORT frag type: " + fragType);
3568 throw "stop execution";
3569 }
3570 var dx = boundsWidth(partial);
3571 var dy = boundsHeight(partial);
3572 minXY = Math.min(minXY, dx * dx + dy * dy);
3573 if (collect_bounds) {
3574 continue;
3575 }
3576 angles.push(tangent(partial));
3577 var from = frags[12];
3578 var to = frags[12];
3579 var sgn = frags[10];
3580 if (sgn < 0) {
3581 from -= frags[11];
3582 } else if (sgn > 0) {
3583 to -= frags[11];
3584 }
3585 windFrom.push(from + (unsortable ? "!" : ""));
3586 windTo.push(to + (unsortable ? "!" : ""));
3587 opp.push(fragType == SORT_BINARY);
3588 if (draw_sort == 1) {
3589 drawOrder(partial, frags[12]);
3590 } else {
3591 drawOrder(partial, (recordIndex / 2) + 1);
3592 }
3593 }
3594 var radius = Math.sqrt(minXY) / 2 * scale;
3595 radius = Math.min(50, radius);
3596 var scaledRadius = radius / scale;
3597 var centerX = partial[0];
3598 var centerY = partial[1];
3599 if (collect_bounds) {
3600 if (focus_enabled) {
3601 focusXmin = Math.min(focusXmin, centerX - scaledRadius);
3602 focusYmin = Math.min(focusYmin, centerY - scaledRadius);
3603 focusXmax = Math.max(focusXmax, centerX + scaledRadius);
3604 focusYmax = Math.max(focusYmax, centerY + scaledRadius);
3605 }
3606 break;
3607 }
3608 break;
3609 default:
3610 break;
3611 }
3612 }
3613 if (collect_bounds) {
3614 return;
3615 }
3616 if (draw_log && logStart >= 0) {
3617 ctx.font = "normal 10px Arial";
3618 ctx.textAlign = "left";
3619 ctx.beginPath();
3620 var top = screenHeight - 20 - (logRange + 2) * 10;
3621 ctx.rect(50, top, screenWidth - 100, (logRange + 2) * 10);
3622 ctx.fillStyle = "white";
3623 ctx.fill();
3624 ctx.fillStyle = "rgba(0,0,0, 0.5)";
3625 if (logStart > 0) {
3626 ctx.fillText(lines[logStart - 1], 50, top + 8);
3627 }
3628 ctx.fillStyle = "black";
3629 for (var idx = 0; idx < logRange; ++idx) {
3630 ctx.fillText(lines[logStart + idx], 50, top + 18 + 10 * idx);
3631 }
3632 ctx.fillStyle = "rgba(0,0,0, 0.5)";
3633 if (logStart + logRange < lines.length) {
3634 ctx.fillText(lines[logStart + logRange], 50, top + 18 + 10 * logRange);
3635 }
3636 }
3637 if (draw_legend) {
3638 var pos = 0;
caryclark624637c2015-05-11 07:21:27 -07003639 var drawSomething = draw_add | draw_active | draw_angle | draw_coincidence | draw_sort | draw_mark;
caryclarkdac1d172014-06-17 05:15:38 -07003640 // drawBox(pos++, "yellow", "black", opLetter, true, '');
3641 drawBox(pos++, "rgba(0,0,255, 0.3)", "black", draw_intersection > 1 ? sectCount : sectMax2, draw_intersection, intersectionKey);
3642 drawBox(pos++, "rgba(0,0,255, 0.3)", "black", draw_add ? addCount : addMax, draw_add, addKey);
3643 drawBox(pos++, "rgba(0,0,255, 0.3)", "black", draw_active ? activeCount : activeMax, draw_active, activeKey);
3644 drawBox(pos++, "rgba(127,127,0, 0.3)", "black", draw_angle ? angleCount : angleMax, draw_angle, angleKey);
caryclark624637c2015-05-11 07:21:27 -07003645 drawBox(pos++, "rgba(127,127,0, 0.3)", "black", draw_coincidence ? coinCount : coinMax, draw_coincidence, coincidenceKey);
caryclarkdac1d172014-06-17 05:15:38 -07003646 drawBox(pos++, "rgba(127,127,0, 0.3)", "black", draw_op ? opCount : opMax, draw_op, opKey);
3647 drawBox(pos++, "rgba(127,127,0, 0.3)", "black", draw_sort ? sortCount : sortMax, draw_sort, sortKey);
caryclark03b03ca2015-04-23 09:13:37 -07003648 drawBox(pos++, "rgba(127,127,0, 0.3)", "black", draw_top ? topCount : topMax, draw_top, topKey);
caryclarkdac1d172014-06-17 05:15:38 -07003649 drawBox(pos++, "rgba(127,0,127, 0.3)", "black", draw_mark ? markCount : markMax, draw_mark, markKey);
3650 drawBox(pos++, "black", "white",
3651 (new Array('P', 'P1', 'P2', 'P'))[draw_path], draw_path != 0, pathKey);
3652 drawBox(pos++, "rgba(0,63,0, 0.7)", "white",
3653 (new Array('Q', 'Q', 'C', 'QC', 'Qc', 'Cq'))[draw_computed],
3654 draw_computed != 0, computedKey);
3655 drawBox(pos++, "green", "black", step_limit, drawSomething, '');
3656 drawBox(pos++, "green", "black", stepMax, drawSomething, '');
3657 drawBox(pos++, "rgba(255,0,0, 0.6)", "black", lastIndex, drawSomething & draw_log, '');
3658 drawBox(pos++, "rgba(255,0,0, 0.6)", "black", test.length - 1, drawSomething & draw_log, '');
3659 if (curve_t) {
3660 drawCurveTControl();
3661 }
3662 ctx.font = "normal 20px Arial";
3663 ctx.fillStyle = "rgba(0,0,0, 0.3)";
3664 ctx.textAlign = "right";
3665 ctx.fillText(scale.toFixed(decimal_places) + 'x' , screenWidth - 10, screenHeight - 5);
3666 }
3667 if (draw_hints) {
3668 ctx.font = "normal 10px Arial";
3669 ctx.fillStyle = "rgba(0,0,0, 0.5)";
3670 ctx.textAlign = "right";
3671 var y = 4;
3672 ctx.fillText("control lines : " + controlLinesKey, ctx.screenWidthwidth - 10, pos * 50 + y++ * 10);
3673 ctx.fillText("curve t : " + curveTKey, screenWidth - 10, pos * 50 + y++ * 10);
3674 ctx.fillText("deriviatives : " + deriviativesKey, screenWidth - 10, pos * 50 + y++ * 10);
3675 ctx.fillText("intersect t : " + intersectTKey, screenWidth - 10, pos * 50 + y++ * 10);
caryclarkdac1d172014-06-17 05:15:38 -07003676 ctx.fillText("log : " + logKey, screenWidth - 10, pos * 50 + y++ * 10);
3677 ctx.fillText("log curve : " + logCurvesKey, screenWidth - 10, pos * 50 + y++ * 10);
3678 ctx.fillText("mid point : " + midpointKey, screenWidth - 10, pos * 50 + y++ * 10);
3679 ctx.fillText("points : " + ptsKey, screenWidth - 10, pos * 50 + y++ * 10);
3680 ctx.fillText("sequence : " + sequenceKey, screenWidth - 10, pos * 50 + y++ * 10);
3681 ctx.fillText("xy : " + xyKey, screenWidth - 10, pos * 50 + y++ * 10);
3682 }
3683}
3684
3685function drawBox(y, backC, foreC, str, enable, label) {
3686 ctx.beginPath();
3687 ctx.fillStyle = backC;
3688 ctx.rect(screenWidth - 40, y * 50 + 10, 40, 30);
3689 ctx.fill();
3690 ctx.font = "normal 16px Arial";
3691 ctx.fillStyle = foreC;
3692 ctx.textAlign = "center";
3693 ctx.fillText(str, screenWidth - 20, y * 50 + 32);
3694 if (!enable) {
3695 ctx.fillStyle = "rgba(255,255,255, 0.5)";
3696 ctx.fill();
3697 }
3698 if (label != '') {
3699 ctx.font = "normal 9px Arial";
3700 ctx.fillStyle = "black";
3701 ctx.fillText(label, screenWidth - 47, y * 50 + 40);
3702 }
3703}
3704
3705function drawCurveTControl() {
3706 ctx.lineWidth = 2;
3707 ctx.strokeStyle = "rgba(0,0,0, 0.3)";
3708 ctx.beginPath();
3709 ctx.rect(screenWidth - 80, 40, 28, screenHeight - 80);
3710 ctx.stroke();
3711 var ty = 40 + curveT * (screenHeight - 80);
3712 ctx.beginPath();
3713 ctx.moveTo(screenWidth - 80, ty);
3714 ctx.lineTo(screenWidth - 85, ty - 5);
3715 ctx.lineTo(screenWidth - 85, ty + 5);
3716 ctx.lineTo(screenWidth - 80, ty);
3717 ctx.fillStyle = "rgba(0,0,0, 0.6)";
3718 ctx.fill();
3719 var num = curveT.toFixed(decimal_places);
3720 ctx.font = "normal 10px Arial";
3721 ctx.textAlign = "left";
3722 ctx.fillText(num, screenWidth - 78, ty);
3723}
3724
3725function ptInTControl() {
3726 var e = window.event;
3727 var tgt = e.target || e.srcElement;
3728 var left = tgt.offsetLeft;
3729 var top = tgt.offsetTop;
3730 var x = (e.clientX - left);
3731 var y = (e.clientY - top);
3732 if (x < screenWidth - 80 || x > screenWidth - 50) {
3733 return false;
3734 }
3735 if (y < 40 || y > screenHeight - 80) {
3736 return false;
3737 }
3738 curveT = (y - 40) / (screenHeight - 120);
3739 if (curveT < 0 || curveT > 1) {
3740 throw "stop execution";
3741 }
3742 return true;
3743}
3744
3745function drawTop() {
3746 if (tests[testIndex] == null) {
3747 var str = testDivs[testIndex].textContent;
3748 parse_all(str);
3749 var title = testDivs[testIndex].id.toString();
3750 testTitles[testIndex] = title;
3751 }
3752 init(tests[testIndex]);
3753 redraw();
3754}
3755
3756function redraw() {
3757 if (focus_on_selection) {
3758 collect_bounds = true;
3759 draw(tests[testIndex], testLines[testIndex], testTitles[testIndex]);
3760 collect_bounds = false;
3761 if (focusXmin < focusXmax && focusYmin < focusYmax) {
3762 setScale(focusXmin, focusXmax, focusYmin, focusYmax);
3763 }
3764 }
3765 ctx.beginPath();
3766 ctx.fillStyle = "white";
3767 ctx.rect(0, 0, screenWidth, screenHeight);
3768 ctx.fill();
3769 draw(tests[testIndex], testLines[testIndex], testTitles[testIndex]);
3770}
3771
3772function dumpCurvePartial(test, id, t0, t1) {
3773 var curve = curveByID(test, id);
3774 var name = ["line", "quad", "cubic"][curve.length / 2 - 2];
3775 console.log("id=" + id + " " + name + "=" + curveToString(curve)
3776 + " t0=" + t0 + " t1=" + t1
3777 + " partial=" + curveToString(curvePartialByID(test, id, t0, t1)));
3778}
3779
3780function dumpAngleTest(test, id, t0, t1) {
3781 var curve = curveByID(test, id);
3782 console.log(" { {" + curveToString(curve) + "}, "
3783 + curve.length / 2 + ", " + t0 + ", " + t1 + ", {} }, //");
3784}
3785
3786function dumpLogToConsole() {
3787 if (logStart < 0) {
3788 return;
3789 }
3790 var test = tests[testIndex];
3791 var recType = REC_TYPE_UNKNOWN;
3792 var records;
3793 for (var index = 0; index < test.length; index += 3) {
3794 var lastLineNo = test[index + 1];
3795 if (lastLineNo >= logStart && lastLineNo < logStart + logRange) {
3796 recType = test[index];
3797 records = test[index + 2];
3798 break;
3799 }
3800 }
3801 if (recType == REC_TYPE_UNKNOWN) {
3802 return;
3803 }
3804 var lines = testLines[testIndex];
3805 for (var idx = 0; idx < logRange; ++idx) {
3806 var line = lines[logStart + idx];
3807 console.log(line);
3808 for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
3809 var fragType = records[recordIndex];
3810 var frags = records[recordIndex + 1];
3811 if (recType == REC_TYPE_ANGLE && fragType == ANGLE_AFTER) {
caryclarkdac1d172014-06-17 05:15:38 -07003812 dumpCurvePartial(test, frags[0], frags[4], frags[5]);
3813 dumpCurvePartial(test, frags[6], frags[10], frags[11]);
3814 dumpCurvePartial(test, frags[12], frags[16], frags[17]);
3815 console.log("\nstatic IntersectData intersectDataSet[] = { //");
3816 dumpAngleTest(test, frags[0], frags[4], frags[5]);
3817 dumpAngleTest(test, frags[6], frags[10], frags[11]);
3818 dumpAngleTest(test, frags[12], frags[16], frags[17]);
3819 console.log("}; //");
3820 }
3821 }
3822 }
3823}
3824
3825var activeKey = 'a';
3826var pathKey = 'b';
3827var pathBackKey = 'B';
3828var centerKey = 'c';
caryclark624637c2015-05-11 07:21:27 -07003829var coincidenceKey = 'C';
caryclarkdac1d172014-06-17 05:15:38 -07003830var addKey = 'd';
3831var deriviativesKey = 'f';
3832var angleKey = 'g';
3833var angleBackKey = 'G';
caryclarkdac1d172014-06-17 05:15:38 -07003834var intersectionKey = 'i';
3835var intersectionBackKey = 'I';
3836var sequenceKey = 'j';
3837var midpointKey = 'k';
3838var logKey = 'l';
3839var logToConsoleKey = 'L';
3840var markKey = 'm';
3841var sortKey = 'o';
3842var opKey = 'p';
3843var opBackKey = 'P';
3844var computedKey = 'q';
3845var computedBackKey = 'Q';
3846var stepKey = 's';
3847var stepBackKey = 'S';
3848var intersectTKey = 't';
caryclark03b03ca2015-04-23 09:13:37 -07003849var topKey = 'T';
caryclarkdac1d172014-06-17 05:15:38 -07003850var curveTKey = 'u';
3851var controlLinesBackKey = 'V';
3852var controlLinesKey = 'v';
3853var ptsKey = 'x';
3854var xyKey = 'y';
3855var logCurvesKey = 'z';
3856var focusKey = '`';
3857var idKey = '.';
3858var retinaKey = '\\';
3859
3860function doKeyPress(evt) {
3861 var char = String.fromCharCode(evt.charCode);
3862 var focusWasOn = false;
3863 switch (char) {
3864 case '0':
3865 case '1':
3866 case '2':
3867 case '3':
3868 case '4':
3869 case '5':
3870 case '6':
3871 case '7':
3872 case '8':
3873 case '9':
3874 decimal_places = char - '0';
3875 redraw();
3876 break;
3877 case activeKey:
3878 draw_active ^= true;
3879 redraw();
3880 break;
3881 case addKey:
3882 draw_add ^= true;
3883 redraw();
3884 break;
3885 case angleKey:
caryclark54359292015-03-26 07:52:43 -07003886 draw_angle = (draw_angle + 1) % 4;
caryclarkdac1d172014-06-17 05:15:38 -07003887 redraw();
3888 break;
3889 case angleBackKey:
3890 draw_angle = (draw_angle + 2) % 3;
3891 redraw();
3892 break;
3893 case centerKey:
3894 setScale(xmin, xmax, ymin, ymax);
3895 redraw();
3896 break;
caryclark624637c2015-05-11 07:21:27 -07003897 case coincidenceKey:
3898 draw_coincidence ^= true;
3899 redraw();
3900 break;
caryclarkdac1d172014-06-17 05:15:38 -07003901 case controlLinesBackKey:
3902 control_lines = (control_lines + 3) % 4;
3903 redraw();
3904 break;
3905 case controlLinesKey:
3906 control_lines = (control_lines + 1) % 4;
3907 redraw();
3908 break;
3909 case computedBackKey:
3910 draw_computed = (draw_computed + 5) % 6;
3911 redraw();
3912 break;
3913 case computedKey:
3914 draw_computed = (draw_computed + 1) % 6;
3915 redraw();
3916 break;
3917 case curveTKey:
3918 curve_t ^= true;
3919 if (curve_t) {
3920 draw_legend = true;
3921 }
3922 redraw();
3923 break;
3924 case deriviativesKey:
3925 draw_deriviatives = (draw_deriviatives + 1) % 3;
3926 redraw();
3927 break;
3928 case focusKey:
3929 focus_on_selection ^= true;
3930 setScale(xmin, xmax, ymin, ymax);
3931 redraw();
3932 break;
caryclarkdac1d172014-06-17 05:15:38 -07003933 case idKey:
3934 draw_id ^= true;
3935 redraw();
3936 break;
3937 case intersectionBackKey:
3938 draw_intersection = (draw_intersection + 3) % 4;
3939 redraw();
3940 break;
3941 case intersectionKey:
3942 draw_intersection = (draw_intersection + 1) % 4;
3943 redraw();
3944 break;
3945 case intersectTKey:
3946 draw_intersectT ^= true;
3947 redraw();
3948 break;
3949 case logCurvesKey:
3950 logCurves(tests[testIndex]);
3951 break;
3952 case logKey:
3953 draw_log ^= true;
3954 redraw();
3955 break;
3956 case logToConsoleKey:
3957 if (draw_log) {
3958 dumpLogToConsole();
3959 }
3960 break;
3961 case markKey:
3962 draw_mark ^= true;
3963 redraw();
3964 break;
3965 case midpointKey:
3966 draw_midpoint ^= true;
3967 redraw();
3968 break;
3969 case opKey:
3970 draw_op = (draw_op + 1) % 3;
3971 redraw();
3972 break;
3973 case opBackKey:
3974 draw_op = (draw_op + 2) % 3;
3975 redraw();
3976 break;
3977 case pathKey:
3978 draw_path = (draw_path + 1) % 4;
3979 redraw();
3980 break;
3981 case pathBackKey:
3982 draw_path = (draw_path + 3) % 4;
3983 redraw();
3984 break;
3985 case ptsKey:
3986 pt_labels = (pt_labels + 1) % 3;
3987 redraw();
3988 break;
3989 case retinaKey:
3990 retina_scale ^= true;
3991 drawTop();
3992 break;
3993 case sequenceKey:
3994 draw_sequence ^= true;
3995 redraw();
3996 break;
3997 case sortKey:
3998 draw_sort = (draw_sort + 1) % 3;
3999 drawTop();
4000 break;
4001 case stepKey:
4002 step_limit++;
4003 if (step_limit > stepMax) {
4004 step_limit = stepMax;
4005 }
4006 redraw();
4007 break;
4008 case stepBackKey:
4009 step_limit--;
4010 if (step_limit < 0) {
4011 step_limit = 0;
4012 }
4013 redraw();
4014 break;
caryclark03b03ca2015-04-23 09:13:37 -07004015 case topKey:
4016 draw_top ^= true;
4017 redraw();
4018 break;
caryclarkdac1d172014-06-17 05:15:38 -07004019 case xyKey:
4020 debug_xy = (debug_xy + 1) % 3;
4021 redraw();
4022 break;
4023 case '-':
4024 focusWasOn = focus_on_selection;
4025 if (focusWasOn) {
4026 focus_on_selection = false;
4027 scale /= 1.2;
4028 } else {
4029 scale /= 2;
4030 calcLeftTop();
4031 }
4032 redraw();
4033 focus_on_selection = focusWasOn;
4034 break;
4035 case '=':
4036 case '+':
4037 focusWasOn = focus_on_selection;
4038 if (focusWasOn) {
4039 focus_on_selection = false;
4040 scale *= 1.2;
4041 } else {
4042 scale *= 2;
4043 calcLeftTop();
4044 }
4045 redraw();
4046 focus_on_selection = focusWasOn;
4047 break;
4048 case '?':
4049 draw_hints ^= true;
4050 if (draw_hints && !draw_legend) {
4051 draw_legend = true;
4052 }
4053 redraw();
4054 break;
4055 case '/':
4056 draw_legend ^= true;
4057 redraw();
4058 break;
4059 }
4060}
4061
4062function doKeyDown(evt) {
4063 var char = evt.keyCode;
4064 var preventDefault = false;
4065 switch (char) {
4066 case 37: // left arrow
4067 if (evt.shiftKey) {
4068 testIndex -= 9;
4069 }
4070 if (--testIndex < 0)
4071 testIndex = tests.length - 1;
4072 drawTop();
4073 preventDefault = true;
4074 break;
4075 case 39: // right arrow
4076 if (evt.shiftKey) {
4077 testIndex += 9;
4078 }
4079 if (++testIndex >= tests.length)
4080 testIndex = 0;
4081 drawTop();
4082 preventDefault = true;
4083 break;
4084 }
4085 if (preventDefault) {
4086 evt.preventDefault();
4087 return false;
4088 }
4089 return true;
4090}
4091
4092(function() {
4093 var hidden = "hidden";
4094
4095 // Standards:
4096 if (hidden in document)
4097 document.addEventListener("visibilitychange", onchange);
4098 else if ((hidden = "mozHidden") in document)
4099 document.addEventListener("mozvisibilitychange", onchange);
4100 else if ((hidden = "webkitHidden") in document)
4101 document.addEventListener("webkitvisibilitychange", onchange);
4102 else if ((hidden = "msHidden") in document)
4103 document.addEventListener("msvisibilitychange", onchange);
4104 // IE 9 and lower:
4105 else if ('onfocusin' in document)
4106 document.onfocusin = document.onfocusout = onchange;
4107 // All others:
4108 else
4109 window.onpageshow = window.onpagehide
4110 = window.onfocus = window.onblur = onchange;
4111
4112 function onchange (evt) {
4113 var v = 'visible', h = 'hidden',
4114 evtMap = {
4115 focus:v, focusin:v, pageshow:v, blur:h, focusout:h, pagehide:h
4116 };
4117
4118 evt = evt || window.event;
4119 if (evt.type in evtMap)
4120 document.body.className = evtMap[evt.type];
4121 else
4122 document.body.className = this[hidden] ? "hidden" : "visible";
4123 }
4124})();
4125
4126function calcXY() {
4127 var e = window.event;
4128 var tgt = e.target || e.srcElement;
4129 var left = tgt.offsetLeft;
4130 var top = tgt.offsetTop;
4131 mouseX = (e.clientX - left) / scale + srcLeft;
4132 mouseY = (e.clientY - top) / scale + srcTop;
4133}
4134
4135function calcLeftTop() {
4136 srcLeft = mouseX - screenWidth / 2 / scale;
4137 srcTop = mouseY - screenHeight / 2 / scale;
4138}
4139
4140var disableClick = false;
4141
4142function handleMouseClick() {
4143 if (disableClick) {
4144 return;
4145 }
4146 if (!curve_t || !ptInTControl()) {
4147 calcXY();
4148 calcLeftTop();
4149 }
4150 redraw();
4151// if (!curve_t || !ptInTControl()) {
4152// mouseX = screenWidth / 2 / scale + srcLeft;
4153// mouseY = screenHeight / 2 / scale + srcTop;
4154// }
4155}
4156
4157function handleMouseOver() {
4158 calcXY();
4159 if (debug_xy != 2) {
4160 return;
4161 }
4162 var num = mouseX.toFixed(decimal_places) + ", " + mouseY.toFixed(decimal_places);
4163 ctx.beginPath();
4164 ctx.rect(300,100,num.length * 6,10);
4165 ctx.fillStyle="white";
4166 ctx.fill();
4167 ctx.font = "normal 10px Arial";
4168 ctx.fillStyle="black";
4169 ctx.textAlign = "left";
4170 ctx.fillText(num, 300, 108);
4171}
4172
4173function start() {
4174 for (var i = 0; i < testDivs.length; ++i) {
4175 tests[i] = null;
4176 }
4177 testIndex = 0;
4178 drawTop();
4179 window.addEventListener('keypress', doKeyPress, true);
4180 window.addEventListener('keydown', doKeyDown, true);
4181 window.onresize = function() {
4182 drawTop();
4183 }
4184 /*
4185 window.onpagehide = function() {
4186 disableClick = true;
4187 }
4188 */
4189 window.onpageshow = function () {
4190 disableClick = false;
4191 }
4192}
4193
4194</script>
4195</head>
4196
4197<body onLoad="start();">
4198<canvas id="canvas" width="750" height="500"
4199 onmousemove="handleMouseOver()"
4200 onclick="handleMouseClick()"
4201 ></canvas >
4202</body>
4203</html>