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>
957
958<script type="text/javascript">
959
960    var testDivs = [
961        skpcarrot_is24x,
962        skpwww_wartepop_blogspot_com_br_6,
963        skpwww_wartepop_blogspot_com_br_6a,
964        skpwww_galaxystwo_com_4,
965        skpwww_kitcheninspirations_wordpress_com_66,
966        skpwww_tcmevents_org_13,
967        skpwww_aceinfographics_com_106,
968        skpwww_educationalcraft_com_4b,
969        skpwww_educationalcraft_com_4a,
970        skpwww_educationalcraft_com_4,
971        cubicLineErr2,
972        cubicLineErr1,
973        cubicLineMiss1,
974        cubicLineMiss2,
975        cubicLineMiss3,
976        cubicLineMiss4,
977        skpwww_pindosiya_com_99,
978        self1,
979        skpwww_seopack_blogspot_com_2153,
980        serp1,
981        serp2,
982        serp3,
983        loop1,
984        skpwww_maturesupertube_com_21,
985        skpwww_cityads_ru_249,
986        skpelpais_com_18,
987        testQuads60_b,
988        testQuads60_a,
989        testQuads60,
990        skpwww_dealnews_com_315_a,
991        skpwww_dealnews_com_315,
992        skpnamecheap_405,
993        slop1,
994        slop2,
995        slop3,
996        slop4,
997        slop5,
998        slop6,
999        slop7,
1000        slop8,
1001        slop9,
1002        slop10,
1003        slop11,
1004        slop12,
1005        slop13,
1006        slop14,
1007        slop15,
1008        slop16,
1009        slop17,
1010        slop18,
1011        slop19,
1012        slop20,
1013        skpcarrot_is24e,
1014        skpcarrot_is24d,
1015        skpcarrot_is24c,
1016        skpcarrot_is24b,
1017        skpcarrot_is24a,
1018        skpcarrot_is24,
1019        testQuads59,
1020        testQuads45,
1021        testQuads54,
1022        findFirst1,
1023        cubicOp59d,
1024        testQuads22,
1025        cubicOp85d,
1026        cubicOp104,
1027        skpnational_com_au81,
1028        cubicOp35d,
1029        testQuad23,
1030        testQuad22,
1031        testQuad21,
1032        testQuad15,
1033        testQuadratic56,
1034        xop1i,
1035        xOp2i,
1036        xop1u,
1037        skpwww_joomla_org_23,
1038        cubicOp109,
1039        cubicOp106,
1040        cubicOp105,
1041        carpetplanet1,
1042        eldorado1,
1043        cubicOp25i,
1044        cubicOp7d,
1045        simplifyQuadratic27,
1046        simplifyQuadratic56a,
1047        simplifyQuadratic56,
1048        quadratic58again,
1049        simplifyQuadratic58a,
1050        simplifyQuadratic58,
1051        simplifyQuadratic36,
1052        quad89987,
1053        quad8741,
1054        quad8b,
1055        quad8a,
1056        quad208,
1057        quad67242,
1058        quad37226,
1059        quad35237,
1060        quad108,
1061        quad212,
1062        quad3160,
1063        quad640,
1064        quad206,
1065        quad136,
1066        quad113,
1067        quad999,
1068        quad0,
1069        quad179,
1070        quad4a,
1071        quad94,
1072        quad77,
1073        quad22a,
1074        quad14a,
1075        quad809,
1076        quad653,
1077        quad584,
1078        quad413,
1079        quad379,
1080        quad159,
1081        quad232,
1082        quad40,
1083        quad39,
1084        quad38,
1085        quad37,
1086        quad36,
1087        quad35,
1088        quad34,
1089        quad33,
1090        quad32,
1091        quad31,
1092        quad30,
1093        quad29,
1094        quad28,
1095        quad27,
1096        quad26,
1097        quad25,
1098        quad24,
1099        quad23,
1100        quad22,
1101        quad21,
1102        quad20,
1103        quad19,
1104        quad18,
1105        quad17,
1106        quad16,
1107        quad15,
1108        quad14,
1109        quad13,
1110        quad12,
1111        quad11,
1112        cubic2,
1113        cubic1,
1114        quad1,
1115        quad2,
1116        quad3,
1117        quad4,
1118        quad5,
1119        quad6,
1120        quad7,
1121        quad8,
1122        quad9,
1123        quad10,
1124    ];
1125
1126    var tests = [];
1127    var testTitles = [];
1128    var testIndex = 0;
1129    var ctx;
1130    var subscale = 1;
1131    var xmin, xmax, ymin, ymax;
1132    var scale;
1133    var initScale;
1134    var mouseX, mouseY;
1135    var mouseDown = false;
1136    var srcLeft, srcTop;
1137    var screenWidth, screenHeight;
1138    var drawnPts;
1139    var curveT = 0;
1140
1141    var lastX, lastY;
1142    var activeCurve = [];
1143    var activePt;
1144
1145    var decimal_places = 3;
1146
1147    var draw_t = false;
1148    var draw_closest_t = false;
1149    var draw_derivative = false;
1150    var draw_endpoints = true;
1151    var draw_midpoint = 0;
1152    var draw_mouse_xy = false;
1153    var draw_order = false;
1154    var draw_point_xy = false;
1155    var draw_ray_intersect = false;
1156    var draw_quarterpoint = 0;
1157    var draw_tangents = 1;
1158    var draw_sortpoint = 0;
1159    var retina_scale = !!window.devicePixelRatio;
1160
1161    function parse(test, title) {
1162        var curveStrs = test.split("{{");
1163        var pattern = /-?\d+\.*\d*e?-?\d*/g;
1164        var curves = [];
1165        for (var c in curveStrs) {
1166            var curveStr = curveStrs[c];
1167            var points = curveStr.match(pattern);
1168            var pts = [];
1169            for (var wd in points) {
1170                var num = parseFloat(points[wd]);
1171                if (isNaN(num)) continue;
1172                pts.push(num);
1173            }
1174            if (pts.length > 2)
1175                curves.push(pts);
1176        }
1177        if (curves.length >= 1) {
1178            tests.push(curves);
1179            testTitles.push(title);
1180        }
1181    }
1182
1183    function init(test) {
1184        var canvas = document.getElementById('canvas');
1185        if (!canvas.getContext) return;
1186        ctx = canvas.getContext('2d');
1187        var resScale = retina_scale && window.devicePixelRatio ? window.devicePixelRatio : 1;
1188        var unscaledWidth = window.innerWidth - 20;
1189        var unscaledHeight = window.innerHeight - 20;
1190        screenWidth = unscaledWidth;
1191        screenHeight = unscaledHeight;
1192        canvas.width = unscaledWidth * resScale;
1193        canvas.height = unscaledHeight * resScale;
1194        canvas.style.width = unscaledWidth + 'px';
1195        canvas.style.height = unscaledHeight + 'px';
1196        if (resScale != 1) {
1197            ctx.scale(resScale, resScale);
1198        }
1199        xmin = Infinity;
1200        xmax = -Infinity;
1201        ymin = Infinity;
1202        ymax = -Infinity;
1203        for (var curves in test) {
1204            var curve = test[curves];
1205            var last = curve.length;
1206            for (var idx = 0; idx < last; idx += 2) {
1207                xmin = Math.min(xmin, curve[idx]);
1208                xmax = Math.max(xmax, curve[idx]);
1209                ymin = Math.min(ymin, curve[idx + 1]);
1210                ymax = Math.max(ymax, curve[idx + 1]);
1211            }
1212        }
1213        xmin -= 1;
1214        var testW = xmax - xmin;
1215        var testH = ymax - ymin;
1216        subscale = 1;
1217        while (testW * subscale < 0.1 && testH * subscale < 0.1) {
1218            subscale *= 10;
1219        }
1220        while (testW * subscale > 10 && testH * subscale > 10) {
1221            subscale /= 10;
1222        }
1223        setScale(xmin, xmax, ymin, ymax);
1224        mouseX = (screenWidth / 2) / scale + srcLeft;
1225        mouseY = (screenHeight / 2) / scale + srcTop;
1226        initScale = scale;
1227    }
1228
1229    function setScale(x0, x1, y0, y1) {
1230        var srcWidth = x1 - x0;
1231        var srcHeight = y1 - y0;
1232        var usableWidth = screenWidth;
1233        var xDigits = Math.ceil(Math.log(Math.abs(xmax)) / Math.log(10));
1234        var yDigits = Math.ceil(Math.log(Math.abs(ymax)) / Math.log(10));
1235        usableWidth -= (xDigits + yDigits) * 10;
1236        usableWidth -= decimal_places * 10;
1237        var hscale = usableWidth / srcWidth;
1238        var vscale = screenHeight / srcHeight;
1239        scale = Math.min(hscale, vscale);
1240        var invScale = 1 / scale;
1241        var sxmin = x0 - invScale * 5;
1242        var symin = y0 - invScale * 10;
1243        var sxmax = x1 + invScale * (6 * decimal_places + 10);
1244        var symax = y1 + invScale * 10;
1245        srcWidth = sxmax - sxmin;
1246        srcHeight = symax - symin;
1247        hscale = usableWidth / srcWidth;
1248        vscale = screenHeight / srcHeight;
1249        scale = Math.min(hscale, vscale);
1250        srcLeft = sxmin;
1251        srcTop = symin;
1252    }
1253
1254function dxy_at_t(curve, t) {
1255    var dxy = {};
1256    if (curve.length == 6) {
1257        var a = t - 1;
1258        var b = 1 - 2 * t;
1259        var c = t;
1260        dxy.x = a * curve[0] + b * curve[2] + c * curve[4];
1261        dxy.y = a * curve[1] + b * curve[3] + c * curve[5];
1262    } else if (curve.length == 8) {
1263        var one_t = 1 - t;
1264        var a = curve[0];
1265        var b = curve[2];
1266        var c = curve[4];
1267        var d = curve[6];
1268        dxy.x = 3 * ((b - a) * one_t * one_t + 2 * (c - b) * t * one_t + (d - c) * t * t);
1269        a = curve[1];
1270        b = curve[3];
1271        c = curve[5];
1272        d = curve[7];
1273        dxy.y = 3 * ((b - a) * one_t * one_t + 2 * (c - b) * t * one_t + (d - c) * t * t);
1274    }
1275    return dxy;
1276}
1277
1278    var flt_epsilon = 1.19209290E-07;
1279
1280    function approximately_zero(A) {
1281        return Math.abs(A) < flt_epsilon;
1282    }
1283
1284    function approximately_zero_inverse(A) {
1285        return Math.abs(A) > (1 / flt_epsilon);
1286    }
1287
1288    function quad_real_roots(A, B, C) {
1289        var s = [];
1290        var p = B / (2 * A);
1291        var q = C / A;
1292        if (approximately_zero(A) && (approximately_zero_inverse(p)
1293                || approximately_zero_inverse(q))) {
1294            if (approximately_zero(B)) {
1295                if (C == 0) {
1296                    s[0] = 0;
1297                }
1298                return s;
1299            }
1300            s[0] = -C / B;
1301            return s;
1302        }
1303        /* normal form: x^2 + px + q = 0 */
1304        var p2 = p * p;
1305        if (!approximately_zero(p2 - q) && p2 < q) {
1306            return s;
1307        }
1308        var sqrt_D = 0;
1309        if (p2 > q) {
1310            sqrt_D = Math.sqrt(p2 - q);
1311        }
1312        s[0] = sqrt_D - p;
1313        var flip = -sqrt_D - p;
1314        if (!approximately_zero(s[0] - flip)) {
1315            s[1] = flip;
1316        }
1317        return s;
1318    }
1319
1320    function cubic_real_roots(A, B, C, D) {
1321        if (approximately_zero(A)) {  // we're just a quadratic
1322            return quad_real_roots(B, C, D);
1323        }
1324        if (approximately_zero(D)) {  // 0 is one root
1325            var s = quad_real_roots(A, B, C);
1326            for (var i = 0; i < s.length; ++i) {
1327                if (approximately_zero(s[i])) {
1328                    return s;
1329                }
1330            }
1331            s.push(0);
1332            return s;
1333        }
1334        if (approximately_zero(A + B + C + D)) {  // 1 is one root
1335            var s = quad_real_roots(A, A + B, -D);
1336            for (var i = 0; i < s.length; ++i) {
1337                if (approximately_zero(s[i] - 1)) {
1338                    return s;
1339                }
1340            }
1341            s.push(1);
1342            return s;
1343        }
1344        var a, b, c;
1345        var invA = 1 / A;
1346        a = B * invA;
1347        b = C * invA;
1348        c = D * invA;
1349        var a2 = a * a;
1350        var Q = (a2 - b * 3) / 9;
1351        var R = (2 * a2 * a - 9 * a * b + 27 * c) / 54;
1352        var R2 = R * R;
1353        var Q3 = Q * Q * Q;
1354        var R2MinusQ3 = R2 - Q3;
1355        var adiv3 = a / 3;
1356        var r;
1357        var roots = [];
1358        if (R2MinusQ3 < 0) {   // we have 3 real roots
1359            var theta = Math.acos(R / Math.sqrt(Q3));
1360            var neg2RootQ = -2 * Math.sqrt(Q);
1361            r = neg2RootQ * Math.cos(theta / 3) - adiv3;
1362            roots.push(r);
1363            r = neg2RootQ * Math.cos((theta + 2 * Math.PI) / 3) - adiv3;
1364            if (!approximately_zero(roots[0] - r)) {
1365                roots.push(r);
1366            }
1367            r = neg2RootQ * Math.cos((theta - 2 * Math.PI) / 3) - adiv3;
1368            if (!approximately_zero(roots[0] - r) && (roots.length == 1
1369                        || !approximately_zero(roots[1] - r))) {
1370                roots.push(r);
1371            }
1372        } else {  // we have 1 real root
1373            var sqrtR2MinusQ3 = Math.sqrt(R2MinusQ3);
1374            var A = Math.abs(R) + sqrtR2MinusQ3;
1375            A = Math.pow(A, 1/3);
1376            if (R > 0) {
1377                A = -A;
1378            }
1379            if (A != 0) {
1380                A += Q / A;
1381            }
1382            r = A - adiv3;
1383            roots.push(r);
1384            if (approximately_zero(R2 - Q3)) {
1385                r = -A / 2 - adiv3;
1386                if (!approximately_zero(s[0] - r)) {
1387                    roots.push(r);
1388                }
1389            }
1390        }
1391        return roots;
1392    }
1393
1394    function approximately_zero_or_more(tValue) {
1395        return tValue >= -flt_epsilon;
1396    }
1397
1398    function approximately_one_or_less(tValue) {
1399        return tValue <= 1 + flt_epsilon;
1400    }
1401
1402    function approximately_less_than_zero(tValue) {
1403        return tValue < flt_epsilon;
1404    }
1405
1406    function approximately_greater_than_one(tValue) {
1407        return tValue > 1 - flt_epsilon;
1408    }
1409
1410    function add_valid_ts(s) {
1411        var t = [];
1412    nextRoot:
1413        for (var index = 0; index < s.length; ++index) {
1414            var tValue = s[index];
1415            if (approximately_zero_or_more(tValue) && approximately_one_or_less(tValue)) {
1416                if (approximately_less_than_zero(tValue)) {
1417                    tValue = 0;
1418                } else if (approximately_greater_than_one(tValue)) {
1419                    tValue = 1;
1420                }
1421                for (var idx2 = 0; idx2 < t.length; ++idx2) {
1422                    if (approximately_zero(t[idx2] - tValue)) {
1423                        continue nextRoot;
1424                    }
1425                }
1426                t.push(tValue);
1427            }
1428        }
1429        return t;
1430    }
1431
1432    function quad_roots(A, B, C) {
1433        var s = quad_real_roots(A, B, C);
1434        var foundRoots = add_valid_ts(s);
1435        return foundRoots;
1436    }
1437
1438    function cubic_roots(A, B, C, D) {
1439        var s = cubic_real_roots(A, B, C, D);
1440        var foundRoots = add_valid_ts(s);
1441        return foundRoots;
1442    }
1443
1444    function ray_curve_intersect(startPt, endPt, curve) {
1445        var adj = endPt[0] - startPt[0];
1446        var opp = endPt[1] - startPt[1];
1447        var r = [];
1448        for (var n = 0; n < curve.length / 2; ++n) {
1449            r[n] = (curve[n * 2 + 1] - startPt[1]) * adj - (curve[n * 2] - startPt[0]) * opp;
1450        }
1451        if (curve.length == 6) {
1452            var A = r[2];
1453            var B = r[1];
1454            var C = r[0];
1455            A += C - 2 * B;  // A = a - 2*b + c
1456            B -= C;  // B = -(b - c)
1457            return quad_roots(A, 2 * B, C);
1458        }
1459        var A = r[3];       // d
1460        var B = r[2] * 3;   // 3*c
1461        var C = r[1] * 3;   // 3*b
1462        var D = r[0];       // a
1463        A -= D - C + B;     // A =   -a + 3*b - 3*c + d
1464        B += 3 * D - 2 * C; // B =  3*a - 6*b + 3*c
1465        C -= 3 * D;         // C = -3*a + 3*b
1466        return cubic_roots(A, B, C, D);
1467    }
1468
1469    function x_at_t(curve, t) {
1470        var one_t = 1 - t;
1471        if (curve.length == 4) {
1472            return one_t * curve[0] + t * curve[2];
1473        }
1474        var one_t2 = one_t * one_t;
1475        var t2 = t * t;
1476        if (curve.length == 6) {
1477            return one_t2 * curve[0] + 2 * one_t * t * curve[2] + t2 * curve[4];
1478        }
1479        var a = one_t2 * one_t;
1480        var b = 3 * one_t2 * t;
1481        var c = 3 * one_t * t2;
1482        var d = t2 * t;
1483        return a * curve[0] + b * curve[2] + c * curve[4] + d * curve[6];
1484    }
1485
1486    function y_at_t(curve, t) {
1487        var one_t = 1 - t;
1488        if (curve.length == 4) {
1489            return one_t * curve[1] + t * curve[3];
1490        }
1491        var one_t2 = one_t * one_t;
1492        var t2 = t * t;
1493        if (curve.length == 6) {
1494            return one_t2 * curve[1] + 2 * one_t * t * curve[3] + t2 * curve[5];
1495        }
1496        var a = one_t2 * one_t;
1497        var b = 3 * one_t2 * t;
1498        var c = 3 * one_t * t2;
1499        var d = t2 * t;
1500        return a * curve[1] + b * curve[3] + c * curve[5] + d * curve[7];
1501    }
1502
1503    function drawPointAtT(curve) {
1504        var x = x_at_t(curve, curveT);
1505        var y = y_at_t(curve, curveT);
1506        drawPoint(x, y);
1507    }
1508
1509    function drawLine(x1, y1, x2, y2) {
1510        ctx.beginPath();
1511        ctx.moveTo((x1 - srcLeft) * scale,
1512                (y1 - srcTop) * scale);
1513        ctx.lineTo((x2 - srcLeft) * scale,
1514                (y2 - srcTop) * scale);
1515        ctx.stroke();
1516    }
1517
1518    function drawPoint(px, py) {
1519        for (var pts = 0; pts < drawnPts.length; pts += 2) {
1520            var x = drawnPts[pts];
1521            var y = drawnPts[pts + 1];
1522            if (px == x && py == y) {
1523                return;
1524            }
1525        }
1526        drawnPts.push(px);
1527        drawnPts.push(py);
1528        var _px = (px - srcLeft) * scale;
1529        var _py = (py - srcTop) * scale;
1530        ctx.beginPath();
1531        ctx.arc(_px, _py, 3, 0, Math.PI * 2, true);
1532        ctx.closePath();
1533        ctx.stroke();
1534        if (draw_point_xy) {
1535            var label = px.toFixed(decimal_places) + ", " + py.toFixed(decimal_places);
1536            ctx.font = "normal 10px Arial";
1537            ctx.textAlign = "left";
1538            ctx.fillStyle = "black";
1539            ctx.fillText(label, _px + 5, _py);
1540        }
1541    }
1542
1543    function drawPointSolid(px, py) {
1544        drawPoint(px, py);
1545        ctx.fillStyle = "rgba(0,0,0, 0.4)";
1546        ctx.fill();
1547    }
1548
1549    function crossPt(origin, pt1, pt2) {
1550        return ((pt1[0] - origin[0]) * (pt2[1] - origin[1])
1551              - (pt1[1] - origin[1]) * (pt2[0] - origin[0])) > 0 ? 0 : 1;
1552    }
1553
1554    // may not work well for cubics
1555    function curveClosestT(curve, x, y) {
1556        var closest = -1;
1557        var closestDist = Infinity;
1558        var l = Infinity, t = Infinity, r = -Infinity, b = -Infinity;
1559        for (var i = 0; i < 16; ++i) {
1560            var testX = x_at_t(curve, i / 16);
1561            l = Math.min(testX, l);
1562            r = Math.max(testX, r);
1563            var testY = y_at_t(curve, i / 16);
1564            t = Math.min(testY, t);
1565            b = Math.max(testY, b);
1566            var dx = testX - x;
1567            var dy = testY - y;
1568            var dist = dx * dx + dy * dy;
1569            if (closestDist > dist) {
1570                closestDist = dist;
1571                closest = i;
1572            }
1573        }
1574        var boundsX = r - l;
1575        var boundsY = b - t;
1576        var boundsDist = boundsX * boundsX + boundsY * boundsY;
1577        if (closestDist > boundsDist) {
1578            return -1;
1579        }
1580        console.log("closestDist = " + closestDist + " boundsDist = " + boundsDist
1581                + " t = " + closest / 16);
1582        return closest / 16;
1583    }
1584
1585    function draw(test, title) {
1586        ctx.font = "normal 50px Arial";
1587        ctx.textAlign = "left";
1588        ctx.fillStyle = "rgba(0,0,0, 0.1)";
1589        ctx.fillText(title, 50, 50);
1590        ctx.font = "normal 10px Arial";
1591        //  ctx.lineWidth = "1.001"; "0.999";
1592        var hullStarts = [];
1593        var hullEnds = [];
1594        var midSpokes = [];
1595        var midDist = [];
1596        var origin = [];
1597        var shortSpokes = [];
1598        var shortDist = [];
1599        var sweeps = [];
1600        drawnPts = [];
1601        for (var curves in test) {
1602            var curve = test[curves];
1603            origin.push(curve[0]);
1604            origin.push(curve[1]);
1605            var startPt = [];
1606            startPt.push(curve[2]);
1607            startPt.push(curve[3]);
1608            hullStarts.push(startPt);
1609            var endPt = [];
1610            if (curve.length == 4) {
1611                endPt.push(curve[2]);
1612                endPt.push(curve[3]);
1613            } else if (curve.length == 6) {
1614                endPt.push(curve[4]);
1615                endPt.push(curve[5]);
1616            } else if (curve.length == 8) {
1617                endPt.push(curve[6]);
1618                endPt.push(curve[7]);
1619            }
1620            hullEnds.push(endPt);
1621            var sweep = crossPt(origin, startPt, endPt);
1622            sweeps.push(sweep);
1623            var midPt = [];
1624            midPt.push(x_at_t(curve, 0.5));
1625            midPt.push(y_at_t(curve, 0.5));
1626            midSpokes.push(midPt);
1627            var shortPt = [];
1628            shortPt.push(x_at_t(curve, 0.25));
1629            shortPt.push(y_at_t(curve, 0.25));
1630            shortSpokes.push(shortPt);
1631            var dx = midPt[0] - origin[0];
1632            var dy = midPt[1] - origin[1];
1633            var dist = Math.sqrt(dx * dx + dy * dy);
1634            midDist.push(dist);
1635            dx = shortPt[0] - origin[0];
1636            dy = shortPt[1] - origin[1];
1637            dist = Math.sqrt(dx * dx + dy * dy);
1638            shortDist.push(dist);
1639        }
1640        var intersect = [];
1641        var useIntersect = false;
1642        var maxWidth = Math.max(xmax - xmin, ymax - ymin);
1643        for (var curves in test) {
1644            var curve = test[curves];
1645            if (curve.length == 6 || curve.length == 8) {
1646                var opp = curves == 0 || curves == 1 ? 0 : 1;
1647                var sects = ray_curve_intersect(origin, hullEnds[opp], curve);
1648                intersect.push(sects);
1649                if (sects.length > 1) {
1650                    var intersection = sects[0];
1651                    if (intersection == 0) {
1652                        intersection = sects[1];
1653                    }
1654                    var ix = x_at_t(curve, intersection) - origin[0];
1655                    var iy = y_at_t(curve, intersection) - origin[1];
1656                    var ex = hullEnds[opp][0] - origin[0];
1657                    var ey = hullEnds[opp][1] - origin[1];
1658                    if (ix * ex >= 0 && iy * ey >= 0) {
1659                        var iDist = Math.sqrt(ix * ix + iy * iy);
1660                        var eDist = Math.sqrt(ex * ex + ey * ey);
1661                        var delta = Math.abs(iDist - eDist) / maxWidth;
1662                        if (delta > (curve.length == 6 ? 1e-5 : 1e-4)) {
1663                            useIntersect ^= true;
1664                        }
1665                    }
1666                }
1667            }
1668        }
1669        var midLeft = curves != 0 ? crossPt(origin, midSpokes[0], midSpokes[1]) : 0;
1670        var firstInside;
1671        if (useIntersect) {
1672            var sect1 = intersect[0].length > 1;
1673            var sIndex = sect1 ? 0 : 1;
1674            var sects = intersect[sIndex];
1675            var intersection = sects[0];
1676            if (intersection == 0) {
1677                intersection = sects[1];
1678            }
1679            var curve = test[sIndex];
1680            var ix = x_at_t(curve, intersection) - origin[0];
1681            var iy = y_at_t(curve, intersection) - origin[1];
1682            var opp = sect1 ? 1 : 0;
1683            var ex = hullEnds[opp][0] - origin[0];
1684            var ey = hullEnds[opp][1] - origin[1];
1685            var iDist = ix * ix + iy * iy;
1686            var eDist = ex * ex + ey * ey;
1687            firstInside = (iDist > eDist) ^ (sIndex == 0) ^ sweeps[0];
1688//            console.log("iDist=" + iDist + " eDist=" + eDist + " sIndex=" + sIndex
1689 //                   + " sweeps[0]=" + sweeps[0]);
1690        } else {
1691 //           console.log("midLeft=" + midLeft);
1692            firstInside = midLeft != 0;
1693        }
1694        var shorter = midDist[1] < midDist[0];
1695        var shortLeft = shorter ? crossPt(origin, shortSpokes[0], midSpokes[1])
1696                : crossPt(origin, midSpokes[0], shortSpokes[1]);
1697        var startCross = crossPt(origin, hullStarts[0], hullStarts[1]);
1698        var disallowShort = midLeft == startCross && midLeft == sweeps[0]
1699                    && midLeft == sweeps[1];
1700
1701  //      console.log("midLeft=" + midLeft + " startCross=" + startCross);
1702        var intersectIndex = 0;
1703        for (var curves in test) {
1704            var curve = test[curves];
1705            if (curve.length != 4 && curve.length != 6 && curve.length != 8) {
1706                continue;
1707            }
1708            ctx.lineWidth = 1;
1709            if (draw_tangents != 0) {
1710                if (firstInside == curves) {
1711                    ctx.strokeStyle = "rgba(255,0,0, 0.3)";
1712                } else {
1713                    ctx.strokeStyle = "rgba(0,0,255, 0.3)";
1714                }
1715                drawLine(curve[0], curve[1], curve[2], curve[3]);
1716                if (draw_tangents != 2) {
1717                    if (curve.length > 4) drawLine(curve[2], curve[3], curve[4], curve[5]);
1718                    if (curve.length > 6) drawLine(curve[4], curve[5], curve[6], curve[7]);
1719                }
1720                if (draw_tangents != 1) {
1721                    if (curve.length == 6) drawLine(curve[0], curve[1], curve[4], curve[5]);
1722                    if (curve.length == 8) drawLine(curve[0], curve[1], curve[6], curve[7]);
1723                }
1724            }
1725            ctx.beginPath();
1726            ctx.moveTo((curve[0] - srcLeft) * scale, (curve[1] - srcTop) * scale);
1727            if (curve.length == 4) {
1728                ctx.lineTo((curve[2] - srcLeft) * scale, (curve[3] - srcTop) * scale);
1729            } else if (curve.length == 6) {
1730                ctx.quadraticCurveTo(
1731                    (curve[2] - srcLeft) * scale, (curve[3] - srcTop) * scale,
1732                    (curve[4] - srcLeft) * scale, (curve[5] - srcTop) * scale);
1733            } else {
1734                ctx.bezierCurveTo(
1735                    (curve[2] - srcLeft) * scale, (curve[3] - srcTop) * scale,
1736                    (curve[4] - srcLeft) * scale, (curve[5] - srcTop) * scale,
1737                    (curve[6] - srcLeft) * scale, (curve[7] - srcTop) * scale);
1738            }
1739            if (firstInside == curves) {
1740                ctx.strokeStyle = "rgba(255,0,0, 1)";
1741            } else {
1742                ctx.strokeStyle = "rgba(0,0,255, 1)";
1743            }
1744            ctx.stroke();
1745            if (draw_endpoints) {
1746                drawPoint(curve[0], curve[1]);
1747                drawPoint(curve[2], curve[3]);
1748                if (curve.length > 4) drawPoint(curve[4], curve[5]);
1749                if (curve.length > 6) drawPoint(curve[6], curve[7]);
1750            }
1751            if (draw_midpoint != 0) {
1752                if ((curves == 0) == (midLeft == 0)) {
1753                    ctx.strokeStyle = "rgba(0,180,127, 0.6)";
1754                } else {
1755                    ctx.strokeStyle = "rgba(127,0,127, 0.6)";
1756                }
1757                var midX = x_at_t(curve, 0.5);
1758                var midY = y_at_t(curve, 0.5);
1759                drawPointSolid(midX, midY);
1760                if (draw_midpoint > 1) {
1761                    drawLine(curve[0], curve[1], midX, midY);
1762                }
1763            }
1764            if (draw_quarterpoint != 0) {
1765                if ((curves == 0) == (shortLeft == 0)) {
1766                    ctx.strokeStyle = "rgba(0,191,63, 0.6)";
1767                } else {
1768                    ctx.strokeStyle = "rgba(63,0,191, 0.6)";
1769                }
1770                var midT = (curves == 0) == shorter ? 0.25 : 0.5;
1771                var midX = x_at_t(curve, midT);
1772                var midY = y_at_t(curve, midT);
1773                drawPointSolid(midX, midY);
1774                if (draw_quarterpoint > 1) {
1775                    drawLine(curve[0], curve[1], midX, midY);
1776                }
1777            }
1778            if (draw_sortpoint != 0) {
1779                if ((curves == 0) == ((disallowShort == -1 ? midLeft : shortLeft) == 0)) {
1780                    ctx.strokeStyle = "rgba(0,155,37, 0.6)";
1781                } else {
1782                    ctx.strokeStyle = "rgba(37,0,155, 0.6)";
1783                }
1784                var midT = (curves == 0) == shorter && disallowShort != curves ? 0.25 : 0.5;
1785                console.log("curves=" + curves + " disallowShort=" + disallowShort
1786                        + " midLeft=" + midLeft + " shortLeft=" + shortLeft
1787                        + " shorter=" + shorter + " midT=" + midT);
1788                var midX = x_at_t(curve, midT);
1789                var midY = y_at_t(curve, midT);
1790                drawPointSolid(midX, midY);
1791                if (draw_sortpoint > 1) {
1792                    drawLine(curve[0], curve[1], midX, midY);
1793                }
1794            }
1795            if (draw_ray_intersect != 0) {
1796                ctx.strokeStyle = "rgba(75,45,199, 0.6)";
1797                if (curve.length == 6 || curve.length == 8) {
1798                    var intersections = intersect[intersectIndex];
1799                    for (var i in intersections) {
1800                        var intersection = intersections[i];
1801                        var x = x_at_t(curve, intersection);
1802                        var y = y_at_t(curve, intersection);
1803                        drawPointSolid(x, y);
1804                        if (draw_ray_intersect > 1) {
1805                            drawLine(curve[0], curve[1], x, y);
1806                        }
1807                    }
1808                }
1809                ++intersectIndex;
1810            }
1811            if (draw_order) {
1812                var px = x_at_t(curve, 0.75);
1813                var py = y_at_t(curve, 0.75);
1814                var _px = (px - srcLeft) * scale;
1815                var _py = (py - srcTop) * scale;
1816                ctx.beginPath();
1817                ctx.arc(_px, _py, 15, 0, Math.PI * 2, true);
1818                ctx.closePath();
1819                ctx.fillStyle = "white";
1820                ctx.fill();
1821                if (firstInside == curves) {
1822                    ctx.strokeStyle = "rgba(255,0,0, 1)";
1823                    ctx.fillStyle = "rgba(255,0,0, 1)";
1824                } else {
1825                    ctx.strokeStyle = "rgba(0,0,255, 1)";
1826                    ctx.fillStyle = "rgba(0,0,255, 1)";
1827                }
1828                ctx.stroke();
1829                ctx.font = "normal 16px Arial";
1830                ctx.textAlign = "center";
1831                ctx.fillText(parseInt(curves) + 1, _px, _py + 5);
1832            }
1833            if (draw_closest_t) {
1834                var t = curveClosestT(curve, mouseX, mouseY);
1835                if (t >= 0) {
1836                    var x = x_at_t(curve, t);
1837                    var y = y_at_t(curve, t);
1838                    drawPointSolid(x, y);
1839                }
1840            }
1841            if (!approximately_zero(scale - initScale)) {
1842                ctx.font = "normal 20px Arial";
1843                ctx.fillStyle = "rgba(0,0,0, 0.3)";
1844                ctx.textAlign = "right";
1845                ctx.fillText(scale.toFixed(decimal_places) + 'x',
1846                        screenWidth - 10, screenHeight - 5);
1847            }
1848            if (draw_t) {
1849                drawPointAtT(curve);
1850            }
1851        }
1852        if (draw_t) {
1853            drawCurveTControl();
1854        }
1855    }
1856
1857    function drawCurveTControl() {
1858        ctx.lineWidth = 2;
1859        ctx.strokeStyle = "rgba(0,0,0, 0.3)";
1860        ctx.beginPath();
1861        ctx.rect(screenWidth - 80, 40, 28, screenHeight - 80);
1862        ctx.stroke();
1863        var ty = 40 + curveT * (screenHeight - 80);
1864        ctx.beginPath();
1865        ctx.moveTo(screenWidth - 80, ty);
1866        ctx.lineTo(screenWidth - 85, ty - 5);
1867        ctx.lineTo(screenWidth - 85, ty + 5);
1868        ctx.lineTo(screenWidth - 80, ty);
1869        ctx.fillStyle = "rgba(0,0,0, 0.6)";
1870        ctx.fill();
1871        var num = curveT.toFixed(decimal_places);
1872        ctx.font = "normal 10px Arial";
1873        ctx.textAlign = "left";
1874        ctx.fillText(num, screenWidth - 78, ty);
1875    }
1876
1877    function ptInTControl() {
1878        var e = window.event;
1879        var tgt = e.target || e.srcElement;
1880        var left = tgt.offsetLeft;
1881        var top = tgt.offsetTop;
1882        var x = (e.clientX - left);
1883        var y = (e.clientY - top);
1884        if (x < screenWidth - 80 || x > screenWidth - 50) {
1885            return false;
1886        }
1887        if (y < 40 || y > screenHeight - 80) {
1888            return false;
1889        }
1890        curveT = (y - 40) / (screenHeight - 120);
1891        if (curveT < 0 || curveT > 1) {
1892            throw "stop execution";
1893        }
1894        return true;
1895    }
1896
1897    function drawTop() {
1898        init(tests[testIndex]);
1899        redraw();
1900    }
1901
1902    function redraw() {
1903        ctx.beginPath();
1904        ctx.rect(0, 0, ctx.canvas.width, ctx.canvas.height);
1905        ctx.fillStyle = "white";
1906        ctx.fill();
1907        draw(tests[testIndex], testTitles[testIndex]);
1908    }
1909
1910    function doKeyPress(evt) {
1911        var char = String.fromCharCode(evt.charCode);
1912        switch (char) {
1913            case '0':
1914            case '1':
1915            case '2':
1916            case '3':
1917            case '4':
1918            case '5':
1919            case '6':
1920            case '7':
1921            case '8':
1922            case '9':
1923                decimal_places = char - '0';
1924                redraw();
1925                break;
1926            case '-':
1927                scale /= 2;
1928                calcLeftTop();
1929                redraw();
1930                break;
1931            case '=':
1932            case '+':
1933                scale *= 2;
1934                calcLeftTop();
1935                redraw();
1936                break;
1937            case 'c':
1938                drawTop();
1939                break;
1940            case 'd':
1941                var test = tests[testIndex];
1942                var testClone = [];
1943                for (var curves in test) {
1944                    var c = test[curves];
1945                    var cClone = [];
1946                    for (var index = 0; index < c.length; ++index) {
1947                        cClone.push(c[index]);
1948                    }
1949                    testClone.push(cClone);
1950                }
1951                tests.push(testClone);
1952                testTitles.push(testTitles[testIndex] + " copy");
1953                testIndex = tests.length - 1;
1954                redraw();
1955                break;
1956            case 'e':
1957                draw_endpoints ^= true;
1958                redraw();
1959                break;
1960            case 'f':
1961                draw_derivative ^= true;
1962                redraw();
1963                break;
1964            case 'i':
1965                draw_ray_intersect = (draw_ray_intersect + 1) % 3;
1966                redraw();
1967                break;
1968            case 'l':
1969                var test = tests[testIndex];
1970                console.log("<div id=\"" + testTitles[testIndex] + "\" >");
1971                for (var curves in test) {
1972                    var c = test[curves];
1973                    var s = "{{";
1974                    for (var i = 0; i < c.length; i += 2) {
1975                        s += "{";
1976                        s += c[i] + "," + c[i + 1];
1977                        s += "}";
1978                        if (i + 2 < c.length) {
1979                            s += ", ";
1980                        }
1981                    }
1982                    console.log(s + "}},");
1983                }
1984                console.log("</div>");
1985                break;
1986            case 'm':
1987                draw_midpoint = (draw_midpoint + 1) % 3;
1988                redraw();
1989                break;
1990            case 'N':
1991                testIndex += 9;
1992            case 'n':
1993                testIndex = (testIndex + 1) % tests.length;
1994                drawTop();
1995                break;
1996            case 'o':
1997                draw_order ^= true;
1998                redraw();
1999                break;
2000            case 'P':
2001                testIndex -= 9;
2002            case 'p':
2003                if (--testIndex < 0)
2004                    testIndex = tests.length - 1;
2005                drawTop();
2006                break;
2007            case 'q':
2008                draw_quarterpoint = (draw_quarterpoint + 1) % 3;
2009                redraw();
2010                break;
2011            case 'r':
2012                for (var i = 0; i < testDivs.length; ++i) {
2013                    var title = testDivs[i].id.toString();
2014                    if (title == testTitles[testIndex]) {
2015                        var str = testDivs[i].firstChild.data;
2016                        parse(str, title);
2017                        var original = tests.pop();
2018                        testTitles.pop();
2019                        tests[testIndex] = original;
2020                        break;
2021                    }
2022                }
2023                redraw();
2024                break;
2025            case 's':
2026                draw_sortpoint = (draw_sortpoint + 1) % 3;
2027                redraw();
2028                break;
2029            case 't':
2030                draw_t ^= true;
2031                redraw();
2032                break;
2033            case 'u':
2034                draw_closest_t ^= true;
2035                redraw();
2036                break;
2037            case 'v':
2038                draw_tangents = (draw_tangents + 1) % 4;
2039                redraw();
2040                break;
2041            case 'x':
2042                draw_point_xy ^= true;
2043                redraw();
2044                break;
2045            case 'y':
2046                draw_mouse_xy ^= true;
2047                redraw();
2048                break;
2049            case '\\':
2050                retina_scale ^= true;
2051                drawTop();
2052                break;
2053        }
2054    }
2055
2056    function doKeyDown(evt) {
2057        var char = evt.keyCode;
2058        var preventDefault = false;
2059        switch (char) {
2060            case 37: // left arrow
2061                if (evt.shiftKey) {
2062                    testIndex -= 9;
2063                }
2064                if (--testIndex < 0)
2065                    testIndex = tests.length - 1;
2066                drawTop();
2067                preventDefault = true;
2068                break;
2069            case 39: // right arrow
2070                if (evt.shiftKey) {
2071                    testIndex += 9;
2072                }
2073                if (++testIndex >= tests.length)
2074                    testIndex = 0;
2075                drawTop();
2076                preventDefault = true;
2077                break;
2078        }
2079        if (preventDefault) {
2080            evt.preventDefault();
2081            return false;
2082        }
2083        return true;
2084    }
2085
2086    function calcXY() {
2087        var e = window.event;
2088        var tgt = e.target || e.srcElement;
2089        var left = tgt.offsetLeft;
2090        var top = tgt.offsetTop;
2091        mouseX = (e.clientX - left) / scale + srcLeft;
2092        mouseY = (e.clientY - top) / scale + srcTop;
2093    }
2094
2095    function calcLeftTop() {
2096        srcLeft = mouseX - screenWidth / 2 / scale;
2097        srcTop = mouseY - screenHeight / 2 / scale;
2098    }
2099
2100    function handleMouseClick() {
2101        if (!draw_t || !ptInTControl()) {
2102            calcXY();
2103        } else {
2104            redraw();
2105        }
2106    }
2107
2108    function initDown() {
2109        var test = tests[testIndex];
2110        var bestDistance = 1000000;
2111        activePt = -1;
2112        for (var curves in test) {
2113            var testCurve = test[curves];
2114            if (testCurve.length != 4 && testCurve.length != 6 && testCurve.length != 8) {
2115                continue;
2116            }
2117            for (var i = 0; i < testCurve.length; i += 2) {
2118                var testX = testCurve[i];
2119                var testY = testCurve[i + 1];
2120                var dx = testX - mouseX;
2121                var dy = testY - mouseY;
2122                var dist = dx * dx + dy * dy;
2123                if (dist > bestDistance) {
2124                    continue;
2125                }
2126                activeCurve = testCurve;
2127                activePt = i;
2128                bestDistance = dist;
2129            }
2130        }
2131        if (activePt >= 0) {
2132            lastX = mouseX;
2133            lastY = mouseY;
2134        }
2135    }
2136
2137    function handleMouseOver() {
2138        calcXY();
2139        if (draw_mouse_xy) {
2140            var num = mouseX.toFixed(decimal_places) + ", " + mouseY.toFixed(decimal_places);
2141            ctx.beginPath();
2142            ctx.rect(300, 100, num.length * 6, 10);
2143            ctx.fillStyle = "white";
2144            ctx.fill();
2145            ctx.font = "normal 10px Arial";
2146            ctx.fillStyle = "black";
2147            ctx.textAlign = "left";
2148            ctx.fillText(num, 300, 108);
2149        }
2150        if (!mouseDown) {
2151            activePt = -1;
2152            return;
2153        }
2154        if (activePt < 0) {
2155            initDown();
2156            return;
2157        }
2158        var deltaX = mouseX - lastX;
2159        var deltaY = mouseY - lastY;
2160        lastX = mouseX;
2161        lastY = mouseY;
2162        if (activePt == 0) {
2163            var test = tests[testIndex];
2164            for (var curves in test) {
2165                var testCurve = test[curves];
2166                testCurve[0] += deltaX;
2167                testCurve[1] += deltaY;
2168            }
2169        } else {
2170            activeCurve[activePt] += deltaX;
2171            activeCurve[activePt + 1] += deltaY;
2172        }
2173        redraw();
2174    }
2175
2176    function start() {
2177        for (var i = 0; i < testDivs.length; ++i) {
2178            var title = testDivs[i].id.toString();
2179            var str = testDivs[i].firstChild.data;
2180            parse(str, title);
2181        }
2182        drawTop();
2183        window.addEventListener('keypress', doKeyPress, true);
2184        window.addEventListener('keydown', doKeyDown, true);
2185        window.onresize = function () {
2186            drawTop();
2187        }
2188    }
2189
2190</script>
2191</head>
2192
2193<body onLoad="start();">
2194
2195<canvas id="canvas" width="750" height="500"
2196    onmousedown="mouseDown = true"
2197    onmouseup="mouseDown = false"
2198    onmousemove="handleMouseOver()"
2199    onclick="handleMouseClick()"
2200    ></canvas >
2201</body>
2202</html>