1<!DOCTYPE html>
2
3<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
4<head>
5    <meta charset="utf-8" />
6    <title></title>
7<div style="height:0">
8
9<div id="quad1">
10{{3.13,2.74}, {1.08,4.62}, {3.71,0.94}} 
11{{3.13,2.74}, {7.99,2.75}, {8.27,1.96}} 
12</div>
13
14<div id="quad2">
15{{4.838888984361574,4.399276078363981}, {5.947577332875065,2.02910379790342}, {3.8092258119951885,2.108659563498883}}
16{{4.838888984361574,4.399276078363981}, {6.192910293864926,1.7797920604914939}, {3.3638348513490293,1.4969462106891218}}
17</div>
18
19<div id="quad3">
20{{4.838888984361574,4.399276078363981}, {5.962263714769107,1.654601059605365}, {3.8789861259918847,2.8650082310420126}}
21{{4.838888984361574,4.399276078363981}, {6.192910293864926,1.7797920604914939}, {3.3638348513490293,1.4969462106891218}}
22</div>
23
24<div id="quad4">
25{{4.838888984361574,4.399276078363981}, {5.77868394109359,1.852867215174923}, {3.915702080726988,2.1820914729690903}}
26{{4.838888984361574,4.399276078363981}, {6.681232491841801,2.5287975370876032}, {3.3638348513490293,1.4969462106891218}}
27</div>
28
29<div id="quad5">
30{{4.838888984361574,4.399276078363981}, {6.082937568878361,1.9951156645288415}, {3.915702080726988,2.1820914729690903}}
31{{4.838888984361574,4.399276078363981}, {6.681232491841801,2.5287975370876032}, {3.3638348513490293,1.4969462106891218}}
32</div>
33
34<div id="quad6">
35{{4.898159171592373,4.367665311840888}, {6.695396170263287,1.769888953051804}, {3.6312051820191513,2.727377195492444}}
36{{4.898159171592373,4.367665311840888}, {6.961778044734251,2.4813813873029633}, {3.3638348513490293,1.4969462106891218}}
37</div>
38
39<div id="quad7">
40{{4.838888984361574,4.399276078363981}, {3.012741870322956,2.449520433298304}, {5.140619283496844,2.110967248292131}}
41{{4.838888984361574,4.399276078363981}, {2.804962246947524,2.232446600933607}, {6.60393841996606,2.077794045550955}}
42</div>
43
44<div id="quad8">
45{{4.838888984361574,4.399276078363981}, {3.1707957029384213,2.607574265913769}, {4.626944327496585,2.2848264641691425}}
46{{4.838888984361574,4.399276078363981}, {2.804962246947524,2.232446600933607}, {6.60393841996606,2.077794045550955}}
47</div>
48
49<div id="quad9">
50{{4.838888984361574,4.399276078363981}, {3.463749932092156,2.935940544745428}, {5.161344349908893,2.4940794849932386}}
51{{4.838888984361574,4.399276078363981}, {2.804962246947524,2.232446600933607}, {6.60393841996606,2.077794045550955}}
52</div>
53
54<div id="quad10">
55{{4.838888984361574,4.399276078363981}, {5.82508561259808,2.495362604119041}, {3.4377993053488463,2.7132154732530362}}
56{{4.838888984361574,4.399276078363981}, {6.192910293864926,1.7797920604914939}, {2.435268584733173,1.817005221735438}}
57</div>
58
59<div id="cubic1">
60{{0,0}, {1,0}, {0,1}, {1,1}}
61{{0,0}, {2,0}, {0,2}, {2,2}}
62</div>
63
64<div id="cubic2" >
65{{0.4655213647959181,1.5608657525510201}, {0.6599868463010203,0.4290098852040817}, {2.473652742346939,1.2464524872448977}, {1.8511738679846936,0.5344786352040818}}
66{{0.4655213647959181,1.5608657525510201}, {0.3250358737244896,0.819226323341837}, {1.4399214764030612,0.3318817761479596}, {1.2703414571528546,0.9081465322144181}}
67</div> 
68
69<div id="quad11">
70{{-378.22698974609375, -987.8935546875}, {-47.53326416015625, 482.7139892578125}, {-626.4708251953125, -338.62969970703125}}
71{{-378.22698974609375, -987.8935546875}, {-847.94854736328125, -861.42230224609375}, {-390.9146728515625, 402.08740234375}}
72</div>
73
74<div id="quad12">
75{{-173.3448486328125, -962.89422607421875}, {-778.321533203125, -161.47637939453125}, {-196.77374267578125, -736.40155029296875}}
76{{-173.3448486328125, -962.89422607421875}, {652.3017578125, -400.67816162109375}, {-386.7855224609375, 361.1614990234375}}
77</div>
78
79<div id="quad13">
80{{{-968.181396484375, 544.0128173828125}, {592.2825927734375, 870.552490234375}, {593.435302734375, 557.8828125}}}
81{{{-968.181396484375, 544.0128173828125}, {593.677001953125, 865.5810546875}, {-66.57171630859375, -847.849853515625}}}
82</div>
83
84<div id="quad14">
85{{{769.693115234375, -626.35089111328125}, {6.60491943359375, -210.43756103515625}, {-898.26654052734375, -17.76312255859375}}}
86{{{769.693115234375, -626.35089111328125}, {192.8486328125, 609.8062744140625}, {888.317626953125, -551.27215576171875}}}
87</div>
88
89<div id="quad15">
90{{{187.410400390625, -343.557373046875}, {-752.7930908203125, 431.57177734375}, {387.663330078125, 701.281982421875}}}
91{{{187.410400390625, -343.557373046875}, {-86.16302490234375, -366.027099609375}, {-468.3883056640625, -25.736572265625}}}
92</div>
93
94<div id="quad16">
95{{{-353.9388427734375, 76.8973388671875}, {-36.00189208984375, 282.289306640625}, {-531.37969970703125, 683.95751953125}}}
96{{{-353.9388427734375, 76.8973388671875}, {-779.3529052734375, 509.6165771484375}, {-662.34088134765625, 124.4027099609375}}}
97</div>
98
99<div id="quad17">
100{{{-657.0289306640625, 681.611083984375}, {-991.8365478515625, 964.4644775390625}, {-843.3585205078125, 904.47998046875}}}
101{{{-657.0289306640625, 681.611083984375}, {-763.1571044921875, 39.1097412109375}, {618.2041015625, 840.6429443359375}}}
102</div>
103
104<div id="quad18">
105{{{-609.406005859375, -684.37506103515625}, {766.4923095703125, 583.657958984375}, {-912.6832275390625, -949.553466796875}}}
106{{{-609.406005859375, -684.37506103515625}, {774.140380859375, 82.2415771484375}, {540.9007568359375, -136.982666015625}}}
107</div>
108
109<div id="quad19">
110{{{-657.0289306640625, 681.611083984375}, {-991.8365478515625, 964.4644775390625}, {-843.3585205078125, 904.47998046875}}}
111{{{-657.0289306640625, 681.611083984375}, {-763.1571044921875, 39.1097412109375}, {618.2041015625, 840.6429443359375}}}
112</div>
113
114<div id="quad20">
115{{{123.2955322265625, -577.799560546875}, {-491.892578125, 704.91748046875}, {478.03759765625, -951.92333984375}}}
116{{{123.2955322265625, -577.799560546875}, {-550.6966552734375, 812.216796875}, {-816.3184814453125, -705.0025634765625}}}
117</div>
118
119<div id="quad21">
120{{{123.2955322265625, -577.799560546875}, {-481.892578125, 704.91748046875}, {478.03759765625, -951.92333984375}}}
121{{{123.2955322265625, -577.799560546875}, {-550.6966552734375, 812.216796875}, {-816.3184814453125, -705.0025634765625}}}
122</div>
123
124<div id="quad22">
125{{{187.410400390625, -343.557373046875}, {-752.7930908203125, 431.57177734375}, {387.663330078125, 701.281982421875}}}
126{{{187.410400390625, -343.557373046875}, {-86.16302490234375, -366.027099609375}, {-468.3883056640625, -25.736572265625}}}
127</div>
128
129<div id="quad23">
130{{{-341.26922607421875, 964.1964111328125}, {883.2567138671875, 812.7301025390625}, {286.0372314453125, 94.979248046875}}}
131{{{-341.26922607421875, 964.1964111328125}, {-158.90765380859375, 597.1875}, {-282.2255859375, 262.430908203125}}}
132</div>
133
134<div id="quad24">
135{{{123.2955322265625, -577.799560546875}, {-481.892578125, 704.91748046875}, {478.03759765625, -951.92333984375}}}
136{{{123.2955322265625, -577.799560546875}, {-550.6966552734375, 812.216796875}, {-816.3184814453125, -705.0025634765625}}}
137{{{417.3499131065152, -577.799560546875}, {417.3499131065152, -699.60087482901156}, {331.22337542585541, -785.72740374616797}}}
138</div>
139
140<div id="quad25">
141{{{922.6107177734375, 291.412109375}, {-939.361572265625, 589.8492431640625}, {-515.70941162109375, 120.2764892578125}}}
142{{{922.6107177734375, 291.412109375}, {148.5115966796875, -751.42095947265625}, {-347.47503662109375, 331.1798095703125}}}
143{{{922.6107177734375, -143.9114969433939}, {742.29377357777753, -143.9114969433939}, {614.79044900323777, -16.408159395199732}}}
144{{{487.2871114550436, 291.412109375}, {487.2871114550436, 471.72905357065997}, {614.79044900323777, 599.23237814519973}}}
145</div>
146
147<div id="quad26">
148{{{187.410400390625, -343.557373046875}, {-752.7930908203125, 431.57177734375}, {387.663330078125, 701.281982421875}}}
149{{{187.410400390625, -343.557373046875}, {-86.16302490234375, -366.027099609375}, {-468.3883056640625, -25.736572265625}}}
150{{{33.221887415632978, -343.557373046875}, {33.221887415632978, -279.69039894717827}, {78.38265915086852, -234.52963180711851}}}
151</div>
152
153<div id="quad27">
154{{{-173.3448486328125, -962.89422607421875}, {-778.321533203125, -161.47637939453125}, {-196.77374267578125, -736.40155029296875}}}
155{{{-173.3448486328125, -962.89422607421875}, {652.3017578125, -400.67816162109375}, {-386.7855224609375, 361.1614990234375}}}
156{{{-270.84959533883426, -865.38947936819704}, {-230.46180860703427, -825.00168852687921}, {-173.3448486328125, -825.00168852687921}}}
157{{{-75.840101926790737, -865.38947936819704}, {-35.4523110854729, -905.77726609999695}, {-35.4523110854729, -962.89422607421875}}}
158</div>
159
160<div id="quad28">
161{{{344.2755126953125, -689.900390625}, {743.6728515625, 512.8448486328125}, {928.598388671875, 111.946044921875}}}
162{{{344.2755126953125, -689.900390625}, {-950.03106689453125, -511.25741577148437}, {850.8173828125, 798.4874267578125}}}
163{{{344.2755126953125, -689.900390625}, {850.8173828125, 798.4874267578125}}}
164{{{344.2755126953125, -689.900390625}, {391.39917554828793, -551.43545842779145}}}
165</div>
166
167<div id="quad29">
168{{{351.8946533203125, 512.8131103515625}, {-294.22332763671875, 183.2200927734375}, {624.4842529296875, 862.0753173828125}}}
169{{{351.8946533203125, 512.8131103515625}, {489.1907958984375, -543.4212646484375}, {-432.7445068359375, 812.5205078125}}}
170</div>
171
172<div id="quad30">
173{{{627.6910400390625, 81.144287109375}, {168.9248046875, -211.72735595703125}, {-61.57086181640625, 915.171875}}}
174{{{627.6910400390625, 81.144287109375}, {918.159423828125, -325.468994140625}, {359.0523681640625, 817.4888916015625}}}
175{{{235.78221371860315, 81.144287109375}, {235.78221371860315, 243.47824037936314}, {350.56965608373537, 358.26567106470213}}},
176</div>
177
178<div id="quad31">
179{{{178.1549072265625, 62.724609375}, {541.3643798828125, 223.823486328125}, {-446.77471923828125, -15.990478515625}}}
180{{{178.1549072265625, 62.724609375}, {-347.14031982421875, -834.27191162109375}, {-495.13888549804687, 96.476806640625}}}
181</div>
182
183<div id="quad32">
184{{{-809.41009521484375, 370.4566650390625}, {622.44677734375, -166.97119140625}, {-285.6748046875, 333.81005859375}}},
185{{{-809.41009521484375, 370.4566650390625}, {-110.36346435546875, -656.96044921875}, {906.4796142578125, 530.2061767578125}}}
186</div>
187
188<div id="quad33">
189{{{-918.58624267578125, 653.6695556640625}, {-639.37548828125, 61.493896484375}, {-198.9605712890625, 243.704345703125}}},
190{{{-918.58624267578125, 653.6695556640625}, {-302.093505859375, -107.10955810546875}, {696.4962158203125, 600.738525390625}}}
191</div>
192
193<div id="quad34">
194{{{-610.4193115234375, 861.173095703125}, {403.3203125, 215.3988037109375}, {-373.5546875, 179.88134765625}}},
195{{{-610.4193115234375, 861.173095703125}, {-757.244140625, -222.137451171875}, {705.892822265625, 87.4090576171875}}}
196</div>
197
198<div id="quad35">
199{{{282.5767822265625, -529.4022216796875}, {392.0968017578125, 768.1014404296875}, {712.11572265625, 189.19677734375}}},
200{{{282.5767822265625, -529.4022216796875}, {699.360595703125, 465.6171875}, {438.5755615234375, 125.5230712890625}}}
201</div>
202
203<div id="quad36">
204{{{-170.1510009765625, -184.905517578125}, {654.734130859375, 120.339599609375}, {-470.98443603515625, -69.4737548828125}}},
205{{{-170.1510009765625, -184.905517578125}, {-500.9822998046875, -148.40911865234375}, {-446.35821533203125, -840.5694580078125}}}
206</div>
207
208<div id="quad37">
209{{{-119.55023193359375, -39.2008056640625}, {-618.14306640625, -620.1419677734375}, {-779.53790283203125, -681.9923095703125}}},
210{{{-119.55023193359375, -39.2008056640625}, {365.968994140625, 55.4974365234375}, {98.1297607421875, -192.474609375}}}
211</div>
212
213<div id="quad38">
214{{{607.9136962890625, 484.1448974609375}, {280.619140625, 982.736572265625}, {-577.5596923828125, 798.9134521484375}}},
215{{{607.9136962890625, 484.1448974609375}, {374.318115234375, -590.5146484375}, {-258.30438232421875, 592.958984375}}}
216</div>
217
218<div id="quad39">
219{{{-491.48846435546875, -470.9105224609375}, {109.7149658203125, -989.5384521484375}, {-275.900390625, 657.1920166015625}}},
220{{{-491.48846435546875, -470.9105224609375}, {-796.935791015625, 191.326171875}, {-852.120849609375, 62.06005859375}}}
221</div>
222
223<div id="quad40">
224{{{-872.76458740234375, -163.30078125}, {723.6697998046875, 177.8204345703125}, {206.470703125, 147.9564208984375}}},
225{{{-872.76458740234375, -163.30078125}, {556.937744140625, 715.4345703125}, {627.348388671875, 77.0643310546875}}}
226</div>
227
228<div id="quad108">
229{{{282.5767822265625, -529.4022216796875}, {392.0968017578125, 768.1014404296875}, {712.11572265625, 189.19677734375}}},
230{{{282.5767822265625, -529.4022216796875}, {699.360595703125, 465.6171875}, {438.5755615234375, 125.5230712890625}}}
231</div>
232
233<div id="quad159">
234{{{-868.3076171875, -212.74591064453125}, {-208.84014892578125, -57.353515625}, {393.79736328125, -986.03607177734375}}},
235{{{-868.3076171875, -212.74591064453125}, {371.0980224609375, -960.9017333984375}, {-236.2821044921875, -441.20074462890625}}}
236</div>
237
238<div id="quad212">
239{{{-610.4193115234375, 861.173095703125}, {403.3203125, 215.3988037109375}, {-373.5546875, 179.88134765625}}},
240{{{-610.4193115234375, 861.173095703125}, {-757.244140625, -222.137451171875}, {705.892822265625, 87.4090576171875}}}
241</div>
242
243<div id="quad232">
244{{{766.497802734375, 675.660400390625}, {639.0235595703125, 351.4776611328125}, {345.9315185546875, 624.685791015625}}},
245{{{766.497802734375, 675.660400390625}, {-901.72650146484375, 923.99169921875}, {755.665283203125, 416.728759765625}}}
246</div>
247
248<div id="quad379">
249{{{-872.76458740234375, -163.30078125}, {723.6697998046875, 177.8204345703125}, {206.470703125, 147.9564208984375}}},
250{{{-872.76458740234375, -163.30078125}, {556.937744140625, 715.4345703125}, {627.348388671875, 77.0643310546875}}}
251</div>
252
253<div id="quad413">
254{{{-127.60784912109375, 384.614990234375}, {-184.46685791015625, 717.5728759765625}, {-981.56524658203125, -827.18109130859375}}},
255{{{-127.60784912109375, 384.614990234375}, {-125.78131103515625, 751.187744140625}, {562.529541015625, -277.5535888671875}}}
256</div>
257
258<div id="quad179">
259{{{-595.956298828125, -113.24383544921875}, {-730.611572265625, 481.5323486328125}, {505.58447265625, -504.9130859375}}},
260{{{-595.956298828125, -113.24383544921875}, {-971.0836181640625, -849.73907470703125}, {-32.39227294921875, -906.3277587890625}}}
261</div>
262
263<div id="quad584">
264{{{-406.65435791015625, 599.96630859375}, {-566.71881103515625, -400.65362548828125}, {-486.0682373046875, 100.34326171875}}},
265{{{-406.65435791015625, 599.96630859375}, {799.783935546875, 992.77783203125}, {180.6688232421875, -490.0054931640625}}}
266</div>
267
268<div id="quad653">
269{{{-46.6143798828125, 164.224853515625}, {-161.7724609375, 327.61376953125}, {168.5106201171875, -948.4150390625}}},
270{{{-46.6143798828125, 164.224853515625}, {412.9364013671875, -199.26715087890625}, {-278.044677734375, 472.3961181640625}}}
271</div>
272
273<div id="quad809">
274{{{-176.8541259765625, -275.9761962890625}, {-723.969482421875, -7.4718017578125}, {931.6959228515625, 231.6737060546875}}},
275{{{-176.8541259765625, -275.9761962890625}, {-250.86737060546875, -748.8143310546875}, {-96.77099609375, -287.76336669921875}}}
276</div>
277
278<div id="quad14a">
279{{{-609.406005859375, -684.37506103515625}, {766.4923095703125, 583.657958984375}, {-912.6832275390625, -949.553466796875}}},
280{{{-609.406005859375, -684.37506103515625}, {774.140380859375, 82.2415771484375}, {540.9007568359375, -136.982666015625}}}
281</div>
282
283<div id="quad22a">
284{{{-728.5626220703125, 141.134521484375}, {749.9122314453125, -645.93359375}, {67.1751708984375, -285.85528564453125}}},
285{{{-728.5626220703125, 141.134521484375}, {-841.0341796875, -988.058349609375}, {34.87939453125, -489.359130859375}}}
286{{{276.48354206343231, -395.24293552482953}, {-728.5626220703125, 141.134521484375}}}
287{{{fX=97.702285839737073, -301.95147049201717}, {-728.5626220703125, 141.134521484375}}}
288{{{fX=-52.525628917174856, -536.31069276053427}, {-728.5626220703125, 141.134521484375}}}
289{{{fX=-5.2463328209585285, -511.63085965304060}, {-728.5626220703125, 141.134521484375}}}
290</div>
291
292<div id="quad77">
293{{{383.7933349609375, -397.5057373046875}, {480.7408447265625, 92.927490234375}, {690.7930908203125, -267.44964599609375}}},
294{{{383.7933349609375, -397.5057373046875}, {83.3685302734375, 619.781005859375}, {688.14111328125, 416.241455078125}}}
295</div>
296
297<div id="quad94">
298{{{627.6910400390625, 81.144287109375}, {168.9248046875, -211.72735595703125}, {-61.57086181640625, 915.171875}}},
299{{{627.6910400390625, 81.144287109375}, {918.159423828125, -325.468994140625}, {359.0523681640625, 817.4888916015625}}}
300{{{564.43435948662466, 47.034527772832369}, {627.6910400390625, 81.144287109375}}}
301{{{699.34014109378302, 79.147174806567705}, {627.6910400390625, 81.144287109375}}}
302</div>
303
304<div id="quad4a">
305{{{187.410400390625, -343.557373046875}, {-752.7930908203125, 431.57177734375}, {387.663330078125, 701.281982421875}}},
306{{{187.410400390625, -343.557373046875}, {-86.16302490234375, -366.027099609375}, {-468.3883056640625, -25.736572265625}}}
307</div>
308
309<div id="quad0">
310{{{-708.0077926931004413, -154.6166947224404566}, {-701.0429781735874712, -128.8517387364408933}, {505.58447265625, -504.9130859375}}},
311{{{-708.0077926931004413, -154.6166947224404566}, {-721.5125661899801344, -174.4028951148648048}, {-32.39227294921875, -906.3277587890625}}}
312{{{-707.8363172079705237, -154.25350453766481}, {-708.0077926931004413, -154.6166947224404566}}}
313{{{-708.1792267111628689, -154.9799046892118213}, {-708.0077926931004413, -154.6166947224404566}}}
314</div>
315
316<div id="quad999">
317{{{-708.00779269310044, -154.61669472244046}, {-707.92342686353186, -154.30459999551294}, {505.58447265625, -504.9130859375}}},
318{{{-708.00779269310044, -154.61669472244046}, {-708.1713780141481, -154.85636789757655}, {-32.39227294921875, -906.3277587890625}}}
319{{{-708.0077672218041, -154.61664072892336}, {-708.00779269310044, -154.61669472244046}}}
320{{{-708.00781827681976, -154.61674895426012}, {-708.00779269310044, -154.61669472244046}}}
321</div>
322
323<div id="quad113">
324{{{425.018310546875, -866.61865234375}, {-918.76531982421875, 209.05322265625}, {964.34716796875, 199.52587890625}}},
325{{{425.018310546875, -866.61865234375}, {703.10693359375, -955.0738525390625}, {-952.24664306640625, -717.94775390625}}}
326</div>
327
328<div id="quad136">
329{{{178.1549072265625, 62.724609375}, {541.3643798828125, 223.823486328125}, {-446.77471923828125, -15.990478515625}}},
330{{{178.1549072265625, 62.724609375}, {-347.14031982421875, -834.27191162109375}, {-495.138885498046875, 96.476806640625}}}
331</div>
332
333<div id="quad206">
334{{{-503.007415771484375, -318.59490966796875}, {-798.330810546875, -881.21630859375}, {-127.2027587890625, 769.6160888671875}}},
335{{{-503.007415771484375, -318.59490966796875}, {-153.6217041015625, -776.896728515625}, {-378.43701171875, -296.3197021484375}}}
336{{{-468.9176053311167607, -89.39573455985038208}, {-503.007415771484375, -318.59490966796875}}}
337{{{-356.1573846604815685, -497.6768266540607328}, {-503.007415771484375, -318.59490966796875}}}
338{{{-559.0376987487186398, -420.2054253473417589}, {-503.007415771484375, -318.59490966796875}}}
339{{{-431.6586315464865606, -409.8353728177644371}, {-503.007415771484375, -318.59490966796875}}}
340</div>
341
342<div id="quad640">
343{{{412.260498046875, 49.193603515625}, {838.97900390625, 86.9951171875}, {427.7896728515625, -605.6881103515625}}},
344{{{412.260498046875, 49.193603515625}, {-995.54583740234375, 990.032470703125}, {-881.18670654296875, 461.211669921875}}}
345</div>
346
347<div id="quad3160">
348{{{426.645751953125, 813.79150390625}, {-387.23828125, -588.89483642578125}, {792.4261474609375, -704.4637451171875}}},
349{{{426.645751953125, 813.79150390625}, {19.24896240234375, -416.09906005859375}, {233.8497314453125, 350.778564453125}}}
350</div>
351
352<div id="quad35237">
353{{{-770.8492431640625, 948.2369384765625}, {-853.37066650390625, 972.0301513671875}, {-200.62042236328125, -26.7174072265625}}},
354{{{-770.8492431640625, 948.2369384765625}, {513.602783203125, 578.8681640625}, {960.641357421875, -813.69757080078125}}}
355</div>
356
357<div id="quad37226">
358{{{563.8267822265625, -107.4566650390625}, {-44.67724609375, -136.57452392578125}, {492.3856201171875, -268.79644775390625}}},
359{{{563.8267822265625, -107.4566650390625}, {708.049072265625, -100.77789306640625}, {-48.88226318359375, 967.9022216796875}}}
360</div>
361
362<div id="quad67242">
363{{{598.857421875, 846.345458984375}, {-644.095703125, -316.12921142578125}, {-97.64599609375, 20.6158447265625}}},
364{{{598.857421875, 846.345458984375}, {715.7142333984375, 955.3599853515625}, {-919.9478759765625, 691.611328125}}}
365</div>
366
367<div id="quad208">
368{{{481.1463623046875, -687.09613037109375}, {643.64697265625, -951.9462890625}, {162.5869140625, 698.7342529296875}}},
369{{{481.1463623046875, -687.09613037109375}, {171.8175048828125, -919.07977294921875}, {153.3433837890625, -587.43072509765625}}}
370</div>
371
372<div id="quad8a">
373{{{344.2755126953125, -689.900390625}, {743.6728515625, 512.8448486328125}, {928.598388671875, 111.946044921875}}},
374{{{344.2755126953125, -689.900390625}, {-950.03106689453125, -511.25741577148437}, {850.8173828125, 798.4874267578125}}}
375</div>
376
377<div id="quad8b">
378{{{344.2755126953125, -689.900390625}, {928.598388671875, 111.946044921875}, {743.6728515625, 512.8448486328125}}},
379{{{344.2755126953125, -689.900390625}, {-950.03106689453125, -511.25741577148437}, {850.8173828125, 798.4874267578125}}}
380</div>
381
382<div id="quad8741">
383{{{944.9024658203125, 939.454345703125}, {-971.06219482421875, -914.24395751953125}, {-878.764404296875, -297.61602783203125}}},
384{{{944.9024658203125, 939.454345703125}, {-838.96612548828125, -785.837646484375}, {-126.80029296875, 921.1981201171875}}}
385{{{107.03238931174118, 218.460612766889}, {944.9024658203125, 939.454345703125}}}
386{{{-292.72752350740279, 99.917575976335598}, {944.9024658203125, 939.454345703125}}}
387</div>
388
389<div id="quad89987">
390{{{939.4808349609375, 914.355224609375}, {-357.7921142578125, 590.842529296875}, {736.8936767578125, -350.717529296875}}},
391{{{939.4808349609375, 914.355224609375}, {-182.85418701171875, 634.4552001953125}, {-509.62615966796875, 576.1182861328125}}}
392</div>
393
394<div id="simplifyQuadratic36">
395{{{1.9474306106567383, 2.3777823448181152}, {1.9234547048814592, 2.2418855043499213}, {1.8885438442230225, 2.1114561557769775}}}
396{{{1.9474306106567383, 2.3777823448181152}, {2.0764266380046235, 2.2048800651418379}, {1.8888888359069824, 2.1111111640930176}}}
397</div>
398
399<div id="simplifyQuadratic58">
400{{326.236786,205.854996}, {329.104431,231.663818}, {351.512085,231.663818}}
401{{303.12088,141.299606}, {330.463562,217.659027}}
402</div>
403
404<div id="simplifyQuadratic58a">
405{{{326.23678588867188, 205.85499572753906}, {328.04376176056422, 222.11778818951981}, {337.6092529296875, 228.13298034667969}
406{{{303.12088012695312, 141.29960632324219}, {330.46356201171875, 217.65902709960937}
407</div>
408
409<div id="quadratic58again">
410{{322.935669,231.030273}, {312.832214,220.393295}, {312.832214,203.454178}}
411{{322.12738,233.397751}, {295.718353,159.505829}}
412</div>
413
414<div id="simplifyQuadratic56">
415{{{380.29449462890625, 140.44486999511719}, {387.29080200195312, 136.67460632324219}, {396.0399169921875, 136.67460632324219}}}
416{{{380.29449462890625, 140.44486999511719}, {388.29925537109375, 136.67460632324219}, {398.16494750976562, 136.67460632324219}}}
417{{{380.29449462890625, 140.44486999511719}, {387.692810, 137.858429}}}
418</div>
419
420<div id="simplifyQuadratic56a">
421{{{380.29449462890625, 140.44486999511719}, {387.29079954793264, 136.67460632324219}, {396.0399169921875, 136.67460632324219}}}
422{{{380.29449462890625, 140.44486999511719}, {388.29925767018653, 136.67460632324219}, {398.16494750976562, 136.67460632324219}}}
423{{fX=380.29449462890625 fY=140.44486999511719 }, {fX=398.16494750976562 fY=136.67460632324219 }} }
424{{fX=380.29449462890625 fY=140.44486999511719 }, {fX=396.03991699218750 fY=136.67460632324219 }}
425</div>
426
427<div id="simplifyQuadratic27">
428{{{1, 1}, {1, 0.666666687f}, {0.888888896f, 0.444444448f}}}
429{{{1, 1}, {1, 0.5f}, {0, 0}}}
430{{fX=1.0000000000000000 fY=1.0000000000000000 }, {fX=0.00000000000000000 fY=0.00000000000000000 }} }
431{{fX=1.0000000000000000 fY=1.0000000000000000 }, {fX=0.88888889551162720 fY=0.44444444775581360 }} }
432</div>
433
434<div id="cubicOp7d">
435{{{0.7114982008934021, 1.6617077589035034}, {0.51239079236984253, 1.4952657222747803}, {0.27760171890258789, 1.2776017189025879}, {0, 1}}}
436{{{0.7114982008934021, 1.6617077589035034}, {0.20600014925003052, 1.7854888439178467}, {9.8686491813063348e-017, 1.9077447652816772}, {0, 1}}}
437</div>
438
439<div id="cubicOp25i">
440{{{3.3856770992279053, 1.6298094987869263}, {3.777235186270762, 1.2744716237277114}, {3.7191683314895783, 1.4127666421509713}, {3.3995792865753174, 1.6371387243270874}}}
441{{{3.3856770992279053, 1.6298094987869263}, {3.3902986605112582, 1.6322361865810757}, {3.3949326825525121, 1.6346792563210237}, {3.3995792865753174, 1.6371387243270874}}}
442{{3.3856770992279053, 1.6298094987869263 }, {3.3995792865753174, 1.6371387243270874 }}
443</div>
444
445<div id="eldorado1">
446{{{1006.69513f, 291}, {1023.26367f, 291}, {1033.84021f, 304.431458f}, {1030.31836f, 321}}}
447{{{1030.318359375, 321}, {1036.695068359375, 291}}}
448{{fX=1030.3183593750000 fY=321.00000000000000 }, {fX=1006.6951293945312 fY=291.00000000000000 }} }
449</div>
450
451<div id="carpetplanet1">
452{{fX=67.000000000000000, 913.00000000000000 }, {194.00000000000000, 1041.0000000000000 }} }
453{{fX=67.000000000000000, 913.00000000000000 }, {67.662002563476562, 926.00000000000000 }} }
454{{{67, 913}, {67, 917.388977f}, {67.223999f, 921.726013f}, {67.6620026f, 926}}}
455{{{67, 913}, {67, 983.692017f}, {123.860001f, 1041}, {194, 1041}}}
456{{{67, 913}, {67.17070902440698, 919.69443917507760}}}
457</div>
458
459<div id="cubicOp104">
460{{{2.25, 2.5}, {4.5, 1}}}
461{{{2.25, 2.5}, {3.0833333333333321, 1.9999999999999973}, {4.0277778307596899, 1.2777777777777759}, {4.8611111640930176, 1}}}
462{{{2.25, 2.5}, {1.9476099234472042, 2.6814340459316774}, {1.6598502000264239, 2.8336073904096661}, {1.3973386287689209, 2.9246666431427002}}}
463{{{2.25, 2.5}, {1.2674896717071533, 3.1550068855285645}}}
464</div>
465
466<div id="cubicOp105">
467{{{2.4060275554656982, 3.4971563816070557}, {2.9702522134213849, 4.2195279679982622}, {3.8172613958721247, 5.0538091166976979}, {5, 6}}}
468{{{2.4060275554656982, 3.4971563816070557}, {3.4194286958002023, 3.5574883660881684}, {4.0077197935900575, 2.6628073781813661}, {2.2602717876434326, 0.33545622229576111}}}
469</div>
470
471<div id="cubicOp106">
472{{{0.80825299024581909, 1.9691258668899536}, {0.8601454496383667, 1.9885541200637817}, {0.92434978485107422, 2}, {1, 2}}}
473{{{0.80825299024581909, 1.9691258668899536}, {2.2400102615356445, 3.5966837406158447}, {2.5486805438995361, 3.362929105758667}, {2.494147777557373, 2.5976591110229492}}}
474{{{0.80825299024581909, 1.9691258668899536}, {2.494147777557373, 2.5976591110229492}}}
475{{{0.80825299024581909, 1.9691258668899536}, {1, 2}}}
476</div>
477
478<div id="cubicOp109">
479{{{5, 4}, {5.443139240552143931, 3.556860759447856069}, {5.297161243696338673, 3.702838775882067335}, {4.649086475372314453, 3.654751062393188477}}}
480{{{5, 4}, {4.876459521889748849, 3.876459521889748849}, {4.759596556247283949, 3.761504502886134915}, {4.649086475372314453, 3.654751062393188477}}}
481</div>
482
483<div id="skpwww_joomla_org_23">
484{{{421, 378}, {421, 380.209137f}, {418.761414f, 382}, {416, 382}}}
485{{{320, 378}, {421, 378.000031f}}}
486{{{421, 378.000031f}, {421, 383}}}
487{{{416, 383}, {418.761414f, 383}, {421, 380.761414f}, {421, 378}}}
488</div>
489
490<div id="xop1i">
491{{5.000,1.000}, {5.191,0.809}, {5.163,0.837}, {4.993,1.000}}
492{{5.000,1.000}, {4.968,1.024}}
493{{5.000,1.000}, {4.998,1.000}, {4.995,1.000}, {4.993,1.000}}
494</div>
495
496<div id="xop1u">
497{{3.500,3.500}, {3.000,4.000}, {2.500,4.500}, {1.000,4.000}}
498{{3.500,3.500}, {3.113,3.887}, {2.725,4.275}, {2.338,3.732}}
499</div>
500
501<div id="xOp2i">
502{{{2, 3}, {1.3475509011665685, 4.9573472965002949}, {2.8235509286078759, 3.5091759365574173}, {3.6505906581878662, 1.9883773326873779}}}
503{{{2, 3}, {2.4604574005585795, 2.654656949581065}, {3.0269255632437986, 2.3093137214344743}, {3.6505906581878662, 1.9883773326873779}}}
504{{{2, 3}, {1.0000000000000013, 3.7500000000000004}, {0.500000000000001, 4.5}, {1, 5}}}
505</div>
506
507<div id="testQuadratic56">
508{{{380.29449462890625, 140.44486999511719}, {379.59701460635523, 140.8207374882179}, {378.91729736328125, 141.23385620117187}}}
509{{{380.29449462890625, 140.44486999511719}, {387.29079954793264, 136.67460632324219}, {396.0399169921875, 136.67460632324219}}}
510{{{380.29449462890625, 140.44486999511719}, {388.29925767018653, 136.67460632324219}, {398.16494750976562, 136.67460632324219}}}
511</div>
512
513<div id="testQuad15">
514{{{1, 3}, {1, 1}}}
515{{{1, 3}, {0, 0}}}
516{{{1, 3}, {2, 0}, {0, 0}}}
517</div>
518
519<div id="testQuad21">
520{{{0, 0}, {1, 1}}}
521{{{0, 0}, {3, 0}, {2, 3}}}
522{{{0, 0}, {2, 3}}}
523{{{0, 0}, {2, 1}}}
524</div>
525
526<div id="testQuad22">
527{{{0, 0}, {1.2000000476837158, 0.80000001192092896}}}
528{{{0, 0}, {2, 0}}}
529{{{0, 0}, {0, 1}, {3, 2}}}
530{{{0, 0}, {1, 1}}}
531</div>
532
533<div id="testQuad23">
534{{{1, 3}, {1.9090908914804459, 1.1818182170391081}, {0.33884298801422119, 1.0165289640426636}}}
535{{{1, 3}, {0.33884298801422119, 1.0165289640426636}}}
536{{{1, 3}, {3, 0}}}
537</div>
538
539<div id="cubicOp35d">
540{{{2.211416482925415, 1.6971458196640015}, {1.2938009262874868, 2.8273619288830005}, {0.64690048634813535, 3.5876019453925414}, {0, 1}}}
541{{{2.211416482925415, 1.6971458196640015}, {1.0082962512969971, 1.997925877571106}}}
542{{{2.211416482925415, 1.6971458196640015}, {5, 1}}}
543</div>
544
545<div id="skpnational_com_au81">
546{{{1110.7071533203125, 817.29290771484375}, {1110.9998779296875, 817.58587646484375}, {1111, 818}}}
547{{{1110.7071533203125, 817.29290771484375}, {1110.526180767307778, 817.1119214508684081}, {1110.276144384999725, 817}, {1110, 817}}}
548{{{1110.7071533203125, 817.29290771484375}, {1110.888097894721341, 817.4738660071997174}, {1111, 817.7238677851287321}, {1111, 818}}}
549{{{1110.7071533203125, 817.29290771484375}, {1110.4140625, 817.0001220703125}, {1110, 817}}}
550</div>
551
552<div id="cubicOp85d">
553{{{1.0648664236068726, 2.9606373310089111}, {0.80208036362614099, 2.7936484180272374}, {0.49170560730211144, 2.2292640182552783}, {0, 1}}}
554{{{1.0648664236068726, 2.9606373310089111}, {0.6261905430171294, 3.2248910899179175}, {0.38860045191888659, 2.9430022595944321}, {0, 1}}}
555{{{1.0648664236068726, 2.9606373310089111}, {1.4282355765013004, 3.191542348791669}, {1.7006143409852195, 2.6626209548338378}, {2.2355968952178955, 2.0810616016387939}}}
556{{{1.0648664236068726, 2.9606373310089111}, {1.3437142856601656, 2.7926622975690494}, {1.7038131304059798, 2.4040122748806132}, {2.2355968952178955, 2.0810616016387939}}}
557</div>
558
559<div id="testQuads22">
560{{{0, 0}, {1.20000004768371582, 0.8000000119209289551}}}
561{{{0, 0}, {2, 0}}}
562{{{0, 0}, {0, 1}, {3, 2}}}
563{{{0, 0}, {1, 1}}}
564</div>
565
566<div id="cubicOp59d">
567{{{4, 1}, {4, 0.37698365082686142}, {4.3881493046286568, 2.4710128800004547}, {3.4716842174530029, 2.9292664527893066}}}
568{{{4, 1}, {0, 1}}}
569</div>
570
571<div id="findFirst1">
572{{{2.5767931938171387, 0.88524383306503296}, {2.4235948002142855, 0.88692501490384834}, {2.2328897699358898, 0.92237007668803672}, {2, 1}}}
573{{{2.5767931938171387, 0.88524383306503296}, {1.6008643534817426, 1.1609015907463158}, {1.1200849961943122, 1.8138386966264941}, {0.75343161821365356, 2.7170474529266357}}}
574{{{2.5767931938171387, 0.88524383306503296}, {4.0492746201577932, 0.86908498848619054}, {2.0567957107800288, 3.9721309710522448}, {0.75343161821365356, 2.7170474529266357}}}
575{{{2.5767931938171387, 0.88524383306503296}, {3.3470152174198557, 0.66768936887879282}, {4.4256496583071421, 0.68512993166142844}, {6, 1}}}
576{{{2.57679319, 0.885243833}, {5.15358639, 0.885243833}}}
577</div>
578
579<div id="testQuads54">
580{{1.000,1.000}, {1.500,0.500}, {1.500,0.250}}
581{{1.000,1.000}, {1.667,0.333}}
582{{1.000,1.000}, {2.000,3.000}}
583</div>
584
585<div id="testQuads45">
586{{{3, 3}, {3, 2.7999999523162842}, {2.880000114440918, 2.6400001049041748}}}
587{{{3, 3}, {3, 2}, {2, 0}}}
588{{{3, 3}, {2, 0}}}
589{{{3, 3}, {2.880000114440918, 2.6400001049041748}}}
590</div>
591
592<div id="testQuads59">
593{{{3, 1}, {3, 0}}}
594{{{3, 1}, {2.6666667461395264, 0.66666668653488159}}}
595{{{3, 1}, {2.8000003099441542, 1.1999996900558463}, {2.6800000667572021, 1.3600000143051147}}}
596{{{3, 1}, {2.6666667461395264, 1.3333333730697632}}}
597</div>
598
599<div id="skpcarrot_is24">
600{{{1020.08099, 672.161987}, {1020.08051, 651.450988}, {1011.68576, 632.700988}, {998.113511, 619.128738}}}
601{{{1020.08099, 672.161987}, {1019.27607, 640.291301}, {998.113511, 619.128738}}}
602{{{1020, 672}, {1020, 651.289307}, {1012.67767, 633.611633}, {998.03302, 618.96698}}}
603{{{1020, 672}, {1020, 640.93396}, {998.03302, 618.96698}}}
604</div>
605
606<div id="skpcarrot_is24a">
607{{{1020, 672}, {1020, 651.289307}, {1012.67767, 633.611633}, {998.03302, 618.96698}}}
608{{{1020, 672}, {1020, 640.93396}, {998.03302, 618.96698}}}
609</div>
610
611<div id="skpcarrot_is24b">
612{{{1020.08099, 672.161987}, {1020.08051, 651.450988}, {1011.68576, 632.700988}, {998.113511, 619.128738}}}
613{{{1020.08099, 672.161987}, {1019.27607, 640.291301}, {998.113511, 619.128738}}}
614</div>
615
616<div id="skpcarrot_is24c">
617{{{{1020.08099,672.161987}, {1020.08002,630.73999}, {986.502014,597.161987}, {945.080994,597.161987}}},
618{{{1020,672}, {1020,640.93396}, {998.03302,618.96698}}},
619</div>
620
621<div id="skpcarrot_is24d">
622{{{1020.08099, 672.161987}, {1019.27607, 640.291301}, {998.113511, 619.128738}}}
623{{{1020, 672}, {1020, 640.93396}, {998.03302, 618.96698}}}
624</div>
625
626<div id="skpcarrot_is24e">
627{{{{1020.08099,672.161987}, {1020.08002,630.73999}, {986.502014,597.161987}, {945.080994,597.161987}}},
628{{{1020.08099, 672.161987}, {1019.27607, 640.291301}, {998.113511, 619.128738}}}
629{{{1020, 672}, {1020, 640.93396}, {998.03302, 618.96698}}}
630</div>
631
632<div id="slop1">
633{{{-378.22698974609375, -987.8935546875}, {-47.53326416015625, 482.7139892578125}, {-626.4708251953125, -338.62969970703125}, {-847.94854736328125, -861.42230224609375}}}
634{{{-378.61790442466736, -987.49146723747253}, {-282.51787429804051, -556.39065286764685}, {-278.55106873374694, -364.17984985308294}}}
635{{{-305.5273847156202, -615.99979442705023}, {-305.04071954345704, -612.87932617187505}}}
636</div>
637
638qT=0.98917687 cT=0.788725084 dist=312.188493 cross=-40759.4852
639<div id="slop2">
640{{{79.5137939,-249.867188}, {260.778931,-561.349854}, {343.375977,-472.657898}, {610.251465,97.8208008}}}
641{{{312.993284,-406.178762}, {418.053808,-326.9483}, {610.036929,97.2408578}}}
642{{{463.107827,-200.015424}, {602.008878,79.5702581}}}
643</div>
644
645qT=0.0192863061 cT=0.241285225 dist=652.007881 cross=528435.665
646<div id="slop3">
647{{{-895.015015,-523.545288}, {223.166992,-999.644531}, {615.428711,-767.162109}, {605.479736,480.355713}}}
648{{{-894.932414,-523.605499}, {-66.4040558,-889.938889}, {278.515212,-667.684158}}}
649{{{-207.851881,-740.109296}, {-831.819002,-550.955104}}}
650</div>
651
652qT=0.0245724525 cT=0.231316637 dist=407.103004 cross=-46286.5686
653<div id="slop4">
654{{{876.492798,-849.716187}, {519.430908,-288.374207}, {187.2771,314.324341}, {335.363403,533.086548}}}
655{{{876.323133,-849.535824}, {594.868958,-415.229224}, {416.667192,-30.0277669}}}
656{{{638.343827,-458.798274}, {849.023879,-807.14691}}}
657</div>
658
659qT=0.000316393778 cT=0.248252634 dist=489.678412 cross=-57352.7653
660<div id="slop5">
661{{{876.492798,-849.716187}, {519.430908,-288.374207}, {187.2771,314.324341}, {335.363403,533.086548}}}
662{{{876.147506,-849.184429}, {593.963775,-414.437342}, {416.842819,-30.3791618}}}
663{{{622.139843,-430.512844}, {876.135915,-849.166571}}}
664</div>
665
666qT=0.989562776 cT=0.760518485 dist=211.50589 cross=134901.42
667<div id="slop6">
668{{{876.492798,-849.716187}, {519.430908,-288.374207}, {187.2771,314.324341}, {335.363403,533.086548}}}
669{{{416.141554,-30.4534414}, {237.846068,356.664216}, {335.719378,533.692585}}}
670{{{305.345404,315.701195}, {331.440368,525.591152}}}
671</div>
672
673qT=0.0978245708 cT=0.397465904 dist=959.737748 cross=158093.403
674<div id="slop7">
675{{{895.800171,-222.213013}, {-528.78833,526.47644}, {-967.299927,776.05603}, {-611.228027,319.934814}}}
676{{{629.666617,-82.159942}, {-661.943328,620.81113}, {-723.44072,537.121833}}}
677{{{-347.560585,421.003177}, {507.062151,-15.707855}}}
678</div>
679
680qT=0.169803964 cT=0.389326872 dist=658.039939 cross=107865.424
681<div id="slop8">
682{{{895.800171,-222.213013}, {-528.78833,526.47644}, {-967.299927,776.05603}, {-611.228027,319.934814}}}
683{{{629.536617,-81.7990275}, {-662.457623,620.485316}, {-723.31072,536.760918}}}
684{{{-330.996421,413.091598}, {257.080063,117.824582}}}
685</div>
686
687qT=0.0863836955 cT=0.387901231 dist=986.24777 cross=157348.113
688<div id="slop9">
689{{{895.800171,-222.213013}, {-528.78833,526.47644}, {-967.299927,776.05603}, {-611.228027,319.934814}}}
690{{{629.248316,-81.8984216}, {-662.339696,620.351182}, {-723.022419,536.860313}}}
691{{{-328.058099,411.68229}, {549.399512,-38.5985162}}}
692</div>
693
694qT=0.175359403 cT=0.390420692 dist=640.051938 cross=105488.084
695<div id="slop10">
696{{{895.800171,-222.213013}, {-528.78833,526.47644}, {-967.299927,776.05603}, {-611.228027,319.934814}}}
697{{{629.760605,-81.9577046}, {-661.301606,620.029216}, {-723.534707,536.919596}}}
698{{{-333.243516,414.168229}, {238.961251,127.37878}}}
699</div>
700
701qT=0.0986412358 cT=0.382365595 dist=921.951857 cross=145651.761
702<div id="slop11">
703{{{895.800171,-222.213013}, {-528.78833,526.47644}, {-967.299927,776.05603}, {-611.228027,319.934814}}}
704{{{629.919588,-82.1841825}, {-662.488256,620.04494}, {-723.693691,537.146073}}}
705{{{-316.541641,406.142013}, {504.067361,-14.0913644}}}
706</div>
707
708qT=0.146746849 cT=0.391456086 dist=750.006927 cross=123679.094
709<div id="slop12">
710{{{895.800171,-222.213013}, {-528.78833,526.47644}, {-967.299927,776.05603}, {-611.228027,319.934814}}}
711{{{629.712675,-82.0366321}, {-661.487948,620.191832}, {-723.486777,536.998523}}}
712{{{-335.364605,415.183549}, {334.079508,77.0194322}}}
713</div>
714
715qT=0.00196158131 cT=0.20357489 dist=466.080185 cross=241741.95
716<div id="slop13">
717{{{-627.671509,-359.277039}, {222.414551,-791.598328}, {390.603027,-581.903687}, {-21.7962036,560.33728}}}
718{{{-627.675958,-359.282959}, {-52.012535,-659.029798}, {116.967835,-524.756101}}}
719{{{-192.427848,-541.033993}, {-622.696937,-361.871356}}}
720</div>
721
722qT=0.948725598 cT=0.744200608 dist=699.694313 cross=179509.878
723<div id="slop14">
724{{{-362.331848,427.292603}, {634.418701,-661.946533}, {438.438599,-626.147278}, {-893.060425,214.243408}}}
725{{{259.978301,-393.549091}, {181.692599,-474.452437}, {-892.389834,213.689096}}}
726{{{-95.1310032,-267.365579}, {-696.89984,89.6307768}}}
727</div>
728
729qT=0.971677129 cT=0.755306143 dist=771.998962 cross=189468.817
730<div id="slop15">
731{{{-362.331848,427.292603}, {634.418701,-661.946533}, {438.438599,-626.147278}, {-893.060425,214.243408}}}
732{{{259.662278,-393.355886}, {181.612843,-473.935297}, {-892.073812,213.495892}}}
733{{{-120.438346,-253.451518}, {-782.461182,143.673352}}}
734</div>
735
736qT=0.571797795 cT=0.773951562 dist=495.560209 cross=221091.889
737<div id="slop16">
738{{{447.192383,-883.210205}, {359.794678,-987.765808}, {755.427612,-754.328735}, {963.672119,746.545776}}}
739{{{635.795655,-580.726915}, {810.704547,-228.491534}, {963.345162,745.921688}}}
740{{{801.470356,-87.7105789}, {646.551495,-558.433498}}}
741</div>
742
743qT=0.579236693 cT=0.782683167 dist=281.750564 cross=65125.1655
744<div id="slop17">
745{{{-931.259155,-883.589966}, {-485.682007,-615.793701}, {-68.5913696,-928.695923}, {431.499268,-810.584778}}}
746{{{-177.087049,-804.265618}, {110.452267,-866.525236}, {430.718323,-810.414444}}}
747{{{116.080189,-836.904702}, {-164.080748,-807.017753}}}
748</div>
749
750qT=0.0102075348 cT=0.2448024 dist=855.408492 cross=463614.179
751<div id="slop18">
752{{{-867.011292,844.139282}, {-136.156799,-281.244263}, {583.27771,-926.761414}, {998.710205,6.19244385}}}
753{{{-866.7221,843.65105}, {-308.756317,-34.8353977}, {183.843514,-346.222431}}}
754{{{-336.612013,120.039627}, {-844.283739,808.5112}}}
755</div>
756
757qT=0.473968306 cT=0.266805943 dist=567.851844 cross=-461509.104
758<div id="slop19">
759{{{-867.011292,844.139282}, {-136.156799,-281.244263}, {583.27771,-926.761414}, {998.710205,6.19244385}}}
760{{{-867.218781,844.133445}, {-310.496711,-35.0458119}, {184.340195,-346.704825}}}
761{{{-290.018097,66.7065093}, {132.536746,-312.639141}}}
762</div>
763
764qT=0.0232589401 cT=0.241085469 dist=789.989464 cross=428119.544
765<div id="slop20">
766{{{-867.011292,844.139282}, {-136.156799,-281.244263}, {583.27771,-926.761414}, {998.710205,6.19244385}}}
767{{{-866.942271,843.928587}, {-309.178151,-34.0018497}, {184.063685,-346.499968}}}
768{{{-344.507162,129.265381}, {-815.30119,763.644082}}}
769</div>
770
771<div id="skpnamecheap_405">
772{{{141.008835f, 837.9646f}, {141.235291f, 1109.05884f}}}
773{{{141, 842}, {141.14502f, 1000}}}
774{{{141.14502f, 1000}, {140, 1000}}}
775</div>
776
777<div id="skpwww_dealnews_com_315">
778{{{969.87066650390625, 4279.810546875}, {967.7166748046875, 4260}}}
779{{{969.87066650390625, 4279.810546875}, {969.866972698829386, 4279.809233889284769}, {969.88751220703125, 4279.81640625}}}
780{{{969.87066650390625, 4279.810546875}, {970, 4281}}}
781{{{969.87066650390625, 4279.810546875}, {968.9217161046863112, 4279.473236623693992}, {968.17156982421875, 4278.53564453125}}}
782{{{969.8706626470486754, 4279.810469740555163}, {969.8790796016525064, 4279.813461598796493}, {969.88751220703125, 4279.81640625}}}
783</div>
784
785<div id="skpwww_dealnews_com_315_a">
786{{{969.8706626470486754, 4279.810469740555163}, {969.8790796016525064, 4279.813461598796493}, {969.88751220703125, 4279.81640625}}}
787{{{969.87066650390625, 4279.810546875}, {969.8790834585100811, 4279.81353873324133}}}
788{{{969.88751220703125, 4279.81640625}, {969.8790796016525064, 4279.813461598796493}}}
789</div>
790
791<div id="testQuads60">
792{{{2, 2}, {1.977731304590550021, 1.97773134708404541}, {1.95645439624786377, 1.95546269416809082}}}
793{{{2, 2}, {2, 3}}}
794{{{2, 2}, {2, 1.960000038146972656}}}
795{{{2, 2}, {1.955341815948486328, 1.955341815948486328}}}
796</div>
797
798<div id="testQuads60_a">
799{{{2, 0}, {1, 1}, {2, 2}}}
800{{{2, 2}, {0, 0}}}
801</div>
802
803<div id="testQuads60_b">
804{{2,1}, {0,2}, {3,2}},
805{{3,2}, {2,3}},
806{{2,3}, {2,1}},
807{{0,0}, {2,0}},
808{{2,0}, {1,1}, {2,2}},
809{{2,2}, {0,0}},
810</div>
811
812<div id="skpelpais_com_18">
813{{183,8507}, {552,8506.99023}},
814{{552,8506.99023}, {552,8508}},
815{{552,8508}, {183,8508}},
816{{183,8508}, {183,8507}},
817op intersect
818{{183,8508}, {183,8506.99023}},
819{{183,8506.99023}, {552,8507}},
820{{552,8507}, {552,8508}},
821</div>
822
823<div id="skpwww_cityads_ru_249">
824{{{1000, 10.4003992f}, {1000, 13.3527431f}}}
825{{{1000, 13.3527431f}, {999.917603f, 13.2607508f}, {999.82843f, 13.1715727f}}}
826{{{1000, 13}, {999.969971f, 37.0299988f}}}
827</div>
828
829<div id="skpwww_maturesupertube_com_21">
830    {{{{3.87867975f, 11831.8789f}, {4.7573595f, 11831}, {6, 11831}}},
831     {{{2, 11830}, {4.5f, 11832.5f}}}},
832</div>
833
834<div id="loop1">
835{{1, 4, 2, 6, 0, 5, 4.5f, 4.33333302f
836{{2, 6, 0, 5, 4.5f, 4.33333302f, 1, 4
837{{{3, 5}, {2.33333325f, 4.33333349f}, {3.83333325f, 3.83333349f}, {2, 4}}}
838{{{2, 4}, {3, 5}, {2.33333325f, 4.33333349f}, {3.83333325f, 3.83333349f}}}
839</div>
840
841<div id="serp1">
842{{{0.55431359440952721, 2.1086271888190544}, {0.1588954256872922, 2.3078315988141811}, {0.57446808656344528, 2.1489361731268914}, {0, 1}}}
843{{{0.55431359440952721, 2.1086271888190544}, {0.1588954256872922, 2.3078315988141811}, {0.57446808656344528, 2.1489361731268914}, {0, 1}}}
844</div>
845<div id="serp2">
846{{{4.0946656649135988, 3.283996994740797}, {4.1983471074380168, 2.1074380165289259}, {4.5454545454545459, 1.3636363636363635}, {4, 3}}}
847{{{4.0946656649135988, 3.283996994740797}, {4.1983471074380168, 2.1074380165289259}, {4.5454545454545459, 1.3636363636363635}, {4, 3}}}
848</div>
849<div id="serp3">
850{{{2.2015477442471254, 1.1371488033013577}, {2.3167674423028526, 0.68323255769714741}, {2.4076432497431028, 0.59235675025689716}, {2, 1}}}
851{{{2.2015477442471254, 1.1371488033013577}, {2.3167674423028526, 0.68323255769714741}, {2.4076432497431028, 0.59235675025689716}, {2, 1}}}
852</div>
853
854<div id="skpwww_seopack_blogspot_com_2153">
855{{{924, 245.472672f}, {1143, 247}}}
856{{{1000, 246}, {927.340759f, 245.505722f}}}
857{{{999.892212f, 246}, {927.340759f, 245.505722f}}}
858</div>
859
860<div id="self1">
861{{{2, 3}, {0, 4}, {3, 2}, {5, 3}}}
862{{{2, 3}, {0, 4}, {3, 2}, {5, 3}}}
863</div>
864
865<div id="skpwww_pindosiya_com_99">
866{{{901.0869140625, 547}, {899, 556}}}
867{{{900.0235595703125, 551.60284423828125}, {900.06072998046875, 551.29705810546875}, {900.15655517578125, 551.0157470703125}}}
868</div>
869
870<div id="cubicLineMiss1">
871{{{-634.60540771484375, -481.262939453125}, {266.2696533203125, -752.70867919921875}, {-751.8370361328125, -317.37921142578125}, {-969.7427978515625, 824.7255859375}}}
872{{{-287.9506133720805678, -557.1376476615772617}, {-285.9506133720805678, -557.1376476615772617}}}
873</div>
874
875<div id="cubicLineMiss2">
876{{{-818.4456787109375, 248.218017578125}, {944.18505859375, -252.2330322265625}, {957.3946533203125, -45.43280029296875}, {-591.766357421875, 868.6187744140625}}}
877{{{435.1963493079119871, -16.42683763243891093}, {437.1963493079119871, -16.42683763243891093}}}
878</div>
879
880<div id="cubicLineMiss3">
881{{{-818.4456787109375, 248.218017578125}, {944.18505859375, -252.2330322265625}, {957.3946533203125, -45.43280029296875}, {-591.766357421875, 868.6187744140625}}}
882{{{397.5007682490800676, -17.35020084021140008}, {399.5007682490800676, -17.35020084021140008}}}
883</div>
884
885<div id="cubicLineMiss4">
886{{{-652.660888671875, -384.6475830078125}, {-551.7723388671875, -925.5025634765625}, {-321.06658935546875, -813.10345458984375}, {142.6982421875, -47.4503173828125}}}
887{{{-478.4372049758064236, -717.868282575075682}, {-476.4372049758064236, -717.868282575075682}}}
888</div>
889
890<div id="cubicLineErr1">
891{{{-954.4322509765625, 827.2216796875}, {-420.24017333984375, -7.80560302734375}, {799.134765625, -971.4295654296875}, {-556.23486328125, 344.400146484375}}}
892
893{{{58.57411390280688579, -302.8879316712078662}, {60.57411390280688579, -302.8879316712078662}}}
894</div>
895
896<div id="cubicLineErr2">
897{{{-634.60540771484375, -481.262939453125}, {266.2696533203125, -752.70867919921875}, {-751.8370361328125, -317.37921142578125}, {-969.7427978515625, 824.7255859375}}}
898{{{-287.95061337208057, -557.13764766157726}, {-285.95061337208057, -557.13764766157726}}}
899{{{-308.65463091760211, -549.4520029924679} -308.65463091760211, -569.4520029924679
900</div>
901
902<div id="skpwww_educationalcraft_com_4">
903{{{974.91998291015625, 1481.7769775390625}, {974.91998291015625, 1481.7760009765625}, {977.3189697265625, 1484.6190185546875}, {975.10699462890625, 1486.97802734375}}}
904{{fX=974.91998291015625 fY=1481.7769775390625 }, {fX=974.92071342468262 fY=1481.7972941398621 }} }
905</div>
906
907<div id="skpwww_educationalcraft_com_4a">
908{{{962.10699462890625, 1485.654052734375}, {962.10699462890625, 1485.654052734375}, {960.58502197265625, 1483.595947265625}, {957.53900146484375, 1482.0970458984375}}}
909{{{963.21502685546875, 1486.6700439453125}, {962.7449951171875, 1486.6700439453125}, {962.10699462890625, 1485.654052734375}, {962.10699462890625, 1485.654052734375}}}
910</div>
911
912<div id="skpwww_educationalcraft_com_4b">
913{{{980.9000244140625, 1474.3280029296875}, {980.9000244140625, 1474.3280029296875}, {978.89300537109375, 1471.95703125}, {981.791015625, 1469.487060546875}}}
914{{{981.791015625, 1469.487060546875}, {981.791015625, 1469.4859619140625}, {983.3580322265625, 1472.72900390625}, {980.9000244140625, 1474.3280029296875}}}
915</div>
916
917<div id="skpwww_aceinfographics_com_106">
918{{{168, 29.6722088f}, {166, 29.6773338f}}}
919{{{166.878677f, 29.6750813f}, {167.388f, 29.6763878f}, {168.019989f, 29.6769352f}}}
920</div>
921
922<div id="skpwww_tcmevents_org_13">
923{{{465.84668f, 547.288391f}, {467.274506f, 552.852356f}, {468.506836f, 560.718567f}}}
924{{{468.506836f, 560.718567f}, {467.336121f, 553.24585f}, {465.951904f, 547.960144f}}
925</div>
926
927<div id="skpwww_kitcheninspirations_wordpress_com_66">
928{{{60.8333359f, 27820.498f}, {47.1666679f, 27820.5f}}}
929{{{60.8333359f, 27820.668f}, {60.8333359f, 27820.498f}}}
930{{{47.1666679f, 27820.498f}, {60.8333359f, 27820.5f}}}
931{{{60.8333359f, 27820.5f}, {60.8333359f, 27820.668f}}}
932</div>
933
934<div id="skpwww_galaxystwo_com_4">
935{{{10105, 2510}, {10123, 2509.98999f}}}
936{{{10105, 2509.98999f}, {10123, 2510}}}
937</div>
938
939<div id="skpwww_wartepop_blogspot_com_br_6">
940{{{124.666672f, 152.333344f}, {125.909309f, 152.333344f}, {126.787994f, 153.309662f}}}
941{{fX=124.66666412353516 fY=152.33334350585937 }, {fX=126.78799438476562 fY=153.30966186523437 }} }
942{{fX=124.66666412353516 fY=152.33334350585937 }, {fX=127.02368927001953 fY=153.30966186523437 }} }
943</div>
944
945<div id="skpwww_wartepop_blogspot_com_br_6a">
946{{{124.666672f, 152.333344f}, {125.909309f, 152.333344f}, {126.787994f, 153.309662f}}}
947{{fX=124.66667175292969 fY=152.33334350585937 }, {fX=126.78799438476562 fY=153.30966186523437 }} }
948{{fX=124.66667175292969 fY=152.33334350585937 }, {fX=127.02368927001953 fY=153.30966186523437 }} }
949</div>
950
951<div id="skpcarrot_is24x">
952{{{1020.08099, 672.16198699999995}, {1020.08002, 630.73999000000003}, {986.50201400000003, 597.16198699999995}, {945.08099400000003, 597.16198699999995}}}
953{{{1020, 672}, {1020, 640.93395999999996}, {998.03301999999996, 618.96698000000004}}}
954</div>
955
956<div id="skpwww_9to5mac_com_64">
957{{{{365.848175,5081.15186}, {368,5103}}},
958{{{367.967712,5102.61084}, {368.278717,5105.71045}}}},
959</div>
960
961<div id="issue2753">
962{{50.6,117.001}, {50.6,117.001}, {164.601,85.2}, {188.201,117.601}},
963{{188.201,117.601}, {188.201,117.601}, {174.801,93}, {39,124.001}},
964computed quadratics set
965{{50.6,117.001}, {52.4926111,116.112083}, {81.0298889,109.956333}},
966{{81.0298889,109.956333}, {109.567167,103.800583}, {142.037778,103.045}},
967{{142.037778,103.045}, {174.508389,102.289417}, {188.201,117.601}},
968computed quadratics set
969{{188.201,117.601}, {189.210269,116.85838}, {179.697259,112.371148}},
970{{179.697259,112.371148}, {170.18425,107.883917}, {138.037741,108.563519}},
971{{138.037741,108.563519}, {105.891231,109.24312}, {39,124.001}},
972</div>
973
974<div id="battle6001">
975{{{0.111722f, -59.999897f}, {0.0895366594f, -59.999939f}, {0.0673542097f, -59.9999695f}, {0.0451717526f, -59.9999847f}}}
976{{{0.0451734141f, -59.9999847f}, {0.0438041016f, -59.9999886f}, {0.0424379632f, -59.9999886f}, {0.0410718247f, -59.9999886f}}}
977</div>
978
979</div>
980
981<script type="text/javascript">
982
983    var testDivs = [
984        battle6001,
985        issue2753,
986        skpwww_9to5mac_com_64,
987        skpcarrot_is24x,
988        skpwww_wartepop_blogspot_com_br_6,
989        skpwww_wartepop_blogspot_com_br_6a,
990        skpwww_galaxystwo_com_4,
991        skpwww_kitcheninspirations_wordpress_com_66,
992        skpwww_tcmevents_org_13,
993        skpwww_aceinfographics_com_106,
994        skpwww_educationalcraft_com_4b,
995        skpwww_educationalcraft_com_4a,
996        skpwww_educationalcraft_com_4,
997        cubicLineErr2,
998        cubicLineErr1,
999        cubicLineMiss1,
1000        cubicLineMiss2,
1001        cubicLineMiss3,
1002        cubicLineMiss4,
1003        skpwww_pindosiya_com_99,
1004        self1,
1005        skpwww_seopack_blogspot_com_2153,
1006        serp1,
1007        serp2,
1008        serp3,
1009        loop1,
1010        skpwww_maturesupertube_com_21,
1011        skpwww_cityads_ru_249,
1012        skpelpais_com_18,
1013        testQuads60_b,
1014        testQuads60_a,
1015        testQuads60,
1016        skpwww_dealnews_com_315_a,
1017        skpwww_dealnews_com_315,
1018        skpnamecheap_405,
1019        slop1,
1020        slop2,
1021        slop3,
1022        slop4,
1023        slop5,
1024        slop6,
1025        slop7,
1026        slop8,
1027        slop9,
1028        slop10,
1029        slop11,
1030        slop12,
1031        slop13,
1032        slop14,
1033        slop15,
1034        slop16,
1035        slop17,
1036        slop18,
1037        slop19,
1038        slop20,
1039        skpcarrot_is24e,
1040        skpcarrot_is24d,
1041        skpcarrot_is24c,
1042        skpcarrot_is24b,
1043        skpcarrot_is24a,
1044        skpcarrot_is24,
1045        testQuads59,
1046        testQuads45,
1047        testQuads54,
1048        findFirst1,
1049        cubicOp59d,
1050        testQuads22,
1051        cubicOp85d,
1052        cubicOp104,
1053        skpnational_com_au81,
1054        cubicOp35d,
1055        testQuad23,
1056        testQuad22,
1057        testQuad21,
1058        testQuad15,
1059        testQuadratic56,
1060        xop1i,
1061        xOp2i,
1062        xop1u,
1063        skpwww_joomla_org_23,
1064        cubicOp109,
1065        cubicOp106,
1066        cubicOp105,
1067        carpetplanet1,
1068        eldorado1,
1069        cubicOp25i,
1070        cubicOp7d,
1071        simplifyQuadratic27,
1072        simplifyQuadratic56a,
1073        simplifyQuadratic56,
1074        quadratic58again,
1075        simplifyQuadratic58a,
1076        simplifyQuadratic58,
1077        simplifyQuadratic36,
1078        quad89987,
1079        quad8741,
1080        quad8b,
1081        quad8a,
1082        quad208,
1083        quad67242,
1084        quad37226,
1085        quad35237,
1086        quad108,
1087        quad212,
1088        quad3160,
1089        quad640,
1090        quad206,
1091        quad136,
1092        quad113,
1093        quad999,
1094        quad0,
1095        quad179,
1096        quad4a,
1097        quad94,
1098        quad77,
1099        quad22a,
1100        quad14a,
1101        quad809,
1102        quad653,
1103        quad584,
1104        quad413,
1105        quad379,
1106        quad159,
1107        quad232,
1108        quad40,
1109        quad39,
1110        quad38,
1111        quad37,
1112        quad36,
1113        quad35,
1114        quad34,
1115        quad33,
1116        quad32,
1117        quad31,
1118        quad30,
1119        quad29,
1120        quad28,
1121        quad27,
1122        quad26,
1123        quad25,
1124        quad24,
1125        quad23,
1126        quad22,
1127        quad21,
1128        quad20,
1129        quad19,
1130        quad18,
1131        quad17,
1132        quad16,
1133        quad15,
1134        quad14,
1135        quad13,
1136        quad12,
1137        quad11,
1138        cubic2,
1139        cubic1,
1140        quad1,
1141        quad2,
1142        quad3,
1143        quad4,
1144        quad5,
1145        quad6,
1146        quad7,
1147        quad8,
1148        quad9,
1149        quad10,
1150    ];
1151
1152    var tests = [];
1153    var testTitles = [];
1154    var testIndex = 0;
1155    var ctx;
1156    var subscale = 1;
1157    var xmin, xmax, ymin, ymax;
1158    var scale;
1159    var initScale;
1160    var mouseX, mouseY;
1161    var mouseDown = false;
1162    var srcLeft, srcTop;
1163    var screenWidth, screenHeight;
1164    var drawnPts;
1165    var curveT = 0;
1166
1167    var lastX, lastY;
1168    var activeCurve = [];
1169    var activePt;
1170
1171    var decimal_places = 3;
1172
1173    var draw_t = false;
1174    var draw_closest_t = false;
1175    var draw_cubic_red = false;
1176    var draw_derivative = false;
1177    var draw_endpoints = true;
1178    var draw_midpoint = 0;
1179    var draw_mouse_xy = false;
1180    var draw_order = false;
1181    var draw_point_xy = false;
1182    var draw_ray_intersect = false;
1183    var draw_quarterpoint = 0;
1184    var draw_tangents = 1;
1185    var draw_sortpoint = 0;
1186    var retina_scale = !!window.devicePixelRatio;
1187
1188    function parse(test, title) {
1189        var curveStrs = test.split("{{");
1190        var pattern = /-?\d+\.*\d*e?-?\d*/g;
1191        var curves = [];
1192        for (var c in curveStrs) {
1193            var curveStr = curveStrs[c];
1194            var points = curveStr.match(pattern);
1195            var pts = [];
1196            for (var wd in points) {
1197                var num = parseFloat(points[wd]);
1198                if (isNaN(num)) continue;
1199                pts.push(num);
1200            }
1201            if (pts.length > 2)
1202                curves.push(pts);
1203        }
1204        if (curves.length >= 1) {
1205            tests.push(curves);
1206            testTitles.push(title);
1207        }
1208    }
1209
1210    function init(test) {
1211        var canvas = document.getElementById('canvas');
1212        if (!canvas.getContext) return;
1213        ctx = canvas.getContext('2d');
1214        var resScale = retina_scale && window.devicePixelRatio ? window.devicePixelRatio : 1;
1215        var unscaledWidth = window.innerWidth - 20;
1216        var unscaledHeight = window.innerHeight - 20;
1217        screenWidth = unscaledWidth;
1218        screenHeight = unscaledHeight;
1219        canvas.width = unscaledWidth * resScale;
1220        canvas.height = unscaledHeight * resScale;
1221        canvas.style.width = unscaledWidth + 'px';
1222        canvas.style.height = unscaledHeight + 'px';
1223        if (resScale != 1) {
1224            ctx.scale(resScale, resScale);
1225        }
1226        xmin = Infinity;
1227        xmax = -Infinity;
1228        ymin = Infinity;
1229        ymax = -Infinity;
1230        for (var curves in test) {
1231            var curve = test[curves];
1232            var last = curve.length;
1233            for (var idx = 0; idx < last; idx += 2) {
1234                xmin = Math.min(xmin, curve[idx]);
1235                xmax = Math.max(xmax, curve[idx]);
1236                ymin = Math.min(ymin, curve[idx + 1]);
1237                ymax = Math.max(ymax, curve[idx + 1]);
1238            }
1239        }
1240        xmin -= 1;
1241        var testW = xmax - xmin;
1242        var testH = ymax - ymin;
1243        subscale = 1;
1244        while (testW * subscale < 0.1 && testH * subscale < 0.1) {
1245            subscale *= 10;
1246        }
1247        while (testW * subscale > 10 && testH * subscale > 10) {
1248            subscale /= 10;
1249        }
1250        setScale(xmin, xmax, ymin, ymax);
1251        mouseX = (screenWidth / 2) / scale + srcLeft;
1252        mouseY = (screenHeight / 2) / scale + srcTop;
1253        initScale = scale;
1254    }
1255
1256    function setScale(x0, x1, y0, y1) {
1257        var srcWidth = x1 - x0;
1258        var srcHeight = y1 - y0;
1259        var usableWidth = screenWidth;
1260        var xDigits = Math.ceil(Math.log(Math.abs(xmax)) / Math.log(10));
1261        var yDigits = Math.ceil(Math.log(Math.abs(ymax)) / Math.log(10));
1262        usableWidth -= (xDigits + yDigits) * 10;
1263        usableWidth -= decimal_places * 10;
1264        var hscale = usableWidth / srcWidth;
1265        var vscale = screenHeight / srcHeight;
1266        scale = Math.min(hscale, vscale);
1267        var invScale = 1 / scale;
1268        var sxmin = x0 - invScale * 5;
1269        var symin = y0 - invScale * 10;
1270        var sxmax = x1 + invScale * (6 * decimal_places + 10);
1271        var symax = y1 + invScale * 10;
1272        srcWidth = sxmax - sxmin;
1273        srcHeight = symax - symin;
1274        hscale = usableWidth / srcWidth;
1275        vscale = screenHeight / srcHeight;
1276        scale = Math.min(hscale, vscale);
1277        srcLeft = sxmin;
1278        srcTop = symin;
1279    }
1280
1281function dxy_at_t(curve, t) {
1282    var dxy = {};
1283    if (curve.length == 6) {
1284        var a = t - 1;
1285        var b = 1 - 2 * t;
1286        var c = t;
1287        dxy.x = a * curve[0] + b * curve[2] + c * curve[4];
1288        dxy.y = a * curve[1] + b * curve[3] + c * curve[5];
1289    } else if (curve.length == 8) {
1290        var one_t = 1 - t;
1291        var a = curve[0];
1292        var b = curve[2];
1293        var c = curve[4];
1294        var d = curve[6];
1295        dxy.x = 3 * ((b - a) * one_t * one_t + 2 * (c - b) * t * one_t + (d - c) * t * t);
1296        a = curve[1];
1297        b = curve[3];
1298        c = curve[5];
1299        d = curve[7];
1300        dxy.y = 3 * ((b - a) * one_t * one_t + 2 * (c - b) * t * one_t + (d - c) * t * t);
1301    }
1302    return dxy;
1303}
1304
1305    var flt_epsilon = 1.19209290E-07;
1306
1307    function approximately_zero(A) {
1308        return Math.abs(A) < flt_epsilon;
1309    }
1310
1311    function approximately_zero_inverse(A) {
1312        return Math.abs(A) > (1 / flt_epsilon);
1313    }
1314
1315    function quad_real_roots(A, B, C) {
1316        var s = [];
1317        var p = B / (2 * A);
1318        var q = C / A;
1319        if (approximately_zero(A) && (approximately_zero_inverse(p)
1320                || approximately_zero_inverse(q))) {
1321            if (approximately_zero(B)) {
1322                if (C == 0) {
1323                    s[0] = 0;
1324                }
1325                return s;
1326            }
1327            s[0] = -C / B;
1328            return s;
1329        }
1330        /* normal form: x^2 + px + q = 0 */
1331        var p2 = p * p;
1332        if (!approximately_zero(p2 - q) && p2 < q) {
1333            return s;
1334        }
1335        var sqrt_D = 0;
1336        if (p2 > q) {
1337            sqrt_D = Math.sqrt(p2 - q);
1338        }
1339        s[0] = sqrt_D - p;
1340        var flip = -sqrt_D - p;
1341        if (!approximately_zero(s[0] - flip)) {
1342            s[1] = flip;
1343        }
1344        return s;
1345    }
1346
1347    function cubic_real_roots(A, B, C, D) {
1348        if (approximately_zero(A)) {  // we're just a quadratic
1349            return quad_real_roots(B, C, D);
1350        }
1351        if (approximately_zero(D)) {  // 0 is one root
1352            var s = quad_real_roots(A, B, C);
1353            for (var i = 0; i < s.length; ++i) {
1354                if (approximately_zero(s[i])) {
1355                    return s;
1356                }
1357            }
1358            s.push(0);
1359            return s;
1360        }
1361        if (approximately_zero(A + B + C + D)) {  // 1 is one root
1362            var s = quad_real_roots(A, A + B, -D);
1363            for (var i = 0; i < s.length; ++i) {
1364                if (approximately_zero(s[i] - 1)) {
1365                    return s;
1366                }
1367            }
1368            s.push(1);
1369            return s;
1370        }
1371        var a, b, c;
1372        var invA = 1 / A;
1373        a = B * invA;
1374        b = C * invA;
1375        c = D * invA;
1376        var a2 = a * a;
1377        var Q = (a2 - b * 3) / 9;
1378        var R = (2 * a2 * a - 9 * a * b + 27 * c) / 54;
1379        var R2 = R * R;
1380        var Q3 = Q * Q * Q;
1381        var R2MinusQ3 = R2 - Q3;
1382        var adiv3 = a / 3;
1383        var r;
1384        var roots = [];
1385        if (R2MinusQ3 < 0) {   // we have 3 real roots
1386            var theta = Math.acos(R / Math.sqrt(Q3));
1387            var neg2RootQ = -2 * Math.sqrt(Q);
1388            r = neg2RootQ * Math.cos(theta / 3) - adiv3;
1389            roots.push(r);
1390            r = neg2RootQ * Math.cos((theta + 2 * Math.PI) / 3) - adiv3;
1391            if (!approximately_zero(roots[0] - r)) {
1392                roots.push(r);
1393            }
1394            r = neg2RootQ * Math.cos((theta - 2 * Math.PI) / 3) - adiv3;
1395            if (!approximately_zero(roots[0] - r) && (roots.length == 1
1396                        || !approximately_zero(roots[1] - r))) {
1397                roots.push(r);
1398            }
1399        } else {  // we have 1 real root
1400            var sqrtR2MinusQ3 = Math.sqrt(R2MinusQ3);
1401            var A = Math.abs(R) + sqrtR2MinusQ3;
1402            A = Math.pow(A, 1/3);
1403            if (R > 0) {
1404                A = -A;
1405            }
1406            if (A != 0) {
1407                A += Q / A;
1408            }
1409            r = A - adiv3;
1410            roots.push(r);
1411            if (approximately_zero(R2 - Q3)) {
1412                r = -A / 2 - adiv3;
1413                if (!approximately_zero(s[0] - r)) {
1414                    roots.push(r);
1415                }
1416            }
1417        }
1418        return roots;
1419    }
1420
1421    function approximately_zero_or_more(tValue) {
1422        return tValue >= -flt_epsilon;
1423    }
1424
1425    function approximately_one_or_less(tValue) {
1426        return tValue <= 1 + flt_epsilon;
1427    }
1428
1429    function approximately_less_than_zero(tValue) {
1430        return tValue < flt_epsilon;
1431    }
1432
1433    function approximately_greater_than_one(tValue) {
1434        return tValue > 1 - flt_epsilon;
1435    }
1436
1437    function add_valid_ts(s) {
1438        var t = [];
1439    nextRoot:
1440        for (var index = 0; index < s.length; ++index) {
1441            var tValue = s[index];
1442            if (approximately_zero_or_more(tValue) && approximately_one_or_less(tValue)) {
1443                if (approximately_less_than_zero(tValue)) {
1444                    tValue = 0;
1445                } else if (approximately_greater_than_one(tValue)) {
1446                    tValue = 1;
1447                }
1448                for (var idx2 = 0; idx2 < t.length; ++idx2) {
1449                    if (approximately_zero(t[idx2] - tValue)) {
1450                        continue nextRoot;
1451                    }
1452                }
1453                t.push(tValue);
1454            }
1455        }
1456        return t;
1457    }
1458
1459    function quad_roots(A, B, C) {
1460        var s = quad_real_roots(A, B, C);
1461        var foundRoots = add_valid_ts(s);
1462        return foundRoots;
1463    }
1464
1465    function cubic_roots(A, B, C, D) {
1466        var s = cubic_real_roots(A, B, C, D);
1467        var foundRoots = add_valid_ts(s);
1468        return foundRoots;
1469    }
1470
1471    function ray_curve_intersect(startPt, endPt, curve) {
1472        var adj = endPt[0] - startPt[0];
1473        var opp = endPt[1] - startPt[1];
1474        var r = [];
1475        for (var n = 0; n < curve.length / 2; ++n) {
1476            r[n] = (curve[n * 2 + 1] - startPt[1]) * adj - (curve[n * 2] - startPt[0]) * opp;
1477        }
1478        if (curve.length == 6) {
1479            var A = r[2];
1480            var B = r[1];
1481            var C = r[0];
1482            A += C - 2 * B;  // A = a - 2*b + c
1483            B -= C;  // B = -(b - c)
1484            return quad_roots(A, 2 * B, C);
1485        }
1486        var A = r[3];       // d
1487        var B = r[2] * 3;   // 3*c
1488        var C = r[1] * 3;   // 3*b
1489        var D = r[0];       // a
1490        A -= D - C + B;     // A =   -a + 3*b - 3*c + d
1491        B += 3 * D - 2 * C; // B =  3*a - 6*b + 3*c
1492        C -= 3 * D;         // C = -3*a + 3*b
1493        return cubic_roots(A, B, C, D);
1494    }
1495
1496    function x_at_t(curve, t) {
1497        var one_t = 1 - t;
1498        if (curve.length == 4) {
1499            return one_t * curve[0] + t * curve[2];
1500        }
1501        var one_t2 = one_t * one_t;
1502        var t2 = t * t;
1503        if (curve.length == 6) {
1504            return one_t2 * curve[0] + 2 * one_t * t * curve[2] + t2 * curve[4];
1505        }
1506        var a = one_t2 * one_t;
1507        var b = 3 * one_t2 * t;
1508        var c = 3 * one_t * t2;
1509        var d = t2 * t;
1510        return a * curve[0] + b * curve[2] + c * curve[4] + d * curve[6];
1511    }
1512
1513    function y_at_t(curve, t) {
1514        var one_t = 1 - t;
1515        if (curve.length == 4) {
1516            return one_t * curve[1] + t * curve[3];
1517        }
1518        var one_t2 = one_t * one_t;
1519        var t2 = t * t;
1520        if (curve.length == 6) {
1521            return one_t2 * curve[1] + 2 * one_t * t * curve[3] + t2 * curve[5];
1522        }
1523        var a = one_t2 * one_t;
1524        var b = 3 * one_t2 * t;
1525        var c = 3 * one_t * t2;
1526        var d = t2 * t;
1527        return a * curve[1] + b * curve[3] + c * curve[5] + d * curve[7];
1528    }
1529
1530    function drawPointAtT(curve) {
1531        var x = x_at_t(curve, curveT);
1532        var y = y_at_t(curve, curveT);
1533        drawPoint(x, y);
1534    }
1535
1536    function drawLine(x1, y1, x2, y2) {
1537        ctx.beginPath();
1538        ctx.moveTo((x1 - srcLeft) * scale,
1539                (y1 - srcTop) * scale);
1540        ctx.lineTo((x2 - srcLeft) * scale,
1541                (y2 - srcTop) * scale);
1542        ctx.stroke();
1543    }
1544
1545    function drawPoint(px, py) {
1546        for (var pts = 0; pts < drawnPts.length; pts += 2) {
1547            var x = drawnPts[pts];
1548            var y = drawnPts[pts + 1];
1549            if (px == x && py == y) {
1550                return;
1551            }
1552        }
1553        drawnPts.push(px);
1554        drawnPts.push(py);
1555        var _px = (px - srcLeft) * scale;
1556        var _py = (py - srcTop) * scale;
1557        ctx.beginPath();
1558        ctx.arc(_px, _py, 3, 0, Math.PI * 2, true);
1559        ctx.closePath();
1560        ctx.stroke();
1561        if (draw_point_xy) {
1562            var label = px.toFixed(decimal_places) + ", " + py.toFixed(decimal_places);
1563            ctx.font = "normal 10px Arial";
1564            ctx.textAlign = "left";
1565            ctx.fillStyle = "black";
1566            ctx.fillText(label, _px + 5, _py);
1567        }
1568    }
1569
1570    function drawPointSolid(px, py) {
1571        drawPoint(px, py);
1572        ctx.fillStyle = "rgba(0,0,0, 0.4)";
1573        ctx.fill();
1574    }
1575
1576    function crossPt(origin, pt1, pt2) {
1577        return ((pt1[0] - origin[0]) * (pt2[1] - origin[1])
1578              - (pt1[1] - origin[1]) * (pt2[0] - origin[0])) > 0 ? 0 : 1;
1579    }
1580
1581    // may not work well for cubics
1582    function curveClosestT(curve, x, y) {
1583        var closest = -1;
1584        var closestDist = Infinity;
1585        var l = Infinity, t = Infinity, r = -Infinity, b = -Infinity;
1586        for (var i = 0; i < 16; ++i) {
1587            var testX = x_at_t(curve, i / 16);
1588            l = Math.min(testX, l);
1589            r = Math.max(testX, r);
1590            var testY = y_at_t(curve, i / 16);
1591            t = Math.min(testY, t);
1592            b = Math.max(testY, b);
1593            var dx = testX - x;
1594            var dy = testY - y;
1595            var dist = dx * dx + dy * dy;
1596            if (closestDist > dist) {
1597                closestDist = dist;
1598                closest = i;
1599            }
1600        }
1601        var boundsX = r - l;
1602        var boundsY = b - t;
1603        var boundsDist = boundsX * boundsX + boundsY * boundsY;
1604        if (closestDist > boundsDist) {
1605            return -1;
1606        }
1607        console.log("closestDist = " + closestDist + " boundsDist = " + boundsDist
1608                + " t = " + closest / 16);
1609        return closest / 16;
1610    }
1611
1612    function draw(test, title) {
1613        ctx.font = "normal 50px Arial";
1614        ctx.textAlign = "left";
1615        ctx.fillStyle = "rgba(0,0,0, 0.1)";
1616        ctx.fillText(title, 50, 50);
1617        ctx.font = "normal 10px Arial";
1618        //  ctx.lineWidth = "1.001"; "0.999";
1619        var hullStarts = [];
1620        var hullEnds = [];
1621        var midSpokes = [];
1622        var midDist = [];
1623        var origin = [];
1624        var shortSpokes = [];
1625        var shortDist = [];
1626        var sweeps = [];
1627        drawnPts = [];
1628        for (var curves in test) {
1629            var curve = test[curves];
1630            origin.push(curve[0]);
1631            origin.push(curve[1]);
1632            var startPt = [];
1633            startPt.push(curve[2]);
1634            startPt.push(curve[3]);
1635            hullStarts.push(startPt);
1636            var endPt = [];
1637            if (curve.length == 4) {
1638                endPt.push(curve[2]);
1639                endPt.push(curve[3]);
1640            } else if (curve.length == 6) {
1641                endPt.push(curve[4]);
1642                endPt.push(curve[5]);
1643            } else if (curve.length == 8) {
1644                endPt.push(curve[6]);
1645                endPt.push(curve[7]);
1646            }
1647            hullEnds.push(endPt);
1648            var sweep = crossPt(origin, startPt, endPt);
1649            sweeps.push(sweep);
1650            var midPt = [];
1651            midPt.push(x_at_t(curve, 0.5));
1652            midPt.push(y_at_t(curve, 0.5));
1653            midSpokes.push(midPt);
1654            var shortPt = [];
1655            shortPt.push(x_at_t(curve, 0.25));
1656            shortPt.push(y_at_t(curve, 0.25));
1657            shortSpokes.push(shortPt);
1658            var dx = midPt[0] - origin[0];
1659            var dy = midPt[1] - origin[1];
1660            var dist = Math.sqrt(dx * dx + dy * dy);
1661            midDist.push(dist);
1662            dx = shortPt[0] - origin[0];
1663            dy = shortPt[1] - origin[1];
1664            dist = Math.sqrt(dx * dx + dy * dy);
1665            shortDist.push(dist);
1666        }
1667        var intersect = [];
1668        var useIntersect = false;
1669        var maxWidth = Math.max(xmax - xmin, ymax - ymin);
1670        for (var curves in test) {
1671            var curve = test[curves];
1672            if (curve.length == 6 || curve.length == 8) {
1673                var opp = curves == 0 || curves == 1 ? 0 : 1;
1674                var sects = ray_curve_intersect(origin, hullEnds[opp], curve);
1675                intersect.push(sects);
1676                if (sects.length > 1) {
1677                    var intersection = sects[0];
1678                    if (intersection == 0) {
1679                        intersection = sects[1];
1680                    }
1681                    var ix = x_at_t(curve, intersection) - origin[0];
1682                    var iy = y_at_t(curve, intersection) - origin[1];
1683                    var ex = hullEnds[opp][0] - origin[0];
1684                    var ey = hullEnds[opp][1] - origin[1];
1685                    if (ix * ex >= 0 && iy * ey >= 0) {
1686                        var iDist = Math.sqrt(ix * ix + iy * iy);
1687                        var eDist = Math.sqrt(ex * ex + ey * ey);
1688                        var delta = Math.abs(iDist - eDist) / maxWidth;
1689                        if (delta > (curve.length == 6 ? 1e-5 : 1e-4)) {
1690                            useIntersect ^= true;
1691                        }
1692                    }
1693                }
1694            }
1695        }
1696        var midLeft = curves != 0 ? crossPt(origin, midSpokes[0], midSpokes[1]) : 0;
1697        var firstInside;
1698        if (useIntersect) {
1699            var sect1 = intersect[0].length > 1;
1700            var sIndex = sect1 ? 0 : 1;
1701            var sects = intersect[sIndex];
1702            var intersection = sects[0];
1703            if (intersection == 0) {
1704                intersection = sects[1];
1705            }
1706            var curve = test[sIndex];
1707            var ix = x_at_t(curve, intersection) - origin[0];
1708            var iy = y_at_t(curve, intersection) - origin[1];
1709            var opp = sect1 ? 1 : 0;
1710            var ex = hullEnds[opp][0] - origin[0];
1711            var ey = hullEnds[opp][1] - origin[1];
1712            var iDist = ix * ix + iy * iy;
1713            var eDist = ex * ex + ey * ey;
1714            firstInside = (iDist > eDist) ^ (sIndex == 0) ^ sweeps[0];
1715//            console.log("iDist=" + iDist + " eDist=" + eDist + " sIndex=" + sIndex
1716 //                   + " sweeps[0]=" + sweeps[0]);
1717        } else {
1718 //           console.log("midLeft=" + midLeft);
1719            firstInside = midLeft != 0;
1720        }
1721        var shorter = midDist[1] < midDist[0];
1722        var shortLeft = shorter ? crossPt(origin, shortSpokes[0], midSpokes[1])
1723                : crossPt(origin, midSpokes[0], shortSpokes[1]);
1724        var startCross = crossPt(origin, hullStarts[0], hullStarts[1]);
1725        var disallowShort = midLeft == startCross && midLeft == sweeps[0]
1726                    && midLeft == sweeps[1];
1727
1728  //      console.log("midLeft=" + midLeft + " startCross=" + startCross);
1729        var intersectIndex = 0;
1730        for (var curves in test) {
1731            var curve = test[curves];
1732            if (curve.length != 4 && curve.length != 6 && curve.length != 8) {
1733                continue;
1734            }
1735            ctx.lineWidth = 1;
1736            if (draw_tangents != 0) {
1737                if (draw_cubic_red ? curve.length == 8 : firstInside == curves) {
1738                    ctx.strokeStyle = "rgba(255,0,0, 0.3)";
1739                } else {
1740                    ctx.strokeStyle = "rgba(0,0,255, 0.3)";
1741                }
1742                drawLine(curve[0], curve[1], curve[2], curve[3]);
1743                if (draw_tangents != 2) {
1744                    if (curve.length > 4) drawLine(curve[2], curve[3], curve[4], curve[5]);
1745                    if (curve.length > 6) drawLine(curve[4], curve[5], curve[6], curve[7]);
1746                }
1747                if (draw_tangents != 1) {
1748                    if (curve.length == 6) drawLine(curve[0], curve[1], curve[4], curve[5]);
1749                    if (curve.length == 8) drawLine(curve[0], curve[1], curve[6], curve[7]);
1750                }
1751            }
1752            ctx.beginPath();
1753            ctx.moveTo((curve[0] - srcLeft) * scale, (curve[1] - srcTop) * scale);
1754            if (curve.length == 4) {
1755                ctx.lineTo((curve[2] - srcLeft) * scale, (curve[3] - srcTop) * scale);
1756            } else if (curve.length == 6) {
1757                ctx.quadraticCurveTo(
1758                    (curve[2] - srcLeft) * scale, (curve[3] - srcTop) * scale,
1759                    (curve[4] - srcLeft) * scale, (curve[5] - srcTop) * scale);
1760            } else {
1761                ctx.bezierCurveTo(
1762                    (curve[2] - srcLeft) * scale, (curve[3] - srcTop) * scale,
1763                    (curve[4] - srcLeft) * scale, (curve[5] - srcTop) * scale,
1764                    (curve[6] - srcLeft) * scale, (curve[7] - srcTop) * scale);
1765            }
1766            if (draw_cubic_red ? curve.length == 8 : firstInside == curves) {
1767                ctx.strokeStyle = "rgba(255,0,0, 1)";
1768            } else {
1769                ctx.strokeStyle = "rgba(0,0,255, 1)";
1770            }
1771            ctx.stroke();
1772            if (draw_endpoints) {
1773                drawPoint(curve[0], curve[1]);
1774                drawPoint(curve[2], curve[3]);
1775                if (curve.length > 4) drawPoint(curve[4], curve[5]);
1776                if (curve.length > 6) drawPoint(curve[6], curve[7]);
1777            }
1778            if (draw_midpoint != 0) {
1779                if ((curves == 0) == (midLeft == 0)) {
1780                    ctx.strokeStyle = "rgba(0,180,127, 0.6)";
1781                } else {
1782                    ctx.strokeStyle = "rgba(127,0,127, 0.6)";
1783                }
1784                var midX = x_at_t(curve, 0.5);
1785                var midY = y_at_t(curve, 0.5);
1786                drawPointSolid(midX, midY);
1787                if (draw_midpoint > 1) {
1788                    drawLine(curve[0], curve[1], midX, midY);
1789                }
1790            }
1791            if (draw_quarterpoint != 0) {
1792                if ((curves == 0) == (shortLeft == 0)) {
1793                    ctx.strokeStyle = "rgba(0,191,63, 0.6)";
1794                } else {
1795                    ctx.strokeStyle = "rgba(63,0,191, 0.6)";
1796                }
1797                var midT = (curves == 0) == shorter ? 0.25 : 0.5;
1798                var midX = x_at_t(curve, midT);
1799                var midY = y_at_t(curve, midT);
1800                drawPointSolid(midX, midY);
1801                if (draw_quarterpoint > 1) {
1802                    drawLine(curve[0], curve[1], midX, midY);
1803                }
1804            }
1805            if (draw_sortpoint != 0) {
1806                if ((curves == 0) == ((disallowShort == -1 ? midLeft : shortLeft) == 0)) {
1807                    ctx.strokeStyle = "rgba(0,155,37, 0.6)";
1808                } else {
1809                    ctx.strokeStyle = "rgba(37,0,155, 0.6)";
1810                }
1811                var midT = (curves == 0) == shorter && disallowShort != curves ? 0.25 : 0.5;
1812                console.log("curves=" + curves + " disallowShort=" + disallowShort
1813                        + " midLeft=" + midLeft + " shortLeft=" + shortLeft
1814                        + " shorter=" + shorter + " midT=" + midT);
1815                var midX = x_at_t(curve, midT);
1816                var midY = y_at_t(curve, midT);
1817                drawPointSolid(midX, midY);
1818                if (draw_sortpoint > 1) {
1819                    drawLine(curve[0], curve[1], midX, midY);
1820                }
1821            }
1822            if (draw_ray_intersect != 0) {
1823                ctx.strokeStyle = "rgba(75,45,199, 0.6)";
1824                if (curve.length == 6 || curve.length == 8) {
1825                    var intersections = intersect[intersectIndex];
1826                    for (var i in intersections) {
1827                        var intersection = intersections[i];
1828                        var x = x_at_t(curve, intersection);
1829                        var y = y_at_t(curve, intersection);
1830                        drawPointSolid(x, y);
1831                        if (draw_ray_intersect > 1) {
1832                            drawLine(curve[0], curve[1], x, y);
1833                        }
1834                    }
1835                }
1836                ++intersectIndex;
1837            }
1838            if (draw_order) {
1839                var px = x_at_t(curve, 0.75);
1840                var py = y_at_t(curve, 0.75);
1841                var _px = (px - srcLeft) * scale;
1842                var _py = (py - srcTop) * scale;
1843                ctx.beginPath();
1844                ctx.arc(_px, _py, 15, 0, Math.PI * 2, true);
1845                ctx.closePath();
1846                ctx.fillStyle = "white";
1847                ctx.fill();
1848                if (draw_cubic_red ? curve.length == 8 : firstInside == curves) {
1849                    ctx.strokeStyle = "rgba(255,0,0, 1)";
1850                    ctx.fillStyle = "rgba(255,0,0, 1)";
1851                } else {
1852                    ctx.strokeStyle = "rgba(0,0,255, 1)";
1853                    ctx.fillStyle = "rgba(0,0,255, 1)";
1854                }
1855                ctx.stroke();
1856                ctx.font = "normal 16px Arial";
1857                ctx.textAlign = "center";
1858                ctx.fillText(parseInt(curves) + 1, _px, _py + 5);
1859            }
1860            if (draw_closest_t) {
1861                var t = curveClosestT(curve, mouseX, mouseY);
1862                if (t >= 0) {
1863                    var x = x_at_t(curve, t);
1864                    var y = y_at_t(curve, t);
1865                    drawPointSolid(x, y);
1866                }
1867            }
1868            if (!approximately_zero(scale - initScale)) {
1869                ctx.font = "normal 20px Arial";
1870                ctx.fillStyle = "rgba(0,0,0, 0.3)";
1871                ctx.textAlign = "right";
1872                ctx.fillText(scale.toFixed(decimal_places) + 'x',
1873                        screenWidth - 10, screenHeight - 5);
1874            }
1875            if (draw_t) {
1876                drawPointAtT(curve);
1877            }
1878        }
1879        if (draw_t) {
1880            drawCurveTControl();
1881        }
1882    }
1883
1884    function drawCurveTControl() {
1885        ctx.lineWidth = 2;
1886        ctx.strokeStyle = "rgba(0,0,0, 0.3)";
1887        ctx.beginPath();
1888        ctx.rect(screenWidth - 80, 40, 28, screenHeight - 80);
1889        ctx.stroke();
1890        var ty = 40 + curveT * (screenHeight - 80);
1891        ctx.beginPath();
1892        ctx.moveTo(screenWidth - 80, ty);
1893        ctx.lineTo(screenWidth - 85, ty - 5);
1894        ctx.lineTo(screenWidth - 85, ty + 5);
1895        ctx.lineTo(screenWidth - 80, ty);
1896        ctx.fillStyle = "rgba(0,0,0, 0.6)";
1897        ctx.fill();
1898        var num = curveT.toFixed(decimal_places);
1899        ctx.font = "normal 10px Arial";
1900        ctx.textAlign = "left";
1901        ctx.fillText(num, screenWidth - 78, ty);
1902    }
1903
1904    function ptInTControl() {
1905        var e = window.event;
1906        var tgt = e.target || e.srcElement;
1907        var left = tgt.offsetLeft;
1908        var top = tgt.offsetTop;
1909        var x = (e.clientX - left);
1910        var y = (e.clientY - top);
1911        if (x < screenWidth - 80 || x > screenWidth - 50) {
1912            return false;
1913        }
1914        if (y < 40 || y > screenHeight - 80) {
1915            return false;
1916        }
1917        curveT = (y - 40) / (screenHeight - 120);
1918        if (curveT < 0 || curveT > 1) {
1919            throw "stop execution";
1920        }
1921        return true;
1922    }
1923
1924    function drawTop() {
1925        init(tests[testIndex]);
1926        redraw();
1927    }
1928
1929    function redraw() {
1930        ctx.beginPath();
1931        ctx.rect(0, 0, ctx.canvas.width, ctx.canvas.height);
1932        ctx.fillStyle = "white";
1933        ctx.fill();
1934        draw(tests[testIndex], testTitles[testIndex]);
1935    }
1936
1937    function doKeyPress(evt) {
1938        var char = String.fromCharCode(evt.charCode);
1939        switch (char) {
1940            case '0':
1941            case '1':
1942            case '2':
1943            case '3':
1944            case '4':
1945            case '5':
1946            case '6':
1947            case '7':
1948            case '8':
1949            case '9':
1950                decimal_places = char - '0';
1951                redraw();
1952                break;
1953            case '-':
1954                scale /= 2;
1955                calcLeftTop();
1956                redraw();
1957                break;
1958            case '=':
1959            case '+':
1960                scale *= 2;
1961                calcLeftTop();
1962                redraw();
1963                break;
1964            case 'b':
1965                draw_cubic_red ^= true;
1966                redraw();
1967                break;
1968            case 'c':
1969                drawTop();
1970                break;
1971            case 'd':
1972                var test = tests[testIndex];
1973                var testClone = [];
1974                for (var curves in test) {
1975                    var c = test[curves];
1976                    var cClone = [];
1977                    for (var index = 0; index < c.length; ++index) {
1978                        cClone.push(c[index]);
1979                    }
1980                    testClone.push(cClone);
1981                }
1982                tests.push(testClone);
1983                testTitles.push(testTitles[testIndex] + " copy");
1984                testIndex = tests.length - 1;
1985                redraw();
1986                break;
1987            case 'e':
1988                draw_endpoints ^= true;
1989                redraw();
1990                break;
1991            case 'f':
1992                draw_derivative ^= true;
1993                redraw();
1994                break;
1995            case 'i':
1996                draw_ray_intersect = (draw_ray_intersect + 1) % 3;
1997                redraw();
1998                break;
1999            case 'l':
2000                var test = tests[testIndex];
2001                console.log("<div id=\"" + testTitles[testIndex] + "\" >");
2002                for (var curves in test) {
2003                    var c = test[curves];
2004                    var s = "{{";
2005                    for (var i = 0; i < c.length; i += 2) {
2006                        s += "{";
2007                        s += c[i] + "," + c[i + 1];
2008                        s += "}";
2009                        if (i + 2 < c.length) {
2010                            s += ", ";
2011                        }
2012                    }
2013                    console.log(s + "}},");
2014                }
2015                console.log("</div>");
2016                break;
2017            case 'm':
2018                draw_midpoint = (draw_midpoint + 1) % 3;
2019                redraw();
2020                break;
2021            case 'N':
2022                testIndex += 9;
2023            case 'n':
2024                testIndex = (testIndex + 1) % tests.length;
2025                drawTop();
2026                break;
2027            case 'o':
2028                draw_order ^= true;
2029                redraw();
2030                break;
2031            case 'P':
2032                testIndex -= 9;
2033            case 'p':
2034                if (--testIndex < 0)
2035                    testIndex = tests.length - 1;
2036                drawTop();
2037                break;
2038            case 'q':
2039                draw_quarterpoint = (draw_quarterpoint + 1) % 3;
2040                redraw();
2041                break;
2042            case 'r':
2043                for (var i = 0; i < testDivs.length; ++i) {
2044                    var title = testDivs[i].id.toString();
2045                    if (title == testTitles[testIndex]) {
2046                        var str = testDivs[i].firstChild.data;
2047                        parse(str, title);
2048                        var original = tests.pop();
2049                        testTitles.pop();
2050                        tests[testIndex] = original;
2051                        break;
2052                    }
2053                }
2054                redraw();
2055                break;
2056            case 's':
2057                draw_sortpoint = (draw_sortpoint + 1) % 3;
2058                redraw();
2059                break;
2060            case 't':
2061                draw_t ^= true;
2062                redraw();
2063                break;
2064            case 'u':
2065                draw_closest_t ^= true;
2066                redraw();
2067                break;
2068            case 'v':
2069                draw_tangents = (draw_tangents + 1) % 4;
2070                redraw();
2071                break;
2072            case 'x':
2073                draw_point_xy ^= true;
2074                redraw();
2075                break;
2076            case 'y':
2077                draw_mouse_xy ^= true;
2078                redraw();
2079                break;
2080            case '\\':
2081                retina_scale ^= true;
2082                drawTop();
2083                break;
2084        }
2085    }
2086
2087    function doKeyDown(evt) {
2088        var char = evt.keyCode;
2089        var preventDefault = false;
2090        switch (char) {
2091            case 37: // left arrow
2092                if (evt.shiftKey) {
2093                    testIndex -= 9;
2094                }
2095                if (--testIndex < 0)
2096                    testIndex = tests.length - 1;
2097                drawTop();
2098                preventDefault = true;
2099                break;
2100            case 39: // right arrow
2101                if (evt.shiftKey) {
2102                    testIndex += 9;
2103                }
2104                if (++testIndex >= tests.length)
2105                    testIndex = 0;
2106                drawTop();
2107                preventDefault = true;
2108                break;
2109        }
2110        if (preventDefault) {
2111            evt.preventDefault();
2112            return false;
2113        }
2114        return true;
2115    }
2116
2117    function calcXY() {
2118        var e = window.event;
2119        var tgt = e.target || e.srcElement;
2120        var left = tgt.offsetLeft;
2121        var top = tgt.offsetTop;
2122        mouseX = (e.clientX - left) / scale + srcLeft;
2123        mouseY = (e.clientY - top) / scale + srcTop;
2124    }
2125
2126    function calcLeftTop() {
2127        srcLeft = mouseX - screenWidth / 2 / scale;
2128        srcTop = mouseY - screenHeight / 2 / scale;
2129    }
2130
2131    function handleMouseClick() {
2132        if (!draw_t || !ptInTControl()) {
2133            calcXY();
2134        } else {
2135            redraw();
2136        }
2137    }
2138
2139    function initDown() {
2140        var test = tests[testIndex];
2141        var bestDistance = 1000000;
2142        activePt = -1;
2143        for (var curves in test) {
2144            var testCurve = test[curves];
2145            if (testCurve.length != 4 && testCurve.length != 6 && testCurve.length != 8) {
2146                continue;
2147            }
2148            for (var i = 0; i < testCurve.length; i += 2) {
2149                var testX = testCurve[i];
2150                var testY = testCurve[i + 1];
2151                var dx = testX - mouseX;
2152                var dy = testY - mouseY;
2153                var dist = dx * dx + dy * dy;
2154                if (dist > bestDistance) {
2155                    continue;
2156                }
2157                activeCurve = testCurve;
2158                activePt = i;
2159                bestDistance = dist;
2160            }
2161        }
2162        if (activePt >= 0) {
2163            lastX = mouseX;
2164            lastY = mouseY;
2165        }
2166    }
2167
2168    function handleMouseOver() {
2169        calcXY();
2170        if (draw_mouse_xy) {
2171            var num = mouseX.toFixed(decimal_places) + ", " + mouseY.toFixed(decimal_places);
2172            ctx.beginPath();
2173            ctx.rect(300, 100, num.length * 6, 10);
2174            ctx.fillStyle = "white";
2175            ctx.fill();
2176            ctx.font = "normal 10px Arial";
2177            ctx.fillStyle = "black";
2178            ctx.textAlign = "left";
2179            ctx.fillText(num, 300, 108);
2180        }
2181        if (!mouseDown) {
2182            activePt = -1;
2183            return;
2184        }
2185        if (activePt < 0) {
2186            initDown();
2187            return;
2188        }
2189        var deltaX = mouseX - lastX;
2190        var deltaY = mouseY - lastY;
2191        lastX = mouseX;
2192        lastY = mouseY;
2193        if (activePt == 0) {
2194            var test = tests[testIndex];
2195            for (var curves in test) {
2196                var testCurve = test[curves];
2197                testCurve[0] += deltaX;
2198                testCurve[1] += deltaY;
2199            }
2200        } else {
2201            activeCurve[activePt] += deltaX;
2202            activeCurve[activePt + 1] += deltaY;
2203        }
2204        redraw();
2205    }
2206
2207    function start() {
2208        for (var i = 0; i < testDivs.length; ++i) {
2209            var title = testDivs[i].id.toString();
2210            var str = testDivs[i].firstChild.data;
2211            parse(str, title);
2212        }
2213        drawTop();
2214        window.addEventListener('keypress', doKeyPress, true);
2215        window.addEventListener('keydown', doKeyDown, true);
2216        window.onresize = function () {
2217            drawTop();
2218        }
2219    }
2220
2221</script>
2222</head>
2223
2224<body onLoad="start();">
2225
2226<canvas id="canvas" width="750" height="500"
2227    onmousedown="mouseDown = true"
2228    onmouseup="mouseDown = false"
2229    onmousemove="handleMouseOver()"
2230    onclick="handleMouseClick()"
2231    ></canvas >
2232</body>
2233</html>