blob: 2d411d1bc3d9da9823eadea9b41ae19c010ae26a [file] [log] [blame]
caryclarkdac1d172014-06-17 05:15:38 -07001<html>
2<head>
Cary Clark5de52332018-08-30 12:58:23 -04003<div height="0" hidden="true">
4<div id="crbug_526025">
5SkDCubic::ComplexBreak
6{{{360, -2147483648}, {593011648, -2147483520}, {1073742208, -1666752896}, {1073742080, -1073741568}}},
7maxCurvature[0]=0.500000161 {{{-406603233.5424470901, -2998846434.998814106}, {1925104612.000926018, -667136804.5425114632}}},
8seg=1 {{{360, -2147483648}, {593011648, -2147483520}, {1073742208, -1666752896}, {1073742080, -1073741568}}}
9seg=2 {{{1073742080, -1073741568}, {1073742080, -480730560}, {593011840, -135.508026f}, {905.953125f, 255.999786f}}}
10seg=3 {{{905.953125f, 255.999786f}, {815.80835f, 897.304565f}}}
11seg=4 {{{815.80835f, 897.304565f}, {213.229446f, 572.949036f}}}
12seg=5 {{{213.229446f, 572.949036f}, {32, 16}}}
13seg=6 {{{32, 16}, {100, 512}}}
14seg=7 {{{100, 512}, {213.229446f, 572.949036f}}}
15seg=8 {{{213.229446f, 572.949036f}, {360, 1024}}}
16seg=9 {{{360, 1024}, {360, 4140}}}
17seg=10 {{{360, 4140}, {360, -2147483648}}}
18op union
19seg=11 {{{127, 321}, {6840, 270}}}
20seg=12 {{{6840, 270}, {-21474836480, 100000000}}}
21seg=13 {{{-21474836480, 100000000}, {2551, 64}}}
22seg=14 {{{2551, 64}, {127, 321}}}
23debugShowCubicIntersection wtTs[0]=1 {{{360,-2.14748365e+09}, {593011648,-2.14748352e+09}, {1.07374221e+09,-1.6667529e+09}, {1.07374208e+09,-1.07374157e+09}}} {{1.07374208e+09,-1.07374157e+09}} wnTs[0]=0 {{{1.07374208e+09,-1.07374157e+09}, {1.07374208e+09,-480730560}, {593011840,-135.508026}, {905.953125,255.999786}}}
24debugShowCubicLineIntersection wtTs[0]=0 {{{360,-2.14748365e+09}, {593011648,-2.14748352e+09}, {1.07374221e+09,-1.6667529e+09}, {1.07374208e+09,-1.07374157e+09}}} {{360,-2.14748365e+09}} wnTs[0]=1 {{{360,4140}, {360,-2.14748365e+09}}}
25debugShowCubicLineIntersection wtTs[0]=1 {{{1.07374208e+09,-1.07374157e+09}, {1.07374208e+09,-480730560}, {593011840,-135.508026}, {905.953125,255.999786}}} {{905.953125,255.999786}} wnTs[0]=0 {{{905.953125,255.999786}, {815.80835,897.304565}}}
26debugShowLineIntersection wtTs[0]=1 {{{905.953125,255.999786}, {815.80835,897.304565}}} {{815.80835,897.304565}} wnTs[0]=0 {{{815.80835,897.304565}, {213.229446,572.949036}}}
27debugShowLineIntersection wtTs[0]=1 {{{815.80835,897.304565}, {213.229446,572.949036}}} {{213.229446,572.949036}} wnTs[0]=0 {{{213.229446,572.949036}, {32,16}}}
28debugShowLineIntersection wtTs[0]=1 {{{815.80835,897.304565}, {213.229446,572.949036}}} {{213.229446,572.949036}} wnTs[0]=1 {{{100,512}, {213.229446,572.949036}}}
29debugShowLineIntersection wtTs[0]=1 {{{815.80835,897.304565}, {213.229446,572.949036}}} {{213.229446,572.949036}} wnTs[0]=0 {{{213.229446,572.949036}, {360,1024}}}
30debugShowLineIntersection wtTs[0]=0.756429319 {{{815.80835,897.304565}, {213.229446,572.949036}}} {{360,651.952515}} wnTs[0]=1.62425e-06 {{{360,4140}, {360,-2.14748365e+09}}}
31SkOpSegment::addT insert t=0.756429319 segID=4 spanID=29
32SkOpSegment::addT insert t=1.62424554e-06 segID=10 spanID=30
33debugShowLineIntersection wtTs[0]=1 {{{213.229446,572.949036}, {32,16}}} {{32,16}} wnTs[0]=0 {{{32,16}, {100,512}}}
34debugShowLineIntersection wtTs[0]=0 {{{213.229446,572.949036}, {32,16}}} {{213.229446,572.949036}} wnTs[0]=1 {{{100,512}, {213.229446,572.949036}}}
35debugShowLineIntersection wtTs[0]=0 {{{213.229446,572.949036}, {32,16}}} {{213.229446,572.949036}} wnTs[0]=0 {{{213.229446,572.949036}, {360,1024}}}
36debugShowLineIntersection wtTs[0]=1 {{{32,16}, {100,512}}} {{100,512}} wnTs[0]=0 {{{100,512}, {213.229446,572.949036}}}
37debugShowLineIntersection wtTs[0]=1 {{{100,512}, {213.229446,572.949036}}} {{213.229446,572.949036}} wnTs[0]=0 {{{213.229446,572.949036}, {360,1024}}}
38debugShowLineIntersection wtTs[0]=1 {{{213.229446,572.949036}, {360,1024}}} {{360,1024}} wnTs[0]=0 {{{360,1024}, {360,4140}}}
39debugShowLineIntersection wtTs[0]=1 {{{213.229446,572.949036}, {360,1024}}} {{360,1024}} wnTs[0]=1.451e-06 {{{360,4140}, {360,-2.14748365e+09}}}
40SkOpSegment::addT insert t=1.45099777e-06 segID=10 spanID=31
41debugShowLineIntersection wtTs[0]=0 {{{360,4140}, {360,-2.14748365e+09}}} {{360,4140}} wtTs[1]=1.45099777e-06 {{360,1024}} wnTs[0]=1 {{{360,1024}, {360,4140}}} wnTs[1]=0
42debugShowCubicLineIntersection wtTs[0]=1 {{{1.07374208e+09,-1.07374157e+09}, {1.07374208e+09,-480730560}, {593011840,-135.508026}, {905.953125,255.999786}}} {{905.953125,255.999786}} wnTs[0]=1 {{{-2.14748365e+10,100000000}, {2551,64}}}
43SkOpSegment::addT insert t=0.999999923 segID=13 spanID=32
44debugShowCubicLineIntersection no intersect {{{1.07374208e+09,-1.07374157e+09}, {1.07374208e+09,-480730560}, {593011840,-135.508026}, {905.953125,255.999786}}} {{{2551,64}, {127,321}}}
45debugShowLineIntersection wtTs[0]=0.0922268392 {{{905.953125,255.999786}, {815.80835,897.304565}}} {{897.639343,315.145294}} wnTs[0]=0.114798 {{{127,321}, {6840,270}}}
46SkOpSegment::addT insert t=0.0922268392 segID=3 spanID=33
47SkOpSegment::addT insert t=0.114798057 segID=11 spanID=34
48debugShowLineIntersection wtTs[0]=0.0649612467 {{{905.953125,255.999786}, {815.80835,897.304565}}} {{900.097229,297.65976}} wtTs[1]=1 {{815.80835,897.304565}} wnTs[0]=2.76598e-07 {{{6840,270}, {-2.14748365e+10,100000000}}} wnTs[1]=2.80653133e-07
49SkOpSegment::addT insert t=0.0649612467 segID=3 spanID=35
50SkOpSegment::addT insert t=2.7659819e-07 segID=12 spanID=36
51SkOpSegment::addT insert t=2.80653133e-07 segID=12 spanID=37
52debugShowLineIntersection wtTs[0]=0 {{{905.953125,255.999786}, {815.80835,897.304565}}} {{905.953125,255.999786}} wtTs[1]=1 {{815.80835,897.304565}} wnTs[0]=1 {{{-2.14748365e+10,100000000}, {2551,64}}} wnTs[1]=0.999999919
53SkOpSegment::addT insert t=0.999999919 segID=13 spanID=38
54debugShowLineIntersection no intersect {{{905.953125,255.999786}, {815.80835,897.304565}}} {{{2551,64}, {127,321}}}
55debugShowLineIntersection wtTs[0]=0 {{{815.80835,897.304565}, {213.229446,572.949036}}} {{815.80835,897.304565}} wtTs[1]=1 {{213.229446,572.949036}} wnTs[0]=2.80653e-07 {{{6840,270}, {-2.14748365e+10,100000000}}} wnTs[1]=3.08641951e-07
56SkOpSegment::addT insert t=3.08641951e-07 segID=12 spanID=39
57debugShowLineIntersection wtTs[0]=0 {{{815.80835,897.304565}, {213.229446,572.949036}}} {{815.80835,897.304565}} wtTs[1]=1 {{213.229446,572.949036}} wnTs[0]=1 {{{-2.14748365e+10,100000000}, {2551,64}}} wnTs[1]=0.999999891
58SkOpSegment::addT insert t=0.999999891 segID=13 spanID=40
59debugShowLineIntersection wtTs[0]=0.452431368 {{{213.229446,572.949036}, {32,16}}} {{131.235565,320.967834}} wnTs[0]=0.000630949 {{{127,321}, {6840,270}}}
60SkOpSegment::addT insert t=0.452431368 segID=5 spanID=41
61SkOpSegment::addT insert t=0.000630948916 segID=11 spanID=42
62debugShowLineIntersection wtTs[0]=0 {{{213.229446,572.949036}, {32,16}}} {{213.229446,572.949036}} wtTs[1]=0.487798966 {{124.825912,301.269867}} wnTs[0]=3.08642e-07 {{{6840,270}, {-2.14748365e+10,100000000}}} wnTs[1]=3.12699562e-07
63SkOpSegment::addT insert t=0.487798966 segID=5 spanID=43
64SkOpSegment::addT insert t=3.12699562e-07 segID=12 spanID=44
65debugShowLineIntersection wtTs[0]=0 {{{213.229446,572.949036}, {32,16}}} {{213.229446,572.949036}} wtTs[1]=0.892917257 {{51.4065475,75.6396332}} wnTs[0]=1 {{{-2.14748365e+10,100000000}, {2551,64}}} wnTs[1]=0.999999884
66SkOpSegment::addT insert t=0.892917257 segID=5 spanID=45
67SkOpSegment::addT insert t=0.999999884 segID=13 spanID=46
68debugShowLineIntersection wtTs[0]=0.453154928 {{{213.229446,572.949036}, {32,16}}} {{131.104431,320.56485}} wnTs[0]=0.998307 {{{2551,64}, {127,321}}}
69SkOpSegment::addT insert t=0.453154928 segID=5 spanID=47
70SkOpSegment::addT insert t=0.998306753 segID=14 spanID=48
71debugShowLineIntersection wtTs[0]=0.575644854 {{{32,16}, {100,512}}} {{71.1438522,301.519836}} wtTs[1]=1 {{100,512}} wnTs[0]=3.15199e-07 {{{6840,270}, {-2.14748365e+10,100000000}}} wnTs[1]=3.13901276e-07
72SkOpSegment::addT insert t=0.575644854 segID=6 spanID=49
73SkOpSegment::addT insert t=3.15199326e-07 segID=12 spanID=50
74SkOpSegment::addT insert t=3.13901276e-07 segID=12 spanID=51
75debugShowLineIntersection wtTs[0]=0.120346555 {{{32,16}, {100,512}}} {{40.183567,75.6918945}} wtTs[1]=1 {{100,512}} wnTs[0]=1 {{{-2.14748365e+10,100000000}, {2551,64}}} wnTs[1]=0.999999886
76SkOpSegment::addT insert t=0.120346555 segID=6 spanID=52
77SkOpSegment::addT insert t=0.999999883 segID=13 spanID=53
78SkOpSegment::addT insert t=0.999999886 segID=13 spanID=54
79debugShowLineIntersection wtTs[0]=0 {{{100,512}, {213.229446,572.949036}}} {{100,512}} wtTs[1]=1 {{213.229446,572.949036}} wnTs[0]=3.13901e-07 {{{6840,270}, {-2.14748365e+10,100000000}}} wnTs[1]=3.08641951e-07
80debugShowLineIntersection wtTs[0]=0 {{{100,512}, {213.229446,572.949036}}} {{100,512}} wtTs[1]=1 {{213.229446,572.949036}} wnTs[0]=1 {{{-2.14748365e+10,100000000}, {2551,64}}} wnTs[1]=0.999999891
81debugShowLineIntersection wtTs[0]=0 {{{213.229446,572.949036}, {360,1024}}} {{213.229446,572.949036}} wtTs[1]=1 {{360,1024}} wnTs[0]=3.08642e-07 {{{6840,270}, {-2.14748365e+10,100000000}}} wnTs[1]=3.01905369e-07
82SkOpSegment::addT insert t=3.01905369e-07 segID=12 spanID=55
83debugShowLineIntersection wtTs[0]=0 {{{213.229446,572.949036}, {360,1024}}} {{213.229446,572.949036}} wtTs[1]=1 {{360,1024}} wnTs[0]=1 {{{-2.14748365e+10,100000000}, {2551,64}}} wnTs[1]=0.999999898
84SkOpSegment::addT insert t=0.999999898 segID=13 spanID=56
85debugShowLineIntersection wtTs[0]=3.01905369e-07 {{{6840,270}, {-2.14748365e+10,100000000}}} {{360,1024}} wnTs[0]=0 {{{360,1024}, {360,4140}}}
86debugShowLineIntersection wtTs[0]=0.999999897 {{{-2.14748365e+10,100000000}, {2551,64}}} {{360,4140}} wnTs[0]=1 {{{360,1024}, {360,4140}}}
87SkOpSegment::addT insert t=0.999999897 segID=13 spanID=57
88debugShowLineIntersection wtTs[0]=0.034708774 {{{127,321}, {6840,270}}} {{360,319.229858}} wnTs[0]=1.77918e-06 {{{360,4140}, {360,-2.14748365e+09}}}
89SkOpSegment::addT insert t=1.77918132e-06 segID=10 spanID=58
90SkOpSegment::addT insert t=0.034708774 segID=11 spanID=59
91debugShowLineIntersection wtTs[0]=3.02581027e-07 {{{6840,270}, {-2.14748365e+10,100000000}}} {{360,4140}} wnTs[0]=0 {{{360,4140}, {360,-2.14748365e+09}}}
92SkOpSegment::addT insert t=3.02581027e-07 segID=12 spanID=60
93debugShowLineIntersection wtTs[0]=0.999999897 {{{-2.14748365e+10,100000000}, {2551,64}}} {{360,4140}} wnTs[0]=0 {{{360,4140}, {360,-2.14748365e+09}}}
94debugShowLineIntersection wtTs[0]=0.903877888 {{{2551,64}, {127,321}}} {{360,296.296631}} wnTs[0]=1.78986e-06 {{{360,4140}, {360,-2.14748365e+09}}}
95SkOpSegment::addT insert t=1.78986041e-06 segID=10 spanID=61
96SkOpSegment::addT insert t=0.903877888 segID=14 spanID=62
97debugShowLineIntersection wtTs[0]=0 {{{127,321}, {6840,270}}} {{127,321}} wtTs[1]=1 {{6840,270}} wnTs[0]=3.12603e-07 {{{6840,270}, {-2.14748365e+10,100000000}}} wnTs[1]=0
98SkOpSegment::addT insert t=3.12602603e-07 segID=12 spanID=63
99debugShowLineIntersection wtTs[0]=0 {{{127,321}, {6840,270}}} {{127,321}} wnTs[0]=1 {{{-2.14748365e+10,100000000}, {2551,64}}}
100SkOpSegment::addT insert t=0.999999887 segID=13 spanID=64
101debugShowLineIntersection wtTs[0]=0 {{{127,321}, {6840,270}}} {{127,321}} wnTs[0]=1 {{{2551,64}, {127,321}}}
102debugShowLineIntersection wtTs[0]=1 {{{6840,270}, {-2.14748365e+10,100000000}}} {{-2.14748365e+10,100000000}} wnTs[0]=0 {{{-2.14748365e+10,100000000}, {2551,64}}}
103debugShowLineIntersection wtTs[0]=3.03529974e-07 {{{6840,270}, {-2.14748365e+10,100000000}}} {{321.741364,300.352905}} wnTs[0]=0.919661 {{{2551,64}, {127,321}}}
104SkOpSegment::addT insert t=3.03529974e-07 segID=12 spanID=65
105SkOpSegment::addT insert t=0.919661149 segID=14 spanID=66
106debugShowLineIntersection wtTs[0]=1 {{{-2.14748365e+10,100000000}, {2551,64}}} {{2551,64}} wnTs[0]=0 {{{2551,64}, {127,321}}}
107--x---x----------xx-xxxx----------x--- addExpanded
10800: seg/base=13/38 coinSeg/Span/PtT=13/54/54 MergeMatches
10901: seg/base=12/37 coinSeg/Span/PtT=12/51/51 MergeMatches
11002: seg/base=13/38 coinSeg/Span/PtT=13/54/54 MergeMatches
11103: seg/base=12/37 coinSeg/Span/PtT=12/51/51 MergeMatches
11204: seg/base=13/38 coinSeg/Span/PtT=13/54/54 MergeMatches
11305: seg/base=12/37 coinSeg/Span/PtT=12/51/51 MergeMatches
11406: seg/base=13/38 coinSeg/Span/PtT=13/54/54 MergeMatches
11507: seg/base=12/37 coinSeg/Span/PtT=12/51/51 MergeMatches
11608: seg/base=13/40 coinSeg/Span/PtT=13/46/46 MergeMatches
11709: seg/base=5/45 coinSeg/Span/PtT=5/9/9 MergeMatches
11810: seg/base=13/40 coinSeg/Span/PtT=13/46/46 MergeMatches
11911: seg/base=5/45 coinSeg/Span/PtT=5/9/9 MergeMatches
12012: seg/base=13/40 coinSeg/Span/PtT=13/54/54 MergeMatches
12113: seg/base=12/39 coinSeg/Span/PtT=12/51/51 MergeMatches
12214: segment=7 MergeMatches
12315: seg/base=13/40 coinSeg/Span/PtT=13/54/54 MergeMatches
12416: seg/base=12/39 coinSeg/Span/PtT=12/51/51 MergeMatches
12517: segment=7 MergeMatches
12618: seg/base=13/54 coinSeg/Span/PtT=13/64/64 MergeMatches
12719: seg/base=12/51 coinSeg/Span/PtT=12/63/63 MergeMatches
12820: seg/base=13/54 coinSeg/Span/PtT=13/64/64 MergeMatches
12921: seg/base=12/51 coinSeg/Span/PtT=12/63/63 MergeMatches
13022: seg/base=13/54 coinSeg/Span/PtT=13/53/53 MergeMatches
13123: seg/base=6/52 coinSeg/Span/PtT=6/12/12 MergeMatches
13224: seg/base=13/54 coinSeg/Span/PtT=13/53/53 MergeMatches
13325: seg/base=6/52 coinSeg/Span/PtT=6/12/12 MergeMatches
13426: seg/base=13/40 coinSeg/Span/PtT=13/46/46 MergeMatches
13527: seg/base=5/45 coinSeg/Span/PtT=5/9/9 MergeMatches
13628: seg/base=13/40 coinSeg/Span/PtT=13/46/46 MergeMatches
13729: seg/base=5/45 coinSeg/Span/PtT=5/9/9 MergeMatches
13830: seg/base=13/40 coinSeg/Span/PtT=13/46/46 MergeMatches
13931: seg/base=5/45 coinSeg/Span/PtT=5/9/9 MergeMatches
14032: seg/base=13/40 coinSeg/Span/PtT=13/46/46 MergeMatches
14133: seg/base=5/45 coinSeg/Span/PtT=5/9/9 MergeMatches
14234: seg/base=13/56 coinSeg/Span/PtT=13/54/54 MergeMatches
14335: seg/base=12/55 coinSeg/Span/PtT=12/51/51 MergeMatches
14436: seg/base=13/56 coinSeg/Span/PtT=13/54/54 MergeMatches
14537: seg/base=12/55 coinSeg/Span/PtT=12/51/51 MergeMatches
14638: seg/base=13/56 coinSeg/Span/PtT=13/54/54 MergeMatches
14739: seg/base=12/55 coinSeg/Span/PtT=12/51/51 MergeMatches
14840: seg/base=13/56 coinSeg/Span/PtT=13/54/54 MergeMatches
14941: seg/base=12/55 coinSeg/Span/PtT=12/51/51 MergeMatches
15042: seg/base=12/60 coinSeg/Span/PtT=12/55/55 MergeMatches
15143: seg/base=10/31 coinSeg/Span/PtT=10/19/19 MergeMatches
15244: segment=9 MergeMatches
15345: seg/base=13/57 coinSeg/Span/PtT=13/56/56 MergeMatches
15446: seg/base=12/60 coinSeg/Span/PtT=12/55/55 MergeMatches
15547: seg/base=10/31 coinSeg/Span/PtT=10/19/19 MergeMatches
15648: segment=9 MergeMatches
15749: seg/base=13/57 coinSeg/Span/PtT=13/56/56 MergeMatches
15850: coinSeg/Span/PtT=13/57/57 endSpan=56 oppSeg/Span/PtT=9/18/18 oppEndSpan=17 MissingCoin
15951: coinSeg/Span/PtT=12/55/55 endSpan=60 oppSeg/Span/PtT=9/17/17 oppEndSpan=18 MissingCoin
16052: seg/base=13/57 coinSeg/Span/PtT=13/54/54 MergeMatches
16153: seg/base=12/60 coinSeg/Span/PtT=12/51/51 MergeMatches
16254: seg/base=13/57 coinSeg/Span/PtT=13/54/54 MergeMatches
16355: seg/base=12/60 coinSeg/Span/PtT=12/51/51 MergeMatches
16456: seg/base=13/56 coinSeg/Span/PtT=13/54/54 MergeMatches
16557: seg/base=12/55 coinSeg/Span/PtT=12/51/51 MergeMatches
16658: seg/base=13/56 coinSeg/Span/PtT=13/54/54 MergeMatches
16759: seg/base=12/55 coinSeg/Span/PtT=12/51/51 MergeMatches
16860: coinSeg/Span/PtT=13/57/57 endSpan=56 oppSeg/Span/PtT=10/19/19 oppEndSpan=31 MissingCoin
16961: coinSeg/Span/PtT=12/55/55 endSpan=60 oppSeg/Span/PtT=10/31/31 oppEndSpan=19 MissingCoin
17062: coinSeg/Span/PtT=13/57/57 endSpan=56 oppSeg/Span/PtT=9/18/18 oppEndSpan=17 MissingCoin
17163: coinSeg/Span/PtT=12/55/55 endSpan=60 oppSeg/Span/PtT=9/17/17 oppEndSpan=18 MissingCoin
17264: coinSeg/Span/PtT=13/57/57 endSpan=56 oppSeg/Span/PtT=10/19/19 oppEndSpan=31 MissingCoin
17365: coinSeg/Span/PtT=12/55/55 endSpan=60 oppSeg/Span/PtT=10/31/31 oppEndSpan=19 MissingCoin
17466: seg/base=13/64 coinSeg/Span/PtT=13/54/54 MergeMatches
17567: seg/base=12/63 coinSeg/Span/PtT=12/51/51 MergeMatches
17668: seg/base=13/64 coinSeg/Span/PtT=13/54/54 MergeMatches
17769: seg/base=12/63 coinSeg/Span/PtT=12/51/51 MergeMatches
17870: seg/base=13/56 coinSeg/Span/PtT=13/57/57 MergeMatches
17971: seg/base=10/31 coinSeg/Span/PtT=10/19/19 MergeMatches
18072: seg/base=12/55 coinSeg/Span/PtT=12/60/60 MergeMatches
18173: segment=9 MergeMatches
18274: seg/base=13/56 coinSeg/Span/PtT=13/57/57 MergeMatches
18375: seg/base=10/31 coinSeg/Span/PtT=10/19/19 MergeMatches
18476: seg/base=12/55 coinSeg/Span/PtT=12/60/60 MergeMatches
18577: segment=9 MergeMatches
18678: coinSeg/Span/PtT=13/25/25 endSpan=54 oppSeg/Span/PtT=12/24/24 oppEndSpan=51 MissingCoin
18779: seg/base=10/31 coinSeg/Span/PtT=10/19/19 MergeMatches
18880: segment=9 MergeMatches
18981: seg/base=13/57 coinSeg/Span/PtT=13/56/56 MergeMatches
19082: seg/base=12/60 coinSeg/Span/PtT=12/55/55 MergeMatches
19183: seg/base=10/31 coinSeg/Span/PtT=10/19/19 MergeMatches
19284: segment=9 MergeMatches
19385: seg/base=13/57 coinSeg/Span/PtT=13/56/56 MergeMatches
19486: seg/base=12/60 coinSeg/Span/PtT=12/55/55 MergeMatches
19587: coinSeg/Span/PtT=12/51/51 endSpan=24 oppSeg/Span/PtT=13/54/54 oppEndSpan=25 MissingCoin
19688: coinSeg/Span/PtT=13/64/64 endSpan=26 oppSeg/Span/PtT=14/28/28 oppEndSpan=27 MissingCoin
19789: coinSeg/Span/PtT=12/65/65 endSpan=63 oppSeg/Span/PtT=14/66/66 oppEndSpan=28 MissingCoin
19890: coinSeg/Span/PtT=13/25/25 endSpan=54 oppSeg/Span/PtT=12/24/24 oppEndSpan=51 MissingCoin
19991: coinSeg/Span/PtT=12/51/51 endSpan=24 oppSeg/Span/PtT=13/54/54 oppEndSpan=25 MissingCoin
20092: coinSeg/Span/PtT=13/64/64 endSpan=26 oppSeg/Span/PtT=14/28/28 oppEndSpan=27 MissingCoin
20193: coinSeg/Span/PtT=12/65/65 endSpan=63 oppSeg/Span/PtT=14/66/66 oppEndSpan=28 MissingCoin
20294: segment=11 ReturnFalse
20395: seg/base=11/21 Fail
20496: seg/base=11/42 Fail
20597: seg/base=11/21 Fail
20698: seg/base=11/42 Fail
20799: seg/base=8/15 Fail
208100: segment=11 ReturnFalse
209101: segment=11 startT=0.0126699 endT=0.0342199 segment=8 oppStartT=0 oppEndT=1 AddMissingCoin
210102: segment=11 ReturnFalse
211103: seg/base=7/13 Fail
212104: seg/base=11/21 Fail
213105: seg/base=11/42 Fail
214106: seg/base=7/13 Fail
215107: segment=11 ReturnFalse
216108: segment=11 startT=0 endT=0.0126699 segment=7 oppStartT=0.246928 oppEndT=1 AddMissingCoin
217109: segment=11 ReturnFalse
218110: seg/base=5/9 Fail
219111: seg/base=5/41 Fail
220112: seg/base=5/47 Fail
221113: seg/base=11/21 Fail
222114: seg/base=11/42 Fail
223115: segment=11 ReturnFalse
224116: segment=11 startT=0 endT=0.0126699 segment=5 oppStartT=0.476143 oppEndT=0 AddMissingCoin
225117: segment=11 ReturnFalse
226118: seg/base=11/21 Fail
227119: seg/base=11/42 Fail
228120: seg/base=4/7 Fail
229121: seg/base=4/29 Fail
230122: seg/base=11/21 Fail
231123: seg/base=11/42 Fail
232124: seg/base=11/59 Fail
233125: segment=11 ReturnFalse
234126: segment=11 startT=0.0126699 endT=0.102205 segment=4 oppStartT=1 oppEndT=0 AddMissingCoin
235127: segment=11 ReturnFalse
236128: seg/base=11/21 Fail
237129: seg/base=11/42 Fail
238130: seg/base=11/59 Fail
239131: seg/base=3/5 Fail
240132: seg/base=3/35 Fail
241133: seg/base=3/33 Fail
242134: seg/base=11/21 Fail
243135: seg/base=11/42 Fail
244136: seg/base=11/59 Fail
245137: seg/base=11/34 Fail
246138: seg/base=3/5 Fail
247139: segment=11 ReturnFalse
248140: segment=11 startT=0.102205 endT=0.115176 segment=3 oppStartT=1 oppEndT=0.0649612 AddMissingCoin
249141: segment=13 ReturnFalse
250142: segment=13 startT=1 endT=1 segment=12 oppStartT=3.08642e-07 oppEndT=3.01905e-07 AddMissingCoin
251143: segment=8 ReturnFalse
252144: seg/base=8/15 Fail
253145: seg/base=4/7 Fail
254146: seg/base=4/29 Fail
255147: segment=8 ReturnFalse
256148: segment=8 startT=0 endT=1 segment=4 oppStartT=1 oppEndT=0.759312 AddMissingCoin
257149: segment=8 ReturnFalse
258150: seg/base=8/15 Fail
259151: seg/base=4/7 Fail
260152: seg/base=4/29 Fail
261153: segment=8 ReturnFalse
262154: segment=8 startT=0 endT=1 segment=4 oppStartT=1 oppEndT=0.759312 AddMissingCoin
263155: segment=13 ReturnFalse
264156: segment=13 startT=1 endT=1 segment=12 oppStartT=3.13901e-07 oppEndT=3.08642e-07 AddMissingCoin
265157: segment=7 ReturnFalse
266158: seg/base=5/9 Fail
267159: seg/base=5/41 Fail
268160: seg/base=5/47 Fail
269161: seg/base=5/43 Fail
270162: segment=7 ReturnFalse
271163: segment=7 startT=0 endT=1 segment=5 oppStartT=0.632267 oppEndT=0 AddMissingCoin
272164: segment=7 ReturnFalse
273165: seg/base=7/13 Fail
274166: seg/base=5/9 Fail
275167: seg/base=5/41 Fail
276168: seg/base=5/47 Fail
277169: segment=7 ReturnFalse
278170: segment=7 startT=0.228492 endT=1 segment=5 oppStartT=0.487799 oppEndT=0 AddMissingCoin
279171: segment=13 ReturnFalse
280172: seg/base=13/25 Fail
281173: seg/base=13/53 Fail
282174: seg/base=13/46 Fail
283175: seg/base=12/23 Fail
284176: seg/base=12/36 Fail
285177: seg/base=12/37 Fail
286178: seg/base=12/55 Fail
287179: seg/base=12/60 Fail
288180: seg/base=12/65 Fail
289181: seg/base=12/39 Fail
290182: seg/base=12/63 Fail
291183: seg/base=12/44 Fail
292184: seg/base=12/51 Fail
293185: segment=13 ReturnFalse
294186: segment=13 startT=1 endT=1 segment=12 oppStartT=3.15199e-07 oppEndT=3.13901e-07 AddMissingCoin
295187: segment=6 ReturnFalse
296188: seg/base=6/11 Fail
297189: seg/base=6/52 Fail
298190: seg/base=5/9 Fail
299191: seg/base=5/41 Fail
300192: seg/base=5/47 Fail
301193: seg/base=5/43 Fail
302194: seg/base=6/11 Fail
303195: seg/base=6/52 Fail
304196: seg/base=6/49 Fail
305197: seg/base=5/9 Fail
306198: seg/base=5/41 Fail
307199: seg/base=5/47 Fail
308200: seg/base=5/43 Fail
309201: segment=6 ReturnFalse
310202: segment=6 startT=0.291197 endT=1 segment=5 oppStartT=0.892917 oppEndT=0.632267 AddMissingCoin
311203: segment=13 ReturnFalse
312204: seg/base=13/25 Fail
313205: seg/base=13/53 Fail
314206: seg/base=13/46 Fail
315207: seg/base=13/54 Fail
316208: seg/base=12/23 Fail
317209: seg/base=12/36 Fail
318210: seg/base=12/37 Fail
319211: seg/base=12/55 Fail
320212: seg/base=12/60 Fail
321213: seg/base=12/65 Fail
322214: seg/base=12/39 Fail
323215: seg/base=12/63 Fail
324216: segment=13 ReturnFalse
325217: segment=13 startT=1 endT=1 segment=12 oppStartT=3.127e-07 oppEndT=3.08642e-07 AddMissingCoin
326218: segment=13 ReturnFalse
327219: segment=13 startT=1 endT=1 segment=12 oppStartT=3.08642e-07 oppEndT=2.80653e-07 AddMissingCoin
328220: segment=13 ReturnFalse
329221: seg/base=13/25 Fail
330222: seg/base=13/53 Fail
331223: seg/base=13/46 Fail
332224: seg/base=13/54 Fail
333225: seg/base=13/64 Fail
334226: seg/base=13/40 Fail
335227: seg/base=13/57 Fail
336228: seg/base=13/56 Fail
337229: seg/base=13/38 Fail
338230: seg/base=12/23 Fail
339231: segment=13 ReturnFalse
340232: segment=13 startT=1 endT=1 segment=12 oppStartT=2.80653e-07 oppEndT=2.76598e-07 AddMissingCoin
341233: seg/base=11/42 startT=3.12405e-07 AddExpandedCoin
342234: seg/base=12/65 startT=0.0300077 AddExpandedCoin
343235: seg/base=12/60 startT=0.0665796 AddExpandedCoin
344236: seg/base=12/55 startT=0.146093 AddExpandedCoin
345237: seg/base=12/37 startT=0.208476 AddExpandedCoin
346238: seg/base=12/36 startT=0.228359 AddExpandedCoin
347239: seg/base=13/57 startT=0.899703 AddExpandedCoin
348240: seg/base=12/65 startT=0.758838 AddExpandedCoin
349241: seg/base=12/60 startT=3.73071 AddExpandedCoin
350242: seg/base=13/64 startT=0.246928 AddExpandedCoin
351243: seg/base=12/44 startT=0.228492 AddExpandedCoin
352244: seg/base=12/63 startT=0.320059 AddExpandedCoin
353245: seg/base=13/46 startT=0.291197 AddExpandedCoin
354246: seg/base=13/54 startT=0.632267 AddExpandedCoin
355247: seg/base=13/64 startT=0.367348 AddExpandedCoin
356248: seg/base=5/41 startT=1 AddExpandedCoin
357249: seg/base=5/41 startT=3.12405e-07 AddExpandedCoin
358250: seg/base=5/47 startT=3.12605e-07 AddExpandedCoin
359251: seg/base=13/57 startT=0.783452 AddExpandedCoin
360252: seg/base=13/56 startT=0.733122 AddExpandedCoin
361253: seg/base=4/29 startT=3.01825e-07 AddExpandedCoin
362254: seg/base=12/60 startT=1.54926 AddExpandedCoin
363255: seg/base=12/65 startT=1.67578 AddExpandedCoin
364256: seg/base=3/33 startT=1 AddExpandedCoin
365257: seg/base=3/35 startT=1 AddExpandedCoin
366258: seg/base=3/33 startT=2.76716e-07 AddExpandedCoin
367259: seg/base=11/21 seg/base=12/23 MarkCoinStart
368260: seg/base=11/22 seg/base=12/63 MarkCoinEnd
369261: coinSeg/Span/PtT=11/21/21 endSpan=22 Fail
370262: seg/base=11/42 segment=12 MarkCoinMissing
371263: seg/base=11/59 segment=12 MarkCoinMissing
372264: seg/base=11/34 segment=12 MarkCoinMissing
373265: seg/base=12/36 segment=11 MarkCoinMissing
374266: seg/base=12/37 segment=11 MarkCoinMissing
375267: seg/base=12/55 segment=11 MarkCoinMissing
376268: seg/base=12/60 segment=11 MarkCoinMissing
377269: seg/base=12/65 segment=11 MarkCoinMissing
378270: seg/base=12/39 segment=11 MarkCoinMissing
379271: seg/base=13/40 seg/base=8/15 MarkCoinStart
380272: seg/base=13/56 seg/base=8/16 MarkCoinEnd
381273: coinSeg/Span/PtT=13/40/40 endSpan=56 Fail
382274: seg/base=13/57 segment=8 MarkCoinMissing
383275: seg/base=8/15 seg/base=12/55 MarkCoinStart
384276: seg/base=8/16 seg/base=12/39 MarkCoinEnd
385277: seg/base=12/60 segment=8 MarkCoinMissing
386278: seg/base=12/65 segment=8 MarkCoinMissing
387279: seg/base=13/54 seg/base=7/13 MarkCoinStart
388280: seg/base=13/40 seg/base=7/14 MarkCoinEnd
389281: coinSeg/Span/PtT=13/54/54 endSpan=40 Fail
390282: seg/base=13/64 segment=7 MarkCoinMissing
391283: seg/base=7/13 seg/base=12/39 MarkCoinStart
392284: seg/base=7/14 seg/base=12/51 MarkCoinEnd
393285: seg/base=12/63 segment=7 MarkCoinMissing
394286: seg/base=12/44 segment=7 MarkCoinMissing
395287: seg/base=13/53 seg/base=6/52 MarkCoinStart
396288: seg/base=13/54 seg/base=6/12 MarkCoinEnd
397289: coinSeg/Span/PtT=13/53/53 endSpan=54 Fail
398290: seg/base=13/46 segment=6 MarkCoinMissing
399291: seg/base=6/49 segment=13 MarkCoinMissing
400292: seg/base=6/49 seg/base=12/51 MarkCoinStart
401293: seg/base=6/12 seg/base=12/50 MarkCoinEnd
402294: seg/base=13/46 seg/base=5/9 MarkCoinStart
403295: seg/base=13/40 seg/base=5/45 MarkCoinEnd
404296: coinSeg/Span/PtT=13/46/46 endSpan=40 Fail
405297: seg/base=13/54 segment=5 MarkCoinMissing
406298: seg/base=13/64 segment=5 MarkCoinMissing
407299: seg/base=5/41 segment=13 MarkCoinMissing
408300: seg/base=5/47 segment=13 MarkCoinMissing
409301: seg/base=5/43 segment=13 MarkCoinMissing
410302: seg/base=5/9 seg/base=12/39 MarkCoinStart
411303: seg/base=5/43 seg/base=12/44 MarkCoinEnd
412304: coinSeg/Span/PtT=5/9/9 endSpan=43 Fail
413305: seg/base=5/41 segment=12 MarkCoinMissing
414306: seg/base=5/47 segment=12 MarkCoinMissing
415307: seg/base=12/63 segment=5 MarkCoinMissing
416308: seg/base=13/40 seg/base=4/7 MarkCoinStart
417309: seg/base=13/38 seg/base=4/8 MarkCoinEnd
418310: coinSeg/Span/PtT=13/40/40 endSpan=38 Fail
419311: seg/base=13/57 segment=4 MarkCoinMissing
420312: seg/base=13/56 segment=4 MarkCoinMissing
421313: seg/base=4/29 segment=13 MarkCoinMissing
422314: seg/base=4/7 seg/base=12/37 MarkCoinStart
423315: seg/base=4/8 seg/base=12/39 MarkCoinEnd
424316: coinSeg/Span/PtT=4/7/7 endSpan=8 Fail
425317: seg/base=4/29 segment=12 MarkCoinMissing
426318: seg/base=12/55 segment=4 MarkCoinMissing
427319: seg/base=12/60 segment=4 MarkCoinMissing
428320: seg/base=12/65 segment=4 MarkCoinMissing
429321: seg/base=13/38 seg/base=3/5 MarkCoinStart
430322: seg/base=13/32 seg/base=3/6 MarkCoinEnd
431323: seg/base=3/35 segment=13 MarkCoinMissing
432324: seg/base=3/33 segment=13 MarkCoinMissing
433325: seg/base=3/35 seg/base=12/36 MarkCoinStart
434326: seg/base=3/6 seg/base=12/37 MarkCoinEnd
435327: coinSeg/Span/PtT=3/35/35 endSpan=6 Fail
436328: seg/base=3/33 segment=12 MarkCoinMissing
437329: seg/base=9/17 seg/base=10/19 MarkCoinStart
438330: seg/base=9/18 seg/base=10/31 MarkCoinEnd
439SkOpSegment::debugShowActiveSpans id=1 (360,-2.14748365e+09 593011648,-2.14748352e+09 1.07374221e+09,-1.6667529e+09 1.07374208e+09,-1.07374157e+09) t=0 tEnd=1 windSum=? windValue=1
440SkOpSegment::debugShowActiveSpans id=2 (1.07374208e+09,-1.07374157e+09 1.07374208e+09,-480730560 593011840,-135.508026 905.953125,255.999786) t=0 tEnd=1 windSum=? windValue=1
441SkOpSegment::debugShowActiveSpans id=3 (905.953125,255.999786 900.097229,297.65976) t=0 tEnd=0.0649612467 windSum=? windValue=1
442SkOpSegment::debugShowActiveSpans id=3 (900.097229,297.65976 897.639343,315.145294) t=0.0649612467 tEnd=0.0922268392 windSum=? windValue=1
443SkOpSegment::debugShowActiveSpans id=3 (897.639343,315.145294 815.80835,897.304565) t=0.0922268392 tEnd=1 windSum=? windValue=1
444SkOpSegment::debugShowActiveSpans id=4 (815.80835,897.304565 360,651.952515) t=0 tEnd=0.756429319 windSum=? windValue=1
445SkOpSegment::debugShowActiveSpans id=4 (360,651.952515 213.229446,572.949036) t=0.756429319 tEnd=1 windSum=? windValue=1
446SkOpSegment::debugShowActiveSpans id=5 (213.229446,572.949036 131.235565,320.967834) t=0 tEnd=0.452431368 windSum=? windValue=1
447SkOpSegment::debugShowActiveSpans id=5 (131.235565,320.967834 131.104431,320.56485) t=0.452431368 tEnd=0.453154928 windSum=? windValue=1
448SkOpSegment::debugShowActiveSpans id=5 (131.104431,320.56485 124.825912,301.269867) t=0.453154928 tEnd=0.487798966 windSum=? windValue=1
449SkOpSegment::debugShowActiveSpans id=5 (124.825912,301.269867 51.4065475,75.6396332) t=0.487798966 tEnd=0.892917257 windSum=? windValue=1
450SkOpSegment::debugShowActiveSpans id=5 (51.4065475,75.6396332 32,16) t=0.892917257 tEnd=1 windSum=? windValue=1
451SkOpSegment::debugShowActiveSpans id=6 (32,16 40.183567,75.6918945) t=0 tEnd=0.120346555 windSum=? windValue=1
452SkOpSegment::debugShowActiveSpans id=6 (40.183567,75.6918945 71.1438522,301.519836) t=0.120346555 tEnd=0.575644854 windSum=? windValue=1
453SkOpSegment::debugShowActiveSpans id=6 (71.1438522,301.519836 100,512) t=0.575644854 tEnd=1 windSum=? windValue=1
454SkOpSegment::debugShowActiveSpans id=7 (100,512 213.229446,572.949036) t=0 tEnd=1 windSum=? windValue=1
455SkOpSegment::debugShowActiveSpans id=8 (213.229446,572.949036 360,1024) t=0 tEnd=1 windSum=? windValue=1
456SkOpSegment::debugShowActiveSpans id=9 (360,1024 360,4140) t=0 tEnd=1 windSum=? windValue=1
457SkOpSegment::debugShowActiveSpans id=10 (360,4140 360,1024) t=0 tEnd=1.45099777e-06 windSum=? windValue=1
458SkOpSegment::debugShowActiveSpans id=10 (360,1024 360,651.952515) t=1.45099777e-06 tEnd=1.62424554e-06 windSum=? windValue=1
459SkOpSegment::debugShowActiveSpans id=10 (360,651.952515 360,319.229858) t=1.62424554e-06 tEnd=1.77918132e-06 windSum=? windValue=1
460SkOpSegment::debugShowActiveSpans id=10 (360,319.229858 360,296.296631) t=1.77918132e-06 tEnd=1.78986041e-06 windSum=? windValue=1
461SkOpSegment::debugShowActiveSpans id=10 (360,296.296631 360,-2.14748365e+09) t=1.78986041e-06 tEnd=1 windSum=? windValue=1
462SkOpSegment::debugShowActiveSpans id=11 (127,321 131.235565,320.967834) t=0 tEnd=0.000630948916 windSum=? windValue=1
463SkOpSegment::debugShowActiveSpans id=11 (131.235565,320.967834 360,319.229858) t=0.000630948916 tEnd=0.034708774 windSum=? windValue=1
464SkOpSegment::debugShowActiveSpans id=11 (360,319.229858 897.639343,315.145294) t=0.034708774 tEnd=0.114798057 windSum=? windValue=1
465SkOpSegment::debugShowActiveSpans id=11 (897.639343,315.145294 6840,270) t=0.114798057 tEnd=1 windSum=? windValue=1
466SkOpSegment::debugShowActiveSpans id=12 (6840,270 900.097229,297.65976) t=0 tEnd=2.7659819e-07 windSum=? windValue=1
467SkOpSegment::debugShowActiveSpans id=12 (900.097229,297.65976 813.017944,298.065247) t=2.7659819e-07 tEnd=2.80653133e-07 windSum=? windValue=1
468SkOpSegment::debugShowActiveSpans id=12 (813.017944,298.065247 360,1024) t=2.80653133e-07 tEnd=3.01905369e-07 windSum=? windValue=1
469SkOpSegment::debugShowActiveSpans id=12 (360,1024 360,4140) t=3.01905369e-07 tEnd=3.02581027e-07 windSum=? windValue=1
470SkOpSegment::debugShowActiveSpans id=12 (360,4140 321.741364,300.352905) t=3.02581027e-07 tEnd=3.03529974e-07 windSum=? windValue=1
471SkOpSegment::debugShowActiveSpans id=12 (321.741364,300.352905 211.962463,300.864105) t=3.03529974e-07 tEnd=3.08641951e-07 windSum=? windValue=1
472SkOpSegment::debugShowActiveSpans id=12 (211.962463,300.864105 127,321) t=3.08641951e-07 tEnd=3.12602603e-07 windSum=? windValue=1
473SkOpSegment::debugShowActiveSpans id=12 (127,321 124.825912,301.269867) t=3.12602603e-07 tEnd=3.12699562e-07 windSum=? windValue=1
474SkOpSegment::debugShowActiveSpans id=12 (124.825912,301.269867 100,512) t=3.12699562e-07 tEnd=3.13901276e-07 windSum=? windValue=1
475SkOpSegment::debugShowActiveSpans id=12 (100,512 71.1438522,301.519836) t=3.13901276e-07 tEnd=3.15199326e-07 windSum=? windValue=1
476SkOpSegment::debugShowActiveSpans id=12 (71.1438522,301.519836 -2.14748365e+10,100000000) t=3.15199326e-07 tEnd=1 windSum=? windValue=1
477SkOpSegment::debugShowActiveSpans id=13 (-2.14748365e+10,100000000 40.183567,75.6918945) t=0 tEnd=0.999999883 windSum=? windValue=1
478SkOpSegment::debugShowActiveSpans id=13 (40.183567,75.6918945 51.4065437,75.6396332) t=0.999999883 tEnd=0.999999884 windSum=? windValue=1
479SkOpSegment::debugShowActiveSpans id=13 (51.4065437,75.6396332 100,512) t=0.999999884 tEnd=0.999999886 windSum=? windValue=1
480SkOpSegment::debugShowActiveSpans id=13 (100,512 127,321) t=0.999999886 tEnd=0.999999887 windSum=? windValue=1
481SkOpSegment::debugShowActiveSpans id=13 (127,321 210.910217,74.8968811) t=0.999999887 tEnd=0.999999891 windSum=? windValue=1
482SkOpSegment::debugShowActiveSpans id=13 (210.910217,74.8968811 360,4140) t=0.999999891 tEnd=0.999999897 windSum=? windValue=1
483SkOpSegment::debugShowActiveSpans id=13 (360,4140 360,1024) t=0.999999897 tEnd=0.999999898 windSum=? windValue=1
484SkOpSegment::debugShowActiveSpans id=13 (360,1024 811.965698,72.0980072) t=0.999999898 tEnd=0.999999919 windSum=? windValue=1
485SkOpSegment::debugShowActiveSpans id=13 (811.965698,72.0980072 905.094727,71.6643372) t=0.999999919 tEnd=0.999999923 windSum=? windValue=1
486SkOpSegment::debugShowActiveSpans id=13 (905.094727,71.6643372 2551,64) t=0.999999923 tEnd=1 windSum=? windValue=1
487SkOpSegment::debugShowActiveSpans id=14 (2551,64 360,296.296631) t=0 tEnd=0.903877888 windSum=? windValue=1
488SkOpSegment::debugShowActiveSpans id=14 (360,296.296631 321.741364,300.352905) t=0.903877888 tEnd=0.919661149 windSum=? windValue=1
489SkOpSegment::debugShowActiveSpans id=14 (321.741364,300.352905 131.104431,320.56485) t=0.919661149 tEnd=0.998306753 windSum=? windValue=1
490SkOpSegment::debugShowActiveSpans id=14 (131.104431,320.56485 127,321) t=0.998306753 tEnd=1 windSum=? windValue=1
491SkOpSegment::addT insert t=3.12405367e-07 segID=12 spanID=67
492SkOpSegment::addT insert t=0.0126699258 segID=11 spanID=68
493SkOpSegment::addT insert t=0.0290228849 segID=11 spanID=69
494SkOpSegment::addT insert t=0.0320585186 segID=11 spanID=70
495SkOpSegment::addT insert t=0.0342199142 segID=11 spanID=71
496SkOpSegment::addT insert t=3.0175255e-07 segID=12 spanID=72
497SkOpSegment::addT insert t=0.102204746 segID=11 spanID=73
498SkOpSegment::addT insert t=2.76716432e-07 segID=12 spanID=74
499SkOpSegment::addT insert t=0.115176306 segID=11 spanID=75
500SkOpSegment::addT insert t=0.899702926 segID=8 spanID=76
501SkOpSegment::addT insert t=0.758838213 segID=8 spanID=77
502SkOpSegment::addT insert t=0.246927782 segID=7 spanID=78
503SkOpSegment::addT insert t=0.228492228 segID=7 spanID=79
504SkOpSegment::addT insert t=0.284429982 segID=7 spanID=80
505SkOpSegment::addT insert t=0.291197031 segID=6 spanID=81
506SkOpSegment::addT insert t=0.999999884 segID=13 spanID=82
507SkOpSegment::addT insert t=0.788316424 segID=5 spanID=83
508SkOpSegment::addT insert t=0.632267074 segID=5 spanID=84
509SkOpSegment::addT insert t=0.999999887 segID=13 spanID=85
510SkOpSegment::addT insert t=0.476142764 segID=5 spanID=86
511SkOpSegment::addT insert t=0.999999887 segID=13 spanID=87
512SkOpSegment::addT insert t=0.999999887 segID=13 spanID=88
513SkOpSegment::addT insert t=3.12411385e-07 segID=12 spanID=89
514SkOpSegment::addT insert t=0.783451987 segID=4 spanID=90
515SkOpSegment::addT insert t=0.759311649 segID=4 spanID=91
516SkOpSegment::addT insert t=0.999999898 segID=13 spanID=92
517SkOpSegment::addT insert t=0.753851653 segID=4 spanID=93
518SkOpSegment::addT insert t=3.01824696e-07 segID=12 spanID=94
519SkOpSegment::addT insert t=0.817356482 segID=4 spanID=95
520SkOpSegment::addT insert t=0.999999923 segID=13 spanID=96
521SkOpSegment::addT insert t=0.999999923 segID=13 spanID=97
522--x---x----------xxxxxxx----------x--- move_multiples
52300: seg/base=13/38 coinSeg/Span/PtT=13/85/85 MergeMatches
52401: seg/base=12/37 coinSeg/Span/PtT=12/44/44 MergeMatches
52502: seg/base=13/38 coinSeg/Span/PtT=13/85/85 MergeMatches
52603: seg/base=12/37 coinSeg/Span/PtT=12/44/44 MergeMatches
52704: seg/base=13/38 coinSeg/Span/PtT=13/85/85 MergeMatches
52805: seg/base=12/37 coinSeg/Span/PtT=12/44/44 MergeMatches
52906: seg/base=13/38 coinSeg/Span/PtT=13/85/85 MergeMatches
53007: seg/base=12/37 coinSeg/Span/PtT=12/44/44 MergeMatches
53108: seg/base=13/40 coinSeg/Span/PtT=13/82/82 MergeMatches
53209: seg/base=5/83 coinSeg/Span/PtT=5/9/9 MergeMatches
53310: seg/base=12/39 coinSeg/Span/PtT=12/50/50 MergeMatches
53411: seg/base=13/40 coinSeg/Span/PtT=13/82/82 MergeMatches
53512: seg/base=5/83 coinSeg/Span/PtT=5/9/9 MergeMatches
53613: seg/base=12/39 coinSeg/Span/PtT=12/50/50 MergeMatches
53714: seg/base=13/40 coinSeg/Span/PtT=13/85/85 MergeMatches
53815: seg/base=12/39 coinSeg/Span/PtT=12/44/44 MergeMatches
53916: seg/base=7/79 coinSeg/Span/PtT=7/14/14 MergeMatches
54017: seg/base=5/43 coinSeg/Span/PtT=5/9/9 MergeMatches
54118: seg/base=13/40 coinSeg/Span/PtT=13/85/85 MergeMatches
54219: seg/base=12/39 coinSeg/Span/PtT=12/44/44 MergeMatches
54320: seg/base=7/79 coinSeg/Span/PtT=7/14/14 MergeMatches
54421: seg/base=5/43 coinSeg/Span/PtT=5/9/9 MergeMatches
54522: seg/base=13/54 coinSeg/Span/PtT=13/82/82 MergeMatches
54623: seg/base=5/84 coinSeg/Span/PtT=5/83/83 MergeMatches
54724: seg/base=12/51 coinSeg/Span/PtT=12/50/50 MergeMatches
54825: seg/base=6/49 coinSeg/Span/PtT=6/12/12 MergeMatches
54926: seg/base=13/54 coinSeg/Span/PtT=13/82/82 MergeMatches
55027: seg/base=5/84 coinSeg/Span/PtT=5/83/83 MergeMatches
55128: seg/base=12/51 coinSeg/Span/PtT=12/50/50 MergeMatches
55229: seg/base=6/49 coinSeg/Span/PtT=6/12/12 MergeMatches
55330: seg/base=13/54 coinSeg/Span/PtT=13/53/53 MergeMatches
55431: seg/base=6/52 coinSeg/Span/PtT=6/12/12 MergeMatches
55532: seg/base=13/54 coinSeg/Span/PtT=13/53/53 MergeMatches
55633: seg/base=6/52 coinSeg/Span/PtT=6/12/12 MergeMatches
55734: seg/base=13/40 coinSeg/Span/PtT=13/82/82 MergeMatches
55835: seg/base=5/83 coinSeg/Span/PtT=5/9/9 MergeMatches
55936: seg/base=12/39 coinSeg/Span/PtT=12/50/50 MergeMatches
56037: seg/base=13/40 coinSeg/Span/PtT=13/82/82 MergeMatches
56138: seg/base=5/83 coinSeg/Span/PtT=5/9/9 MergeMatches
56239: seg/base=12/39 coinSeg/Span/PtT=12/50/50 MergeMatches
56340: seg/base=13/40 coinSeg/Span/PtT=13/82/82 MergeMatches
56441: seg/base=5/83 coinSeg/Span/PtT=5/9/9 MergeMatches
56542: seg/base=12/39 coinSeg/Span/PtT=12/50/50 MergeMatches
56643: seg/base=13/40 coinSeg/Span/PtT=13/82/82 MergeMatches
56744: seg/base=5/83 coinSeg/Span/PtT=5/9/9 MergeMatches
56845: seg/base=12/39 coinSeg/Span/PtT=12/50/50 MergeMatches
56946: seg/base=13/56 coinSeg/Span/PtT=13/85/85 MergeMatches
57047: seg/base=12/55 coinSeg/Span/PtT=12/44/44 MergeMatches
57148: seg/base=13/56 coinSeg/Span/PtT=13/85/85 MergeMatches
57249: seg/base=12/55 coinSeg/Span/PtT=12/44/44 MergeMatches
57350: seg/base=13/56 coinSeg/Span/PtT=13/85/85 MergeMatches
57451: seg/base=12/55 coinSeg/Span/PtT=12/44/44 MergeMatches
57552: seg/base=13/56 coinSeg/Span/PtT=13/85/85 MergeMatches
57653: seg/base=12/55 coinSeg/Span/PtT=12/44/44 MergeMatches
57754: seg/base=10/30 coinSeg/Span/PtT=10/19/19 MergeMatches
57855: seg/base=4/90 coinSeg/Span/PtT=4/29/29 MergeMatches
57956: seg/base=12/60 coinSeg/Span/PtT=12/94/94 MergeMatches
58057: seg/base=13/57 coinSeg/Span/PtT=13/92/92 MergeMatches
58158: seg/base=10/30 coinSeg/Span/PtT=10/19/19 MergeMatches
58259: seg/base=4/90 coinSeg/Span/PtT=4/29/29 MergeMatches
58360: seg/base=12/60 coinSeg/Span/PtT=12/94/94 MergeMatches
58461: seg/base=13/57 coinSeg/Span/PtT=13/92/92 MergeMatches
58562: coinSeg/Span/PtT=13/57/57 endSpan=56 oppSeg/Span/PtT=9/18/18 oppEndSpan=17 MissingCoin
58663: coinSeg/Span/PtT=12/55/55 endSpan=60 oppSeg/Span/PtT=9/17/17 oppEndSpan=18 MissingCoin
58764: seg/base=12/60 coinSeg/Span/PtT=12/23/23 MergeMatches
58865: seg/base=11/70 coinSeg/Span/PtT=11/22/22 MergeMatches
58966: seg/base=12/60 coinSeg/Span/PtT=12/23/23 MergeMatches
59067: seg/base=11/70 coinSeg/Span/PtT=11/22/22 MergeMatches
59168: seg/base=13/56 coinSeg/Span/PtT=13/85/85 MergeMatches
59269: seg/base=12/55 coinSeg/Span/PtT=12/44/44 MergeMatches
59370: seg/base=13/56 coinSeg/Span/PtT=13/85/85 MergeMatches
59471: seg/base=12/55 coinSeg/Span/PtT=12/44/44 MergeMatches
59572: coinSeg/Span/PtT=13/57/57 endSpan=56 oppSeg/Span/PtT=10/19/19 oppEndSpan=31 MissingCoin
59673: coinSeg/Span/PtT=12/55/55 endSpan=60 oppSeg/Span/PtT=10/31/31 oppEndSpan=19 MissingCoin
59774: coinSeg/Span/PtT=13/57/57 endSpan=56 oppSeg/Span/PtT=9/18/18 oppEndSpan=17 MissingCoin
59875: coinSeg/Span/PtT=12/55/55 endSpan=60 oppSeg/Span/PtT=9/17/17 oppEndSpan=18 MissingCoin
59976: coinSeg/Span/PtT=13/57/57 endSpan=56 oppSeg/Span/PtT=10/19/19 oppEndSpan=31 MissingCoin
60077: coinSeg/Span/PtT=12/55/55 endSpan=60 oppSeg/Span/PtT=10/31/31 oppEndSpan=19 MissingCoin
60178: seg/base=13/64 coinSeg/Span/PtT=13/82/82 MergeMatches
60279: seg/base=5/86 coinSeg/Span/PtT=5/83/83 MergeMatches
60380: seg/base=12/63 coinSeg/Span/PtT=12/50/50 MergeMatches
60481: seg/base=13/64 coinSeg/Span/PtT=13/82/82 MergeMatches
60582: seg/base=5/86 coinSeg/Span/PtT=5/83/83 MergeMatches
60683: seg/base=12/63 coinSeg/Span/PtT=12/50/50 MergeMatches
60784: seg/base=13/56 coinSeg/Span/PtT=13/88/88 MergeMatches
60885: seg/base=11/71 coinSeg/Span/PtT=11/42/42 MergeMatches
60986: seg/base=12/55 coinSeg/Span/PtT=12/67/67 MergeMatches
61087: seg/base=13/56 coinSeg/Span/PtT=13/88/88 MergeMatches
61188: seg/base=11/71 coinSeg/Span/PtT=11/42/42 MergeMatches
61289: seg/base=12/55 coinSeg/Span/PtT=12/67/67 MergeMatches
61390: coinSeg/Span/PtT=13/25/25 endSpan=82 oppSeg/Span/PtT=12/24/24 oppEndSpan=50 MissingCoin
61491: seg/base=10/31 coinSeg/Span/PtT=10/19/19 MergeMatches
61592: segment=9 MergeMatches
61693: seg/base=8/76 coinSeg/Span/PtT=8/16/16 MergeMatches
61794: seg/base=13/57 coinSeg/Span/PtT=13/56/56 MergeMatches
61895: seg/base=4/90 coinSeg/Span/PtT=4/91/91 MergeMatches
61996: seg/base=12/60 coinSeg/Span/PtT=12/55/55 MergeMatches
62097: seg/base=11/70 coinSeg/Span/PtT=11/71/71 MergeMatches
62198: seg/base=10/31 coinSeg/Span/PtT=10/19/19 MergeMatches
62299: segment=9 MergeMatches
623100: seg/base=8/76 coinSeg/Span/PtT=8/16/16 MergeMatches
624101: seg/base=13/57 coinSeg/Span/PtT=13/56/56 MergeMatches
625102: seg/base=4/90 coinSeg/Span/PtT=4/91/91 MergeMatches
626103: seg/base=12/60 coinSeg/Span/PtT=12/55/55 MergeMatches
627104: seg/base=11/70 coinSeg/Span/PtT=11/71/71 MergeMatches
628105: coinSeg/Span/PtT=12/50/50 endSpan=24 oppSeg/Span/PtT=13/82/82 oppEndSpan=25 MissingCoin
629106: coinSeg/Span/PtT=13/25/25 endSpan=82 oppSeg/Span/PtT=12/24/24 oppEndSpan=50 MissingCoin
630107: coinSeg/Span/PtT=12/50/50 endSpan=24 oppSeg/Span/PtT=13/82/82 oppEndSpan=25 MissingCoin
631108: segment=11 ReturnFalse
632109: segment=11 startT=0.0126699 endT=0.0342199 segment=8 oppStartT=0 oppEndT=1 AddMissingCoin
633110: segment=11 ReturnFalse
634111: segment=11 startT=0 endT=0.0126699 segment=7 oppStartT=0.246928 oppEndT=1 AddMissingCoin
635112: segment=11 ReturnFalse
636113: segment=11 startT=0 endT=0.0126699 segment=5 oppStartT=0.476143 oppEndT=0 AddMissingCoin
637114: segment=11 ReturnFalse
638115: segment=11 startT=0.0126699 endT=0.102205 segment=4 oppStartT=1 oppEndT=0 AddMissingCoin
639116: segment=11 ReturnFalse
640117: segment=11 startT=0.102205 endT=0.115176 segment=3 oppStartT=1 oppEndT=0.0649612 AddMissingCoin
641118: segment=13 ReturnFalse
642119: segment=13 startT=1 endT=1 segment=12 oppStartT=3.08642e-07 oppEndT=3.01905e-07 AddMissingCoin
643120: segment=8 ReturnFalse
644121: segment=8 startT=0 endT=1 segment=4 oppStartT=1 oppEndT=0.759312 AddMissingCoin
645122: segment=8 ReturnFalse
646123: segment=8 startT=0 endT=1 segment=4 oppStartT=1 oppEndT=0.759312 AddMissingCoin
647124: segment=13 ReturnFalse
648125: segment=13 startT=1 endT=1 segment=12 oppStartT=3.13901e-07 oppEndT=3.08642e-07 AddMissingCoin
649126: segment=7 ReturnFalse
650127: segment=7 startT=0 endT=1 segment=5 oppStartT=0.632267 oppEndT=0 AddMissingCoin
651128: segment=7 ReturnFalse
652129: segment=7 startT=0.228492 endT=1 segment=5 oppStartT=0.487799 oppEndT=0 AddMissingCoin
653130: segment=13 ReturnFalse
654131: segment=13 startT=1 endT=1 segment=12 oppStartT=3.15199e-07 oppEndT=3.13901e-07 AddMissingCoin
655132: segment=6 ReturnFalse
656133: segment=6 startT=0.291197 endT=1 segment=5 oppStartT=0.892917 oppEndT=0.632267 AddMissingCoin
657134: segment=13 ReturnFalse
658135: segment=13 startT=1 endT=1 segment=12 oppStartT=3.127e-07 oppEndT=3.08642e-07 AddMissingCoin
659136: segment=13 ReturnFalse
660137: segment=13 startT=1 endT=1 segment=12 oppStartT=3.08642e-07 oppEndT=2.80653e-07 AddMissingCoin
661138: segment=13 ReturnFalse
662139: segment=13 startT=1 endT=1 segment=12 oppStartT=2.80653e-07 oppEndT=2.76598e-07 AddMissingCoin
663140: seg/base=12/89 startT=0.000611695 AddExpandedCoin
664141: seg/base=12/94 startT=0.0689388 AddExpandedCoin
665142: seg/base=8/77 startT=1 AddExpandedCoin
666143: seg/base=13/87 startT=0.283286 AddExpandedCoin
667144: seg/base=12/89 startT=0.530213 AddExpandedCoin
668145: seg/base=4/95 startT=1 AddExpandedCoin
669146: seg/base=4/93 startT=1 AddExpandedCoin
670147: seg/base=11/21 seg/base=12/23 MarkCoinStart
671148: seg/base=11/22 seg/base=12/63 MarkCoinEnd
672149: seg/base=12/39 MarkCoinInsert
673150: seg/base=12/65 MarkCoinInsert
674151: seg/base=12/60 MarkCoinInsert
675152: seg/base=12/55 MarkCoinInsert
676153: seg/base=12/94 MarkCoinInsert
677154: seg/base=12/37 MarkCoinInsert
678155: seg/base=12/74 MarkCoinInsert
679156: seg/base=12/36 MarkCoinInsert
680157: seg/base=12/23 MarkCoinInsert
681158: seg/base=11/34 MarkCoinInsert
682159: seg/base=11/73 MarkCoinInsert
683160: seg/base=11/59 MarkCoinInsert
684161: seg/base=11/71 MarkCoinInsert
685162: seg/base=12/94 segment=11 MarkCoinMissing
686163: seg/base=11/70 MarkCoinInsert
687164: seg/base=11/69 MarkCoinInsert
688165: seg/base=11/68 MarkCoinInsert
689166: seg/base=11/42 MarkCoinInsert
690167: seg/base=11/21 MarkCoinInsert
691168: seg/base=12/89 segment=11 MarkCoinMissing
692169: seg/base=13/40 seg/base=8/15 MarkCoinStart
693170: seg/base=13/56 seg/base=8/16 MarkCoinEnd
694171: seg/base=8/76 MarkCoinInsert
695172: seg/base=8/77 segment=13 MarkCoinMissing
696173: seg/base=13/57 MarkCoinInsert
697174: seg/base=8/15 seg/base=12/55 MarkCoinStart
698175: seg/base=8/16 seg/base=12/39 MarkCoinEnd
699176: seg/base=12/60 MarkCoinInsert
700177: seg/base=12/55 MarkCoinInsert
701178: seg/base=8/77 MarkCoinInsert
702179: seg/base=8/15 MarkCoinInsert
703180: seg/base=13/54 seg/base=7/13 MarkCoinStart
704181: seg/base=13/40 seg/base=7/14 MarkCoinEnd
705182: coinSeg/Span/PtT=13/54/54 endSpan=40 Fail
706183: seg/base=7/79 MarkCoinInsert
707184: seg/base=7/78 MarkCoinInsert
708185: seg/base=13/87 segment=7 MarkCoinMissing
709186: seg/base=7/80 MarkCoinInsert
710187: seg/base=13/85 MarkCoinInsert
711188: seg/base=13/64 MarkCoinInsert
712189: seg/base=13/88 MarkCoinInsert
713190: seg/base=7/13 seg/base=12/39 MarkCoinStart
714191: seg/base=7/14 seg/base=12/51 MarkCoinEnd
715192: seg/base=12/63 MarkCoinInsert
716193: seg/base=12/89 MarkCoinInsert
717194: seg/base=12/39 MarkCoinInsert
718195: seg/base=7/78 MarkCoinInsert
719196: seg/base=12/89 segment=7 MarkCoinMissing
720197: seg/base=7/79 MarkCoinInsert
721198: seg/base=7/13 MarkCoinInsert
722199: seg/base=13/53 seg/base=6/52 MarkCoinStart
723200: seg/base=13/54 seg/base=6/12 MarkCoinEnd
724201: seg/base=6/81 MarkCoinInsert
725202: seg/base=6/49 MarkCoinInsert
726203: seg/base=13/46 MarkCoinInsert
727204: seg/base=13/82 MarkCoinInsert
728205: seg/base=6/49 seg/base=12/51 MarkCoinStart
729206: seg/base=6/12 seg/base=12/50 MarkCoinEnd
730207: seg/base=13/46 seg/base=5/9 MarkCoinStart
731208: seg/base=13/40 seg/base=5/45 MarkCoinEnd
732209: seg/base=5/84 MarkCoinInsert
733210: seg/base=5/43 MarkCoinInsert
734211: seg/base=5/86 MarkCoinInsert
735212: seg/base=5/47 MarkCoinInsert
736213: seg/base=5/41 MarkCoinInsert
737214: seg/base=5/9 MarkCoinInsert
738215: seg/base=13/87 MarkCoinInsert
739216: seg/base=13/64 MarkCoinInsert
740217: seg/base=13/85 MarkCoinInsert
741218: seg/base=13/54 MarkCoinInsert
742219: seg/base=13/82 MarkCoinInsert
743220: seg/base=13/46 MarkCoinInsert
744221: seg/base=5/9 seg/base=12/39 MarkCoinStart
745222: seg/base=5/43 seg/base=12/44 MarkCoinEnd
746223: seg/base=12/67 MarkCoinInsert
747224: seg/base=12/89 MarkCoinInsert
748225: seg/base=12/63 MarkCoinInsert
749226: seg/base=5/41 MarkCoinInsert
750227: seg/base=5/47 MarkCoinInsert
751228: seg/base=5/86 MarkCoinInsert
752229: seg/base=13/40 seg/base=4/7 MarkCoinStart
753230: seg/base=13/38 seg/base=4/8 MarkCoinEnd
754231: seg/base=4/91 MarkCoinInsert
755232: seg/base=4/29 MarkCoinInsert
756233: seg/base=4/93 MarkCoinInsert
757234: seg/base=4/93 segment=13 MarkCoinMissing
758235: seg/base=13/56 MarkCoinInsert
759236: seg/base=13/57 MarkCoinInsert
760237: seg/base=13/40 MarkCoinInsert
761238: seg/base=4/95 segment=13 MarkCoinMissing
762239: seg/base=4/7 seg/base=12/37 MarkCoinStart
763240: seg/base=4/8 seg/base=12/39 MarkCoinEnd
764241: seg/base=12/72 MarkCoinInsert
765242: seg/base=12/94 MarkCoinInsert
766243: seg/base=12/55 MarkCoinInsert
767244: seg/base=12/60 MarkCoinInsert
768245: seg/base=12/65 MarkCoinInsert
769246: seg/base=4/93 MarkCoinInsert
770247: seg/base=4/29 MarkCoinInsert
771248: seg/base=4/91 MarkCoinInsert
772249: seg/base=4/90 MarkCoinInsert
773250: seg/base=4/95 MarkCoinInsert
774251: seg/base=13/38 seg/base=3/5 MarkCoinStart
775252: seg/base=13/32 seg/base=3/6 MarkCoinEnd
776253: seg/base=3/35 MarkCoinInsert
777254: seg/base=3/5 MarkCoinInsert
778255: seg/base=13/96 MarkCoinInsert
779256: seg/base=13/38 MarkCoinInsert
780257: seg/base=3/35 seg/base=12/36 MarkCoinStart
781258: seg/base=3/6 seg/base=12/37 MarkCoinEnd
782259: seg/base=12/74 MarkCoinInsert
783260: seg/base=3/33 MarkCoinInsert
784261: seg/base=9/17 seg/base=10/19 MarkCoinStart
785262: seg/base=9/18 seg/base=10/31 MarkCoinEnd
786SkOpSegment::debugShowActiveSpans id=1 (360,-2.14748365e+09 593011648,-2.14748352e+09 1.07374221e+09,-1.6667529e+09 1.07374208e+09,-1.07374157e+09) t=0 tEnd=1 windSum=? windValue=1
787SkOpSegment::debugShowActiveSpans id=2 (1.07374208e+09,-1.07374157e+09 1.07374208e+09,-480730560 593011840,-135.508026 905.953125,255.999786) t=0 tEnd=1 windSum=? windValue=1
788SkOpSegment::debugShowActiveSpans id=3 (905.953125,255.999786 900.097229,297.65976) t=0 tEnd=0.0649612467 windSum=? windValue=1
789SkOpSegment::debugShowActiveSpans id=3 (900.097229,297.65976 897.639343,315.145294) t=0.0649612467 tEnd=0.0922268392 windSum=? windValue=1
790SkOpSegment::debugShowActiveSpans id=3 (897.639343,315.145294 815.80835,897.304565) t=0.0922268392 tEnd=1 windSum=? windValue=1
791SkOpSegment::debugShowActiveSpans id=4 (815.80835,897.304565 361.553253,652.788635) t=0 tEnd=0.753851653 windSum=? windValue=1
792SkOpSegment::debugShowActiveSpans id=4 (361.553253,652.788635 360,651.952515) t=0.753851653 tEnd=0.756429319 windSum=? windValue=1
793SkOpSegment::debugShowActiveSpans id=4 (360,651.952515 358.263184,651.017639) t=0.756429319 tEnd=0.759311649 windSum=? windValue=1
794SkOpSegment::debugShowActiveSpans id=4 (358.263184,651.017639 343.716705,643.187561) t=0.759311649 tEnd=0.783451987 windSum=? windValue=1
795SkOpSegment::debugShowActiveSpans id=4 (343.716705,643.187561 323.286591,632.190491) t=0.783451987 tEnd=0.817356482 windSum=? windValue=1
796SkOpSegment::debugShowActiveSpans id=4 (323.286591,632.190491 213.229446,572.949036) t=0.817356482 tEnd=1 windSum=? windValue=1
797SkOpSegment::debugShowActiveSpans id=5 (213.229446,572.949036 131.235565,320.967834) t=0 tEnd=0.452431368 windSum=? windValue=1
798SkOpSegment::debugShowActiveSpans id=5 (131.235565,320.967834 131.104431,320.56485) t=0.452431368 tEnd=0.453154928 windSum=? windValue=1
799SkOpSegment::debugShowActiveSpans id=5 (131.104431,320.56485 126.938354,307.76178) t=0.453154928 tEnd=0.476142764 windSum=? windValue=1
800SkOpSegment::debugShowActiveSpans id=5 (126.938354,307.76178 124.825912,301.269867) t=0.476142764 tEnd=0.487798966 windSum=? windValue=1
801SkOpSegment::debugShowActiveSpans id=5 (124.825912,301.269867 98.6440353,220.808502) t=0.487798966 tEnd=0.632267074 windSum=? windValue=1
802SkOpSegment::debugShowActiveSpans id=5 (98.6440353,220.808502 70.3632965,133.896957) t=0.632267074 tEnd=0.788316424 windSum=? windValue=1
803SkOpSegment::debugShowActiveSpans id=5 (70.3632965,133.896957 51.4065475,75.6396332) t=0.788316424 tEnd=0.892917257 windSum=? windValue=1
804SkOpSegment::debugShowActiveSpans id=5 (51.4065475,75.6396332 32,16) t=0.892917257 tEnd=1 windSum=? windValue=1
805SkOpSegment::debugShowActiveSpans id=6 (32,16 40.183567,75.6918945) t=0 tEnd=0.120346555 windSum=? windValue=1
806SkOpSegment::debugShowActiveSpans id=6 (40.183567,75.6918945 51.8013992,160.433731) t=0.120346555 tEnd=0.291197031 windSum=? windValue=1
807SkOpSegment::debugShowActiveSpans id=6 (51.8013992,160.433731 71.1438522,301.519836) t=0.291197031 tEnd=0.575644854 windSum=? windValue=1
808SkOpSegment::debugShowActiveSpans id=6 (71.1438522,301.519836 100,512) t=0.575644854 tEnd=1 windSum=? windValue=1
809SkOpSegment::debugShowActiveSpans id=7 (100,512 125.872047,525.926392) t=0 tEnd=0.228492228 windSum=? windValue=1
810SkOpSegment::debugShowActiveSpans id=7 (125.872047,525.926392 127.959496,527.049988) t=0.228492228 tEnd=0.246927782 windSum=? windValue=1
811SkOpSegment::debugShowActiveSpans id=7 (127.959496,527.049988 132.205856,529.335754) t=0.246927782 tEnd=0.284429982 windSum=? windValue=1
812SkOpSegment::debugShowActiveSpans id=7 (132.205856,529.335754 213.229446,572.949036) t=0.284429982 tEnd=1 windSum=? windValue=1
813SkOpSegment::debugShowActiveSpans id=8 (213.229446,572.949036 324.604553,915.223755) t=0 tEnd=0.758838213 windSum=? windValue=1
814SkOpSegment::debugShowActiveSpans id=8 (324.604553,915.223755 345.279358,978.760925) t=0.758838213 tEnd=0.899702926 windSum=? windValue=1
815SkOpSegment::debugShowActiveSpans id=8 (345.279358,978.760925 360,1024) t=0.899702926 tEnd=1 windSum=? windValue=1
816SkOpSegment::debugShowActiveSpans id=9 (360,1024 360,4140) t=0 tEnd=1 windSum=? windValue=1
817SkOpSegment::debugShowActiveSpans id=10 (360,4140 360,1024) t=0 tEnd=1.45099777e-06 windSum=? windValue=1
818SkOpSegment::debugShowActiveSpans id=10 (360,1024 360,651.952515) t=1.45099777e-06 tEnd=1.62424554e-06 windSum=? windValue=1
819SkOpSegment::debugShowActiveSpans id=10 (360,651.952515 360,319.229858) t=1.62424554e-06 tEnd=1.77918132e-06 windSum=? windValue=1
820SkOpSegment::debugShowActiveSpans id=10 (360,319.229858 360,296.296631) t=1.77918132e-06 tEnd=1.78986041e-06 windSum=? windValue=1
821SkOpSegment::debugShowActiveSpans id=10 (360,296.296631 360,-2.14748365e+09) t=1.78986041e-06 tEnd=1 windSum=? windValue=1
822SkOpSegment::debugShowActiveSpans id=11 (127,321 131.235565,320.967834) t=0 tEnd=0.000630948916 windSum=? windValue=1
823SkOpSegment::debugShowActiveSpans id=11 (131.235565,320.967834 212.053207,320.353821) t=0.000630948916 tEnd=0.0126699258 windSum=? windValue=1
824SkOpSegment::debugShowActiveSpans id=11 (212.053207,320.353821 321.830627,319.519836) t=0.0126699258 tEnd=0.0290228849 windSum=? windValue=1
825SkOpSegment::debugShowActiveSpans id=11 (321.830627,319.519836 342.208832,319.365021) t=0.0290228849 tEnd=0.0320585186 windSum=? windValue=1
826SkOpSegment::debugShowActiveSpans id=11 (342.208832,319.365021 356.718292,319.254791) t=0.0320585186 tEnd=0.0342199142 windSum=? windValue=1
827SkOpSegment::debugShowActiveSpans id=11 (356.718292,319.254791 360,319.229858) t=0.0342199142 tEnd=0.034708774 windSum=? windValue=1
828SkOpSegment::debugShowActiveSpans id=11 (360,319.229858 813.100464,315.787567) t=0.034708774 tEnd=0.102204746 windSum=? windValue=1
829SkOpSegment::debugShowActiveSpans id=11 (813.100464,315.787567 897.639343,315.145294) t=0.102204746 tEnd=0.114798057 windSum=? windValue=1
830SkOpSegment::debugShowActiveSpans id=11 (897.639343,315.145294 900.178528,315.126007) t=0.114798057 tEnd=0.115176306 windSum=? windValue=1
831SkOpSegment::debugShowActiveSpans id=11 (900.178528,315.126007 6840,270) t=0.115176306 tEnd=1 windSum=? windValue=1
832SkOpSegment::debugShowActiveSpans id=12 (6840,270 900.097229,297.65976) t=0 tEnd=2.7659819e-07 windSum=? windValue=1
833SkOpSegment::debugShowActiveSpans id=12 (900.097229,297.65976 897.557983,297.67157) t=2.7659819e-07 tEnd=2.76716432e-07 windSum=? windValue=1
834SkOpSegment::debugShowActiveSpans id=12 (897.557983,297.67157 813.017944,298.065247) t=2.76716432e-07 tEnd=2.80653133e-07 windSum=? windValue=1
835SkOpSegment::debugShowActiveSpans id=12 (813.017944,298.065247 359.911255,300.175171) t=2.80653133e-07 tEnd=3.0175255e-07 windSum=? windValue=1
836SkOpSegment::debugShowActiveSpans id=12 (359.911255,300.175171 358.361938,300.182373) t=3.0175255e-07 tEnd=3.01824696e-07 windSum=? windValue=1
837SkOpSegment::debugShowActiveSpans id=12 (358.361938,300.182373 360,1024) t=3.01824696e-07 tEnd=3.01905369e-07 windSum=? windValue=1
838SkOpSegment::debugShowActiveSpans id=12 (360,1024 360,4140) t=3.01905369e-07 tEnd=3.02581027e-07 windSum=? windValue=1
839SkOpSegment::debugShowActiveSpans id=12 (360,4140 321.741364,300.352905) t=3.02581027e-07 tEnd=3.03529974e-07 windSum=? windValue=1
840SkOpSegment::debugShowActiveSpans id=12 (321.741364,300.352905 211.962463,300.864105) t=3.03529974e-07 tEnd=3.08641951e-07 windSum=? windValue=1
841SkOpSegment::debugShowActiveSpans id=12 (211.962463,300.864105 131.143692,301.240448) t=3.08641951e-07 tEnd=3.12405367e-07 windSum=? windValue=1
842SkOpSegment::debugShowActiveSpans id=12 (131.143692,301.240448 131.01445,301.241058) t=3.12405367e-07 tEnd=3.12411385e-07 windSum=? windValue=1
843SkOpSegment::debugShowActiveSpans id=12 (131.01445,301.241058 127,321) t=3.12411385e-07 tEnd=3.12602603e-07 windSum=? windValue=1
844SkOpSegment::debugShowActiveSpans id=12 (127,321 124.825912,301.269867) t=3.12602603e-07 tEnd=3.12699562e-07 windSum=? windValue=1
845SkOpSegment::debugShowActiveSpans id=12 (124.825912,301.269867 100,512) t=3.12699562e-07 tEnd=3.13901276e-07 windSum=? windValue=1
846SkOpSegment::debugShowActiveSpans id=12 (100,512 71.1438522,301.519836) t=3.13901276e-07 tEnd=3.15199326e-07 windSum=? windValue=1
847SkOpSegment::debugShowActiveSpans id=12 (71.1438522,301.519836 -2.14748365e+10,100000000) t=3.15199326e-07 tEnd=1 windSum=? windValue=1
848SkOpSegment::debugShowActiveSpans id=13 (-2.14748365e+10,100000000 40.183567,75.6918945) t=0 tEnd=0.999999883 windSum=? windValue=1
849SkOpSegment::debugShowActiveSpans id=13 (40.183567,75.6918945 51.4065437,75.6396332) t=0.999999883 tEnd=0.999999884 windSum=? windValue=1
850SkOpSegment::debugShowActiveSpans id=13 (51.4065437,75.6396332 70.0916061,75.5526199) t=0.999999884 tEnd=0.999999884 windSum=? windValue=1
851SkOpSegment::debugShowActiveSpans id=13 (70.0916061,75.5526199 100,512) t=0.999999884 tEnd=0.999999886 windSum=? windValue=1
852SkOpSegment::debugShowActiveSpans id=13 (100,512 123.773666,75.3026428) t=0.999999886 tEnd=0.999999887 windSum=? windValue=1
853SkOpSegment::debugShowActiveSpans id=13 (123.773666,75.3026428 127,321) t=0.999999887 tEnd=0.999999887 windSum=? windValue=1
854SkOpSegment::debugShowActiveSpans id=13 (127,321 129.962204,75.2738266) t=0.999999887 tEnd=0.999999887 windSum=? windValue=1
855SkOpSegment::debugShowActiveSpans id=13 (129.962204,75.2738266 130.091461,75.2732239) t=0.999999887 tEnd=0.999999887 windSum=? windValue=1
856SkOpSegment::debugShowActiveSpans id=13 (130.091461,75.2732239 210.910217,74.8968811) t=0.999999887 tEnd=0.999999891 windSum=? windValue=1
857SkOpSegment::debugShowActiveSpans id=13 (210.910217,74.8968811 360,4140) t=0.999999891 tEnd=0.999999897 windSum=? windValue=1
858SkOpSegment::debugShowActiveSpans id=13 (360,4140 360,1024) t=0.999999897 tEnd=0.999999898 windSum=? windValue=1
859SkOpSegment::debugShowActiveSpans id=13 (360,1024 357.309692,74.2151566) t=0.999999898 tEnd=0.999999898 windSum=? windValue=1
860SkOpSegment::debugShowActiveSpans id=13 (357.309692,74.2151566 811.965698,72.0980072) t=0.999999898 tEnd=0.999999919 windSum=? windValue=1
861SkOpSegment::debugShowActiveSpans id=13 (811.965698,72.0980072 896.505737,71.7043304) t=0.999999919 tEnd=0.999999923 windSum=? windValue=1
862SkOpSegment::debugShowActiveSpans id=13 (896.505737,71.7043304 899.044983,71.6925125) t=0.999999923 tEnd=0.999999923 windSum=? windValue=1
863SkOpSegment::debugShowActiveSpans id=13 (899.044983,71.6925125 905.094727,71.6643372) t=0.999999923 tEnd=0.999999923 windSum=? windValue=1
864SkOpSegment::debugShowActiveSpans id=13 (905.094727,71.6643372 2551,64) t=0.999999923 tEnd=1 windSum=? windValue=1
865SkOpSegment::debugShowActiveSpans id=14 (2551,64 360,296.296631) t=0 tEnd=0.903877888 windSum=? windValue=1
866SkOpSegment::debugShowActiveSpans id=14 (360,296.296631 321.741364,300.352905) t=0.903877888 tEnd=0.919661149 windSum=? windValue=1
867SkOpSegment::debugShowActiveSpans id=14 (321.741364,300.352905 131.104431,320.56485) t=0.919661149 tEnd=0.998306753 windSum=? windValue=1
868SkOpSegment::debugShowActiveSpans id=14 (131.104431,320.56485 127,321) t=0.998306753 tEnd=1 windSum=? windValue=1
869SkOpSegment::markDone id=4 (815.80835,897.304565 213.229446,572.949036) t=0 [7] (815.80835,897.304565) tEnd=0.753851653 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
870SkOpSegment::markDone id=4 (815.80835,897.304565 213.229446,572.949036) t=0.753851653 [93] (361.553253,652.788635) tEnd=0.756429319 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
871SkOpSegment::markDone id=4 (815.80835,897.304565 213.229446,572.949036) t=0.756429319 [29] (360,651.952515) tEnd=0.759311649 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
872SkOpSegment::markDone id=4 (815.80835,897.304565 213.229446,572.949036) t=0.759311649 [91] (358.263184,651.017639) tEnd=0.783451987 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
873SkOpSegment::markDone id=4 (815.80835,897.304565 213.229446,572.949036) t=0.783451987 [90] (343.716705,643.187561) tEnd=0.817356482 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
874SkOpSegment::markDone id=4 (815.80835,897.304565 213.229446,572.949036) t=0.817356482 [95] (323.286591,632.190491) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
875SkOpSegment::markDone id=7 (100,512 213.229446,572.949036) t=0 [13] (100,512) tEnd=0.246927782 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
876SkOpSegment::markDone id=7 (100,512 213.229446,572.949036) t=0.246927782 [78] (127.959496,527.049988) tEnd=0.284429982 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
877SkOpSegment::markDone id=7 (100,512 213.229446,572.949036) t=0.284429982 [80] (132.205856,529.335754) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
878SkOpSegment::markDone id=8 (213.229446,572.949036 360,1024) t=0 [15] (213.229446,572.949036) tEnd=0.758838213 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
879SkOpSegment::markDone id=8 (213.229446,572.949036 360,1024) t=0.758838213 [77] (324.604553,915.223755) tEnd=0.899702926 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
880SkOpSegment::markDone id=8 (213.229446,572.949036 360,1024) t=0.899702926 [76] (345.279358,978.760925) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
881SkOpSegment::markDone id=9 (360,1024 360,4140) t=0 [17] (360,1024) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
882------------------xx-xxx----x--x------ move_nearby
88300: seg/base=13/96 coinSeg/Span/PtT=13/46/46 MergeMatches
88401: seg/base=6/81 coinSeg/Span/PtT=6/12/12 MergeMatches
88502: seg/base=5/45 coinSeg/Span/PtT=5/9/9 MergeMatches
88603: seg/base=13/96 coinSeg/Span/PtT=13/46/46 MergeMatches
88704: seg/base=6/81 coinSeg/Span/PtT=6/12/12 MergeMatches
88805: seg/base=5/45 coinSeg/Span/PtT=5/9/9 MergeMatches
88906: seg/base=13/96 coinSeg/Span/PtT=13/46/46 MergeMatches
89007: seg/base=6/81 coinSeg/Span/PtT=6/12/12 MergeMatches
89108: seg/base=5/45 coinSeg/Span/PtT=5/9/9 MergeMatches
89209: seg/base=13/96 coinSeg/Span/PtT=13/46/46 MergeMatches
89310: seg/base=6/81 coinSeg/Span/PtT=6/12/12 MergeMatches
89411: seg/base=5/45 coinSeg/Span/PtT=5/9/9 MergeMatches
89512: seg/base=12/89 coinSeg/Span/PtT=12/23/23 MergeMatches
89613: seg/base=13/96 coinSeg/Span/PtT=13/87/87 MergeMatches
89714: segment=11 MergeMatches
89815: seg/base=5/47 coinSeg/Span/PtT=5/9/9 MergeMatches
89916: seg/base=12/89 coinSeg/Span/PtT=12/23/23 MergeMatches
90017: seg/base=13/96 coinSeg/Span/PtT=13/87/87 MergeMatches
90118: segment=11 MergeMatches
90219: seg/base=5/47 coinSeg/Span/PtT=5/9/9 MergeMatches
90320: seg/base=4/90 coinSeg/Span/PtT=4/7/7 MoveNearbyRelease
90421: seg/base=4/29 coinSeg/Span/PtT=4/7/7 MoveNearbyRelease
90522: seg/base=4/91 coinSeg/Span/PtT=4/7/7 MoveNearbyRelease
90623: seg/base=4/91 coinSeg/Span/PtT=4/29/29 MoveNearbyRelease
90724: seg/base=4/90 coinSeg/Span/PtT=4/29/29 MoveNearbyRelease
90825: seg/base=4/90 coinSeg/Span/PtT=4/91/91 MoveNearbyRelease
90926: seg/base=4/29 coinSeg/Span/PtT=4/91/91 MoveNearbyRelease
91027: seg/base=4/29 coinSeg/Span/PtT=4/90/90 MoveNearbyRelease
91128: seg/base=4/91 coinSeg/Span/PtT=4/90/90 MoveNearbyRelease
91229: seg/base=12/72 coinSeg/Span/PtT=12/23/23 MergeMatches
91330: seg/base=10/58 coinSeg/Span/PtT=10/19/19 MergeMatches
91431: seg/base=11/59 coinSeg/Span/PtT=11/22/22 MergeMatches
91532: seg/base=12/72 coinSeg/Span/PtT=12/23/23 MergeMatches
91633: seg/base=10/58 coinSeg/Span/PtT=10/19/19 MergeMatches
91734: seg/base=11/59 coinSeg/Span/PtT=11/22/22 MergeMatches
91835: seg/base=13/96 coinSeg/Span/PtT=13/87/87 MergeMatches
91936: segment=11 MergeMatches
92037: seg/base=5/47 coinSeg/Span/PtT=5/9/9 MergeMatches
92138: seg/base=12/89 coinSeg/Span/PtT=12/23/23 MergeMatches
92239: seg/base=13/96 coinSeg/Span/PtT=13/87/87 MergeMatches
92340: segment=11 MergeMatches
92441: seg/base=5/47 coinSeg/Span/PtT=5/9/9 MergeMatches
92542: seg/base=12/89 coinSeg/Span/PtT=12/23/23 MergeMatches
92643: seg/base=13/96 coinSeg/Span/PtT=13/46/46 MergeMatches
92744: seg/base=6/81 coinSeg/Span/PtT=6/12/12 MergeMatches
92845: seg/base=5/45 coinSeg/Span/PtT=5/9/9 MergeMatches
92946: seg/base=13/96 coinSeg/Span/PtT=13/46/46 MergeMatches
93047: seg/base=6/81 coinSeg/Span/PtT=6/12/12 MergeMatches
93148: seg/base=5/45 coinSeg/Span/PtT=5/9/9 MergeMatches
93249: seg/base=12/72 coinSeg/Span/PtT=12/23/23 MergeMatches
93350: seg/base=10/58 coinSeg/Span/PtT=10/19/19 MergeMatches
93451: seg/base=11/59 coinSeg/Span/PtT=11/22/22 MergeMatches
93552: seg/base=12/72 coinSeg/Span/PtT=12/23/23 MergeMatches
93653: seg/base=10/58 coinSeg/Span/PtT=10/19/19 MergeMatches
93754: seg/base=11/59 coinSeg/Span/PtT=11/22/22 MergeMatches
93855: seg/base=7/80 coinSeg/Span/PtT=7/13/13 MoveNearbyRelease
93956: seg/base=12/72 coinSeg/Span/PtT=12/23/23 MergeMatches
94057: seg/base=10/58 coinSeg/Span/PtT=10/19/19 MergeMatches
94158: seg/base=11/59 coinSeg/Span/PtT=11/22/22 MergeMatches
94259: seg/base=12/72 coinSeg/Span/PtT=12/23/23 MergeMatches
94360: seg/base=10/58 coinSeg/Span/PtT=10/19/19 MergeMatches
94461: seg/base=11/59 coinSeg/Span/PtT=11/22/22 MergeMatches
94562: seg/base=12/72 coinSeg/Span/PtT=12/23/23 MergeMatches
94663: seg/base=10/58 coinSeg/Span/PtT=10/19/19 MergeMatches
94764: seg/base=11/59 coinSeg/Span/PtT=11/22/22 MergeMatches
94865: seg/base=12/72 coinSeg/Span/PtT=12/23/23 MergeMatches
94966: seg/base=10/58 coinSeg/Span/PtT=10/19/19 MergeMatches
95067: seg/base=11/59 coinSeg/Span/PtT=11/22/22 MergeMatches
95168: seg/base=8/76 coinSeg/Span/PtT=8/15/15 MoveNearbyRelease
95269: seg/base=12/72 coinSeg/Span/PtT=12/23/23 MergeMatches
95370: seg/base=10/58 coinSeg/Span/PtT=10/19/19 MergeMatches
95471: seg/base=11/59 coinSeg/Span/PtT=11/22/22 MergeMatches
95572: seg/base=12/72 coinSeg/Span/PtT=12/23/23 MergeMatches
95673: seg/base=10/58 coinSeg/Span/PtT=10/19/19 MergeMatches
95774: seg/base=11/59 coinSeg/Span/PtT=11/22/22 MergeMatches
95875: seg/base=13/96 coinSeg/Span/PtT=13/46/46 MergeMatches
95976: seg/base=6/81 coinSeg/Span/PtT=6/12/12 MergeMatches
96077: seg/base=5/45 coinSeg/Span/PtT=5/9/9 MergeMatches
96178: seg/base=13/96 coinSeg/Span/PtT=13/46/46 MergeMatches
96279: seg/base=6/81 coinSeg/Span/PtT=6/12/12 MergeMatches
96380: seg/base=5/45 coinSeg/Span/PtT=5/9/9 MergeMatches
96481: segment=9 MoveNearbyClearAll2
96582: seg/base=12/72 coinSeg/Span/PtT=12/23/23 MergeMatches
96683: seg/base=10/58 coinSeg/Span/PtT=10/19/19 MergeMatches
96784: seg/base=11/59 coinSeg/Span/PtT=11/22/22 MergeMatches
96885: seg/base=12/72 coinSeg/Span/PtT=12/23/23 MergeMatches
96986: seg/base=10/58 coinSeg/Span/PtT=10/19/19 MergeMatches
97087: seg/base=11/59 coinSeg/Span/PtT=11/22/22 MergeMatches
97188: seg/base=12/89 coinSeg/Span/PtT=12/23/23 MergeMatches
97289: seg/base=5/47 coinSeg/Span/PtT=5/9/9 MergeMatches
97390: segment=11 MergeMatches
97491: seg/base=13/87 coinSeg/Span/PtT=13/96/96 MergeMatches
97592: seg/base=12/89 coinSeg/Span/PtT=12/23/23 MergeMatches
97693: seg/base=5/47 coinSeg/Span/PtT=5/9/9 MergeMatches
97794: segment=11 MergeMatches
97895: seg/base=13/87 coinSeg/Span/PtT=13/96/96 MergeMatches
97996: coinSeg/Span/PtT=13/25/25 endSpan=87 oppSeg/Span/PtT=12/24/24 oppEndSpan=89 MissingCoin
98097: coinSeg/Span/PtT=12/89/89 endSpan=24 oppSeg/Span/PtT=13/87/87 oppEndSpan=25 MissingCoin
98198: coinSeg/Span/PtT=13/25/25 endSpan=87 oppSeg/Span/PtT=12/24/24 oppEndSpan=89 MissingCoin
98299: coinSeg/Span/PtT=12/89/89 endSpan=24 oppSeg/Span/PtT=13/87/87 oppEndSpan=25 MissingCoin
983100: seg/base=11/21 seg/base=12/23 MarkCoinStart
984101: seg/base=11/22 seg/base=12/89 MarkCoinEnd
985102: seg/base=12/72 MarkCoinInsert
986103: seg/base=12/23 MarkCoinInsert
987104: seg/base=11/69 MarkCoinInsert
988105: seg/base=11/21 MarkCoinInsert
989106: seg/base=13/46 seg/base=5/9 MarkCoinStart
990107: seg/base=13/96 seg/base=5/45 MarkCoinEnd
991108: seg/base=5/9 MarkCoinInsert
992109: seg/base=13/46 MarkCoinInsert
993110: seg/base=13/96 seg/base=3/5 MarkCoinStart
994111: seg/base=13/32 seg/base=3/6 MarkCoinEnd
995SkOpSegment::debugShowActiveSpans id=1 (360,-2.14748365e+09 593011648,-2.14748352e+09 1.07374221e+09,-1.6667529e+09 1.07374208e+09,-1.07374157e+09) t=0 tEnd=1 windSum=? windValue=1
996SkOpSegment::debugShowActiveSpans id=2 (1.07374208e+09,-1.07374157e+09 1.07374208e+09,-480730560 593011840,-135.508026 905.953125,255.999786) t=0 tEnd=1 windSum=? windValue=1
997SkOpSegment::debugShowActiveSpans id=3 (905.953125,255.999786 815.80835,897.304565) t=0 tEnd=1 windSum=? windValue=1
998SkOpSegment::debugShowActiveSpans id=5 (213.229446,572.949036 131.104431,320.56485) t=0 tEnd=0.453154928 windSum=? windValue=1
999SkOpSegment::debugShowActiveSpans id=5 (131.104431,320.56485 51.4065475,75.6396332) t=0.453154928 tEnd=0.892917257 windSum=? windValue=1
1000SkOpSegment::debugShowActiveSpans id=5 (51.4065475,75.6396332 32,16) t=0.892917257 tEnd=1 windSum=? windValue=1
1001SkOpSegment::debugShowActiveSpans id=6 (32,16 51.8013992,160.433731) t=0 tEnd=0.291197031 windSum=? windValue=1
1002SkOpSegment::debugShowActiveSpans id=6 (51.8013992,160.433731 100,512) t=0.291197031 tEnd=1 windSum=? windValue=1
1003SkOpSegment::debugShowActiveSpans id=10 (360,4140 360,319.229858) t=0 tEnd=1.77918132e-06 windSum=? windValue=1
1004SkOpSegment::debugShowActiveSpans id=10 (360,319.229858 360,296.296631) t=1.77918132e-06 tEnd=1.78986041e-06 windSum=? windValue=1
1005SkOpSegment::debugShowActiveSpans id=10 (360,296.296631 360,-2.14748365e+09) t=1.78986041e-06 tEnd=1 windSum=? windValue=1
1006SkOpSegment::debugShowActiveSpans id=11 (127,321 321.830627,319.519836) t=0 tEnd=0.0290228849 windSum=? windValue=1
1007SkOpSegment::debugShowActiveSpans id=11 (321.830627,319.519836 360,319.229858) t=0.0290228849 tEnd=0.034708774 windSum=? windValue=1
1008SkOpSegment::debugShowActiveSpans id=11 (360,319.229858 6840,270) t=0.034708774 tEnd=1 windSum=? windValue=1
1009SkOpSegment::debugShowActiveSpans id=12 (6840,270 359.911255,300.175171) t=0 tEnd=3.0175255e-07 windSum=? windValue=1
1010SkOpSegment::debugShowActiveSpans id=12 (359.911255,300.175171 321.741364,300.352905) t=3.0175255e-07 tEnd=3.03529974e-07 windSum=? windValue=1
1011SkOpSegment::debugShowActiveSpans id=12 (321.741364,300.352905 131.01445,301.241058) t=3.03529974e-07 tEnd=3.12411385e-07 windSum=? windValue=1
1012SkOpSegment::debugShowActiveSpans id=12 (131.01445,301.241058 -2.14748365e+10,100000000) t=3.12411385e-07 tEnd=1 windSum=? windValue=1
1013SkOpSegment::debugShowActiveSpans id=13 (-2.14748365e+10,100000000 51.4065437,75.6396332) t=0 tEnd=0.999999884 windSum=? windValue=1
1014SkOpSegment::debugShowActiveSpans id=13 (51.4065437,75.6396332 129.962204,75.2738266) t=0.999999884 tEnd=0.999999887 windSum=? windValue=1
1015SkOpSegment::debugShowActiveSpans id=13 (129.962204,75.2738266 896.505737,71.7043304) t=0.999999887 tEnd=0.999999923 windSum=? windValue=1
1016SkOpSegment::debugShowActiveSpans id=13 (896.505737,71.7043304 905.094727,71.6643372) t=0.999999923 tEnd=0.999999923 windSum=? windValue=1
1017SkOpSegment::debugShowActiveSpans id=13 (905.094727,71.6643372 2551,64) t=0.999999923 tEnd=1 windSum=? windValue=1
1018SkOpSegment::debugShowActiveSpans id=14 (2551,64 360,296.296631) t=0 tEnd=0.903877888 windSum=? windValue=1
1019SkOpSegment::debugShowActiveSpans id=14 (360,296.296631 321.741364,300.352905) t=0.903877888 tEnd=0.919661149 windSum=? windValue=1
1020SkOpSegment::debugShowActiveSpans id=14 (321.741364,300.352905 127,321) t=0.919661149 tEnd=1 windSum=? windValue=1
1021c:\skia\src\pathops\skopsegment.cpp(1358): fatal error: "assert((this->globalState() && (this->globalState()->debugCheckHealth() || this->globalState()->debugSkipAssert())) || (!SkDPoint::ApproximatelyEqual(dBugRef->fPt, dBugCheck->fPt)))"
1022pathops_unittest.exe has triggered a breakpoint.
1023 </div>
1024
1025
1026
1027 </div>
caryclarkdac1d172014-06-17 05:15:38 -07001028
1029<script type="text/javascript">
1030
caryclark55888e42016-07-18 10:01:36 -07001031 var testDivs = [
Cary Clark5de52332018-08-30 12:58:23 -04001032 crbug_526025,
caryclark30b9fdd2016-08-31 14:36:29 -07001033 ];
caryclarkdac1d172014-06-17 05:15:38 -07001034
1035var decimal_places = 3; // make this 3 to show more precision
1036
1037var tests = [];
1038var testLines = [];
1039var testTitles = [];
1040var testIndex = 0;
1041var ctx;
1042
1043var xmin, xmax, focusXmin, focusXmax;
1044var ymin, ymax, focusYmin, focusYmax;
1045var scale;
1046var mouseX, mouseY;
1047var srcLeft, srcTop;
1048var screenWidth, screenHeight;
caryclark1049f122015-04-20 08:31:59 -07001049var drawnPts, drawnLines, drawnQuads, drawnConics, drawnCubics;
caryclarkdac1d172014-06-17 05:15:38 -07001050var curveT = 0;
1051
1052var pt_labels = 2;
1053var collect_bounds = false;
1054var control_lines = 0;
1055var curve_t = false;
1056var debug_xy = 1;
1057var focus_enabled = false;
1058var focus_on_selection = false;
1059var step_limit = 0;
1060var draw_active = false;
1061var draw_add = false;
1062var draw_angle = 0;
caryclark624637c2015-05-11 07:21:27 -07001063var draw_coincidence = false;
caryclarkdac1d172014-06-17 05:15:38 -07001064var draw_deriviatives = 0;
Cary Clarkff114282016-12-14 11:56:16 -05001065var draw_direction = false;
caryclarkdac1d172014-06-17 05:15:38 -07001066var draw_hints = false;
caryclarkdac1d172014-06-17 05:15:38 -07001067var draw_id = false;
1068var draw_intersection = 0;
1069var draw_intersectT = false;
1070var draw_legend = true;
1071var draw_log = false;
1072var draw_mark = false;
1073var draw_midpoint = false;
1074var draw_op = 0;
1075var draw_sequence = false;
1076var draw_sort = 0;
caryclark03b03ca2015-04-23 09:13:37 -07001077var draw_top = false;
caryclarkdac1d172014-06-17 05:15:38 -07001078var draw_path = 3;
1079var draw_computed = 0;
1080var retina_scale = !!window.devicePixelRatio;
1081
1082var activeCount = 0;
1083var addCount = 0;
1084var angleCount = 0;
caryclark624637c2015-05-11 07:21:27 -07001085var coinCount = 0;
caryclarkdac1d172014-06-17 05:15:38 -07001086var opCount = 0;
1087var sectCount = 0;
1088var sortCount = 0;
caryclark03b03ca2015-04-23 09:13:37 -07001089var topCount = 0;
caryclarkdac1d172014-06-17 05:15:38 -07001090var markCount = 0;
1091var activeMax = 0;
1092var addMax = 0;
1093var angleMax = 0;
caryclark624637c2015-05-11 07:21:27 -07001094var coinMax = 0;
caryclarkdac1d172014-06-17 05:15:38 -07001095var sectMax = 0;
1096var sectMax2 = 0;
1097var sortMax = 0;
caryclark03b03ca2015-04-23 09:13:37 -07001098var topMax = 0;
caryclarkdac1d172014-06-17 05:15:38 -07001099var markMax = 0;
1100var opMax = 0;
1101var stepMax = 0;
1102var lastIndex = 0;
1103var hasPath = false;
caryclark26ad22a2015-10-16 09:03:38 -07001104var hasAlignedPath = false;
caryclarkdac1d172014-06-17 05:15:38 -07001105var hasComputedPath = false;
caryclark54359292015-03-26 07:52:43 -07001106var angleBetween = false;
1107var afterIndex = 0;
caryclarkdac1d172014-06-17 05:15:38 -07001108
1109var firstActiveSpan = -1;
1110var logStart = -1;
1111var logRange = 0;
1112
1113var SPAN_ID = 0;
1114var SPAN_X1 = SPAN_ID + 1;
1115var SPAN_Y1 = SPAN_X1 + 1;
1116var SPAN_X2 = SPAN_Y1 + 1;
1117var SPAN_Y2 = SPAN_X2 + 1;
caryclark1049f122015-04-20 08:31:59 -07001118
caryclark55888e42016-07-18 10:01:36 -07001119var SPAN_L_TX = SPAN_Y2 + 1;
caryclarkdac1d172014-06-17 05:15:38 -07001120var SPAN_L_TY = SPAN_L_TX + 1;
caryclark55888e42016-07-18 10:01:36 -07001121var SPAN_L_OTHER = SPAN_L_TY + 1;
caryclarkdac1d172014-06-17 05:15:38 -07001122var SPAN_L_OTHERT = SPAN_L_OTHER + 1;
1123var SPAN_L_OTHERI = SPAN_L_OTHERT + 1;
1124var SPAN_L_SUM = SPAN_L_OTHERI + 1;
1125var SPAN_L_VAL = SPAN_L_SUM + 1;
1126var SPAN_L_OPP = SPAN_L_VAL + 1;
1127
1128var SPAN_X3 = SPAN_Y2 + 1;
1129var SPAN_Y3 = SPAN_X3 + 1;
caryclark1049f122015-04-20 08:31:59 -07001130
caryclark55888e42016-07-18 10:01:36 -07001131var SPAN_Q_TX = SPAN_Y3 + 1;
caryclarkdac1d172014-06-17 05:15:38 -07001132var SPAN_Q_TY = SPAN_Q_TX + 1;
caryclark55888e42016-07-18 10:01:36 -07001133var SPAN_Q_OTHER = SPAN_Q_TY + 1;
caryclarkdac1d172014-06-17 05:15:38 -07001134var SPAN_Q_OTHERT = SPAN_Q_OTHER + 1;
1135var SPAN_Q_OTHERI = SPAN_Q_OTHERT + 1;
1136var SPAN_Q_SUM = SPAN_Q_OTHERI + 1;
1137var SPAN_Q_VAL = SPAN_Q_SUM + 1;
1138var SPAN_Q_OPP = SPAN_Q_VAL + 1;
1139
caryclark1049f122015-04-20 08:31:59 -07001140var SPAN_K_W = SPAN_Y3 + 1;
caryclark55888e42016-07-18 10:01:36 -07001141var SPAN_K_TX = SPAN_K_W + 1;
caryclark1049f122015-04-20 08:31:59 -07001142var SPAN_K_TY = SPAN_K_TX + 1;
caryclark55888e42016-07-18 10:01:36 -07001143var SPAN_K_OTHER = SPAN_K_TY + 1;
caryclark1049f122015-04-20 08:31:59 -07001144var SPAN_K_OTHERT = SPAN_K_OTHER + 1;
1145var SPAN_K_OTHERI = SPAN_K_OTHERT + 1;
1146var SPAN_K_SUM = SPAN_K_OTHERI + 1;
1147var SPAN_K_VAL = SPAN_K_SUM + 1;
1148var SPAN_K_OPP = SPAN_K_VAL + 1;
1149
caryclarkdac1d172014-06-17 05:15:38 -07001150var SPAN_X4 = SPAN_Y3 + 1;
1151var SPAN_Y4 = SPAN_X4 + 1;
caryclark1049f122015-04-20 08:31:59 -07001152
caryclark55888e42016-07-18 10:01:36 -07001153var SPAN_C_TX = SPAN_Y4 + 1;
caryclarkdac1d172014-06-17 05:15:38 -07001154var SPAN_C_TY = SPAN_C_TX + 1;
caryclark55888e42016-07-18 10:01:36 -07001155var SPAN_C_OTHER = SPAN_C_TY + 1;
caryclarkdac1d172014-06-17 05:15:38 -07001156var SPAN_C_OTHERT = SPAN_C_OTHER + 1;
1157var SPAN_C_OTHERI = SPAN_C_OTHERT + 1;
1158var SPAN_C_SUM = SPAN_C_OTHERI + 1;
1159var SPAN_C_VAL = SPAN_C_SUM + 1;
1160var SPAN_C_OPP = SPAN_C_VAL + 1;
1161
1162var ACTIVE_LINE_SPAN = 1;
1163var ACTIVE_QUAD_SPAN = ACTIVE_LINE_SPAN + 1;
caryclark1049f122015-04-20 08:31:59 -07001164var ACTIVE_CONIC_SPAN = ACTIVE_QUAD_SPAN + 1;
1165var ACTIVE_CUBIC_SPAN = ACTIVE_CONIC_SPAN + 1;
caryclarkdac1d172014-06-17 05:15:38 -07001166
1167var ADD_MOVETO = ACTIVE_CUBIC_SPAN + 1;
1168var ADD_LINETO = ADD_MOVETO + 1;
1169var ADD_QUADTO = ADD_LINETO + 1;
caryclark1049f122015-04-20 08:31:59 -07001170var ADD_CONICTO = ADD_QUADTO + 1;
1171var ADD_CUBICTO = ADD_CONICTO + 1;
caryclarkdac1d172014-06-17 05:15:38 -07001172var ADD_CLOSE = ADD_CUBICTO + 1;
1173var ADD_FILL = ADD_CLOSE + 1;
1174
1175var PATH_LINE = ADD_FILL + 1;
1176var PATH_QUAD = PATH_LINE + 1;
caryclark1049f122015-04-20 08:31:59 -07001177var PATH_CONIC = PATH_QUAD + 1;
1178var PATH_CUBIC = PATH_CONIC + 1;
caryclarkdac1d172014-06-17 05:15:38 -07001179
1180var INTERSECT_LINE = PATH_CUBIC + 1;
1181var INTERSECT_LINE_2 = INTERSECT_LINE + 1;
1182var INTERSECT_LINE_NO = INTERSECT_LINE_2 + 1;
1183var INTERSECT_QUAD_LINE = INTERSECT_LINE_NO + 1;
1184var INTERSECT_QUAD_LINE_2 = INTERSECT_QUAD_LINE + 1;
1185var INTERSECT_QUAD_LINE_NO = INTERSECT_QUAD_LINE_2 + 1;
1186var INTERSECT_QUAD = INTERSECT_QUAD_LINE_NO + 1;
1187var INTERSECT_QUAD_2 = INTERSECT_QUAD + 1;
1188var INTERSECT_QUAD_NO = INTERSECT_QUAD_2 + 1;
caryclark1049f122015-04-20 08:31:59 -07001189var INTERSECT_CONIC_LINE = INTERSECT_QUAD_NO + 1;
1190var INTERSECT_CONIC_LINE_2 = INTERSECT_CONIC_LINE + 1;
1191var INTERSECT_CONIC_LINE_NO = INTERSECT_CONIC_LINE_2 + 1;
caryclark55888e42016-07-18 10:01:36 -07001192var INTERSECT_CONIC_QUAD = INTERSECT_CONIC_LINE_NO + 1;
1193var INTERSECT_CONIC_QUAD_2 = INTERSECT_CONIC_QUAD + 1;
caryclark6c3b9cd2016-09-26 05:36:58 -07001194var INTERSECT_CONIC_QUAD_3 = INTERSECT_CONIC_QUAD_2 + 1;
1195var INTERSECT_CONIC_QUAD_4 = INTERSECT_CONIC_QUAD_3 + 1;
1196var INTERSECT_CONIC_QUAD_NO = INTERSECT_CONIC_QUAD_4 + 1;
caryclark55888e42016-07-18 10:01:36 -07001197var INTERSECT_CONIC = INTERSECT_CONIC_QUAD_NO + 1;
caryclark1049f122015-04-20 08:31:59 -07001198var INTERSECT_CONIC_2 = INTERSECT_CONIC + 1;
1199var INTERSECT_CONIC_NO = INTERSECT_CONIC_2 + 1;
1200var INTERSECT_SELF_CUBIC = INTERSECT_CONIC_NO + 1;
caryclarkdac1d172014-06-17 05:15:38 -07001201var INTERSECT_SELF_CUBIC_NO = INTERSECT_SELF_CUBIC + 1;
1202var INTERSECT_CUBIC_LINE = INTERSECT_SELF_CUBIC_NO + 1;
1203var INTERSECT_CUBIC_LINE_2 = INTERSECT_CUBIC_LINE + 1;
1204var INTERSECT_CUBIC_LINE_3 = INTERSECT_CUBIC_LINE_2 + 1;
1205var INTERSECT_CUBIC_LINE_NO = INTERSECT_CUBIC_LINE_3 + 1;
1206var INTERSECT_CUBIC_QUAD = INTERSECT_CUBIC_LINE_NO + 1;
1207var INTERSECT_CUBIC_QUAD_2 = INTERSECT_CUBIC_QUAD + 1;
1208var INTERSECT_CUBIC_QUAD_3 = INTERSECT_CUBIC_QUAD_2 + 1;
1209var INTERSECT_CUBIC_QUAD_4 = INTERSECT_CUBIC_QUAD_3 + 1;
1210var INTERSECT_CUBIC_QUAD_NO = INTERSECT_CUBIC_QUAD_4 + 1;
1211var INTERSECT_CUBIC = INTERSECT_CUBIC_QUAD_NO + 1;
1212var INTERSECT_CUBIC_2 = INTERSECT_CUBIC + 1;
1213var INTERSECT_CUBIC_3 = INTERSECT_CUBIC_2 + 1;
1214var INTERSECT_CUBIC_4 = INTERSECT_CUBIC_3 + 1;
1215// FIXME: add cubic 5- 9
1216var INTERSECT_CUBIC_NO = INTERSECT_CUBIC_4 + 1;
1217
1218var SORT_UNARY = INTERSECT_CUBIC_NO + 1;
1219var SORT_BINARY = SORT_UNARY + 1;
1220
1221var OP_DIFFERENCE = SORT_BINARY + 1;
1222var OP_INTERSECT = OP_DIFFERENCE + 1;
1223var OP_UNION = OP_INTERSECT + 1;
1224var OP_XOR = OP_UNION + 1;
1225
1226var MARK_LINE = OP_XOR + 1;
1227var MARK_QUAD = MARK_LINE + 1;
caryclark1049f122015-04-20 08:31:59 -07001228var MARK_CONIC = MARK_QUAD + 1;
1229var MARK_CUBIC = MARK_CONIC + 1;
caryclarkdac1d172014-06-17 05:15:38 -07001230var MARK_DONE_LINE = MARK_CUBIC + 1;
1231var MARK_DONE_QUAD = MARK_DONE_LINE + 1;
caryclark1049f122015-04-20 08:31:59 -07001232var MARK_DONE_CONIC = MARK_DONE_QUAD + 1;
1233var MARK_DONE_CUBIC = MARK_DONE_CONIC + 1;
caryclarkdac1d172014-06-17 05:15:38 -07001234var MARK_UNSORTABLE_LINE = MARK_DONE_CUBIC + 1;
1235var MARK_UNSORTABLE_QUAD = MARK_UNSORTABLE_LINE + 1;
caryclark1049f122015-04-20 08:31:59 -07001236var MARK_UNSORTABLE_CONIC = MARK_UNSORTABLE_QUAD + 1;
1237var MARK_UNSORTABLE_CUBIC = MARK_UNSORTABLE_CONIC + 1;
caryclarkdac1d172014-06-17 05:15:38 -07001238var MARK_SIMPLE_LINE = MARK_UNSORTABLE_CUBIC + 1;
1239var MARK_SIMPLE_QUAD = MARK_SIMPLE_LINE + 1;
caryclark1049f122015-04-20 08:31:59 -07001240var MARK_SIMPLE_CONIC = MARK_SIMPLE_QUAD + 1;
1241var MARK_SIMPLE_CUBIC = MARK_SIMPLE_CONIC + 1;
caryclarkdac1d172014-06-17 05:15:38 -07001242var MARK_SIMPLE_DONE_LINE = MARK_SIMPLE_CUBIC + 1;
1243var MARK_SIMPLE_DONE_QUAD = MARK_SIMPLE_DONE_LINE + 1;
caryclark1049f122015-04-20 08:31:59 -07001244var MARK_SIMPLE_DONE_CONIC = MARK_SIMPLE_DONE_QUAD + 1;
1245var MARK_SIMPLE_DONE_CUBIC = MARK_SIMPLE_DONE_CONIC + 1;
caryclarkdac1d172014-06-17 05:15:38 -07001246var MARK_DONE_UNARY_LINE = MARK_SIMPLE_DONE_CUBIC + 1;
1247var MARK_DONE_UNARY_QUAD = MARK_DONE_UNARY_LINE + 1;
caryclark1049f122015-04-20 08:31:59 -07001248var MARK_DONE_UNARY_CONIC = MARK_DONE_UNARY_QUAD + 1;
1249var MARK_DONE_UNARY_CUBIC = MARK_DONE_UNARY_CONIC + 1;
caryclarkdac1d172014-06-17 05:15:38 -07001250var MARK_ANGLE_LAST = MARK_DONE_UNARY_CUBIC + 1;
1251
1252var COMPUTED_SET_1 = MARK_ANGLE_LAST + 1;
1253var COMPUTED_SET_2 = COMPUTED_SET_1 + 1;
1254
caryclark624637c2015-05-11 07:21:27 -07001255var ANGLE_AFTER = COMPUTED_SET_2 + 1;
caryclark54359292015-03-26 07:52:43 -07001256var ANGLE_AFTERPART = ANGLE_AFTER + 1;
caryclarkdac1d172014-06-17 05:15:38 -07001257
caryclark54359292015-03-26 07:52:43 -07001258var ACTIVE_OP = ANGLE_AFTERPART + 1;
caryclarkdac1d172014-06-17 05:15:38 -07001259
caryclark624637c2015-05-11 07:21:27 -07001260var COIN_MAIN_SPAN = ACTIVE_OP + 1;
1261var COIN_OPP_SPAN = COIN_MAIN_SPAN + 1;
1262
1263var FRAG_TYPE_LAST = COIN_OPP_SPAN;
caryclarkdac1d172014-06-17 05:15:38 -07001264
1265var REC_TYPE_UNKNOWN = -1;
1266var REC_TYPE_PATH = 0;
caryclark54359292015-03-26 07:52:43 -07001267var REC_TYPE_PATH2 = 1;
1268var REC_TYPE_SECT = 2;
1269var REC_TYPE_ACTIVE = 3;
1270var REC_TYPE_ADD = 4;
1271var REC_TYPE_SORT = 5;
1272var REC_TYPE_OP = 6;
1273var REC_TYPE_MARK = 7;
1274var REC_TYPE_COMPUTED = 8;
1275var REC_TYPE_COIN = 9;
1276var REC_TYPE_ANGLE = 10;
1277var REC_TYPE_ACTIVE_OP = 11;
1278var REC_TYPE_AFTERPART = 12;
caryclark03b03ca2015-04-23 09:13:37 -07001279var REC_TYPE_TOP = 13;
caryclark624637c2015-05-11 07:21:27 -07001280var REC_TYPE_COINCIDENCE = 14;
caryclark26ad22a2015-10-16 09:03:38 -07001281var REC_TYPE_ALIGNED = 15;
1282var REC_TYPE_LAST = REC_TYPE_ALIGNED;
caryclarkdac1d172014-06-17 05:15:38 -07001283
1284function strs_to_nums(strs) {
1285 var result = [];
1286 for (var idx = 1; idx < strs.length; ++idx) {
1287 var str = strs[idx];
1288 var num = parseFloat(str);
1289 if (isNaN(num)) {
1290 result.push(str);
1291 } else {
1292 result.push(num);
1293 }
1294 }
1295 return result;
1296}
1297
1298function filter_str_by(id, str, regex, array) {
1299 if (regex.test(str)) {
1300 var strs = regex.exec(str);
1301 var result = strs_to_nums(strs);
1302 array.push(id);
1303 array.push(result);
1304 return true;
1305 }
1306 return false;
1307}
1308
1309function construct_regexp2(pattern) {
1310 var escape = pattern.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
1311 escape = escape.replace(/UNSORTABLE/g, "\\*\\*\\* UNSORTABLE \\*\\*\\*");
1312 escape = escape.replace(/CUBIC_VAL/g, "\\(P_VAL P_VAL P_VAL P_VAL\\)");
caryclark1049f122015-04-20 08:31:59 -07001313 escape = escape.replace(/CONIC_VAL/g, "\\(P_VAL P_VAL P_VAL W_VAL\\)");
caryclarkdac1d172014-06-17 05:15:38 -07001314 escape = escape.replace(/QUAD_VAL/g, "\\(P_VAL P_VAL P_VAL\\)");
1315 escape = escape.replace(/LINE_VAL/g, "\\(P_VAL P_VAL\\)");
1316 escape = escape.replace(/FILL_TYPE/g, "SkPath::k[a-zA-Z]+_FillType");
caryclark54359292015-03-26 07:52:43 -07001317 escape = escape.replace(/PTR_VAL/g, "0x[0-9A-F]+");
caryclarkdac1d172014-06-17 05:15:38 -07001318 escape = escape.replace(/PT_VAL/g, "\\(P_VAL\\)");
Cary Clark5de52332018-08-30 12:58:23 -04001319 escape = escape.replace(/P_VAL/g, "(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)[Ff]?, ?(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)[Ff]?");
1320 escape = escape.replace(/T_VAL/g, "(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)");
1321 escape = escape.replace(/W_VAL/g, "(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)[Ff]?");
caryclarkdac1d172014-06-17 05:15:38 -07001322 escape = escape.replace(/PATH/g, "pathB?");
caryclark1049f122015-04-20 08:31:59 -07001323 escape = escape.replace(/IDX/g, "(-?\\d+)");
caryclarkdac1d172014-06-17 05:15:38 -07001324 escape = escape.replace(/NUM/g, "(-?\\d+)");
1325 escape = escape.replace(/OPT/g, "(\\?|-?\\d+)");
1326 return new RegExp(escape, 'i');
1327}
1328
1329function construct_regexp2c(pattern) {
1330 var escape = pattern.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
1331 escape = escape.replace(/UNSORTABLE/g, "\\*\\*\\* UNSORTABLE \\*\\*\\*");
caryclark54359292015-03-26 07:52:43 -07001332 escape = escape.replace(/CUBIC_VAL/g, "(?:\\$\\d = )?\\{\\{\\{P_VAL\\}, \\{P_VAL\\}, \\{P_VAL\\}, \\{P_VAL\\}\\}\\}");
caryclark1049f122015-04-20 08:31:59 -07001333 escape = escape.replace(/CONIC_VAL/g, "(?:\\$\\d = )?\\{\\{\\{\\{P_VAL\\}, \\{P_VAL\\}, \\{P_VAL\\}\\}\\}, W_VAL\\}");
caryclark54359292015-03-26 07:52:43 -07001334 escape = escape.replace(/QUAD_VAL/g, "(?:\\$\\d = )?\\{\\{\\{P_VAL\\}, \\{P_VAL\\}, \\{P_VAL\\}\\}\\}");
1335 escape = escape.replace(/LINE_VAL/g, "(?:\\$\\d = )?\\{\\{\\{P_VAL\\}, \\{P_VAL\\}\\}\\}");
caryclarkdac1d172014-06-17 05:15:38 -07001336 escape = escape.replace(/FILL_TYPE/g, "SkPath::k[a-zA-Z]+_FillType");
caryclark54359292015-03-26 07:52:43 -07001337 escape = escape.replace(/PTR_VAL/g, "0x[0-9A-F]+");
caryclarkdac1d172014-06-17 05:15:38 -07001338 escape = escape.replace(/PT_VAL/g, "\\{\\{P_VAL\\}\\}");
Cary Clark5de52332018-08-30 12:58:23 -04001339 escape = escape.replace(/P_VAL/g, "(?:f?[xX] = )?(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)[Ff]?, *(?: f?[yY] = )?(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)[Ff]?");
1340 escape = escape.replace(/T_VAL/g, "(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)");
1341 escape = escape.replace(/W_VAL/g, "(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)[Ff]?");
caryclarkdac1d172014-06-17 05:15:38 -07001342 escape = escape.replace(/OPER/g, "[a-z]+");
1343 escape = escape.replace(/PATH/g, "pathB?");
1344 escape = escape.replace(/T_F/g, "([TF])");
caryclark1049f122015-04-20 08:31:59 -07001345 escape = escape.replace(/IDX/g, "(-?\\d+)");
caryclarkdac1d172014-06-17 05:15:38 -07001346 escape = escape.replace(/NUM/g, "(-?\\d+)");
1347 escape = escape.replace(/OPT/g, "(\\?|-?\\d+)");
1348 return new RegExp(escape, 'i');
1349}
1350
1351function match_regexp(str, lineNo, array, id, pattern) {
1352 var regex = construct_regexp2(pattern);
1353 if (filter_str_by(id, str, regex, array)) {
1354 return true;
1355 }
1356 regex = construct_regexp2c(pattern);
1357 return filter_str_by(id, str, regex, array);
1358}
1359
1360function endsWith(str, suffix) {
1361 return str.indexOf(suffix, str.length - suffix.length) !== -1;
1362}
1363
1364function parse_all(test) {
1365 var lines = test.match(/[^\r\n]+/g);
1366 var records = []; // a rec can be the original paths, a set of intersections, a set of active spans, a sort, or a path add
1367 var record = [];
1368 var recType = REC_TYPE_UNKNOWN;
1369 var lastLineNo;
1370 var moveX, moveY;
1371 for (var lineNo = 0; lineNo < lines.length; ++lineNo) {
1372 var line = lines[lineNo];
1373 if (line.length == 0) {
1374 continue;
1375 }
1376 var opStart = "SkOpSegment::";
1377 if (line.lastIndexOf(opStart, 0) === 0) {
1378 line = line.substr(opStart.length);
1379 }
1380 var angleStart = "SkOpAngle::";
1381 if (line.lastIndexOf(angleStart, 0) === 0) {
1382 line = line.substr(angleStart.length);
1383 }
caryclark624637c2015-05-11 07:21:27 -07001384 var coinStart = "SkOpCoincidence::";
1385 if (line.lastIndexOf(coinStart, 0) === 0) {
1386 line = line.substr(coinStart.length);
1387 }
caryclark54359292015-03-26 07:52:43 -07001388 var type = line.lastIndexOf("debugShowActiveSpans", 0) === 0 ? REC_TYPE_ACTIVE
caryclark624637c2015-05-11 07:21:27 -07001389 : line.lastIndexOf("debugShowCoincidence", 0) === 0 ? REC_TYPE_COINCIDENCE
caryclark54359292015-03-26 07:52:43 -07001390 : line.lastIndexOf("((SkOpSegment*)", 0) === 0 ? REC_TYPE_PATH2
caryclark55888e42016-07-18 10:01:36 -07001391 : line.lastIndexOf("debugShowTs", 0) === 0 ? REC_TYPE_COIN
caryclark54359292015-03-26 07:52:43 -07001392 : line.lastIndexOf("afterPart", 0) === 0 ? REC_TYPE_AFTERPART
caryclarkdac1d172014-06-17 05:15:38 -07001393 : line.lastIndexOf("debugShow", 0) === 0 ? REC_TYPE_SECT
1394 : line.lastIndexOf("activeOp", 0) === 0 ? REC_TYPE_ACTIVE_OP
1395 : line.lastIndexOf("computed", 0) === 0 ? REC_TYPE_COMPUTED
1396 : line.lastIndexOf("debugOne", 0) === 0 ? REC_TYPE_SORT
caryclark26ad22a2015-10-16 09:03:38 -07001397 : line.lastIndexOf("aligned=", 0) === 0 ? REC_TYPE_ALIGNED
caryclarkdac1d172014-06-17 05:15:38 -07001398 : line.lastIndexOf("dumpOne", 0) === 0 ? REC_TYPE_SORT
caryclark03b03ca2015-04-23 09:13:37 -07001399 : line.lastIndexOf("findTop", 0) === 0 ? REC_TYPE_TOP
caryclarkdac1d172014-06-17 05:15:38 -07001400 : line.lastIndexOf("pathB.", 0) === 0 ? REC_TYPE_ADD
1401 : line.lastIndexOf("path.", 0) === 0 ? REC_TYPE_ADD
Cary Clark59d5a0e2017-01-23 14:38:52 +00001402 : line.lastIndexOf("after", 0) === 0 ? REC_TYPE_ANGLE
caryclarkdac1d172014-06-17 05:15:38 -07001403 : line.lastIndexOf("mark", 0) === 0 ? REC_TYPE_MARK
1404 : line.lastIndexOf(" {{", 0) === 0 ? REC_TYPE_COMPUTED
caryclark54359292015-03-26 07:52:43 -07001405 : line.lastIndexOf("seg=", 0) === 0 ? REC_TYPE_PATH
caryclarkdac1d172014-06-17 05:15:38 -07001406 : line.lastIndexOf("op", 0) === 0 ? REC_TYPE_OP
1407 : line.lastIndexOf("$", 0) === 0 ? REC_TYPE_PATH
1408 : REC_TYPE_UNKNOWN;
1409 if (recType != type || recType == REC_TYPE_ADD || recType == REC_TYPE_SECT
1410 || recType == REC_TYPE_ACTIVE_OP || recType == REC_TYPE_ANGLE) {
1411 if (recType != REC_TYPE_UNKNOWN) {
1412 records.push(recType);
1413 records.push(lastLineNo);
1414 records.push(record);
1415 }
1416 record = [];
1417 recType = type;
1418 lastLineNo = lineNo;
1419 }
1420 var found = false;
1421 switch (recType) {
1422 case REC_TYPE_ACTIVE:
1423 found = match_regexp(line, lineNo, record, ACTIVE_LINE_SPAN, "debugShowActiveSpans" +
caryclark55888e42016-07-18 10:01:36 -07001424" id=IDX LINE_VAL t=T_VAL tEnd=T_VAL windSum=OPT windValue=IDX"
caryclarkdac1d172014-06-17 05:15:38 -07001425 ) || match_regexp(line, lineNo, record, ACTIVE_QUAD_SPAN, "debugShowActiveSpans" +
caryclark55888e42016-07-18 10:01:36 -07001426" id=IDX QUAD_VAL t=T_VAL tEnd=T_VAL windSum=OPT windValue=IDX"
caryclark1049f122015-04-20 08:31:59 -07001427 ) || match_regexp(line, lineNo, record, ACTIVE_CONIC_SPAN, "debugShowActiveSpans" +
caryclark55888e42016-07-18 10:01:36 -07001428" id=IDX CONIC_VAL t=T_VAL tEnd=T_VAL windSum=OPT windValue=IDX"
caryclarkdac1d172014-06-17 05:15:38 -07001429 ) || match_regexp(line, lineNo, record, ACTIVE_CUBIC_SPAN, "debugShowActiveSpans" +
caryclark55888e42016-07-18 10:01:36 -07001430" id=IDX CUBIC_VAL t=T_VAL tEnd=T_VAL windSum=OPT windValue=IDX"
caryclark624637c2015-05-11 07:21:27 -07001431 ) || match_regexp(line, lineNo, record, ACTIVE_LINE_SPAN, "debugShowActiveSpans" +
caryclark55888e42016-07-18 10:01:36 -07001432" id=IDX LINE_VAL t=T_VAL tEnd=T_VAL windSum=OPT oppSum=OPT windValue=IDX oppValue=NUM"
caryclark624637c2015-05-11 07:21:27 -07001433 ) || match_regexp(line, lineNo, record, ACTIVE_QUAD_SPAN, "debugShowActiveSpans" +
caryclark55888e42016-07-18 10:01:36 -07001434" id=IDX QUAD_VAL t=T_VAL tEnd=T_VAL windSum=OPT oppSum=OPT windValue=IDX oppValue=NUM"
caryclark624637c2015-05-11 07:21:27 -07001435 ) || match_regexp(line, lineNo, record, ACTIVE_CONIC_SPAN, "debugShowActiveSpans" +
caryclark55888e42016-07-18 10:01:36 -07001436" id=IDX CONIC_VAL t=T_VAL tEnd=T_VAL windSum=OPT oppSum=OPT windValue=IDX oppValue=NUM"
caryclark624637c2015-05-11 07:21:27 -07001437 ) || match_regexp(line, lineNo, record, ACTIVE_CUBIC_SPAN, "debugShowActiveSpans" +
caryclark55888e42016-07-18 10:01:36 -07001438" id=IDX CUBIC_VAL t=T_VAL tEnd=T_VAL windSum=OPT oppSum=OPT windValue=IDX oppValue=NUM"
caryclarkdac1d172014-06-17 05:15:38 -07001439 );
1440 break;
1441 case REC_TYPE_ACTIVE_OP:
1442 found = match_regexp(line, lineNo, record, ACTIVE_OP, "activeOp" +
1443" id=IDX t=T_VAL tEnd=T_VAL op=OPER miFrom=NUM miTo=NUM suFrom=NUM suTo=NUM result=IDX"
1444 );
1445 break;
1446 case REC_TYPE_ADD:
1447 if (match_regexp(line, lineNo, record, ADD_MOVETO, "PATH.moveTo(P_VAL);")) {
1448 moveX = record[1][0];
1449 moveY = record[1][1];
1450 found = true;
1451 } else if (match_regexp(line, lineNo, record, ADD_LINETO, "PATH.lineTo(P_VAL);")) {
1452 record[1].unshift(moveY);
1453 record[1].unshift(moveX);
1454 moveX = record[1][2];
1455 moveY = record[1][3];
1456 found = true;
1457 } else if (match_regexp(line, lineNo, record, ADD_QUADTO, "PATH.quadTo(P_VAL, P_VAL);")) {
1458 record[1].unshift(moveY);
1459 record[1].unshift(moveX);
1460 moveX = record[1][4];
1461 moveY = record[1][5];
1462 found = true;
caryclark1049f122015-04-20 08:31:59 -07001463 } else if (match_regexp(line, lineNo, record, ADD_CONICTO, "PATH.conicTo(P_VAL, P_VAL, T_VAL);")) {
1464 record[1].unshift(moveY);
1465 record[1].unshift(moveX);
1466 moveX = record[1][4];
1467 moveY = record[1][5];
1468 found = true;
caryclarkdac1d172014-06-17 05:15:38 -07001469 } else if (match_regexp(line, lineNo, record, ADD_CUBICTO, "PATH.cubicTo(P_VAL, P_VAL, P_VAL);")) {
1470 record[1].unshift(moveY);
1471 record[1].unshift(moveX);
1472 moveX = record[1][6];
1473 moveY = record[1][7];
1474 found = true;
1475 } else if (match_regexp(line, lineNo, record, ADD_FILL, "PATH.setFillType(FILL_TYPE);")) {
1476 found = true;
1477 } else {
1478 found = match_regexp(line, lineNo, record, ADD_CLOSE, "PATH.close();");
1479 }
1480 break;
caryclark54359292015-03-26 07:52:43 -07001481 case REC_TYPE_AFTERPART:
Cary Clarkff114282016-12-14 11:56:16 -05001482 found = match_regexp(line, lineNo, record, PATH_LINE, "afterPart LINE_VAL id=IDX")
1483 || match_regexp(line, lineNo, record, PATH_QUAD, "afterPart QUAD_VAL id=IDX")
1484 || match_regexp(line, lineNo, record, PATH_CONIC, "afterPart CONIC_VAL id=IDX")
1485 || match_regexp(line, lineNo, record, PATH_CUBIC, "afterPart CUBIC_VAL id=IDX")
caryclark54359292015-03-26 07:52:43 -07001486 break;
caryclark26ad22a2015-10-16 09:03:38 -07001487 case REC_TYPE_ALIGNED:
1488 found = match_regexp(line, lineNo, record, PATH_LINE, "aligned=IDX LINE_VAL"
1489 ) || match_regexp(line, lineNo, record, PATH_QUAD, "aligned=IDX QUAD_VAL"
1490 ) || match_regexp(line, lineNo, record, PATH_CONIC, "aligned=IDX CONIC_VAL"
1491 ) || match_regexp(line, lineNo, record, PATH_CUBIC, "aligned=IDX CUBIC_VAL"
1492 );
1493 break;
caryclarkdac1d172014-06-17 05:15:38 -07001494 case REC_TYPE_ANGLE:
Cary Clark59d5a0e2017-01-23 14:38:52 +00001495 found = match_regexp(line, lineNo, record, ANGLE_AFTER, "after " +
caryclarkdac1d172014-06-17 05:15:38 -07001496"[IDX/IDX] NUM/NUM tStart=T_VAL tEnd=T_VAL < [IDX/IDX] NUM/NUM tStart=T_VAL tEnd=T_VAL < [IDX/IDX] NUM/NUM tStart=T_VAL tEnd=T_VAL T_F IDX");
1497 break;
1498 case REC_TYPE_COIN:
1499 found = true;
1500 break;
caryclark624637c2015-05-11 07:21:27 -07001501 case REC_TYPE_COINCIDENCE:
1502 found = match_regexp(line, lineNo, record, COIN_MAIN_SPAN, "debugShowCoincidence" +
1503" + id=IDX t=T_VAL tEnd=T_VAL"
1504 ) || match_regexp(line, lineNo, record, COIN_OPP_SPAN, "debugShowCoincidence" +
1505" - id=IDX t=T_VAL tEnd=T_VAL"
1506 );
1507 break;
caryclarkdac1d172014-06-17 05:15:38 -07001508 case REC_TYPE_COMPUTED:
1509 found = line == "computed quadratics given"
1510 || match_regexp(line, lineNo, record, COMPUTED_SET_1, "computed quadratics set 1"
1511 ) || match_regexp(line, lineNo, record, COMPUTED_SET_2, "computed quadratics set 2"
1512 ) || match_regexp(line, lineNo, record, PATH_QUAD, " QUAD_VAL,"
caryclark1049f122015-04-20 08:31:59 -07001513 ) || match_regexp(line, lineNo, record, PATH_CONIC, " CONIC_VAL,"
caryclarkdac1d172014-06-17 05:15:38 -07001514 ) || match_regexp(line, lineNo, record, PATH_CUBIC, " CUBIC_VAL,"
1515 );
1516 break;
1517 case REC_TYPE_PATH:
caryclark54359292015-03-26 07:52:43 -07001518 found = match_regexp(line, lineNo, record, PATH_LINE, "seg=IDX LINE_VAL"
1519 ) || match_regexp(line, lineNo, record, PATH_QUAD, "seg=IDX QUAD_VAL"
caryclark1049f122015-04-20 08:31:59 -07001520 ) || match_regexp(line, lineNo, record, PATH_CONIC, "seg=IDX CONIC_VAL"
caryclark54359292015-03-26 07:52:43 -07001521 ) || match_regexp(line, lineNo, record, PATH_CUBIC, "seg=IDX CUBIC_VAL"
1522 );
1523 break;
1524 case REC_TYPE_PATH2:
1525 found = match_regexp(line, lineNo, record, PATH_LINE, "((SkOpSegment*) PTR_VAL) [IDX] {LINE_VAL}"
1526 ) || match_regexp(line, lineNo, record, PATH_QUAD, "((SkOpSegment*) PTR_VAL) [IDX] {QUAD_VAL}"
caryclark1049f122015-04-20 08:31:59 -07001527 ) || match_regexp(line, lineNo, record, PATH_CONIC, "((SkOpSegment*) PTR_VAL) [IDX] {CONIC_VAL}"
caryclark54359292015-03-26 07:52:43 -07001528 ) || match_regexp(line, lineNo, record, PATH_CUBIC, "((SkOpSegment*) PTR_VAL) [IDX] {CUBIC_VAL}"
caryclarkdac1d172014-06-17 05:15:38 -07001529 );
1530 break;
1531 case REC_TYPE_SECT:
1532 found = match_regexp(line, lineNo, record, INTERSECT_LINE, "debugShowLineIntersection" +
1533" wtTs[0]=T_VAL LINE_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL"
1534 ) || match_regexp(line, lineNo, record, INTERSECT_LINE_2, "debugShowLineIntersection" +
1535" wtTs[0]=T_VAL LINE_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL wnTs[1]=T_VAL"
1536 ) || match_regexp(line, lineNo, record, INTERSECT_LINE_NO, "debugShowLineIntersection" +
1537" no intersect LINE_VAL LINE_VAL"
1538 ) || match_regexp(line, lineNo, record, INTERSECT_QUAD_LINE, "debugShowQuadLineIntersection" +
1539" wtTs[0]=T_VAL QUAD_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL"
1540 ) || match_regexp(line, lineNo, record, INTERSECT_QUAD_LINE_2, "debugShowQuadLineIntersection" +
1541" wtTs[0]=T_VAL QUAD_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL wnTs[1]=T_VAL"
1542 ) || match_regexp(line, lineNo, record, INTERSECT_QUAD_LINE_NO, "debugShowQuadLineIntersection" +
1543" no intersect QUAD_VAL LINE_VAL"
1544 ) || match_regexp(line, lineNo, record, INTERSECT_QUAD, "debugShowQuadIntersection" +
1545" wtTs[0]=T_VAL QUAD_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL"
1546 ) || match_regexp(line, lineNo, record, INTERSECT_QUAD_2, "debugShowQuadIntersection" +
1547" wtTs[0]=T_VAL QUAD_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL wnTs[1]=T_VAL"
1548 ) || match_regexp(line, lineNo, record, INTERSECT_QUAD_NO, "debugShowQuadIntersection" +
1549" no intersect QUAD_VAL QUAD_VAL"
caryclark55888e42016-07-18 10:01:36 -07001550
caryclark1049f122015-04-20 08:31:59 -07001551 ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_LINE, "debugShowConicLineIntersection" +
1552" wtTs[0]=T_VAL CONIC_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL"
1553 ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_LINE_2, "debugShowConicLineIntersection" +
1554" wtTs[0]=T_VAL CONIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL wnTs[1]=T_VAL"
1555 ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_LINE_NO, "debugShowConicLineIntersection" +
1556" no intersect CONIC_VAL LINE_VAL"
caryclark55888e42016-07-18 10:01:36 -07001557
1558 ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_QUAD, "debugShowConicQuadIntersection" +
1559" wtTs[0]=T_VAL CONIC_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL"
1560 ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_QUAD_2, "debugShowConicQuadIntersection" +
1561" wtTs[0]=T_VAL CONIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL wnTs[1]=T_VAL"
caryclark6c3b9cd2016-09-26 05:36:58 -07001562 ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_QUAD_3, "debugShowConicQuadIntersection" +
1563" wtTs[0]=T_VAL CONIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wtTs[2]=T_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL wnTs[1]=T_VAL wnTs[2]=T_VAL"
1564 ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_QUAD_4, "debugShowConicQuadIntersection" +
1565" wtTs[0]=T_VAL CONIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wtTs[2]=T_VAL PT_VAL wtTs[3]=T_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL wnTs[1]=T_VAL wnTs[2]=T_VAL wnTs[3]=T_VAL"
caryclark55888e42016-07-18 10:01:36 -07001566 ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_QUAD_NO, "debugShowConicQuadIntersection" +
1567" no intersect CONIC_VAL QUAD_VAL"
1568
caryclark1049f122015-04-20 08:31:59 -07001569 ) || match_regexp(line, lineNo, record, INTERSECT_CONIC, "debugShowConicIntersection" +
1570" wtTs[0]=T_VAL CONIC_VAL PT_VAL wnTs[0]=T_VAL CONIC_VAL"
1571 ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_2, "debugShowConicIntersection" +
1572" wtTs[0]=T_VAL CONIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL CONIC_VAL wnTs[1]=T_VAL"
1573 ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_NO, "debugShowConicIntersection" +
1574" no intersect CONIC_VAL CONIC_VAL"
caryclarkdac1d172014-06-17 05:15:38 -07001575 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_LINE, "debugShowCubicLineIntersection" +
1576" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL"
1577 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_LINE_2, "debugShowCubicLineIntersection" +
1578" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL wnTs[1]=T_VAL"
1579 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_LINE_3, "debugShowCubicLineIntersection" +
1580" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wtTs[2]=T_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL wnTs[1]=T_VAL wnTs[2]=T_VAL"
1581 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_LINE_NO, "debugShowCubicLineIntersection" +
1582" no intersect CUBIC_VAL LINE_VAL"
1583 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_QUAD, "debugShowCubicQuadIntersection" +
1584" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL"
1585 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_QUAD_2, "debugShowCubicQuadIntersection" +
1586" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL wnTs[1]=T_VAL"
1587 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_QUAD_3, "debugShowCubicQuadIntersection" +
1588" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wtTs[2]=T_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL wnTs[1]=T_VAL wnTs[2]=T_VAL"
1589 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_QUAD_4, "debugShowCubicQuadIntersection" +
1590" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wtTs[2]=T_VAL wtTs[3]=T_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL wnTs[1]=T_VAL wnTs[2]=T_VAL wnTs[3]=T_VAL"
1591 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_QUAD_NO, "debugShowCubicQuadIntersection" +
1592" no intersect CUBIC_VAL QUAD_VAL"
1593 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC, "debugShowCubicIntersection" +
1594" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wnTs[0]=T_VAL CUBIC_VAL"
1595 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_2, "debugShowCubicIntersection" +
1596" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL CUBIC_VAL wnTs[1]=T_VAL"
1597 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_3, "debugShowCubicIntersection" +
1598" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wtTs[2]=T_VAL PT_VAL wnTs[0]=T_VAL CUBIC_VAL wnTs[1]=T_VAL wnTs[2]=T_VAL"
1599 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_4, "debugShowCubicIntersection" +
1600" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wtTs[2]=T_VAL PT_VAL wtTs[3]=T_VAL PT_VAL wnTs[0]=T_VAL CUBIC_VAL wnTs[1]=T_VAL wnTs[2]=T_VAL wnTs[3]=T_VAL"
1601 ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_NO, "debugShowCubicIntersection" +
1602" no intersect CUBIC_VAL CUBIC_VAL"
1603 ) || match_regexp(line, lineNo, record, INTERSECT_SELF_CUBIC, "debugShowCubicIntersection" +
1604" wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL"
1605 ) || match_regexp(line, lineNo, record, INTERSECT_SELF_CUBIC_NO, "debugShowCubicIntersection" +
1606" no self intersect CUBIC_VAL"
1607 );
1608 break;
1609 case REC_TYPE_SORT:
1610 var hasDone = / done/.test(line);
1611 var hasUnorderable = / unorderable/.test(line);
1612 var hasSmall = / small/.test(line);
1613 var hasTiny = / tiny/.test(line);
1614 var hasOperand = / operand/.test(line);
1615 var hasStop = / stop/.test(line);
1616 line.replace(/[ a-z]+$/, "");
1617 found = match_regexp(line, lineNo, record, SORT_UNARY, "debugOne" +
1618" [IDX/IDX] next=IDX/IDX sect=IDX/IDX s=T_VAL [IDX] e=T_VAL [IDX] sgn=NUM windVal=IDX windSum=OPT"
1619 ) || match_regexp(line, lineNo, record, SORT_BINARY, "debugOne" +
1620" [IDX/IDX] next=IDX/IDX sect=IDX/IDX s=T_VAL [IDX] e=T_VAL [IDX] sgn=NUM windVal=IDX windSum=OPT oppVal=IDX oppSum=OPT"
1621 ) || match_regexp(line, lineNo, record, SORT_UNARY, "dumpOne" +
1622" [IDX/IDX] next=IDX/IDX sect=NUM/NUM s=T_VAL [IDX] e=T_VAL [IDX] sgn=NUM windVal=IDX windSum=OPT"
1623 ) || match_regexp(line, lineNo, record, SORT_BINARY, "dumpOne" +
1624" [IDX/IDX] next=IDX/IDX sect=NUM/NUM s=T_VAL [IDX] e=T_VAL [IDX] sgn=NUM windVal=IDX windSum=OPT oppVal=IDX oppSum=OPT"
1625 );
1626 if (found) {
1627 record[1].push(hasDone);
1628 record[1].push(hasUnorderable);
1629 record[1].push(hasSmall);
1630 record[1].push(hasTiny);
1631 record[1].push(hasOperand);
1632 record[1].push(hasStop);
1633 }
1634 break;
caryclark03b03ca2015-04-23 09:13:37 -07001635 case REC_TYPE_TOP:
1636 found = match_regexp(line, lineNo, record, ACTIVE_OP, "findTop" +
1637" id=IDX s=T_VAL e=T_VAL cw=NUM swap=NUM inflections=NUM monotonic=NUM"
1638 ) || match_regexp(line, lineNo, record, ACTIVE_OP, "findTop" +
1639" id=IDX s=T_VAL e=T_VAL (-) cw=NUM swap=NUM inflections=NUM monotonic=NUM"
1640 ) || match_regexp(line, lineNo, record, ACTIVE_OP, "findTop" +
1641" id=IDX s=T_VAL e=T_VAL (+) cw=NUM swap=NUM inflections=NUM monotonic=NUM"
1642 );
1643 break;
caryclarkdac1d172014-06-17 05:15:38 -07001644 case REC_TYPE_MARK:
1645 found = match_regexp(line, lineNo, record, MARK_LINE, "markWinding" +
caryclark54359292015-03-26 07:52:43 -07001646" id=IDX LINE_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX"
caryclarkdac1d172014-06-17 05:15:38 -07001647 ) || match_regexp(line, lineNo, record, MARK_QUAD, "markWinding" +
caryclark54359292015-03-26 07:52:43 -07001648" id=IDX QUAD_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX"
caryclark1049f122015-04-20 08:31:59 -07001649 ) || match_regexp(line, lineNo, record, MARK_CONIC, "markWinding" +
1650" id=IDX CONIC_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX"
caryclarkdac1d172014-06-17 05:15:38 -07001651 ) || match_regexp(line, lineNo, record, MARK_CUBIC, "markWinding" +
caryclark54359292015-03-26 07:52:43 -07001652" id=IDX CUBIC_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX"
1653 ) || match_regexp(line, lineNo, record, MARK_DONE_LINE, "markDone" +
1654" id=IDX LINE_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=OPT newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX oppValue=OPT"
1655 ) || match_regexp(line, lineNo, record, MARK_DONE_QUAD, "markDone" +
1656" id=IDX QUAD_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=OPT newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX oppValue=OPT"
caryclark1049f122015-04-20 08:31:59 -07001657 ) || match_regexp(line, lineNo, record, MARK_DONE_CONIC, "markDone" +
1658" id=IDX CONIC_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=OPT newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX oppValue=OPT"
caryclark54359292015-03-26 07:52:43 -07001659 ) || match_regexp(line, lineNo, record, MARK_DONE_CUBIC, "markDone" +
1660" id=IDX CUBIC_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=OPT newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX oppValue=OPT"
caryclarkdac1d172014-06-17 05:15:38 -07001661 ) || match_regexp(line, lineNo, record, MARK_SIMPLE_LINE, "markWinding" +
1662" id=IDX LINE_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM windSum=OPT windValue=IDX"
1663 ) || match_regexp(line, lineNo, record, MARK_SIMPLE_QUAD, "markWinding" +
1664" id=IDX QUAD_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM windSum=OPT windValue=IDX"
caryclark1049f122015-04-20 08:31:59 -07001665 ) || match_regexp(line, lineNo, record, MARK_SIMPLE_CONIC, "markWinding" +
1666" id=IDX CONIC_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM windSum=OPT windValue=IDX"
caryclarkdac1d172014-06-17 05:15:38 -07001667 ) || match_regexp(line, lineNo, record, MARK_SIMPLE_CUBIC, "markWinding" +
1668" id=IDX CUBIC_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM windSum=OPT windValue=IDX"
caryclarkdac1d172014-06-17 05:15:38 -07001669 ) || match_regexp(line, lineNo, record, MARK_ANGLE_LAST, "markAngle" +
caryclark1049f122015-04-20 08:31:59 -07001670" last segment=IDX span=IDX"
caryclark54359292015-03-26 07:52:43 -07001671 ) || match_regexp(line, lineNo, record, MARK_ANGLE_LAST, "markAngle" +
caryclark55888e42016-07-18 10:01:36 -07001672" last seg=IDX span=IDX"
1673 ) || match_regexp(line, lineNo, record, MARK_ANGLE_LAST, "markAngle" +
1674" last segment=IDX span=IDX windSum=OPT"
1675 ) || match_regexp(line, lineNo, record, MARK_ANGLE_LAST, "markAngle" +
1676" last seg=IDX span=IDX windSum=OPT"
1677 );
caryclarkdac1d172014-06-17 05:15:38 -07001678 break;
1679 case REC_TYPE_OP:
1680 if (line.lastIndexOf("oppSign oppSign=", 0) === 0
1681 || line.lastIndexOf("operator<", 0) === 0) {
1682 found = true;
1683 break;
1684 }
caryclark54359292015-03-26 07:52:43 -07001685 found = match_regexp(line, lineNo, record, OP_DIFFERENCE, "op diff"
caryclarkdac1d172014-06-17 05:15:38 -07001686 ) || match_regexp(line, lineNo, record, OP_INTERSECT, "op intersect"
caryclark54359292015-03-26 07:52:43 -07001687 ) || match_regexp(line, lineNo, record, OP_INTERSECT, "op sect"
caryclarkdac1d172014-06-17 05:15:38 -07001688 ) || match_regexp(line, lineNo, record, OP_UNION, "op union"
1689 ) || match_regexp(line, lineNo, record, OP_XOR, "op xor"
1690 );
1691 break;
1692 case REC_TYPE_UNKNOWN:
1693 found = true;
1694 break;
1695 }
1696 if (!found) {
1697 console.log(line + " [" + lineNo + "] of type " + type + " not found");
1698 }
1699 }
1700 if (recType != REC_TYPE_UNKNOWN) {
1701 records.push(recType);
1702 records.push(lastLineNo);
1703 records.push(record);
1704 }
1705 if (records.length >= 1) {
1706 tests[testIndex] = records;
1707 testLines[testIndex] = lines;
1708 }
1709}
1710
1711function init(test) {
1712 var canvas = document.getElementById('canvas');
1713 if (!canvas.getContext) return;
1714 ctx = canvas.getContext('2d');
1715 var resScale = retina_scale && window.devicePixelRatio ? window.devicePixelRatio : 1;
1716 var unscaledWidth = window.innerWidth - 20;
1717 var unscaledHeight = window.innerHeight - 20;
1718 screenWidth = unscaledWidth;
1719 screenHeight = unscaledHeight;
1720 canvas.width = unscaledWidth * resScale;
1721 canvas.height = unscaledHeight * resScale;
1722 canvas.style.width = unscaledWidth + 'px';
1723 canvas.style.height = unscaledHeight + 'px';
1724 if (resScale != 1) {
1725 ctx.scale(resScale, resScale);
1726 }
1727 xmin = Infinity;
1728 xmax = -Infinity;
1729 ymin = Infinity;
1730 ymax = -Infinity;
caryclark26ad22a2015-10-16 09:03:38 -07001731 hasPath = hasAlignedPath = hasComputedPath = false;
caryclarkdac1d172014-06-17 05:15:38 -07001732 firstActiveSpan = -1;
1733 for (var tIndex = 0; tIndex < test.length; tIndex += 3) {
1734 var recType = test[tIndex];
1735 if (!typeof recType == 'number' || recType < REC_TYPE_UNKNOWN || recType > REC_TYPE_LAST) {
1736 console.log("unknown rec type: " + recType);
1737 throw "stop execution";
1738 }
1739 var records = test[tIndex + 2];
1740 for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
1741 var fragType = records[recordIndex];
1742 if (!typeof fragType == 'number' || fragType < 1 || fragType > FRAG_TYPE_LAST) {
1743 console.log("unknown in range frag type: " + fragType);
1744 throw "stop execution";
1745 }
1746 var frags = records[recordIndex + 1];
1747 var first = 0;
1748 var last = -1;
1749 var first2 = 0;
1750 var last2 = 0;
1751 switch (recType) {
caryclark26ad22a2015-10-16 09:03:38 -07001752 case REC_TYPE_ALIGNED:
1753 hasAlignedPath = true;
caryclarkdac1d172014-06-17 05:15:38 -07001754 case REC_TYPE_COMPUTED:
1755 if (fragType == COMPUTED_SET_1 || fragType == COMPUTED_SET_2) {
1756 break;
1757 }
caryclark26ad22a2015-10-16 09:03:38 -07001758 if (REC_TYPE_COMPUTED == recType) {
1759 hasComputedPath = true;
1760 }
caryclarkdac1d172014-06-17 05:15:38 -07001761 case REC_TYPE_PATH:
caryclark54359292015-03-26 07:52:43 -07001762 first = 1;
caryclarkdac1d172014-06-17 05:15:38 -07001763 switch (fragType) {
1764 case PATH_LINE:
caryclark54359292015-03-26 07:52:43 -07001765 last = 5;
caryclarkdac1d172014-06-17 05:15:38 -07001766 break;
caryclark1049f122015-04-20 08:31:59 -07001767 case PATH_CONIC:
caryclarkdac1d172014-06-17 05:15:38 -07001768 case PATH_QUAD:
caryclark54359292015-03-26 07:52:43 -07001769 last = 7;
caryclarkdac1d172014-06-17 05:15:38 -07001770 break;
1771 case PATH_CUBIC:
caryclark54359292015-03-26 07:52:43 -07001772 last = 9;
caryclarkdac1d172014-06-17 05:15:38 -07001773 break;
1774 default:
caryclark55888e42016-07-18 10:01:36 -07001775 console.log("unknown " + (recType == REC_TYPE_PATH ? "REC_TYPE_PATH"
caryclarkdac1d172014-06-17 05:15:38 -07001776 : "REC_TYPE_COMPUTED") + " frag type:" + fragType);
1777 throw "stop execution";
1778 }
1779 if (recType == REC_TYPE_PATH) {
1780 hasPath = true;
1781 }
1782 break;
caryclark54359292015-03-26 07:52:43 -07001783 case REC_TYPE_PATH2:
1784 first = 1;
1785 switch (fragType) {
1786 case PATH_LINE:
1787 last = 5;
1788 break;
caryclark1049f122015-04-20 08:31:59 -07001789 case PATH_CONIC:
caryclark54359292015-03-26 07:52:43 -07001790 case PATH_QUAD:
1791 last = 7;
1792 break;
1793 case PATH_CUBIC:
1794 last = 9;
1795 break;
1796 default:
caryclark55888e42016-07-18 10:01:36 -07001797 console.log("unknown " + (recType == REC_TYPE_PATH2 ? "REC_TYPE_PATH2"
caryclark54359292015-03-26 07:52:43 -07001798 : "REC_TYPE_COMPUTED") + " frag type:" + fragType);
1799 throw "stop execution";
1800 }
1801 if (recType == REC_TYPE_PATH2) {
1802 hasPath = true;
1803 }
1804 break;
caryclarkdac1d172014-06-17 05:15:38 -07001805 case REC_TYPE_ACTIVE:
1806 if (firstActiveSpan < 0) {
1807 firstActiveSpan = tIndex;
1808 }
1809 first = 1;
1810 switch (fragType) {
1811 case ACTIVE_LINE_SPAN:
1812 last = 5;
1813 break;
caryclark1049f122015-04-20 08:31:59 -07001814 case ACTIVE_CONIC_SPAN:
caryclarkdac1d172014-06-17 05:15:38 -07001815 case ACTIVE_QUAD_SPAN:
1816 last = 7;
1817 break;
1818 case ACTIVE_CUBIC_SPAN:
1819 last = 9;
1820 break;
1821 default:
1822 console.log("unknown REC_TYPE_ACTIVE frag type: " + fragType);
1823 throw "stop execution";
1824 }
1825 break;
1826 case REC_TYPE_ADD:
1827 switch (fragType) {
1828 case ADD_MOVETO:
1829 break;
1830 case ADD_LINETO:
1831 last = 4;
1832 break;
caryclark1049f122015-04-20 08:31:59 -07001833 case ADD_CONICTO:
caryclarkdac1d172014-06-17 05:15:38 -07001834 case ADD_QUADTO:
1835 last = 6;
1836 break;
1837 case ADD_CUBICTO:
1838 last = 8;
1839 break;
1840 case ADD_CLOSE:
1841 case ADD_FILL:
1842 break;
1843 default:
1844 console.log("unknown REC_TYPE_ADD frag type: " + fragType);
1845 throw "stop execution";
1846 }
1847 break;
caryclark54359292015-03-26 07:52:43 -07001848 case REC_TYPE_AFTERPART:
1849 switch (fragType) {
1850 case PATH_LINE:
1851 last = 4;
1852 break;
caryclark1049f122015-04-20 08:31:59 -07001853 case PATH_CONIC:
caryclark54359292015-03-26 07:52:43 -07001854 case PATH_QUAD:
1855 last = 6;
1856 break;
1857 case PATH_CUBIC:
1858 last = 8;
1859 break;
1860 default:
1861 console.log("unknown REC_TYPE_ACTIVEPART frag type: " + fragType);
1862 throw "stop execution";
1863 }
1864 break;
caryclarkdac1d172014-06-17 05:15:38 -07001865 case REC_TYPE_SECT:
1866 switch (fragType) {
1867 case INTERSECT_LINE:
1868 first = 1; last = 5; first2 = 8; last2 = 12;
1869 break;
1870 case INTERSECT_LINE_2:
1871 first = 1; last = 5; first2 = 11; last2 = 15;
1872 break;
1873 case INTERSECT_LINE_NO:
1874 first = 0; last = 4; first2 = 4; last2 = 8;
1875 break;
caryclark1049f122015-04-20 08:31:59 -07001876 case INTERSECT_CONIC_LINE:
1877 first = 1; last = 7; first2 = 11; last2 = 15;
1878 break;
caryclarkdac1d172014-06-17 05:15:38 -07001879 case INTERSECT_QUAD_LINE:
1880 first = 1; last = 7; first2 = 10; last2 = 14;
1881 break;
caryclark1049f122015-04-20 08:31:59 -07001882 case INTERSECT_CONIC_LINE_2:
1883 first = 1; last = 7; first2 = 14; last2 = 18;
1884 break;
caryclarkdac1d172014-06-17 05:15:38 -07001885 case INTERSECT_QUAD_LINE_2:
1886 first = 1; last = 7; first2 = 13; last2 = 17;
1887 break;
caryclark1049f122015-04-20 08:31:59 -07001888 case INTERSECT_CONIC_LINE_NO:
1889 first = 0; last = 6; first2 = 7; last2 = 11;
1890 break;
caryclarkdac1d172014-06-17 05:15:38 -07001891 case INTERSECT_QUAD_LINE_NO:
1892 first = 0; last = 6; first2 = 6; last2 = 10;
1893 break;
caryclark1049f122015-04-20 08:31:59 -07001894 case INTERSECT_CONIC:
1895 first = 1; last = 7; first2 = 11; last2 = 17;
1896 break;
caryclarkdac1d172014-06-17 05:15:38 -07001897 case INTERSECT_QUAD:
1898 first = 1; last = 7; first2 = 10; last2 = 16;
1899 break;
caryclark1049f122015-04-20 08:31:59 -07001900 case INTERSECT_CONIC_2:
1901 first = 1; last = 7; first2 = 14; last2 = 20;
1902 break;
caryclarkdac1d172014-06-17 05:15:38 -07001903 case INTERSECT_QUAD_2:
1904 first = 1; last = 7; first2 = 13; last2 = 19;
1905 break;
caryclark1049f122015-04-20 08:31:59 -07001906 case INTERSECT_CONIC_NO:
1907 first = 0; last = 6; first2 = 7; last2 = 13;
1908 break;
caryclarkdac1d172014-06-17 05:15:38 -07001909 case INTERSECT_QUAD_NO:
1910 first = 0; last = 6; first2 = 6; last2 = 12;
1911 break;
1912 case INTERSECT_SELF_CUBIC:
1913 first = 1; last = 9;
1914 break;
1915 case INTERSECT_SELF_CUBIC_NO:
1916 first = 0; last = 8;
1917 break;
1918 case INTERSECT_CUBIC_LINE:
1919 first = 1; last = 9; first2 = 12; last2 = 16;
1920 break;
1921 case INTERSECT_CUBIC_LINE_2:
1922 first = 1; last = 9; first2 = 15; last2 = 19;
1923 break;
1924 case INTERSECT_CUBIC_LINE_3:
1925 first = 1; last = 9; first2 = 18; last2 = 22;
1926 break;
1927 case INTERSECT_CUBIC_LINE_NO:
1928 first = 0; last = 8; first2 = 8; last2 = 12;
1929 break;
caryclark55888e42016-07-18 10:01:36 -07001930 case INTERSECT_CONIC_QUAD:
1931 first = 1; last = 7; first2 = 11; last2 = 17;
1932 break;
1933 case INTERSECT_CONIC_QUAD_2:
1934 first = 1; last = 7; first2 = 14; last2 = 20;
1935 break;
caryclark6c3b9cd2016-09-26 05:36:58 -07001936 case INTERSECT_CONIC_QUAD_3:
1937 first = 1; last = 7; first2 = 17; last2 = 23;
1938 break;
1939 case INTERSECT_CONIC_QUAD_4:
1940 first = 1; last = 7; first2 = 20; last2 = 26;
1941 break;
caryclark55888e42016-07-18 10:01:36 -07001942 case INTERSECT_CONIC_QUAD_NO:
1943 first = 0; last = 6; first2 = 7; last2 = 13;
1944 break;
caryclarkdac1d172014-06-17 05:15:38 -07001945 case INTERSECT_CUBIC_QUAD:
1946 first = 1; last = 9; first2 = 12; last2 = 18;
1947 break;
1948 case INTERSECT_CUBIC_QUAD_2:
1949 first = 1; last = 9; first2 = 15; last2 = 21;
1950 break;
1951 case INTERSECT_CUBIC_QUAD_3:
1952 first = 1; last = 9; first2 = 18; last2 = 24;
1953 break;
1954 case INTERSECT_CUBIC_QUAD_4:
1955 first = 1; last = 9; first2 = 21; last2 = 27;
1956 break;
1957 case INTERSECT_CUBIC_QUAD_NO:
1958 first = 0; last = 8; first2 = 8; last2 = 14;
1959 break;
1960 case INTERSECT_CUBIC:
1961 first = 1; last = 9; first2 = 12; last2 = 20;
1962 break;
1963 case INTERSECT_CUBIC_2:
1964 first = 1; last = 9; first2 = 15; last2 = 23;
1965 break;
1966 case INTERSECT_CUBIC_3:
1967 first = 1; last = 9; first2 = 18; last2 = 26;
1968 break;
1969 case INTERSECT_CUBIC_4:
1970 first = 1; last = 9; first2 = 21; last2 = 29;
1971 break;
1972 case INTERSECT_CUBIC_NO:
1973 first = 0; last = 8; first2 = 8; last2 = 16;
1974 break;
1975 default:
1976 console.log("unknown REC_TYPE_SECT frag type: " + fragType);
1977 throw "stop execution";
1978 }
1979 break;
1980 default:
1981 continue;
1982 }
1983 for (var idx = first; idx < last; idx += 2) {
1984 xmin = Math.min(xmin, frags[idx]);
1985 xmax = Math.max(xmax, frags[idx]);
1986 ymin = Math.min(ymin, frags[idx + 1]);
1987 ymax = Math.max(ymax, frags[idx + 1]);
1988 }
1989 for (var idx = first2; idx < last2; idx += 2) {
1990 xmin = Math.min(xmin, frags[idx]);
1991 xmax = Math.max(xmax, frags[idx]);
1992 ymin = Math.min(ymin, frags[idx + 1]);
1993 ymax = Math.max(ymax, frags[idx + 1]);
1994 }
1995 }
1996 }
1997 var angleBounds = [Infinity, Infinity, -Infinity, -Infinity];
1998 for (var tIndex = 0; tIndex < test.length; tIndex += 3) {
1999 var recType = test[tIndex];
2000 var records = test[tIndex + 2];
2001 for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
2002 var fragType = records[recordIndex];
2003 var frags = records[recordIndex + 1];
2004 switch (recType) {
2005 case REC_TYPE_ACTIVE_OP:
2006 if (!draw_op) {
2007 break;
2008 }
2009 {
2010 var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
2011 curve_extremes(curve, angleBounds);
2012 }
2013 break;
2014 case REC_TYPE_ANGLE:
2015 if (!draw_angle) {
2016 break;
2017 }
caryclark54359292015-03-26 07:52:43 -07002018 {
caryclarkdac1d172014-06-17 05:15:38 -07002019 var curve = curvePartialByID(test, frags[0], frags[4], frags[5]);
2020 curve_extremes(curve, angleBounds);
2021 curve = curvePartialByID(test, frags[6], frags[10], frags[11]);
2022 curve_extremes(curve, angleBounds);
2023 curve = curvePartialByID(test, frags[12], frags[16], frags[17]);
2024 }
2025 break;
caryclark624637c2015-05-11 07:21:27 -07002026 case REC_TYPE_COINCIDENCE:
2027 if (!draw_coincidence) {
2028 break;
2029 }
2030 {
2031 var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
2032 curve_extremes(curve, angleBounds);
2033 }
2034 break;
caryclarkdac1d172014-06-17 05:15:38 -07002035 case REC_TYPE_SORT:
2036 if (!draw_sort) {
2037 break;
2038 }
2039 if (fragType == SORT_UNARY || fragType == SORT_BINARY) {
2040 var curve = curvePartialByID(test, frags[0], frags[6], frags[8]);
2041 curve_extremes(curve, angleBounds);
2042 }
2043 break;
caryclark03b03ca2015-04-23 09:13:37 -07002044 case REC_TYPE_TOP:
2045 if (!draw_top) {
2046 break;
2047 }
2048 {
2049 var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
2050 curve_extremes(curve, angleBounds);
2051 }
2052 break;
caryclarkdac1d172014-06-17 05:15:38 -07002053 }
2054 }
2055 }
2056 xmin = Math.min(xmin, angleBounds[0]);
2057 ymin = Math.min(ymin, angleBounds[1]);
2058 xmax = Math.max(xmax, angleBounds[2]);
2059 ymax = Math.max(ymax, angleBounds[3]);
2060 setScale(xmin, xmax, ymin, ymax);
2061 if (hasPath == false && hasComputedPath == true && !draw_computed) {
caryclark1049f122015-04-20 08:31:59 -07002062 draw_computed = 7; // show quadratics, conics, and cubics
caryclarkdac1d172014-06-17 05:15:38 -07002063 }
2064 if (hasPath == true && hasComputedPath == false && draw_computed) {
2065 draw_computed = 0;
2066 }
2067}
2068
caryclark26ad22a2015-10-16 09:03:38 -07002069function curveByIDMatch(test, id, recMatch) {
caryclark54359292015-03-26 07:52:43 -07002070 var tIndex = -3;
2071 while ((tIndex += 3) < test.length) {
caryclarkdac1d172014-06-17 05:15:38 -07002072 var recType = test[tIndex];
caryclark54359292015-03-26 07:52:43 -07002073 if (recType == REC_TYPE_OP) {
2074 continue;
2075 }
caryclark26ad22a2015-10-16 09:03:38 -07002076 if (recType != recMatch) {
caryclarkdac1d172014-06-17 05:15:38 -07002077 return [];
2078 }
2079 var records = test[tIndex + 2];
2080 for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
2081 var fragType = records[recordIndex];
2082 var frags = records[recordIndex + 1];
2083 if (frags[0] == id) {
2084 switch (fragType) {
caryclark54359292015-03-26 07:52:43 -07002085 case PATH_LINE:
caryclarkdac1d172014-06-17 05:15:38 -07002086 return [frags[1], frags[2], frags[3], frags[4]];
caryclark54359292015-03-26 07:52:43 -07002087 case PATH_QUAD:
caryclarkdac1d172014-06-17 05:15:38 -07002088 return [frags[1], frags[2], frags[3], frags[4],
2089 frags[5], frags[6]];
caryclark1049f122015-04-20 08:31:59 -07002090 case PATH_CONIC:
2091 return [frags[1], frags[2], frags[3], frags[4],
2092 frags[5], frags[6], frags[7]];
caryclark54359292015-03-26 07:52:43 -07002093 case PATH_CUBIC:
caryclarkdac1d172014-06-17 05:15:38 -07002094 return [frags[1], frags[2], frags[3], frags[4],
2095 frags[5], frags[6], frags[7], frags[8]];
2096 }
2097 }
2098 }
caryclarkdac1d172014-06-17 05:15:38 -07002099 }
2100 return [];
2101}
2102
caryclark26ad22a2015-10-16 09:03:38 -07002103function curveByID(test, id) {
2104 var result = draw_path >= 4 ? curveByIDMatch(test, id, REC_TYPE_ALIGNED) : [];
2105 if (!result.length) {
2106 result = curveByIDMatch(test, id, REC_TYPE_PATH);
2107 }
2108 return result;
2109}
2110
2111function curvePartialByIDMatch(test, id, t0, t1, recMatch) {
caryclark54359292015-03-26 07:52:43 -07002112 var tIndex = -3;
2113 while ((tIndex += 3) < test.length) {
caryclarkdac1d172014-06-17 05:15:38 -07002114 var recType = test[tIndex];
caryclark54359292015-03-26 07:52:43 -07002115 if (recType == REC_TYPE_OP) {
2116 continue;
2117 }
caryclark26ad22a2015-10-16 09:03:38 -07002118 if (recType != recMatch) {
caryclarkdac1d172014-06-17 05:15:38 -07002119 return [];
2120 }
2121 var records = test[tIndex + 2];
2122 for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
2123 var fragType = records[recordIndex];
2124 var frags = records[recordIndex + 1];
2125 if (frags[0] == id) {
2126 switch (fragType) {
caryclark54359292015-03-26 07:52:43 -07002127 case PATH_LINE:
caryclarkdac1d172014-06-17 05:15:38 -07002128 return linePartial(frags[1], frags[2], frags[3], frags[4], t0, t1);
caryclark54359292015-03-26 07:52:43 -07002129 case PATH_QUAD:
caryclarkdac1d172014-06-17 05:15:38 -07002130 return quadPartial(frags[1], frags[2], frags[3], frags[4],
2131 frags[5], frags[6], t0, t1);
caryclark1049f122015-04-20 08:31:59 -07002132 case PATH_CONIC:
2133 return conicPartial(frags[1], frags[2], frags[3], frags[4],
2134 frags[5], frags[6], frags[7], t0, t1);
caryclark54359292015-03-26 07:52:43 -07002135 case PATH_CUBIC:
caryclarkdac1d172014-06-17 05:15:38 -07002136 return cubicPartial(frags[1], frags[2], frags[3], frags[4],
2137 frags[5], frags[6], frags[7], frags[8], t0, t1);
2138 }
2139 }
2140 }
caryclarkdac1d172014-06-17 05:15:38 -07002141 }
2142 return [];
2143}
2144
caryclark26ad22a2015-10-16 09:03:38 -07002145function curvePartialByID(test, id, t0, t1) {
2146 var result = draw_path >= 4 ? curvePartialByIDMatch(test, id, t0, t1, REC_TYPE_ALIGNED) : [];
2147 if (!result.length) {
2148 result = curvePartialByIDMatch(test, id, t0, t1, REC_TYPE_PATH);
2149 }
2150 return result;
2151}
2152
2153function idByCurveIDMatch(test, frag, type, recMatch) {
caryclark54359292015-03-26 07:52:43 -07002154 var tIndex = 0;
caryclarkdac1d172014-06-17 05:15:38 -07002155 while (tIndex < test.length) {
2156 var recType = test[tIndex];
caryclark26ad22a2015-10-16 09:03:38 -07002157 if (recType != recMatch) {
caryclark54359292015-03-26 07:52:43 -07002158 ++tIndex;
2159 continue;
caryclarkdac1d172014-06-17 05:15:38 -07002160 }
2161 var records = test[tIndex + 2];
2162 for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
2163 var fragType = records[recordIndex];
2164 var frags = records[recordIndex + 1];
caryclark54359292015-03-26 07:52:43 -07002165 if (frag.length != frags.length - 1) {
2166 continue;
2167 }
caryclarkdac1d172014-06-17 05:15:38 -07002168 switch (fragType) {
caryclark54359292015-03-26 07:52:43 -07002169 case PATH_LINE:
caryclarkdac1d172014-06-17 05:15:38 -07002170 if (frag[0] != frags[1] || frag[1] != frags[2]
2171 || frag[2] != frags[3] || frag[3] != frags[4]) {
2172 continue;
2173 }
2174 return frags[0];
caryclark54359292015-03-26 07:52:43 -07002175 case PATH_QUAD:
caryclarkdac1d172014-06-17 05:15:38 -07002176 if (frag[0] != frags[1] || frag[1] != frags[2]
2177 || frag[2] != frags[3] || frag[3] != frags[4]
2178 || frag[4] != frags[5] || frag[5] != frags[6]) {
2179 continue;
2180 }
2181 return frags[0];
caryclark1049f122015-04-20 08:31:59 -07002182 case PATH_CONIC:
2183 if (frag[0] != frags[1] || frag[1] != frags[2]
2184 || frag[2] != frags[3] || frag[3] != frags[4]
2185 || frag[4] != frags[5] || frag[5] != frags[6]
2186 || frag[6] != frags[7]) {
2187 continue;
2188 }
2189 return frags[0];
caryclark54359292015-03-26 07:52:43 -07002190 case PATH_CUBIC:
caryclarkdac1d172014-06-17 05:15:38 -07002191 if (frag[0] != frags[1] || frag[1] != frags[2]
2192 || frag[2] != frags[3] || frag[3] != frags[4]
2193 || frag[4] != frags[5] || frag[5] != frags[6]
2194 || frag[6] != frags[7] || frag[7] != frags[8]) {
2195 continue;
2196 }
2197 return frags[0];
2198 }
2199 }
2200 ++tIndex;
2201 }
2202 return -1;
2203}
2204
caryclark26ad22a2015-10-16 09:03:38 -07002205function idByCurve(test, frag, type) {
2206 var result = draw_path >= 4 ? idByCurveIDMatch(test, frag, type, REC_TYPE_ALIGNED) : [];
2207 if (!result.length) {
2208 result = idByCurveIDMatch(test, frag, type, REC_TYPE_PATH);
2209 }
2210 return result;
2211}
2212
caryclarkdac1d172014-06-17 05:15:38 -07002213function curve_extremes(curve, bounds) {
caryclark1049f122015-04-20 08:31:59 -07002214 var length = curve.length == 7 ? 6 : curve.length;
caryclarked0935a2015-10-22 07:23:52 -07002215 for (var index = 0; index < length; index += 2) {
caryclarkdac1d172014-06-17 05:15:38 -07002216 var x = curve[index];
2217 var y = curve[index + 1];
2218 bounds[0] = Math.min(bounds[0], x);
2219 bounds[1] = Math.min(bounds[1], y);
2220 bounds[2] = Math.max(bounds[2], x);
2221 bounds[3] = Math.max(bounds[3], y);
2222 }
2223}
2224
2225function setScale(x0, x1, y0, y1) {
2226 var srcWidth = x1 - x0;
2227 var srcHeight = y1 - y0;
2228 var usableWidth = screenWidth;
2229 var xDigits = Math.ceil(Math.log(Math.abs(xmax)) / Math.log(10));
2230 var yDigits = Math.ceil(Math.log(Math.abs(ymax)) / Math.log(10));
2231 usableWidth -= (xDigits + yDigits) * 10;
2232 usableWidth -= decimal_places * 10;
2233 if (draw_legend) {
2234 usableWidth -= 40;
2235 }
2236 var hscale = usableWidth / srcWidth;
2237 var vscale = screenHeight / srcHeight;
2238 scale = Math.min(hscale, vscale);
2239 var invScale = 1 / scale;
2240 var sxmin = x0 - invScale * 5;
2241 var symin = y0 - invScale * 10;
2242 var sxmax = x1 + invScale * (6 * decimal_places + 10);
2243 var symax = y1 + invScale * 10;
2244 srcWidth = sxmax - sxmin;
2245 srcHeight = symax - symin;
2246 hscale = usableWidth / srcWidth;
2247 vscale = screenHeight / srcHeight;
2248 scale = Math.min(hscale, vscale);
2249 srcLeft = sxmin;
2250 srcTop = symin;
2251}
2252
2253function drawArc(curve, op, from, to) {
2254 var type = PATH_LINE + (curve.length / 2 - 2);
2255 var pt = pointAtT(curve, type, op ? 0.4 : 0.6);
2256 var dy = pt.y - curve[1];
2257 var dx = pt.x - curve[0];
2258 var dist = Math.sqrt(dy * dy + dx * dx);
2259 var _dist = dist * scale;
2260 var angle = Math.atan2(dy, dx);
2261 var _px = (curve[0] - srcLeft) * scale;
2262 var _py = (curve[1] - srcTop) * scale;
2263 var divisor = 4;
2264 var endDist;
2265 do {
2266 var ends = [];
2267 for (var index = -1; index <= 1; index += 2) {
2268 var px = Math.cos(index * Math.PI / divisor);
2269 var py = Math.sin(index * Math.PI / divisor);
2270 ends.push(px);
2271 ends.push(py);
2272 }
2273 var endDx = (ends[2] - ends[0]) * scale * dist;
2274 var endDy = (ends[3] - ends[1]) * scale * dist;
2275 endDist = Math.sqrt(endDx * endDx + endDy * endDy);
2276 if (endDist < 100) {
2277 break;
2278 }
2279 divisor *= 2;
2280 } while (true);
2281 if (endDist < 30) {
2282 return;
2283 }
2284 if (op) {
2285 divisor *= 2;
2286 }
2287 ctx.strokeStyle = op ? "rgba(210,0,45, 0.4)" : "rgba(90,90,90, 0.5)";
2288 ctx.beginPath();
2289 ctx.arc(_px, _py, _dist, angle - Math.PI / divisor, angle + Math.PI / divisor, false);
2290 ctx.stroke();
2291 var saveAlign = ctx.textAlign;
2292 var saveStyle = ctx.fillStyle;
2293 var saveFont = ctx.font;
2294 ctx.textAlign = "center";
2295 ctx.fillStyle = "black";
2296 ctx.font = "normal 24px Arial";
2297 divisor *= 0.8;
2298 for (var index = -1; index <= 1; index += 2) {
2299 var px = curve[0] + Math.cos(angle + index * Math.PI / divisor) * dist;
2300 var py = curve[1] + Math.sin(angle + index * Math.PI / divisor) * dist;
2301 var _px = (px - srcLeft) * scale;
2302 var _py = (py - srcTop) * scale;
2303 ctx.fillText(index < 0 ? to.toString() : from.toString(), _px, _py + 8);
2304 }
2305 ctx.textAlign = saveAlign;
2306 ctx.fillStyle = saveStyle;
2307 ctx.font = saveFont;
2308}
2309
2310function drawPoint(px, py, end) {
caryclark1049f122015-04-20 08:31:59 -07002311 var length = drawnPts.length == 7 ? 6 : drawnPts.length;
2312 for (var pts = 0; pts < length; pts += 2) {
caryclarkdac1d172014-06-17 05:15:38 -07002313 var x = drawnPts[pts];
2314 var y = drawnPts[pts + 1];
2315 if (px == x && py == y) {
2316 return;
2317 }
2318 }
2319 drawnPts.push(px);
2320 drawnPts.push(py);
2321 var label = px.toFixed(decimal_places) + ", " + py.toFixed(decimal_places);
2322 var _px = (px - srcLeft) * scale;
2323 var _py = (py - srcTop) * scale;
2324 ctx.beginPath();
2325 ctx.arc(_px, _py, 3, 0, Math.PI*2, true);
2326 ctx.closePath();
2327 if (end) {
2328 ctx.fill();
2329 } else {
2330 ctx.stroke();
2331 }
2332 if (debug_xy) {
2333 ctx.textAlign = "left";
2334 ctx.fillText(label, _px + 5, _py);
2335 }
2336}
2337
caryclark1049f122015-04-20 08:31:59 -07002338function coordCount(curveType) {
2339 switch (curveType) {
2340 case PATH_LINE:
2341 return 4;
2342 case PATH_QUAD:
2343 return 6;
2344 case PATH_CONIC:
2345 return 6;
2346 case PATH_CUBIC:
2347 return 8;
2348 }
2349 return -1;
2350}
2351
caryclarkdac1d172014-06-17 05:15:38 -07002352function drawPoints(ptArray, curveType, drawControls) {
caryclark1049f122015-04-20 08:31:59 -07002353 var count = coordCount(curveType);
caryclarkdac1d172014-06-17 05:15:38 -07002354 for (var idx = 0; idx < count; idx += 2) {
2355 if (!drawControls && idx != 0 && idx != count - 2) {
2356 continue;
2357 }
2358 drawPoint(ptArray[idx], ptArray[idx + 1], idx == 0 || idx == count - 2);
2359 }
2360}
2361
2362function drawControlLines(curve, curveType, drawEnd) {
2363 if (curveType == PATH_LINE) {
2364 return;
2365 }
2366 ctx.strokeStyle = "rgba(0,0,0, 0.3)";
2367 drawLine(curve[0], curve[1], curve[2], curve[3]);
2368 drawLine(curve[2], curve[3], curve[4], curve[5]);
2369 if (curveType == PATH_CUBIC) {
2370 drawLine(curve[4], curve[5], curve[6], curve[7]);
2371 if (drawEnd > 1) {
2372 drawLine(curve[6], curve[7], curve[0], curve[1]);
2373 if (drawEnd > 2) {
2374 drawLine(curve[0], curve[1], curve[4], curve[5]);
2375 drawLine(curve[6], curve[7], curve[2], curve[3]);
2376 }
2377 }
2378 } else if (drawEnd > 1) {
2379 drawLine(curve[4], curve[5], curve[0], curve[1]);
2380 }
2381}
2382
2383function pointAtT(curve, curveType, t) {
2384 var xy = {};
2385 switch (curveType) {
2386 case PATH_LINE:
2387 var a = 1 - t;
2388 var b = t;
2389 xy.x = a * curve[0] + b * curve[2];
2390 xy.y = a * curve[1] + b * curve[3];
2391 break;
2392 case PATH_QUAD:
2393 var one_t = 1 - t;
2394 var a = one_t * one_t;
2395 var b = 2 * one_t * t;
2396 var c = t * t;
2397 xy.x = a * curve[0] + b * curve[2] + c * curve[4];
2398 xy.y = a * curve[1] + b * curve[3] + c * curve[5];
2399 break;
caryclark1049f122015-04-20 08:31:59 -07002400 case PATH_CONIC:
2401 var one_t = 1 - t;
2402 var a = one_t * one_t;
2403 var b = 2 * one_t * t;
2404 var c = t * t;
2405 xy.x = a * curve[0] + b * curve[2] * curve[6] + c * curve[4];
2406 xy.y = a * curve[1] + b * curve[3] * curve[6] + c * curve[5];
2407 var d = a + b * curve[6] + c;
2408 xy.x /= d;
2409 xy.y /= d;
2410 break;
caryclarkdac1d172014-06-17 05:15:38 -07002411 case PATH_CUBIC:
2412 var one_t = 1 - t;
2413 var one_t2 = one_t * one_t;
2414 var a = one_t2 * one_t;
2415 var b = 3 * one_t2 * t;
2416 var t2 = t * t;
2417 var c = 3 * one_t * t2;
2418 var d = t2 * t;
2419 xy.x = a * curve[0] + b * curve[2] + c * curve[4] + d * curve[6];
2420 xy.y = a * curve[1] + b * curve[3] + c * curve[5] + d * curve[7];
2421 break;
2422 }
2423 return xy;
2424}
caryclark55888e42016-07-18 10:01:36 -07002425
caryclarkdac1d172014-06-17 05:15:38 -07002426function drawPointAtT(curve, curveType) {
2427 var x, y;
2428 var xy = pointAtT(curve, curveType, curveT);
2429 drawPoint(xy.x, xy.y, true);
2430 if (!draw_intersectT) {
2431 return;
2432 }
2433 ctx.fillStyle = "red";
2434 drawTAtPointUp(xy.x, xy.y, curveT);
2435}
2436
2437function drawTAtPointUp(px, py, t) {
2438 var label = t.toFixed(decimal_places);
2439 var _px = (px - srcLeft)* scale;
2440 var _py = (py - srcTop) * scale;
2441 ctx.fillText(label, _px + 5, _py - 10);
2442}
2443
2444function drawTAtPointDown(px, py, t) {
2445 var label = t.toFixed(decimal_places);
2446 var _px = (px - srcLeft)* scale;
2447 var _py = (py - srcTop) * scale;
2448 ctx.fillText(label, _px + 5, _py + 10);
2449}
2450
2451function alreadyDrawnLine(x1, y1, x2, y2) {
2452 if (collect_bounds) {
2453 if (focus_enabled) {
2454 focusXmin = Math.min(focusXmin, x1, x2);
2455 focusYmin = Math.min(focusYmin, y1, y2);
2456 focusXmax = Math.max(focusXmax, x1, x2);
2457 focusYmax = Math.max(focusYmax, y1, y2);
2458 }
2459 return true;
2460 }
2461 for (var pts = 0; pts < drawnLines.length; pts += 4) {
2462 if (x1 == drawnLines[pts] && y1 == drawnLines[pts + 1]
2463 && x2 == drawnLines[pts + 2] && y2 == drawnLines[pts + 3]) {
2464 return true;
2465 }
2466 }
2467 drawnLines.push(x1);
2468 drawnLines.push(y1);
2469 drawnLines.push(x2);
2470 drawnLines.push(y2);
2471 return false;
2472}
2473
2474function drawLine(x1, y1, x2, y2) {
2475 if (alreadyDrawnLine(x1, y1, x2, y2)) {
2476 return;
2477 }
2478 ctx.beginPath();
2479 ctx.moveTo((x1 - srcLeft) * scale,
2480 (y1 - srcTop) * scale);
2481 ctx.lineTo((x2 - srcLeft) * scale,
2482 (y2 - srcTop) * scale);
2483 ctx.stroke();
2484}
2485
2486function linePartial(x1, y1, x2, y2, t1, t2) {
2487 var dx = x1 - x2;
2488 var dy = y1 - y2;
2489 var array = [
2490 x1 - t1 * dx,
2491 y1 - t1 * dy,
2492 x1 - t2 * dx,
2493 y1 - t2 * dy
2494 ];
2495 return array;
2496}
2497
2498function drawLinePartial(x1, y1, x2, y2, t1, t2) {
2499 var a = linePartial(x1, y1, x2, y2, t1, t2);
2500 var ax = a[0];
2501 var ay = a[1];
2502 var bx = a[2];
2503 var by = a[3];
2504 if (alreadyDrawnLine(ax, ay, bx, by)) {
2505 return;
2506 }
2507 ctx.beginPath();
2508 ctx.moveTo((ax - srcLeft) * scale,
2509 (ay - srcTop) * scale);
2510 ctx.lineTo((bx - srcLeft) * scale,
2511 (by - srcTop) * scale);
2512 ctx.stroke();
2513}
2514
2515function alreadyDrawnQuad(x1, y1, x2, y2, x3, y3) {
2516 if (collect_bounds) {
2517 if (focus_enabled) {
2518 focusXmin = Math.min(focusXmin, x1, x2, x3);
2519 focusYmin = Math.min(focusYmin, y1, y2, y3);
2520 focusXmax = Math.max(focusXmax, x1, x2, x3);
2521 focusYmax = Math.max(focusYmax, y1, y2, y3);
2522 }
2523 return true;
2524 }
2525 for (var pts = 0; pts < drawnQuads.length; pts += 6) {
2526 if (x1 == drawnQuads[pts] && y1 == drawnQuads[pts + 1]
2527 && x2 == drawnQuads[pts + 2] && y2 == drawnQuads[pts + 3]
2528 && x3 == drawnQuads[pts + 4] && y3 == drawnQuads[pts + 5]) {
2529 return true;
2530 }
2531 }
2532 drawnQuads.push(x1);
2533 drawnQuads.push(y1);
2534 drawnQuads.push(x2);
2535 drawnQuads.push(y2);
2536 drawnQuads.push(x3);
2537 drawnQuads.push(y3);
2538 return false;
2539}
2540
2541function drawQuad(x1, y1, x2, y2, x3, y3) {
2542 if (alreadyDrawnQuad(x1, y1, x2, y2, x3, y3)) {
2543 return;
2544 }
2545 ctx.beginPath();
2546 ctx.moveTo((x1 - srcLeft) * scale,
2547 (y1 - srcTop) * scale);
2548 ctx.quadraticCurveTo((x2 - srcLeft) * scale,
2549 (y2 - srcTop) * scale,
2550 (x3 - srcLeft) * scale,
2551 (y3 - srcTop) * scale);
2552 ctx.stroke();
2553}
2554
2555function interp(A, B, t) {
2556 return A + (B - A) * t;
2557}
2558
2559function interp_quad_coords(x1, x2, x3, t)
2560{
2561 var ab = interp(x1, x2, t);
2562 var bc = interp(x2, x3, t);
2563 var abc = interp(ab, bc, t);
2564 return abc;
2565}
2566
2567function quadPartial(x1, y1, x2, y2, x3, y3, t1, t2) {
2568 var ax = interp_quad_coords(x1, x2, x3, t1);
2569 var ay = interp_quad_coords(y1, y2, y3, t1);
2570 var dx = interp_quad_coords(x1, x2, x3, (t1 + t2) / 2);
2571 var dy = interp_quad_coords(y1, y2, y3, (t1 + t2) / 2);
2572 var cx = interp_quad_coords(x1, x2, x3, t2);
2573 var cy = interp_quad_coords(y1, y2, y3, t2);
2574 var bx = 2*dx - (ax + cx)/2;
2575 var by = 2*dy - (ay + cy)/2;
2576 var array = [
2577 ax, ay, bx, by, cx, cy
2578 ];
2579 return array;
2580}
2581
2582function drawQuadPartial(x1, y1, x2, y2, x3, y3, t1, t2) {
2583 var a = quadPartial(x1, y1, x2, y2, x3, y3, t1, t2);
2584 var ax = a[0];
2585 var ay = a[1];
2586 var bx = a[2];
2587 var by = a[3];
2588 var cx = a[4];
2589 var cy = a[5];
2590 if (alreadyDrawnQuad(ax, ay, bx, by, cx, cy)) {
2591 return;
2592 }
2593 ctx.beginPath();
2594 ctx.moveTo((ax - srcLeft) * scale,
2595 (ay - srcTop) * scale);
2596 ctx.quadraticCurveTo((bx - srcLeft) * scale,
2597 (by - srcTop) * scale,
2598 (cx - srcLeft) * scale,
2599 (cy - srcTop) * scale);
2600 ctx.stroke();
2601}
2602
caryclark1049f122015-04-20 08:31:59 -07002603function alreadyDrawnConic(x1, y1, x2, y2, x3, y3, w) {
2604 if (collect_bounds) {
2605 if (focus_enabled) {
2606 focusXmin = Math.min(focusXmin, x1, x2, x3);
2607 focusYmin = Math.min(focusYmin, y1, y2, y3);
2608 focusXmax = Math.max(focusXmax, x1, x2, x3);
2609 focusYmax = Math.max(focusYmax, y1, y2, y3);
2610 }
2611 return true;
2612 }
2613 for (var pts = 0; pts < drawnConics.length; pts += 8) {
2614 if (x1 == drawnConics[pts] && y1 == drawnCubics[pts + 1]
caryclark55888e42016-07-18 10:01:36 -07002615 && x2 == drawnCubics[pts + 2] && y2 == drawnCubics[pts + 3]
2616 && x3 == drawnCubics[pts + 4] && y3 == drawnCubics[pts + 5]
caryclark1049f122015-04-20 08:31:59 -07002617 && w == drawnCubics[pts + 6]) {
2618 return true;
2619 }
2620 }
2621 drawnConics.push(x1);
2622 drawnConics.push(y1);
2623 drawnConics.push(x2);
2624 drawnConics.push(y2);
2625 drawnConics.push(x3);
2626 drawnConics.push(y3);
2627 drawnCubics.push(w);
2628 return false;
2629}
2630
2631var kMaxConicToQuadPOW2 = 5;
2632
2633function computeQuadPOW2(curve, tol) {
2634 var a = curve[6] - 1;
2635 var k = a / (4 * (2 + a));
2636 var x = k * (curve[0] - 2 * curve[2] + curve[4]);
2637 var y = k * (curve[1] - 2 * curve[3] + curve[5]);
2638
2639 var error = Math.sqrt(x * x + y * y);
2640 var pow2;
2641 for (pow2 = 0; pow2 < kMaxConicToQuadPOW2; ++pow2) {
2642 if (error <= tol) {
2643 break;
2644 }
2645 error *= 0.25;
2646 }
2647 return pow2;
2648}
2649
2650function subdivide_w_value(w) {
2651 return Math.sqrt(0.5 + w * 0.5);
2652}
2653
2654function chop(curve, part1, part2) {
2655 var w = curve[6];
2656 var scale = 1 / (1 + w);
2657 part1[0] = curve[0];
2658 part1[1] = curve[1];
2659 part1[2] = (curve[0] + curve[2] * w) * scale;
2660 part1[3] = (curve[1] + curve[3] * w) * scale;
2661 part1[4] = part2[0] = (curve[0] + (curve[2] * w) * 2 + curve[4]) * scale * 0.5;
2662 part1[5] = part2[1] = (curve[1] + (curve[3] * w) * 2 + curve[5]) * scale * 0.5;
2663 part2[2] = (curve[2] * w + curve[4]) * scale;
2664 part2[3] = (curve[3] * w + curve[5]) * scale;
2665 part2[4] = curve[4];
2666 part2[5] = curve[5];
2667 part1[6] = part2[6] = subdivide_w_value(w);
2668}
2669
2670function subdivide(curve, level, pts) {
2671 if (0 == level) {
2672 pts.push(curve[2]);
2673 pts.push(curve[3]);
2674 pts.push(curve[4]);
2675 pts.push(curve[5]);
2676 } else {
2677 var part1 = [], part2 = [];
2678 chop(curve, part1, part2);
2679 --level;
2680 subdivide(part1, level, pts);
2681 subdivide(part2, level, pts);
2682 }
2683}
2684
2685function chopIntoQuadsPOW2(curve, pow2, pts) {
2686 subdivide(curve, pow2, pts);
2687 return 1 << pow2;
2688}
2689
2690function drawConicWithQuads(x1, y1, x2, y2, x3, y3, w) {
2691 if (alreadyDrawnConic(x1, y1, x2, y2, x3, y3, w)) {
2692 return;
2693 }
2694 ctx.beginPath();
2695 ctx.moveTo((x1 - srcLeft) * scale,
2696 (y1 - srcTop) * scale);
2697 var tol = 1 / scale;
2698 var curve = [x1, y1, x2, y2, x3, y3, w];
2699 var pow2 = computeQuadPOW2(curve, tol);
2700 var pts = [];
2701 chopIntoQuadsPOW2(curve, pow2, pts);
2702 for (var i = 0; i < pts.length; i += 4) {
2703 ctx.quadraticCurveTo(
2704 (pts[i + 0] - srcLeft) * scale, (pts[i + 1] - srcTop) * scale,
2705 (pts[i + 2] - srcLeft) * scale, (pts[i + 3] - srcTop) * scale);
2706 }
2707 ctx.stroke();
2708}
2709
2710function conic_eval_numerator(x1, x2, x3, w, t) {
2711 var src2w = x2 * w;
2712 var C = x1;
2713 var A = x3 - 2 * src2w + C;
2714 var B = 2 * (src2w - C);
2715 return (A * t + B) * t + C;
2716}
2717
2718
2719function conic_eval_denominator(w, t) {
2720 var B = 2 * (w - 1);
2721 var C = 1;
2722 var A = -B;
2723 return (A * t + B) * t + C;
2724}
2725
2726function conicPartial(x1, y1, x2, y2, x3, y3, w, t1, t2) {
2727 var ax = conic_eval_numerator(x1, x2, x3, w, t1);
2728 var ay = conic_eval_numerator(y1, y2, y3, w, t1);
2729 var az = conic_eval_denominator(w, t1);
2730 var midT = (t1 + t2) / 2;
2731 var dx = conic_eval_numerator(x1, x2, x3, w, midT);
2732 var dy = conic_eval_numerator(y1, y2, y3, w, midT);
2733 var dz = conic_eval_denominator(w, midT);
2734 var cx = conic_eval_numerator(x1, x2, x3, w, t2);
2735 var cy = conic_eval_numerator(y1, y2, y3, w, t2);
2736 var cz = conic_eval_denominator(w, t2);
2737 var bx = 2 * dx - (ax + cx) / 2;
2738 var by = 2 * dy - (ay + cy) / 2;
2739 var bz = 2 * dz - (az + cz) / 2;
2740 var dt = t2 - t1;
2741 var dt_1 = 1 - dt;
caryclark1049f122015-04-20 08:31:59 -07002742 var array = [
caryclarked0935a2015-10-22 07:23:52 -07002743 ax / az, ay / az, bx / bz, by / bz, cx / cz, cy / cz, 0
caryclark1049f122015-04-20 08:31:59 -07002744 ];
caryclarked0935a2015-10-22 07:23:52 -07002745 var dMidAC = { x:(array[0] + array[4]) / 2, y:(array[1] + array[5]) / 2 };
2746 var dMid = { x:dx / dz, y:dy / dz };
2747 var dWNumer = { x:dMidAC.x - dMid.x, y:dMidAC.y - dMid.y };
2748 var dWDenom = { x:dMid.x - array[2], y:dMid.y - array[3] };
2749 var partW = Math.sqrt(dWNumer.x * dWNumer.x + dWNumer.y * dWNumer.y)
2750 / Math.sqrt(dWDenom.x * dWDenom.x + dWDenom.y * dWDenom.y);
2751 array[6] = partW;
caryclark1049f122015-04-20 08:31:59 -07002752 return array;
2753}
caryclark55888e42016-07-18 10:01:36 -07002754
caryclark1049f122015-04-20 08:31:59 -07002755function drawConicPartial(x1, y1, x2, y2, x3, y3, w, t1, t2) {
2756 var a = conicPartial(x1, y1, x2, y2, x3, y3, w, t1, t2);
2757 var ax = a[0];
2758 var ay = a[1];
2759 var bx = a[2];
2760 var by = a[3];
2761 var cx = a[4];
2762 var cy = a[5];
2763 var w_ = a[6];
2764 drawConicWithQuads(ax, ay, bx, by, cx, cy, w_);
2765}
2766
caryclarkdac1d172014-06-17 05:15:38 -07002767function alreadyDrawnCubic(x1, y1, x2, y2, x3, y3, x4, y4) {
2768 if (collect_bounds) {
2769 if (focus_enabled) {
2770 focusXmin = Math.min(focusXmin, x1, x2, x3, x4);
2771 focusYmin = Math.min(focusYmin, y1, y2, y3, y4);
2772 focusXmax = Math.max(focusXmax, x1, x2, x3, x4);
2773 focusYmax = Math.max(focusYmax, y1, y2, y3, y4);
2774 }
2775 return true;
2776 }
2777 for (var pts = 0; pts < drawnCubics.length; pts += 8) {
2778 if (x1 == drawnCubics[pts] && y1 == drawnCubics[pts + 1]
caryclark55888e42016-07-18 10:01:36 -07002779 && x2 == drawnCubics[pts + 2] && y2 == drawnCubics[pts + 3]
2780 && x3 == drawnCubics[pts + 4] && y3 == drawnCubics[pts + 5]
caryclarkdac1d172014-06-17 05:15:38 -07002781 && x4 == drawnCubics[pts + 6] && y4 == drawnCubics[pts + 7]) {
2782 return true;
2783 }
2784 }
2785 drawnCubics.push(x1);
2786 drawnCubics.push(y1);
2787 drawnCubics.push(x2);
2788 drawnCubics.push(y2);
2789 drawnCubics.push(x3);
2790 drawnCubics.push(y3);
2791 drawnCubics.push(x4);
2792 drawnCubics.push(y4);
2793 return false;
2794}
2795
2796function drawCubic(x1, y1, x2, y2, x3, y3, x4, y4) {
2797 if (alreadyDrawnCubic(x1, y1, x2, y2, x3, y3, x4, y4)) {
2798 return;
2799 }
2800 ctx.beginPath();
2801 ctx.moveTo((x1 - srcLeft) * scale,
2802 (y1 - srcTop) * scale);
2803 ctx.bezierCurveTo((x2 - srcLeft) * scale,
2804 (y2 - srcTop) * scale,
2805 (x3 - srcLeft) * scale,
2806 (y3 - srcTop) * scale,
2807 (x4 - srcLeft) * scale,
2808 (y4 - srcTop) * scale);
2809 ctx.stroke();
2810}
2811
2812function interp_cubic_coords(x1, x2, x3, x4, t)
2813{
2814 var ab = interp(x1, x2, t);
2815 var bc = interp(x2, x3, t);
2816 var cd = interp(x3, x4, t);
2817 var abc = interp(ab, bc, t);
2818 var bcd = interp(bc, cd, t);
2819 var abcd = interp(abc, bcd, t);
2820 return abcd;
2821}
2822
2823function cubicPartial(x1, y1, x2, y2, x3, y3, x4, y4, t1, t2) {
2824 var ax = interp_cubic_coords(x1, x2, x3, x4, t1);
2825 var ay = interp_cubic_coords(y1, y2, y3, y4, t1);
2826 var ex = interp_cubic_coords(x1, x2, x3, x4, (t1*2+t2)/3);
2827 var ey = interp_cubic_coords(y1, y2, y3, y4, (t1*2+t2)/3);
2828 var fx = interp_cubic_coords(x1, x2, x3, x4, (t1+t2*2)/3);
2829 var fy = interp_cubic_coords(y1, y2, y3, y4, (t1+t2*2)/3);
2830 var dx = interp_cubic_coords(x1, x2, x3, x4, t2);
2831 var dy = interp_cubic_coords(y1, y2, y3, y4, t2);
2832 var mx = ex * 27 - ax * 8 - dx;
2833 var my = ey * 27 - ay * 8 - dy;
2834 var nx = fx * 27 - ax - dx * 8;
2835 var ny = fy * 27 - ay - dy * 8;
2836 var bx = (mx * 2 - nx) / 18;
2837 var by = (my * 2 - ny) / 18;
2838 var cx = (nx * 2 - mx) / 18;
2839 var cy = (ny * 2 - my) / 18;
2840 var array = [
2841 ax, ay, bx, by, cx, cy, dx, dy
2842 ];
2843 return array;
2844}
caryclark55888e42016-07-18 10:01:36 -07002845
caryclarkdac1d172014-06-17 05:15:38 -07002846function drawCubicPartial(x1, y1, x2, y2, x3, y3, x4, y4, t1, t2) {
2847 var a = cubicPartial(x1, y1, x2, y2, x3, y3, x4, y4, t1, t2);
2848 var ax = a[0];
2849 var ay = a[1];
2850 var bx = a[2];
2851 var by = a[3];
2852 var cx = a[4];
2853 var cy = a[5];
2854 var dx = a[6];
2855 var dy = a[7];
2856 if (alreadyDrawnCubic(ax, ay, bx, by, cx, cy, dx, dy)) {
2857 return;
2858 }
2859 ctx.beginPath();
2860 ctx.moveTo((ax - srcLeft) * scale,
2861 (ay - srcTop) * scale);
2862 ctx.bezierCurveTo((bx - srcLeft) * scale,
2863 (by - srcTop) * scale,
2864 (cx - srcLeft) * scale,
2865 (cy - srcTop) * scale,
2866 (dx - srcLeft) * scale,
2867 (dy - srcTop) * scale);
2868 ctx.stroke();
2869}
2870
2871function drawCurve(c) {
2872 switch (c.length) {
2873 case 4:
2874 drawLine(c[0], c[1], c[2], c[3]);
2875 break;
2876 case 6:
2877 drawQuad(c[0], c[1], c[2], c[3], c[4], c[5]);
2878 break;
caryclark1049f122015-04-20 08:31:59 -07002879 case 7:
2880 drawConicWithQuads(c[0], c[1], c[2], c[3], c[4], c[5], c[6]);
2881 break;
caryclarkdac1d172014-06-17 05:15:38 -07002882 case 8:
2883 drawCubic(c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]);
2884 break;
2885 }
2886}
2887
2888function boundsWidth(pts) {
2889 var min = pts[0];
2890 var max = pts[0];
caryclark1049f122015-04-20 08:31:59 -07002891 var length = pts.length == 7 ? 6 : pts.length;
2892 for (var idx = 2; idx < length; idx += 2) {
caryclarkdac1d172014-06-17 05:15:38 -07002893 min = Math.min(min, pts[idx]);
2894 max = Math.max(max, pts[idx]);
2895 }
2896 return max - min;
2897}
2898
2899function boundsHeight(pts) {
2900 var min = pts[1];
2901 var max = pts[1];
caryclark1049f122015-04-20 08:31:59 -07002902 var length = pts.length == 7 ? 6 : pts.length;
2903 for (var idx = 3; idx < length; idx += 2) {
caryclarkdac1d172014-06-17 05:15:38 -07002904 min = Math.min(min, pts[idx]);
2905 max = Math.max(max, pts[idx]);
2906 }
2907 return max - min;
2908}
2909
2910function tangent(pts) {
2911 var dx = pts[2] - pts[0];
2912 var dy = pts[3] - pts[1];
2913 if (dx == 0 && dy == 0 && pts.length > 4) {
2914 dx = pts[4] - pts[0];
2915 dy = pts[5] - pts[1];
caryclark1049f122015-04-20 08:31:59 -07002916 if (dx == 0 && dy == 0 && pts.length == 8) {
caryclarkdac1d172014-06-17 05:15:38 -07002917 dx = pts[6] - pts[0];
2918 dy = pts[7] - pts[1];
2919 }
2920 }
2921 return Math.atan2(-dy, dx);
2922}
2923
2924function hodograph(cubic) {
2925 var hodo = [];
2926 hodo[0] = 3 * (cubic[2] - cubic[0]);
2927 hodo[1] = 3 * (cubic[3] - cubic[1]);
2928 hodo[2] = 3 * (cubic[4] - cubic[2]);
2929 hodo[3] = 3 * (cubic[5] - cubic[3]);
2930 hodo[4] = 3 * (cubic[6] - cubic[4]);
2931 hodo[5] = 3 * (cubic[7] - cubic[5]);
2932 return hodo;
2933}
2934
2935function hodograph2(cubic) {
2936 var quad = hodograph(cubic);
2937 var hodo = [];
2938 hodo[0] = 2 * (quad[2] - quad[0]);
2939 hodo[1] = 2 * (quad[3] - quad[1]);
2940 hodo[2] = 2 * (quad[4] - quad[2]);
2941 hodo[3] = 2 * (quad[5] - quad[3]);
2942 return hodo;
2943}
2944
2945function quadraticRootsReal(A, B, C, s) {
2946 if (A == 0) {
2947 if (B == 0) {
2948 s[0] = 0;
2949 return C == 0;
2950 }
2951 s[0] = -C / B;
2952 return 1;
2953 }
2954 /* normal form: x^2 + px + q = 0 */
2955 var p = B / (2 * A);
2956 var q = C / A;
2957 var p2 = p * p;
2958 if (p2 < q) {
2959 return 0;
2960 }
2961 var sqrt_D = 0;
2962 if (p2 > q) {
2963 sqrt_D = sqrt(p2 - q);
2964 }
2965 s[0] = sqrt_D - p;
2966 s[1] = -sqrt_D - p;
2967 return 1 + s[0] != s[1];
2968}
2969
2970function add_valid_ts(s, realRoots, t) {
2971 var foundRoots = 0;
2972 for (var index = 0; index < realRoots; ++index) {
2973 var tValue = s[index];
2974 if (tValue >= 0 && tValue <= 1) {
2975 for (var idx2 = 0; idx2 < foundRoots; ++idx2) {
2976 if (t[idx2] != tValue) {
2977 t[foundRoots++] = tValue;
2978 }
2979 }
2980 }
2981 }
2982 return foundRoots;
2983}
2984
2985function quadraticRootsValidT(a, b, c, t) {
2986 var s = [];
2987 var realRoots = quadraticRootsReal(A, B, C, s);
2988 var foundRoots = add_valid_ts(s, realRoots, t);
2989 return foundRoots != 0;
2990}
2991
2992function find_cubic_inflections(cubic, tValues) {
2993 var Ax = src[2] - src[0];
2994 var Ay = src[3] - src[1];
2995 var Bx = src[4] - 2 * src[2] + src[0];
2996 var By = src[5] - 2 * src[3] + src[1];
2997 var Cx = src[6] + 3 * (src[2] - src[4]) - src[0];
2998 var Cy = src[7] + 3 * (src[3] - src[5]) - src[1];
2999 return quadraticRootsValidT(Bx * Cy - By * Cx, (Ax * Cy - Ay * Cx),
3000 Ax * By - Ay * Bx, tValues);
3001}
3002
3003function dxy_at_t(curve, type, t) {
3004 var dxy = {};
Cary Clarkff114282016-12-14 11:56:16 -05003005 if (type == PATH_LINE) {
3006 dxy.x = curve[2] - curve[0];
3007 dxy.y = curve[3] - curve[1];
3008 } else if (type == PATH_QUAD) {
caryclarkdac1d172014-06-17 05:15:38 -07003009 var a = t - 1;
3010 var b = 1 - 2 * t;
3011 var c = t;
3012 dxy.x = a * curve[0] + b * curve[2] + c * curve[4];
3013 dxy.y = a * curve[1] + b * curve[3] + c * curve[5];
caryclark1049f122015-04-20 08:31:59 -07003014 } else if (type == PATH_CONIC) {
3015 var p20x = curve[4] - curve[0];
3016 var p20y = curve[5] - curve[1];
3017 var p10xw = (curve[2] - curve[0]) * curve[6];
3018 var p10yw = (curve[3] - curve[1]) * curve[6];
3019 var coeff0x = curve[6] * p20x - p20x;
3020 var coeff0y = curve[6] * p20y - p20y;
3021 var coeff1x = p20x - 2 * p10xw;
3022 var coeff1y = p20y - 2 * p10yw;
3023 dxy.x = t * (t * coeff0x + coeff1x) + p10xw;
3024 dxy.y = t * (t * coeff0y + coeff1y) + p10yw;
caryclarkdac1d172014-06-17 05:15:38 -07003025 } else if (type == PATH_CUBIC) {
3026 var one_t = 1 - t;
3027 var a = curve[0];
3028 var b = curve[2];
3029 var c = curve[4];
3030 var d = curve[6];
3031 dxy.x = 3 * ((b - a) * one_t * one_t + 2 * (c - b) * t * one_t + (d - c) * t * t);
3032 a = curve[1];
3033 b = curve[3];
3034 c = curve[5];
3035 d = curve[7];
3036 dxy.y = 3 * ((b - a) * one_t * one_t + 2 * (c - b) * t * one_t + (d - c) * t * t);
3037 }
3038 return dxy;
3039}
3040
Ben Wagner29380bd2017-10-09 14:43:00 -04003041function dpt_at_t(curve, t) {
Cary Clarkff114282016-12-14 11:56:16 -05003042 var type = PATH_LINE + (curve.length / 2 - 2);
Ben Wagner29380bd2017-10-09 14:43:00 -04003043 return dxy_at_t(curve, type, t);
Cary Clarkff114282016-12-14 11:56:16 -05003044}
3045
caryclarkdac1d172014-06-17 05:15:38 -07003046function drawLabel(num, px, py) {
3047 ctx.beginPath();
3048 ctx.arc(px, py, 8, 0, Math.PI*2, true);
3049 ctx.closePath();
3050 ctx.strokeStyle = "rgba(0,0,0, 0.4)";
3051 ctx.lineWidth = num == 0 || num == 3 ? 2 : 1;
3052 ctx.stroke();
3053 ctx.fillStyle = "black";
3054 ctx.font = "normal 10px Arial";
3055 // ctx.rotate(0.001);
3056 ctx.fillText(num, px - 2, py + 3);
3057 // ctx.rotate(-0.001);
3058}
3059
3060function drawLabelX(ymin, num, loc) {
3061 var px = (loc - srcLeft) * scale;
3062 var py = (ymin - srcTop) * scale - 20;
3063 drawLabel(num, px, py);
3064}
3065
3066function drawLabelY(xmin, num, loc) {
3067 var px = (xmin - srcLeft) * scale - 20;
3068 var py = (loc - srcTop) * scale;
3069 drawLabel(num, px, py);
3070}
3071
3072function drawHodoOrigin(hx, hy, hMinX, hMinY, hMaxX, hMaxY) {
3073 ctx.beginPath();
3074 ctx.moveTo(hx, hy - 100);
3075 ctx.lineTo(hx, hy);
3076 ctx.strokeStyle = hMinY < 0 ? "green" : "blue";
3077 ctx.stroke();
3078 ctx.beginPath();
3079 ctx.moveTo(hx, hy);
3080 ctx.lineTo(hx, hy + 100);
3081 ctx.strokeStyle = hMaxY > 0 ? "green" : "blue";
3082 ctx.stroke();
3083 ctx.beginPath();
3084 ctx.moveTo(hx - 100, hy);
3085 ctx.lineTo(hx, hy);
3086 ctx.strokeStyle = hMinX < 0 ? "green" : "blue";
3087 ctx.stroke();
3088 ctx.beginPath();
3089 ctx.moveTo(hx, hy);
3090 ctx.lineTo(hx + 100, hy);
3091 ctx.strokeStyle = hMaxX > 0 ? "green" : "blue";
3092 ctx.stroke();
3093}
3094
3095function scalexy(x, y, mag) {
3096 var length = Math.sqrt(x * x + y * y);
3097 return mag / length;
3098}
3099
caryclark03b03ca2015-04-23 09:13:37 -07003100function drawArrow(x, y, dx, dy, s) {
3101 var dscale = scalexy(dx, dy, 1 / scale * 100 * s);
caryclarkdac1d172014-06-17 05:15:38 -07003102 dx *= dscale;
3103 dy *= dscale;
3104 ctx.beginPath();
3105 ctx.moveTo((x - srcLeft) * scale, (y - srcTop) * scale);
3106 x += dx;
3107 y += dy;
3108 ctx.lineTo((x - srcLeft) * scale, (y - srcTop) * scale);
3109 dx /= 10;
3110 dy /= 10;
3111 ctx.lineTo((x - dy - srcLeft) * scale, (y + dx - srcTop) * scale);
3112 ctx.lineTo((x + dx * 2 - srcLeft) * scale, (y + dy * 2 - srcTop) * scale);
3113 ctx.lineTo((x + dy - srcLeft) * scale, (y - dx - srcTop) * scale);
3114 ctx.lineTo((x - srcLeft) * scale, (y - srcTop) * scale);
3115 ctx.strokeStyle = "rgba(0,75,0, 0.4)";
3116 ctx.stroke();
3117}
3118
3119function x_at_t(curve, t) {
3120 var one_t = 1 - t;
3121 if (curve.length == 4) {
3122 return one_t * curve[0] + t * curve[2];
3123 }
3124 var one_t2 = one_t * one_t;
3125 var t2 = t * t;
3126 if (curve.length == 6) {
3127 return one_t2 * curve[0] + 2 * one_t * t * curve[2] + t2 * curve[4];
3128 }
caryclark1049f122015-04-20 08:31:59 -07003129 if (curve.length == 7) {
3130 return (one_t2 * curve[0] + 2 * one_t * t * curve[2] * curve[6] + t2 * curve[4])
3131 / (one_t2 +2 * one_t * t * curve[6] + t2);
3132 }
caryclarkdac1d172014-06-17 05:15:38 -07003133 var a = one_t2 * one_t;
3134 var b = 3 * one_t2 * t;
3135 var c = 3 * one_t * t2;
3136 var d = t2 * t;
3137 return a * curve[0] + b * curve[2] + c * curve[4] + d * curve[6];
3138}
3139
3140function y_at_t(curve, t) {
3141 var one_t = 1 - t;
3142 if (curve.length == 4) {
3143 return one_t * curve[1] + t * curve[3];
3144 }
3145 var one_t2 = one_t * one_t;
3146 var t2 = t * t;
3147 if (curve.length == 6) {
3148 return one_t2 * curve[1] + 2 * one_t * t * curve[3] + t2 * curve[5];
3149 }
caryclark1049f122015-04-20 08:31:59 -07003150 if (curve.length == 7) {
3151 return (one_t2 * curve[1] + 2 * one_t * t * curve[3] * curve[6] + t2 * curve[5])
3152 / (one_t2 +2 * one_t * t * curve[6] + t2);
3153 }
caryclarkdac1d172014-06-17 05:15:38 -07003154 var a = one_t2 * one_t;
3155 var b = 3 * one_t2 * t;
3156 var c = 3 * one_t * t2;
3157 var d = t2 * t;
3158 return a * curve[1] + b * curve[3] + c * curve[5] + d * curve[7];
3159}
3160
Ben Wagner29380bd2017-10-09 14:43:00 -04003161function pt_at_t(curve, t) {
3162 var pt = {};
3163 pt.x = x_at_t(curve, t);
3164 pt.y = y_at_t(curve, t);
3165 return pt;
Cary Clarkff114282016-12-14 11:56:16 -05003166}
3167
3168function drawOrder(curve, t, label) {
3169 var px = x_at_t(curve, t);
3170 var py = y_at_t(curve, t);
caryclarkdac1d172014-06-17 05:15:38 -07003171 var _px = (px - srcLeft) * scale;
3172 var _py = (py - srcTop) * scale;
3173 ctx.beginPath();
3174 ctx.arc(_px, _py, 15, 0, Math.PI * 2, true);
3175 ctx.closePath();
3176 ctx.fillStyle = "white";
3177 ctx.fill();
3178 if (label == 'L') {
3179 ctx.strokeStyle = "rgba(255,0,0, 1)";
3180 ctx.fillStyle = "rgba(255,0,0, 1)";
3181 } else {
3182 ctx.strokeStyle = "rgba(0,0,255, 1)";
3183 ctx.fillStyle = "rgba(0,0,255, 1)";
3184 }
3185 ctx.stroke();
3186 ctx.font = "normal 16px Arial";
3187 ctx.textAlign = "center";
3188 ctx.fillText(label, _px, _py + 5);
3189 ctx.font = "normal 10px Arial";
3190}
3191
Ben Wagner29380bd2017-10-09 14:43:00 -04003192function drawVisibleOrder(curve, label) {
3193 var s = pt_at_t(curve, 0);
3194 var e = pt_at_t(curve, 1);
3195 var sOn = ptOnScreen(s);
3196 var eOn = ptOnScreen(e);
3197 var defaultT = 0.85;
3198 if (sOn && eOn)
3199 return drawOrder(curve, defaultT, label);
3200 if (sOn || eOn) {
3201 if (eOn) {
3202 defaultT = 1 - defaultT;
3203 }
3204 var step = sOn ? -defaultT / 2 : (1 - defaultT) / 2;
3205 var t = defaultT;
3206 var tries = 16;
3207 do {
3208 var mid = pt_at_t(curve, t);
3209 if (ptOnScreen(mid))
3210 return drawOrder(curve, t, label);
3211 t += step;
3212 step /= 2;
3213 } while (--tries > 0);
3214 drawOrder(curve, defaultT, label);
3215 }
3216 // scattershot until we find a visible point
3217 var denom = 2; // visit odd number num / denom to hit unique pts
3218 var tries = 6; // tries 1/2, 1/4, 3/4, 1/8, 3/8, 5/8, 7/8, 1/16 ...
3219 do {
3220 for (var numer = 1; numer < denom; numer += 2) {
3221 var t = numer / denom + 0.1;
3222 if (t >= 1) {
3223 break;
3224 }
3225 var mid = pt_at_t(curve, t);
3226 if (ptOnScreen(mid))
3227 return drawOrder(curve, t, label);
3228 }
3229 denom *= 2;
3230 } while (--tries > 0);
3231 drawOrder(curve, defaultT, label);
Cary Clarkff114282016-12-14 11:56:16 -05003232}
3233
Ben Wagner29380bd2017-10-09 14:43:00 -04003234function set_length(pt, newLen) {
3235 var len = Math.sqrt(pt.x * pt.x + pt.y * pt.y);
3236 var scale = newLen / len;
3237 var newPt = { x: pt.x * scale, y: pt.y * scale };
3238 return newPt;
Cary Clarkff114282016-12-14 11:56:16 -05003239}
3240
Ben Wagner29380bd2017-10-09 14:43:00 -04003241function drawDirection(curve, t) {
Cary Clarkff114282016-12-14 11:56:16 -05003242 var d = dpt_at_t(curve, t);
3243 d = set_length(d, 16);
Ben Wagner29380bd2017-10-09 14:43:00 -04003244 var pt = localToGlobal(pt_at_t(curve, t));
Cary Clarkff114282016-12-14 11:56:16 -05003245 ctx.beginPath();
3246 ctx.moveTo(pt.x - d.y, pt.y + d.x);
3247 ctx.lineTo(pt.x + d.x, pt.y + d.y);
3248 ctx.lineTo(pt.x + d.y, pt.y - d.x);
3249 ctx.strokeStyle = "rgba(0,75,0, 0.4)";
3250 ctx.stroke();
3251}
3252
Ben Wagner29380bd2017-10-09 14:43:00 -04003253function drawVisibleDirection(curve) {
3254 var s = pt_at_t(curve, 0);
3255 var e = pt_at_t(curve, 1);
3256 var sOn = ptOnScreen(s);
3257 var eOn = ptOnScreen(e);
3258 var defaultT = 0.65;
3259 if (sOn && eOn) {
3260 return drawDirection(curve, defaultT);
3261 }
3262 if (sOn || eOn) {
3263 if (eOn) {
3264 defaultT = 1 - defaultT;
3265 }
3266 var step = sOn ? -defaultT / 2 : (1 - defaultT) / 2;
3267 var t = defaultT;
3268 var tries = 16;
3269 do {
3270 var mid = pt_at_t(curve, t);
3271 if (ptOnScreen(mid))
3272 return drawDirection(curve, t);
3273 t += step;
3274 step /= 2;
3275 } while (--tries > 0);
3276 drawDirection(curve, defaultT);
3277 }
3278 // scattershot until we find a visible point
3279 var denom = 2; // visit odd number num / denom to hit unique pts
3280 var tries = 6; // tries 1/2, 1/4, 3/4, 1/8, 3/8, 5/8, 7/8, 1/16 ...
3281 do {
3282 for (var numer = 1; numer < denom; numer += 2) {
3283 var t = numer / denom + 0.1;
3284 if (t >= 1) {
3285 break;
3286 }
3287 var mid = pt_at_t(curve, t);
3288 if (ptOnScreen(mid))
3289 return drawDirection(curve, t);
3290 }
3291 denom *= 2;
3292 } while (--tries > 0);
3293 drawDirection(curve, defaultT);
Cary Clarkff114282016-12-14 11:56:16 -05003294}
3295
3296function drawID(curve, t, id) {
3297 var px = x_at_t(curve, t);
3298 var py = y_at_t(curve, t);
caryclarkdac1d172014-06-17 05:15:38 -07003299 var _px = (px - srcLeft) * scale;
3300 var _py = (py - srcTop) * scale;
3301 draw_id_at(id, _px, _py);
3302}
3303
Ben Wagner29380bd2017-10-09 14:43:00 -04003304function localToGlobal(local) {
3305 var global = {};
3306 global.x = (local.x - srcLeft) * scale;
3307 global.y = (local.y - srcTop) * scale;
3308 return global;
Cary Clarkff114282016-12-14 11:56:16 -05003309}
3310
Ben Wagner29380bd2017-10-09 14:43:00 -04003311function ptOnScreen(local) {
3312 var pt = localToGlobal(local);
3313 return 10 <= pt.x && pt.x <= screenWidth - 10
3314 && 10 <= pt.y && pt.y <= screenHeight - 10;
Cary Clarkff114282016-12-14 11:56:16 -05003315}
3316
Ben Wagner29380bd2017-10-09 14:43:00 -04003317function drawVisibleID(curve, defaultT, id) {
3318 // determine if either or both ends are visible
3319 var s = pt_at_t(curve, 0);
3320 var e = pt_at_t(curve, 1);
3321 var sOn = ptOnScreen(s);
3322 var eOn = ptOnScreen(e);
3323 if (sOn && eOn)
3324 return drawID(curve, defaultT, id);
3325 if (sOn || eOn) {
3326 var step = sOn ? -defaultT / 2 : (1 - defaultT) / 2;
3327 var t = defaultT;
3328 var tries = 16;
3329 do {
3330 var mid = pt_at_t(curve, t);
3331 if (ptOnScreen(mid))
3332 return drawID(curve, t, id);
3333 t += step;
3334 step /= 2;
3335 } while (--tries > 0);
3336 drawID(curve, defaultT, id);
3337 }
3338 // scattershot until we find a visible point
3339 var denom = 2; // visit odd number num / denom to hit unique pts
3340 var tries = 6; // tries 1/2, 1/4, 3/4, 1/8, 3/8, 5/8, 7/8, 1/16 ...
3341 do {
3342 for (var numer = 1; numer < denom; numer += 2) {
3343 var t = numer / denom;
3344 var mid = pt_at_t(curve, t);
3345 if (ptOnScreen(mid))
3346 return drawID(curve, t, id);
3347 }
3348 denom *= 2;
3349 } while (--tries > 0);
3350 drawID(curve, defaultT, id);
Cary Clarkff114282016-12-14 11:56:16 -05003351}
3352
caryclarkdac1d172014-06-17 05:15:38 -07003353function draw_id_at(id, _px, _py) {
3354 ctx.beginPath();
3355 ctx.arc(_px, _py, 15, 0, Math.PI * 2, true);
3356 ctx.closePath();
3357 ctx.fillStyle = "white";
3358 ctx.fill();
3359 ctx.strokeStyle = "rgba(127,127,0, 1)";
3360 ctx.fillStyle = "rgba(127,127,0, 1)";
3361 ctx.stroke();
3362 ctx.font = "normal 16px Arial";
3363 ctx.textAlign = "center";
3364 ctx.fillText(id, _px, _py + 5);
3365 ctx.font = "normal 10px Arial";
3366}
3367
3368function drawLinePartialID(id, x1, y1, x2, y2, t1, t2) {
3369 var curve = [x1, y1, x2, y2];
3370 drawCurvePartialID(id, curve, t1, t2);
3371}
3372
caryclark55888e42016-07-18 10:01:36 -07003373function drawLineID(id, x1, y1, x2, y2) {
3374 drawLinePartialID(id, x1, y1, x2, y2, 0, 1);
3375}
3376
caryclarkdac1d172014-06-17 05:15:38 -07003377function drawQuadPartialID(id, x1, y1, x2, y2, x3, y3, t1, t2) {
3378 var curve = [x1, y1, x2, y2, x3, y3];
3379 drawCurvePartialID(id, curve, t1, t2);
3380}
3381
caryclark55888e42016-07-18 10:01:36 -07003382function drawQuadID(id, x1, y1, x2, y2, x3, y3) {
3383 drawQuadPartialID(id, x1, y1, x2, y2, x3, y3, 0, 1);
3384}
3385
caryclark1049f122015-04-20 08:31:59 -07003386function drawConicPartialID(id, x1, y1, x2, y2, x3, y3, w, t1, t2) {
3387 var curve = [x1, y1, x2, y2, x3, y3, w];
3388 drawCurvePartialID(id, curve, t1, t2);
3389}
3390
caryclark55888e42016-07-18 10:01:36 -07003391function drawConicID(id, x1, y1, x2, y2, x3, y3, w) {
3392 drawConicPartialID(id, x1, y1, x2, y2, x3, y3, w, 0, 1);
3393}
3394
caryclarkdac1d172014-06-17 05:15:38 -07003395function drawCubicPartialID(id, x1, y1, x2, y2, x3, y3, x4, y4, t1, t2) {
3396 var curve = [x1, y1, x2, y2, x3, y3, x4, y4];
3397 drawCurvePartialID(id, curve, t1, t2);
3398}
3399
caryclark55888e42016-07-18 10:01:36 -07003400function drawCubicID(id, x1, y1, x2, y2, x3, y3, x4, y4) {
3401 drawCubicPartialID(id, x1, y1, x2, y2, x3, y3, x4, y4, 0, 1);
3402}
3403
caryclarkdac1d172014-06-17 05:15:38 -07003404function drawCurvePartialID(id, curve, t1, t2) {
Cary Clarkff114282016-12-14 11:56:16 -05003405 drawVisibleID(curve, (t1 + t2) / 2, id);
caryclarkdac1d172014-06-17 05:15:38 -07003406}
3407
3408function drawCurveSpecials(test, curve, type) {
3409 if (pt_labels) {
3410 drawPoints(curve, type, pt_labels == 2);
3411 }
3412 if (control_lines != 0) {
3413 drawControlLines(curve, type, control_lines);
3414 }
3415 if (curve_t) {
3416 drawPointAtT(curve, type);
3417 }
3418 if (draw_midpoint) {
3419 var mid = pointAtT(curve, type, 0.5);
3420 drawPoint(mid.x, mid.y, true);
3421 }
3422 if (draw_id) {
3423 var id = idByCurve(test, curve, type);
3424 if (id >= 0) {
Cary Clarkff114282016-12-14 11:56:16 -05003425 drawVisibleID(curve, 0.5, id);
caryclarkdac1d172014-06-17 05:15:38 -07003426 }
3427 }
Ben Wagner29380bd2017-10-09 14:43:00 -04003428 if (draw_direction) {
3429 drawVisibleDirection(curve);
Cary Clarkff114282016-12-14 11:56:16 -05003430 }
caryclarkdac1d172014-06-17 05:15:38 -07003431 if (type == PATH_LINE) {
3432 return;
3433 }
3434 if (draw_deriviatives > 0) {
3435 var d = dxy_at_t(curve, type, 0);
caryclark03b03ca2015-04-23 09:13:37 -07003436 drawArrow(curve[0], curve[1], d.x, d.y, 1);
caryclarkdac1d172014-06-17 05:15:38 -07003437 if (draw_deriviatives == 2) {
3438 d = dxy_at_t(curve, type, 1);
3439 if (type == PATH_CUBIC) {
caryclark03b03ca2015-04-23 09:13:37 -07003440 drawArrow(curve[6], curve[7], d.x, d.y, 1);
caryclarkdac1d172014-06-17 05:15:38 -07003441 } else {
caryclark03b03ca2015-04-23 09:13:37 -07003442 drawArrow(curve[4], curve[5], d.x, d.y, 1);
caryclarkdac1d172014-06-17 05:15:38 -07003443 }
3444 }
3445 if (draw_midpoint) {
3446 var mid = pointAtT(curve, type, 0.5);
3447 d = dxy_at_t(curve, type, 0.5);
caryclark03b03ca2015-04-23 09:13:37 -07003448 drawArrow(mid.x, mid.y, d.x, d.y, 1);
caryclarkdac1d172014-06-17 05:15:38 -07003449 }
3450 }
3451 if (type != PATH_CUBIC) {
3452 return;
3453 }
caryclarkdac1d172014-06-17 05:15:38 -07003454 if (draw_sequence) {
3455 var ymin = Math.min(curve[1], curve[3], curve[5], curve[7]);
3456 for (var i = 0; i < 8; i+= 2) {
3457 drawLabelX(ymin, i >> 1, curve[i]);
3458 }
3459 var xmin = Math.min(curve[0], curve[2], curve[4], curve[6]);
3460 for (var i = 1; i < 8; i+= 2) {
3461 drawLabelY(xmin, i >> 1, curve[i]);
3462 }
3463 }
3464}
3465
3466function logCurves(test) {
3467 for (curves in test) {
3468 var curve = test[curves];
3469 dumpCurve(curve);
3470 }
3471}
3472
3473function curveToString(curve) {
3474 var str = "{{";
caryclark1049f122015-04-20 08:31:59 -07003475 var length = curve.length == 7 ? 6 : curve.length;
3476 if (curve.length == 7) {
3477 str += "{";
3478 }
3479 for (i = 0; i < length; i += 2) {
caryclarkdac1d172014-06-17 05:15:38 -07003480 str += curve[i].toFixed(decimal_places) + "," + curve[i + 1].toFixed(decimal_places);
3481 if (i < curve.length - 2) {
3482 str += "}, {";
3483 }
3484 }
caryclark1049f122015-04-20 08:31:59 -07003485 str += "}";
3486 if (curve.length == 7) {
3487 str += "}, " + curve[6].toFixed(decimal_places);
3488 }
3489 str += "}";
caryclarkdac1d172014-06-17 05:15:38 -07003490 return str;
3491}
3492
3493function dumpCurve(curve) {
3494 console.log(curveToString(curve));
3495}
3496
3497function draw(test, lines, title) {
3498 ctx.fillStyle = "rgba(0,0,0, 0.1)";
3499 ctx.font = "normal 50px Arial";
3500 ctx.textAlign = "left";
3501 ctx.fillText(title, 50, 50);
3502 ctx.font = "normal 10px Arial";
3503 ctx.lineWidth = "1.001"; "0.999";
3504 var secondPath = test.length;
3505 var closeCount = 0;
3506 logStart = -1;
3507 logRange = 0;
3508 // find last active rec type at this step
3509 var curType = test[0];
3510 var curStep = 0;
3511 var hasOp = false;
3512 var lastActive = 0;
3513 var lastAdd = 0;
caryclark624637c2015-05-11 07:21:27 -07003514 var lastCoin = 0;
caryclarkdac1d172014-06-17 05:15:38 -07003515 var lastSect = 0;
3516 var lastSort = 0;
3517 var lastMark = 0;
caryclark03b03ca2015-04-23 09:13:37 -07003518 var lastTop = 0;
caryclarkdac1d172014-06-17 05:15:38 -07003519 activeCount = 0;
3520 addCount = 0;
3521 angleCount = 0;
3522 opCount = 0;
3523 sectCount = 0;
3524 sortCount = 0;
caryclark03b03ca2015-04-23 09:13:37 -07003525 topCount = 0;
caryclarkdac1d172014-06-17 05:15:38 -07003526 markCount = 0;
3527 activeMax = 0;
3528 addMax = 0;
3529 angleMax = 0;
caryclark624637c2015-05-11 07:21:27 -07003530 coinMax = 0;
caryclarkdac1d172014-06-17 05:15:38 -07003531 opMax = 0;
3532 sectMax = 0;
3533 sectMax2 = 0;
3534 sortMax = 0;
caryclark03b03ca2015-04-23 09:13:37 -07003535 topMax = 0;
caryclarkdac1d172014-06-17 05:15:38 -07003536 markMax = 0;
3537 lastIndex = test.length - 3;
3538 for (var tIndex = 0; tIndex < test.length; tIndex += 3) {
3539 var recType = test[tIndex];
3540 if (!typeof recType == 'number' || recType < REC_TYPE_UNKNOWN || recType > REC_TYPE_LAST) {
3541 console.log("unknown rec type: " + recType);
3542 throw "stop execution";
3543 }
3544 // if (curType == recType && curType != REC_TYPE_ADD) {
3545 // continue;
3546 // }
3547 var inStepRange = step_limit == 0 || curStep < step_limit;
3548 curType = recType;
3549 if (recType == REC_TYPE_OP) {
3550 hasOp = true;
3551 continue;
3552 }
3553 if (recType == REC_TYPE_UNKNOWN) {
3554 // these types do not advance step
3555 continue;
3556 }
3557 var bumpStep = false;
3558 var records = test[tIndex + 2];
3559 var fragType = records[0];
3560 if (recType == REC_TYPE_ADD) {
3561 if (records.length != 2) {
3562 console.log("expect only two elements: " + records.length);
3563 throw "stop execution";
3564 }
3565 if (fragType == ADD_MOVETO || fragType == ADD_CLOSE) {
3566 continue;
3567 }
3568 ++addMax;
3569 if (!draw_add || !inStepRange) {
3570 continue;
3571 }
3572 lastAdd = tIndex;
3573 ++addCount;
3574 bumpStep = true;
3575 }
3576 if (recType == REC_TYPE_PATH && hasOp) {
3577 secondPath = tIndex;
3578 }
caryclark54359292015-03-26 07:52:43 -07003579 if (recType == REC_TYPE_PATH2 && hasOp) {
3580 secondPath = tIndex;
3581 }
caryclarkdac1d172014-06-17 05:15:38 -07003582 if (recType == REC_TYPE_ACTIVE) {
3583 ++activeMax;
3584 if (!draw_active || !inStepRange) {
3585 continue;
3586 }
3587 lastActive = tIndex;
3588 ++activeCount;
3589 bumpStep = true;
3590 }
3591 if (recType == REC_TYPE_ACTIVE_OP) {
3592 ++opMax;
3593 if (!draw_op || !inStepRange) {
3594 continue;
3595 }
3596 lastOp = tIndex;
3597 ++opCount;
3598 bumpStep = true;
3599 }
caryclark54359292015-03-26 07:52:43 -07003600 if (recType == REC_TYPE_AFTERPART) {
3601 if (draw_angle != 3 || !inStepRange) {
3602 continue;
3603 }
3604 lastAngle = tIndex;
3605 ++angleCount;
3606 bumpStep = true;
3607 }
caryclarkdac1d172014-06-17 05:15:38 -07003608 if (recType == REC_TYPE_ANGLE) {
3609 ++angleMax;
caryclark54359292015-03-26 07:52:43 -07003610 if (draw_angle == 0 || draw_angle == 3 || !inStepRange) {
caryclarkdac1d172014-06-17 05:15:38 -07003611 continue;
3612 }
3613 lastAngle = tIndex;
3614 ++angleCount;
3615 bumpStep = true;
3616 }
caryclark624637c2015-05-11 07:21:27 -07003617 if (recType == REC_TYPE_COINCIDENCE) {
3618 ++coinMax;
3619 if (!draw_coincidence || !inStepRange) {
3620 continue;
3621 }
3622 lastCoin = tIndex;
3623 ++coinCount;
3624 bumpStep = true;
3625 }
caryclarkdac1d172014-06-17 05:15:38 -07003626 if (recType == REC_TYPE_SECT) {
3627 if (records.length != 2) {
3628 console.log("expect only two elements: " + records.length);
3629 throw "stop execution";
3630 }
3631 ++sectMax;
3632 var sectBump = 1;
3633 switch (fragType) {
3634 case INTERSECT_LINE:
3635 case INTERSECT_QUAD_LINE:
3636 case INTERSECT_QUAD:
caryclark1049f122015-04-20 08:31:59 -07003637 case INTERSECT_CONIC_LINE:
caryclark55888e42016-07-18 10:01:36 -07003638 case INTERSECT_CONIC_QUAD:
caryclark1049f122015-04-20 08:31:59 -07003639 case INTERSECT_CONIC:
caryclarkdac1d172014-06-17 05:15:38 -07003640 case INTERSECT_SELF_CUBIC:
3641 case INTERSECT_CUBIC_LINE:
3642 case INTERSECT_CUBIC_QUAD:
3643 case INTERSECT_CUBIC:
3644 sectBump = 1;
3645 break;
3646 case INTERSECT_LINE_2:
3647 case INTERSECT_QUAD_LINE_2:
3648 case INTERSECT_QUAD_2:
caryclark1049f122015-04-20 08:31:59 -07003649 case INTERSECT_CONIC_LINE_2:
caryclark55888e42016-07-18 10:01:36 -07003650 case INTERSECT_CONIC_QUAD_2:
caryclark1049f122015-04-20 08:31:59 -07003651 case INTERSECT_CONIC_2:
caryclarkdac1d172014-06-17 05:15:38 -07003652 case INTERSECT_CUBIC_LINE_2:
3653 case INTERSECT_CUBIC_QUAD_2:
3654 case INTERSECT_CUBIC_2:
3655 sectBump = 2;
3656 break;
3657 case INTERSECT_LINE_NO:
3658 case INTERSECT_QUAD_LINE_NO:
3659 case INTERSECT_QUAD_NO:
caryclark1049f122015-04-20 08:31:59 -07003660 case INTERSECT_CONIC_LINE_NO:
caryclark55888e42016-07-18 10:01:36 -07003661 case INTERSECT_CONIC_QUAD_NO:
caryclark1049f122015-04-20 08:31:59 -07003662 case INTERSECT_CONIC_NO:
caryclarkdac1d172014-06-17 05:15:38 -07003663 case INTERSECT_SELF_CUBIC_NO:
3664 case INTERSECT_CUBIC_LINE_NO:
3665 case INTERSECT_CUBIC_QUAD_NO:
3666 case INTERSECT_CUBIC_NO:
3667 sectBump = 0;
3668 break;
caryclark6c3b9cd2016-09-26 05:36:58 -07003669 case INTERSECT_CONIC_QUAD_3:
caryclarkdac1d172014-06-17 05:15:38 -07003670 case INTERSECT_CUBIC_LINE_3:
3671 case INTERSECT_CUBIC_QUAD_3:
3672 case INTERSECT_CUBIC_3:
3673 sectBump = 3;
3674 break;
caryclark6c3b9cd2016-09-26 05:36:58 -07003675 case INTERSECT_CONIC_QUAD_4:
caryclarkdac1d172014-06-17 05:15:38 -07003676 case INTERSECT_CUBIC_QUAD_4:
3677 case INTERSECT_CUBIC_4:
3678 sectBump = 4;
3679 break;
3680 default:
3681 console.log("missing case " + records.length);
3682 throw "stop execution";
3683 }
3684 sectMax2 += sectBump;
3685 if (draw_intersection <= 1 || !inStepRange) {
3686 continue;
3687 }
3688 lastSect = tIndex;
3689 sectCount += sectBump;
3690 bumpStep = true;
3691 }
3692 if (recType == REC_TYPE_SORT) {
3693 ++sortMax;
3694 if (!draw_sort || !inStepRange) {
3695 continue;
3696 }
3697 lastSort = tIndex;
3698 ++sortCount;
3699 bumpStep = true;
3700 }
caryclark03b03ca2015-04-23 09:13:37 -07003701 if (recType == REC_TYPE_TOP) {
3702 ++topMax;
3703 if (!draw_top || !inStepRange) {
3704 continue;
3705 }
3706 lastTop = tIndex;
3707 ++topCount;
3708 bumpStep = true;
3709 }
caryclarkdac1d172014-06-17 05:15:38 -07003710 if (recType == REC_TYPE_MARK) {
3711 ++markMax;
3712 if (!draw_mark || !inStepRange) {
3713 continue;
3714 }
3715 lastMark = tIndex;
3716 ++markCount;
3717 bumpStep = true;
3718 }
3719 if (bumpStep) {
3720 lastIndex = tIndex;
3721 logStart = test[tIndex + 1];
3722 logRange = records.length / 2;
3723 ++curStep;
3724 }
3725 }
3726 stepMax = (draw_add ? addMax : 0)
3727 + (draw_active ? activeMax : 0)
reed0dc4dd62015-03-24 13:55:33 -07003728 + (draw_angle ? angleMax : 0)
caryclark624637c2015-05-11 07:21:27 -07003729 + (draw_coincidence ? coinMax : 0)
caryclark54359292015-03-26 07:52:43 -07003730 + (draw_op ? opMax : 0)
caryclarkdac1d172014-06-17 05:15:38 -07003731 + (draw_sort ? sortMax : 0)
caryclark03b03ca2015-04-23 09:13:37 -07003732 + (draw_top ? topMax : 0)
caryclarkdac1d172014-06-17 05:15:38 -07003733 + (draw_mark ? markMax : 0)
3734 + (draw_intersection == 2 ? sectMax : draw_intersection == 3 ? sectMax2 : 0);
3735 if (stepMax == 0) {
caryclark624637c2015-05-11 07:21:27 -07003736 stepMax = addMax + activeMax + angleMax + coinMax + opMax + sortMax + topMax + markMax;
caryclarkdac1d172014-06-17 05:15:38 -07003737 }
3738 drawnPts = [];
3739 drawnLines = [];
3740 drawnQuads = [];
caryclark1049f122015-04-20 08:31:59 -07003741 drawnConics = [];
caryclarkdac1d172014-06-17 05:15:38 -07003742 drawnCubics = [];
3743 focusXmin = focusYmin = Infinity;
3744 focusXmax = focusYmax = -Infinity;
3745 var pathIndex = 0;
3746 var opLetter = 'S';
3747 for (var tIndex = lastIndex; tIndex >= 0; tIndex -= 3) {
3748 var recType = test[tIndex];
3749 var records = test[tIndex + 2];
3750 for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
3751 var fragType = records[recordIndex];
3752 if (!typeof fragType == 'number' || fragType < 1 || fragType > FRAG_TYPE_LAST) {
3753 console.log("unknown in range frag type: " + fragType);
3754 throw "stop execution";
3755 }
3756 var frags = records[recordIndex + 1];
3757 focus_enabled = false;
3758 switch (recType) {
3759 case REC_TYPE_COMPUTED:
3760 if (draw_computed == 0) {
3761 continue;
3762 }
3763 ctx.lineWidth = 1;
3764 ctx.strokeStyle = pathIndex == 0 ? "black" : "red";
3765 ctx.fillStyle = "blue";
3766 var drawThis = false;
3767 switch (fragType) {
3768 case PATH_QUAD:
caryclark1049f122015-04-20 08:31:59 -07003769 if ((draw_computed & 0x9) == 1 || ((draw_computed & 8) != 0
3770 && (draw_computed & 7) == pathIndex)) {
caryclarkdac1d172014-06-17 05:15:38 -07003771 drawQuad(frags[0], frags[1], frags[2], frags[3],
3772 frags[4], frags[5]);
3773 drawThis = true;
3774 }
3775 break;
caryclark1049f122015-04-20 08:31:59 -07003776 case PATH_CONIC:
3777 if ((draw_computed & 0xA) == 2 || ((draw_computed & 8) != 0
3778 && (draw_computed & 7) == pathIndex)) {
3779 drawConicWithQuads(frags[0], frags[1], frags[2], frags[3],
3780 frags[4], frags[5], frags[6]);
3781 drawThis = true;
3782 }
3783 break;
caryclarkdac1d172014-06-17 05:15:38 -07003784 case PATH_CUBIC:
caryclark1049f122015-04-20 08:31:59 -07003785 if ((draw_computed & 0xC) == 4 || ((draw_computed & 8) != 0
3786 && (draw_computed & 7) == pathIndex)) {
caryclarkdac1d172014-06-17 05:15:38 -07003787 drawCubic(frags[0], frags[1], frags[2], frags[3],
3788 frags[4], frags[5], frags[6], frags[7]);
3789 drawThis = true;
3790 }
3791 ++pathIndex;
3792 break;
3793 case COMPUTED_SET_1:
3794 pathIndex = 0;
3795 break;
3796 case COMPUTED_SET_2:
3797 pathIndex = 1;
3798 break;
3799 default:
3800 console.log("unknown REC_TYPE_COMPUTED frag type: " + fragType);
3801 throw "stop execution";
3802 }
3803 if (!drawThis || collect_bounds) {
3804 break;
3805 }
3806 drawCurveSpecials(test, frags, fragType);
3807 break;
caryclark26ad22a2015-10-16 09:03:38 -07003808 case REC_TYPE_ALIGNED:
3809 if (draw_path < 4) {
3810 continue;
3811 }
caryclarkdac1d172014-06-17 05:15:38 -07003812 case REC_TYPE_PATH:
caryclark54359292015-03-26 07:52:43 -07003813 case REC_TYPE_PATH2:
caryclark26ad22a2015-10-16 09:03:38 -07003814 if (REC_TYPE_ALIGNED != recType && draw_path >= 4) {
3815 continue;
3816 }
caryclarkdac1d172014-06-17 05:15:38 -07003817 if (!draw_path) {
3818 continue;
3819 }
3820 var firstPath = tIndex < secondPath;
3821 if ((draw_path & (firstPath ? 1 : 2)) == 0) {
3822 continue;
3823 }
3824 ctx.lineWidth = 1;
3825 ctx.strokeStyle = firstPath ? "black" : "red";
3826 ctx.fillStyle = "blue";
caryclark55888e42016-07-18 10:01:36 -07003827 var frags2 = [];
caryclarkdac1d172014-06-17 05:15:38 -07003828 switch (fragType) {
3829 case PATH_LINE:
caryclark54359292015-03-26 07:52:43 -07003830 for (var i = 0; i < 4; ++ i) { frags2[i] = frags[i + 1]; }
3831 drawLine(frags2[0], frags2[1], frags2[2], frags2[3]);
caryclarkdac1d172014-06-17 05:15:38 -07003832 break;
3833 case PATH_QUAD:
caryclark54359292015-03-26 07:52:43 -07003834 for (var i = 0; i < 6; ++ i) { frags2[i] = frags[i + 1]; }
3835 drawQuad(frags2[0], frags2[1], frags2[2], frags2[3],
3836 frags2[4], frags2[5]);
caryclarkdac1d172014-06-17 05:15:38 -07003837 break;
caryclark1049f122015-04-20 08:31:59 -07003838 case PATH_CONIC:
3839 for (var i = 0; i < 7; ++ i) { frags2[i] = frags[i + 1]; }
3840 drawConicWithQuads(frags2[0], frags2[1], frags2[2], frags2[3],
3841 frags2[4], frags2[5], frags2[6]);
3842 break;
caryclarkdac1d172014-06-17 05:15:38 -07003843 case PATH_CUBIC:
caryclark54359292015-03-26 07:52:43 -07003844 for (var i = 0; i < 8; ++ i) { frags2[i] = frags[i + 1]; }
3845 drawCubic(frags2[0], frags2[1], frags2[2], frags2[3],
3846 frags2[4], frags2[5], frags2[6], frags2[7]);
caryclarkdac1d172014-06-17 05:15:38 -07003847 break;
3848 default:
caryclark26ad22a2015-10-16 09:03:38 -07003849 console.log("unknown " + recType + " frag type: " + fragType);
caryclarkdac1d172014-06-17 05:15:38 -07003850 throw "stop execution";
3851 }
3852 if (collect_bounds) {
3853 break;
3854 }
caryclark54359292015-03-26 07:52:43 -07003855 drawCurveSpecials(test, frags2, fragType);
caryclarkdac1d172014-06-17 05:15:38 -07003856 break;
3857 case REC_TYPE_OP:
3858 switch (fragType) {
3859 case OP_INTERSECT: opLetter = 'I'; break;
3860 case OP_DIFFERENCE: opLetter = 'D'; break;
3861 case OP_UNION: opLetter = 'U'; break;
3862 case OP_XOR: opLetter = 'X'; break;
3863 default:
3864 console.log("unknown REC_TYPE_OP frag type: " + fragType);
3865 throw "stop execution";
3866 }
3867 break;
3868 case REC_TYPE_ACTIVE:
3869 if (!draw_active || (step_limit > 0 && tIndex < lastActive)) {
3870 continue;
3871 }
3872 var x1 = frags[SPAN_X1];
3873 var y1 = frags[SPAN_Y1];
3874 var x2 = frags[SPAN_X2];
3875 var y2 = frags[SPAN_Y2];
caryclark55888e42016-07-18 10:01:36 -07003876 var x3, y3, x3, y4, w;
caryclarkdac1d172014-06-17 05:15:38 -07003877 ctx.lineWidth = 3;
3878 ctx.strokeStyle = "rgba(0,0,255, 0.3)";
3879 focus_enabled = true;
3880 switch (fragType) {
3881 case ACTIVE_LINE_SPAN:
caryclark55888e42016-07-18 10:01:36 -07003882 drawLine(x1, y1, x2, y2);
caryclarkdac1d172014-06-17 05:15:38 -07003883 if (draw_id) {
caryclark55888e42016-07-18 10:01:36 -07003884 drawLineID(frags[0], x1, y1, x2, y2);
3885 }
3886 if (pt_labels) {
3887 var curve = [x1, y1, x2, y2];
3888 ctx.fillStyle = "blue";
3889 drawPoints(curve, PATH_LINE, pt_labels == 2);
caryclarkdac1d172014-06-17 05:15:38 -07003890 }
3891 break;
3892 case ACTIVE_QUAD_SPAN:
3893 x3 = frags[SPAN_X3];
3894 y3 = frags[SPAN_Y3];
caryclark55888e42016-07-18 10:01:36 -07003895 drawQuad(x1, y1, x2, y2, x3, y3);
caryclarkdac1d172014-06-17 05:15:38 -07003896 if (draw_id) {
caryclark55888e42016-07-18 10:01:36 -07003897 drawQuadID(frags[0], x1, y1, x2, y2, x3, y3);
3898 }
3899 if (pt_labels) {
3900 var curve = [x1, y1, x2, y2, x3, y3];
3901 ctx.fillStyle = "blue";
3902 drawPoints(curve, PATH_QUAD, pt_labels == 2);
caryclarkdac1d172014-06-17 05:15:38 -07003903 }
3904 break;
caryclark1049f122015-04-20 08:31:59 -07003905 case ACTIVE_CONIC_SPAN:
3906 x3 = frags[SPAN_X3];
3907 y3 = frags[SPAN_Y3];
caryclark1049f122015-04-20 08:31:59 -07003908 w = frags[SPAN_K_W];
caryclark55888e42016-07-18 10:01:36 -07003909 drawConicWithQuads(x1, y1, x2, y2, x3, y3, w);
caryclark1049f122015-04-20 08:31:59 -07003910 if (draw_id) {
caryclark55888e42016-07-18 10:01:36 -07003911 drawConicID(frags[0], x1, y1, x2, y2, x3, y3, w);
3912 }
3913 if (pt_labels) {
3914 var curve = [x1, y1, x2, y2, x3, y3, w];
3915 ctx.fillStyle = "blue";
3916 drawPoints(curve, PATH_CONIC, pt_labels == 2);
caryclark1049f122015-04-20 08:31:59 -07003917 }
3918 break;
caryclarkdac1d172014-06-17 05:15:38 -07003919 case ACTIVE_CUBIC_SPAN:
3920 x3 = frags[SPAN_X3];
3921 y3 = frags[SPAN_Y3];
3922 x4 = frags[SPAN_X4];
3923 y4 = frags[SPAN_Y4];
caryclark55888e42016-07-18 10:01:36 -07003924 drawCubic(x1, y1, x2, y2, x3, y3, x4, y4);
caryclarkdac1d172014-06-17 05:15:38 -07003925 if (draw_id) {
caryclark55888e42016-07-18 10:01:36 -07003926 drawCubicID(frags[0], x1, y1, x2, y2, x3, y3, x4, y4);
3927 }
3928 if (pt_labels) {
3929 var curve = [x1, y1, x2, y2, x3, y3, x4, y4];
3930 ctx.fillStyle = "blue";
3931 drawPoints(curve, PATH_CUBIC, pt_labels == 2);
caryclarkdac1d172014-06-17 05:15:38 -07003932 }
3933 break;
3934 default:
3935 console.log("unknown REC_TYPE_ACTIVE frag type: " + fragType);
3936 throw "stop execution";
3937 }
3938 break;
3939 case REC_TYPE_ACTIVE_OP:
3940 if (!draw_op || (step_limit > 0 && tIndex < lastOp)) {
3941 continue;
3942 }
3943 focus_enabled = true;
3944 ctx.lineWidth = 3;
3945 var activeSpan = frags[7] == "1";
3946 ctx.strokeStyle = activeSpan ? "rgba(45,160,0, 0.3)" : "rgba(255,45,0, 0.5)";
3947 var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
3948 drawCurve(curve);
3949 if (draw_op > 1) {
3950 drawArc(curve, false, frags[3], frags[4]);
3951 drawArc(curve, true, frags[5], frags[6]);
3952 }
3953 break;
3954 case REC_TYPE_ADD:
3955 if (!draw_add) {
3956 continue;
3957 }
3958 ctx.lineWidth = 3;
3959 ctx.strokeStyle = closeCount == 0 ? "rgba(0,0,255, 0.3)"
3960 : closeCount == 1 ? "rgba(0,127,0, 0.3)"
3961 : closeCount == 2 ? "rgba(0,127,127, 0.3)"
3962 : closeCount == 3 ? "rgba(127,127,0, 0.3)"
3963 : "rgba(127,0,127, 0.3)";
3964 focus_enabled = true;
3965 switch (fragType) {
3966 case ADD_MOVETO:
3967 break;
3968 case ADD_LINETO:
3969 if (step_limit == 0 || tIndex >= lastAdd) {
3970 drawLine(frags[0], frags[1], frags[2], frags[3]);
3971 }
3972 break;
3973 case ADD_QUADTO:
3974 if (step_limit == 0 || tIndex >= lastAdd) {
3975 drawQuad(frags[0], frags[1], frags[2], frags[3], frags[4], frags[5]);
3976 }
3977 break;
caryclark1049f122015-04-20 08:31:59 -07003978 case ADD_CONICTO:
3979 if (step_limit == 0 || tIndex >= lastAdd) {
3980 drawConicWithQuads(frags[0], frags[1], frags[2], frags[3],
3981 frags[4], frags[5], frags[6]);
3982 }
3983 break;
caryclarkdac1d172014-06-17 05:15:38 -07003984 case ADD_CUBICTO:
3985 if (step_limit == 0 || tIndex >= lastAdd) {
3986 drawCubic(frags[0], frags[1], frags[2], frags[3],
3987 frags[4], frags[5], frags[6], frags[7]);
3988 }
3989 break;
3990 case ADD_CLOSE:
3991 ++closeCount;
3992 break;
3993 case ADD_FILL:
3994 break;
3995 default:
3996 console.log("unknown REC_TYPE_ADD frag type: " + fragType);
3997 throw "stop execution";
3998 }
3999 break;
4000 case REC_TYPE_ANGLE:
caryclark54359292015-03-26 07:52:43 -07004001 angleBetween = frags[18] == "T";
4002 afterIndex = 0;
4003 if (draw_angle == 0 || draw_angle == 3 || (step_limit > 0 && tIndex < lastAngle)) {
caryclarkdac1d172014-06-17 05:15:38 -07004004 continue;
4005 }
4006 focus_enabled = true;
4007 ctx.lineWidth = 3;
4008 ctx.strokeStyle = "rgba(127,45,127, 0.3)";
caryclark54359292015-03-26 07:52:43 -07004009 var leftCurve = curvePartialByID(test, frags[0], frags[4], frags[5]);
4010 var midCurve = curvePartialByID(test, frags[6], frags[10], frags[11]);
4011 var rightCurve = curvePartialByID(test, frags[12], frags[16], frags[17]);
caryclarkdac1d172014-06-17 05:15:38 -07004012 drawCurve(leftCurve);
4013 drawCurve(rightCurve);
caryclark54359292015-03-26 07:52:43 -07004014 ctx.strokeStyle = angleBetween ? "rgba(0,160,45, 0.3)" : "rgba(255,0,45, 0.5)";
caryclarkdac1d172014-06-17 05:15:38 -07004015 drawCurve(midCurve);
4016 if (draw_angle > 1) {
Cary Clarkff114282016-12-14 11:56:16 -05004017 drawVisibleOrder(leftCurve, 'L');
4018 drawVisibleOrder(rightCurve, 'R');
4019 }
Ben Wagner29380bd2017-10-09 14:43:00 -04004020 if (draw_id) {
4021 drawVisibleID(leftCurve, 0.5, frags[0]);
4022 drawVisibleID(midCurve, 0.5, frags[6]);
4023 drawVisibleID(rightCurve, 0.5, frags[12]);
caryclarkdac1d172014-06-17 05:15:38 -07004024 }
4025 break;
caryclark54359292015-03-26 07:52:43 -07004026 case REC_TYPE_AFTERPART:
4027 if (draw_angle != 3 || (step_limit > 0 && tIndex < lastAngle)) {
4028 continue;
4029 }
4030 ctx.strokeStyle = afterIndex == 0 ? "rgba(255,0,0, 1.0)"
4031 : (afterIndex == 1) == angleBetween ? "rgba(0,128,0, 1.0)"
Cary Clarkff114282016-12-14 11:56:16 -05004032 : "rgba(0,0,255, 1.0)";
4033 var curve;
4034 var id;
caryclark54359292015-03-26 07:52:43 -07004035 switch (fragType) {
4036 case PATH_LINE:
Cary Clarkff114282016-12-14 11:56:16 -05004037 curve = [ frags[0], frags[1], frags[2], frags[3] ];
4038 id = frags[4];
caryclark54359292015-03-26 07:52:43 -07004039 break;
4040 case PATH_QUAD:
Cary Clarkff114282016-12-14 11:56:16 -05004041 curve = [ frags[0], frags[1], frags[2], frags[3],
4042 frags[4], frags[5] ];
4043 id = frags[6];
caryclark54359292015-03-26 07:52:43 -07004044 break;
caryclark1049f122015-04-20 08:31:59 -07004045 case PATH_CONIC:
Cary Clarkff114282016-12-14 11:56:16 -05004046 curve = [ frags[0], frags[1], frags[2], frags[3],
4047 frags[4], frags[5], frags[6] ];
4048 id = frags[7];
caryclark1049f122015-04-20 08:31:59 -07004049 break;
caryclark54359292015-03-26 07:52:43 -07004050 case PATH_CUBIC:
Cary Clarkff114282016-12-14 11:56:16 -05004051 curve = [ frags[0], frags[1], frags[2], frags[3],
4052 frags[4], frags[5], frags[6], frags[7] ];
4053 id = frags[8];
caryclark54359292015-03-26 07:52:43 -07004054 break;
4055 default:
4056 console.log("unknown REC_TYPE_AFTERPART frag type: " + fragType);
4057 throw "stop execution";
4058 }
Cary Clarkff114282016-12-14 11:56:16 -05004059 drawCurve(curve);
Ben Wagner29380bd2017-10-09 14:43:00 -04004060 if (draw_id) {
4061 drawVisibleID(curve, 0.5, id);
Cary Clarkff114282016-12-14 11:56:16 -05004062 }
caryclark54359292015-03-26 07:52:43 -07004063 ++afterIndex;
4064 break;
caryclark624637c2015-05-11 07:21:27 -07004065 case REC_TYPE_COINCIDENCE:
4066 if (!draw_coincidence || (step_limit > 0 && tIndex < lastCoin)) {
4067 continue;
4068 }
4069 focus_enabled = true;
4070 ctx.lineWidth = 3;
4071 ctx.strokeStyle = "rgba(127,45,63, 0.3)";
4072 var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
4073 drawCurve(curve);
4074 break;
caryclarkdac1d172014-06-17 05:15:38 -07004075 case REC_TYPE_SECT:
4076 if (!draw_intersection) {
4077 continue;
4078 }
4079 if (draw_intersection != 1 && (step_limit > 0 && tIndex < lastSect)) {
4080 continue;
4081 }
4082 // draw_intersection == 1 : show all
4083 // draw_intersection == 2 : step == 0 ? show all : show intersection line #step
4084 // draw_intersection == 3 : step == 0 ? show all : show intersection #step
4085 ctx.lineWidth = 1;
4086 ctx.strokeStyle = "rgba(0,0,255, 0.3)";
4087 ctx.fillStyle = "blue";
4088 focus_enabled = true;
4089 var f = [];
4090 var c1s;
4091 var c1l;
4092 var c2s;
4093 var c2l;
4094 switch (fragType) {
4095 case INTERSECT_LINE:
4096 f.push(5, 6, 0, 7);
4097 c1s = 1; c1l = 4; c2s = 8; c2l = 4;
4098 break;
4099 case INTERSECT_LINE_2:
4100 f.push(5, 6, 0, 10);
4101 f.push(8, 9, 7, 15);
4102 c1s = 1; c1l = 4; c2s = 11; c2l = 4;
4103 break;
4104 case INTERSECT_LINE_NO:
4105 c1s = 0; c1l = 4; c2s = 4; c2l = 4;
4106 break;
4107 case INTERSECT_QUAD_LINE:
4108 f.push(7, 8, 0, 9);
4109 c1s = 1; c1l = 6; c2s = 10; c2l = 4;
4110 break;
4111 case INTERSECT_QUAD_LINE_2:
4112 f.push(7, 8, 0, 12);
4113 f.push(10, 11, 9, 17);
4114 c1s = 1; c1l = 6; c2s = 13; c2l = 4;
4115 break;
4116 case INTERSECT_QUAD_LINE_NO:
4117 c1s = 0; c1l = 6; c2s = 6; c2l = 4;
4118 break;
4119 case INTERSECT_QUAD:
4120 f.push(7, 8, 0, 9);
4121 c1s = 1; c1l = 6; c2s = 10; c2l = 6;
4122 break;
4123 case INTERSECT_QUAD_2:
4124 f.push(7, 8, 0, 12);
4125 f.push(10, 11, 9, 19);
4126 c1s = 1; c1l = 6; c2s = 13; c2l = 6;
4127 break;
4128 case INTERSECT_QUAD_NO:
4129 c1s = 0; c1l = 6; c2s = 6; c2l = 6;
4130 break;
caryclark1049f122015-04-20 08:31:59 -07004131 case INTERSECT_CONIC_LINE:
4132 f.push(8, 9, 0, 10);
4133 c1s = 1; c1l = 7; c2s = 11; c2l = 4;
4134 break;
4135 case INTERSECT_CONIC_LINE_2:
4136 f.push(8, 9, 0, 12);
4137 f.push(11, 12, 10, 18);
4138 c1s = 1; c1l = 7; c2s = 14; c2l = 4;
4139 break;
4140 case INTERSECT_CONIC_LINE_NO:
4141 c1s = 0; c1l = 7; c2s = 7; c2l = 4;
4142 break;
caryclark55888e42016-07-18 10:01:36 -07004143 case INTERSECT_CONIC_QUAD:
4144 f.push(8, 9, 0, 10);
4145 c1s = 1; c1l = 7; c2s = 11; c2l = 6;
4146 break;
4147 case INTERSECT_CONIC_QUAD_2:
4148 f.push(8, 9, 0, 12);
4149 f.push(11, 12, 10, 18);
4150 c1s = 1; c1l = 7; c2s = 14; c2l = 6;
4151 break;
caryclark6c3b9cd2016-09-26 05:36:58 -07004152 case INTERSECT_CONIC_QUAD_3:
4153 f.push(8, 9, 0, 15);
4154 f.push(11, 12, 10, 21);
4155 f.push(14, 15, 13, 22);
4156 c1s = 1; c1l = 7; c2s = 17; c2l = 6;
4157 break;
4158 case INTERSECT_CONIC_QUAD_4:
4159 f.push(8, 9, 0, 18);
4160 f.push(11, 12, 10, 24);
4161 f.push(14, 15, 13, 25);
4162 f.push(17, 18, 16, 26);
4163 c1s = 1; c1l = 7; c2s = 20; c2l = 6;
4164 break;
caryclark55888e42016-07-18 10:01:36 -07004165 case INTERSECT_CONIC_QUAD_NO:
4166 c1s = 0; c1l = 7; c2s = 7; c2l = 6;
4167 break;
caryclark1049f122015-04-20 08:31:59 -07004168 case INTERSECT_CONIC:
4169 f.push(8, 9, 0, 10);
4170 c1s = 1; c1l = 7; c2s = 11; c2l = 7;
4171 break;
4172 case INTERSECT_CONIC_2:
4173 f.push(8, 9, 0, 13);
4174 f.push(11, 12, 10, 21);
4175 c1s = 1; c1l = 7; c2s = 14; c2l = 7;
4176 break;
4177 case INTERSECT_CONIC_NO:
4178 c1s = 0; c1l = 7; c2s = 7; c2l = 7;
4179 break;
caryclarkdac1d172014-06-17 05:15:38 -07004180 case INTERSECT_SELF_CUBIC:
4181 f.push(9, 10, 0, 11);
4182 c1s = 1; c1l = 8; c2s = 0; c2l = 0;
4183 break;
4184 case INTERSECT_SELF_CUBIC_NO:
4185 c1s = 0; c1l = 8; c2s = 0; c2l = 0;
4186 break;
4187 case INTERSECT_CUBIC_LINE:
4188 f.push(9, 10, 0, 11);
4189 c1s = 1; c1l = 8; c2s = 12; c2l = 4;
4190 break;
4191 case INTERSECT_CUBIC_LINE_2:
4192 f.push(9, 10, 0, 14);
4193 f.push(12, 13, 11, 19);
4194 c1s = 1; c1l = 8; c2s = 15; c2l = 4;
4195 break;
4196 case INTERSECT_CUBIC_LINE_3:
4197 f.push(9, 10, 0, 17);
4198 f.push(12, 13, 11, 22);
4199 f.push(15, 16, 14, 23);
4200 c1s = 1; c1l = 8; c2s = 18; c2l = 4;
4201 break;
4202 case INTERSECT_CUBIC_QUAD_NO:
4203 c1s = 0; c1l = 8; c2s = 8; c2l = 6;
4204 break;
4205 case INTERSECT_CUBIC_QUAD:
4206 f.push(9, 10, 0, 11);
4207 c1s = 1; c1l = 8; c2s = 12; c2l = 6;
4208 break;
4209 case INTERSECT_CUBIC_QUAD_2:
4210 f.push(9, 10, 0, 14);
4211 f.push(12, 13, 11, 21);
4212 c1s = 1; c1l = 8; c2s = 15; c2l = 6;
4213 break;
4214 case INTERSECT_CUBIC_QUAD_3:
4215 f.push(9, 10, 0, 17);
4216 f.push(12, 13, 11, 24);
4217 f.push(15, 16, 14, 25);
4218 c1s = 1; c1l = 8; c2s = 18; c2l = 6;
4219 break;
4220 case INTERSECT_CUBIC_QUAD_4:
4221 f.push(9, 10, 0, 20);
4222 f.push(12, 13, 11, 27);
4223 f.push(15, 16, 14, 28);
4224 f.push(18, 19, 17, 29);
4225 c1s = 1; c1l = 8; c2s = 21; c2l = 6;
4226 break;
4227 case INTERSECT_CUBIC_LINE_NO:
4228 c1s = 0; c1l = 8; c2s = 8; c2l = 4;
4229 break;
4230 case INTERSECT_CUBIC:
4231 f.push(9, 10, 0, 11);
4232 c1s = 1; c1l = 8; c2s = 12; c2l = 8;
4233 break;
4234 case INTERSECT_CUBIC_2:
4235 f.push(9, 10, 0, 14);
4236 f.push(12, 13, 11, 23);
4237 c1s = 1; c1l = 8; c2s = 15; c2l = 8;
4238 break;
4239 case INTERSECT_CUBIC_3:
4240 f.push(9, 10, 0, 17);
4241 f.push(12, 13, 11, 26);
4242 f.push(15, 16, 14, 27);
4243 c1s = 1; c1l = 8; c2s = 18; c2l = 8;
4244 break;
4245 case INTERSECT_CUBIC_4:
4246 f.push(9, 10, 0, 20);
4247 f.push(12, 13, 11, 29);
4248 f.push(15, 16, 14, 30);
4249 f.push(18, 19, 17, 31);
4250 c1s = 1; c1l = 8; c2s = 21; c2l = 8;
4251 break;
4252 case INTERSECT_CUBIC_NO:
4253 c1s = 0; c1l = 8; c2s = 8; c2l = 8;
4254 break;
4255 default:
4256 console.log("unknown REC_TYPE_SECT frag type: " + fragType);
4257 throw "stop execution";
4258 }
4259 if (draw_intersection != 1) {
4260 var id = -1;
4261 var curve;
4262 switch (c1l) {
caryclark55888e42016-07-18 10:01:36 -07004263 case 4:
caryclarkdac1d172014-06-17 05:15:38 -07004264 drawLine(frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3]);
4265 if (draw_id) {
4266 curve = [frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3]];
4267 id = idByCurve(test, curve, PATH_LINE);
4268 }
4269 break;
4270 case 6:
4271 drawQuad(frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
4272 frags[c1s + 4], frags[c1s + 5]);
4273 if (draw_id) {
4274 curve = [frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
4275 frags[c1s + 4], frags[c1s + 5]];
4276 id = idByCurve(test, curve, PATH_QUAD);
4277 }
4278 break;
caryclark1049f122015-04-20 08:31:59 -07004279 case 7:
4280 drawConicWithQuads(frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
4281 frags[c1s + 4], frags[c1s + 5], frags[c1s + 6]);
4282 if (draw_id) {
4283 curve = [frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
4284 frags[c1s + 4], frags[c1s + 5], frags[c1s + 6]];
4285 id = idByCurve(test, curve, PATH_CONIC);
4286 }
4287 break;
caryclarkdac1d172014-06-17 05:15:38 -07004288 case 8:
4289 drawCubic(frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
4290 frags[c1s + 4], frags[c1s + 5], frags[c1s + 6], frags[c1s + 7]);
4291 if (draw_id) {
4292 curve = [frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
4293 frags[c1s + 4], frags[c1s + 5], frags[c1s + 6], frags[c1s + 7]];
4294 id = idByCurve(test, curve, PATH_CUBIC);
4295 }
4296 break;
4297 }
4298 if (id >= 0) {
Cary Clarkff114282016-12-14 11:56:16 -05004299 drawVisibleID(curve, 0.5, id);
caryclarkdac1d172014-06-17 05:15:38 -07004300 }
4301 id = -1;
4302 switch (c2l) {
4303 case 0:
4304 break;
caryclark55888e42016-07-18 10:01:36 -07004305 case 4:
caryclarkdac1d172014-06-17 05:15:38 -07004306 drawLine(frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3]);
4307 if (draw_id) {
4308 curve = [frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3]];
4309 id = idByCurve(test, curve, PATH_LINE);
4310 }
4311 break;
4312 case 6:
4313 drawQuad(frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
4314 frags[c2s + 4], frags[c2s + 5]);
4315 if (draw_id) {
4316 curve = [frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
4317 frags[c2s + 4], frags[c2s + 5]];
4318 id = idByCurve(test, curve, PATH_QUAD);
4319 }
4320 break;
caryclark1049f122015-04-20 08:31:59 -07004321 case 7:
4322 drawConicWithQuads(frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
4323 frags[c2s + 4], frags[c2s + 5], frags[c2s + 6]);
4324 if (draw_id) {
4325 curve = [frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
4326 frags[c2s + 4], frags[c2s + 5], frags[c2s + 6]];
4327 id = idByCurve(test, curve, PATH_CONIC);
4328 }
4329 break;
caryclarkdac1d172014-06-17 05:15:38 -07004330 case 8:
4331 drawCubic(frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
4332 frags[c2s + 4], frags[c2s + 5], frags[c2s + 6], frags[c2s + 7]);
4333 if (draw_id) {
4334 curve = [frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
4335 frags[c2s + 4], frags[c2s + 5], frags[c2s + 6], frags[c2s + 7]];
4336 id = idByCurve(test, curve, PATH_CUBIC);
4337 }
4338 break;
4339 }
4340 if (id >= 0) {
Cary Clarkff114282016-12-14 11:56:16 -05004341 drawVisibleID(curve, 0.5, id);
caryclarkdac1d172014-06-17 05:15:38 -07004342 }
4343 }
4344 if (collect_bounds) {
4345 break;
4346 }
caryclark54359292015-03-26 07:52:43 -07004347 if (draw_intersection != 3 || step_limit == 0 || tIndex >= lastSect) {
4348 for (var idx = 0; idx < f.length; idx += 4) {
caryclarkdac1d172014-06-17 05:15:38 -07004349 drawPoint(frags[f[idx]], frags[f[idx + 1]], true);
4350 }
4351 }
4352 if (!draw_intersectT) {
4353 break;
4354 }
4355 ctx.fillStyle = "red";
caryclark54359292015-03-26 07:52:43 -07004356 if (draw_intersection != 3 || step_limit == 0 || tIndex >= lastSect) {
4357 for (var idx = 0; idx < f.length; idx += 4) {
caryclarkdac1d172014-06-17 05:15:38 -07004358 drawTAtPointUp(frags[f[idx]], frags[f[idx + 1]], frags[f[idx + 2]]);
4359 drawTAtPointDown(frags[f[idx]], frags[f[idx + 1]], frags[f[idx + 3]]);
4360 }
4361 }
4362 break;
4363 case REC_TYPE_SORT:
4364 if (!draw_sort || (step_limit > 0 && tIndex < lastSort)) {
4365 continue;
4366 }
4367 ctx.lineWidth = 3;
4368 ctx.strokeStyle = "rgba(127,127,0, 0.5)";
4369 focus_enabled = true;
4370 switch (fragType) {
4371 case SORT_UNARY:
4372 case SORT_BINARY:
4373 var curve = curvePartialByID(test, frags[0], frags[6], frags[8]);
4374 drawCurve(curve);
4375 break;
4376 default:
4377 console.log("unknown REC_TYPE_SORT frag type: " + fragType);
4378 throw "stop execution";
4379 }
4380 break;
caryclark03b03ca2015-04-23 09:13:37 -07004381 case REC_TYPE_TOP:
4382 if (!draw_top || (step_limit > 0 && tIndex < lastTop)) {
4383 continue;
4384 }
4385 ctx.lineWidth = 3;
4386 ctx.strokeStyle = "rgba(127,127,0, 0.5)";
4387 focus_enabled = true;
4388 {
4389 var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
4390 drawCurve(curve);
4391 var type = PATH_LINE + (curve.length / 2 - 2);
4392 var mid = pointAtT(curve, type, 0.5);
4393 var d = dxy_at_t(curve, type, 0.5);
4394 drawArrow(mid.x, mid.y, d.x, d.y, 0.3);
4395 }
4396 break;
caryclarkdac1d172014-06-17 05:15:38 -07004397 case REC_TYPE_MARK:
4398 if (!draw_mark || (step_limit > 0 && tIndex < lastMark)) {
4399 continue;
4400 }
4401 ctx.lineWidth = 3;
4402 ctx.strokeStyle = fragType >= MARK_DONE_LINE ?
4403 "rgba(127,0,127, 0.5)" : "rgba(127,127,0, 0.5)";
4404 focus_enabled = true;
4405 switch (fragType) {
4406 case MARK_LINE:
4407 case MARK_DONE_LINE:
4408 case MARK_UNSORTABLE_LINE:
4409 case MARK_SIMPLE_LINE:
4410 case MARK_SIMPLE_DONE_LINE:
4411 case MARK_DONE_UNARY_LINE:
4412 drawLinePartial(frags[1], frags[2], frags[3], frags[4],
4413 frags[5], frags[9]);
4414 if (draw_id) {
4415 drawLinePartialID(frags[0], frags[1], frags[2], frags[3], frags[4],
4416 frags[5], frags[9]);
4417 }
4418 break;
4419 case MARK_QUAD:
4420 case MARK_DONE_QUAD:
4421 case MARK_UNSORTABLE_QUAD:
4422 case MARK_SIMPLE_QUAD:
4423 case MARK_SIMPLE_DONE_QUAD:
4424 case MARK_DONE_UNARY_QUAD:
4425 drawQuadPartial(frags[1], frags[2], frags[3], frags[4],
4426 frags[5], frags[6], frags[7], frags[11]);
4427 if (draw_id) {
4428 drawQuadPartialID(frags[0], frags[1], frags[2], frags[3], frags[4],
4429 frags[5], frags[6], frags[7], frags[11]);
4430 }
4431 break;
4432 case MARK_CUBIC:
4433 case MARK_DONE_CUBIC:
4434 case MARK_UNSORTABLE_CUBIC:
4435 case MARK_SIMPLE_CUBIC:
4436 case MARK_SIMPLE_DONE_CUBIC:
4437 case MARK_DONE_UNARY_CUBIC:
4438 drawCubicPartial(frags[1], frags[2], frags[3], frags[4],
4439 frags[5], frags[6], frags[7], frags[8], frags[9], frags[13]);
4440 if (draw_id) {
4441 drawCubicPartialID(frags[0], frags[1], frags[2], frags[3], frags[4],
4442 frags[5], frags[6], frags[7], frags[8], frags[9], frags[13]);
4443 }
4444 break;
4445 case MARK_ANGLE_LAST:
4446 // FIXME: ignored for now
4447 break;
4448 default:
4449 console.log("unknown REC_TYPE_MARK frag type: " + fragType);
4450 throw "stop execution";
4451 }
4452 break;
4453 default:
4454 continue;
4455 }
4456 }
4457 switch (recType) {
4458 case REC_TYPE_SORT:
4459 if (!draw_sort || (step_limit > 0 && tIndex < lastSort)) {
4460 break;
4461 }
4462 var angles = []; // use tangent lines to describe arcs
4463 var windFrom = [];
4464 var windTo = [];
4465 var opp = [];
4466 var minXY = Number.MAX_VALUE;
4467 var partial;
4468 focus_enabled = true;
4469 var someUnsortable = false;
4470 for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
4471 var fragType = records[recordIndex];
4472 var frags = records[recordIndex + 1];
4473 var unsortable = (fragType == SORT_UNARY && frags[14]) ||
4474 (fragType == SORT_BINARY && frags[16]);
4475 someUnsortable |= unsortable;
4476 switch (fragType) {
4477 case SORT_UNARY:
4478 case SORT_BINARY:
4479 partial = curvePartialByID(test, frags[0], frags[6], frags[8]);
4480 break;
4481 default:
4482 console.log("unknown REC_TYPE_SORT frag type: " + fragType);
4483 throw "stop execution";
4484 }
4485 var dx = boundsWidth(partial);
4486 var dy = boundsHeight(partial);
4487 minXY = Math.min(minXY, dx * dx + dy * dy);
4488 if (collect_bounds) {
4489 continue;
4490 }
4491 angles.push(tangent(partial));
4492 var from = frags[12];
4493 var to = frags[12];
4494 var sgn = frags[10];
4495 if (sgn < 0) {
4496 from -= frags[11];
4497 } else if (sgn > 0) {
4498 to -= frags[11];
4499 }
4500 windFrom.push(from + (unsortable ? "!" : ""));
4501 windTo.push(to + (unsortable ? "!" : ""));
4502 opp.push(fragType == SORT_BINARY);
4503 if (draw_sort == 1) {
Cary Clarkff114282016-12-14 11:56:16 -05004504 drawVisibleOrder(partial, frags[12]);
caryclarkdac1d172014-06-17 05:15:38 -07004505 } else {
Cary Clarkff114282016-12-14 11:56:16 -05004506 drawVisibleOrder(partial, (recordIndex / 2) + 1);
caryclarkdac1d172014-06-17 05:15:38 -07004507 }
4508 }
4509 var radius = Math.sqrt(minXY) / 2 * scale;
4510 radius = Math.min(50, radius);
4511 var scaledRadius = radius / scale;
4512 var centerX = partial[0];
4513 var centerY = partial[1];
4514 if (collect_bounds) {
4515 if (focus_enabled) {
4516 focusXmin = Math.min(focusXmin, centerX - scaledRadius);
4517 focusYmin = Math.min(focusYmin, centerY - scaledRadius);
4518 focusXmax = Math.max(focusXmax, centerX + scaledRadius);
4519 focusYmax = Math.max(focusYmax, centerY + scaledRadius);
4520 }
4521 break;
4522 }
4523 break;
4524 default:
4525 break;
4526 }
4527 }
4528 if (collect_bounds) {
4529 return;
4530 }
4531 if (draw_log && logStart >= 0) {
4532 ctx.font = "normal 10px Arial";
4533 ctx.textAlign = "left";
4534 ctx.beginPath();
4535 var top = screenHeight - 20 - (logRange + 2) * 10;
4536 ctx.rect(50, top, screenWidth - 100, (logRange + 2) * 10);
4537 ctx.fillStyle = "white";
4538 ctx.fill();
4539 ctx.fillStyle = "rgba(0,0,0, 0.5)";
4540 if (logStart > 0) {
4541 ctx.fillText(lines[logStart - 1], 50, top + 8);
4542 }
4543 ctx.fillStyle = "black";
4544 for (var idx = 0; idx < logRange; ++idx) {
4545 ctx.fillText(lines[logStart + idx], 50, top + 18 + 10 * idx);
4546 }
4547 ctx.fillStyle = "rgba(0,0,0, 0.5)";
4548 if (logStart + logRange < lines.length) {
4549 ctx.fillText(lines[logStart + logRange], 50, top + 18 + 10 * logRange);
4550 }
4551 }
4552 if (draw_legend) {
4553 var pos = 0;
caryclark624637c2015-05-11 07:21:27 -07004554 var drawSomething = draw_add | draw_active | draw_angle | draw_coincidence | draw_sort | draw_mark;
caryclarkdac1d172014-06-17 05:15:38 -07004555 // drawBox(pos++, "yellow", "black", opLetter, true, '');
4556 drawBox(pos++, "rgba(0,0,255, 0.3)", "black", draw_intersection > 1 ? sectCount : sectMax2, draw_intersection, intersectionKey);
4557 drawBox(pos++, "rgba(0,0,255, 0.3)", "black", draw_add ? addCount : addMax, draw_add, addKey);
4558 drawBox(pos++, "rgba(0,0,255, 0.3)", "black", draw_active ? activeCount : activeMax, draw_active, activeKey);
4559 drawBox(pos++, "rgba(127,127,0, 0.3)", "black", draw_angle ? angleCount : angleMax, draw_angle, angleKey);
caryclark624637c2015-05-11 07:21:27 -07004560 drawBox(pos++, "rgba(127,127,0, 0.3)", "black", draw_coincidence ? coinCount : coinMax, draw_coincidence, coincidenceKey);
caryclarkdac1d172014-06-17 05:15:38 -07004561 drawBox(pos++, "rgba(127,127,0, 0.3)", "black", draw_op ? opCount : opMax, draw_op, opKey);
4562 drawBox(pos++, "rgba(127,127,0, 0.3)", "black", draw_sort ? sortCount : sortMax, draw_sort, sortKey);
caryclark03b03ca2015-04-23 09:13:37 -07004563 drawBox(pos++, "rgba(127,127,0, 0.3)", "black", draw_top ? topCount : topMax, draw_top, topKey);
caryclarkdac1d172014-06-17 05:15:38 -07004564 drawBox(pos++, "rgba(127,0,127, 0.3)", "black", draw_mark ? markCount : markMax, draw_mark, markKey);
caryclark55888e42016-07-18 10:01:36 -07004565 drawBox(pos++, "black", "white",
caryclark26ad22a2015-10-16 09:03:38 -07004566 (new Array('P', 'P1', 'P2', 'P', 'p', 'p1', 'p2'))[draw_path], draw_path != 0, pathKey);
caryclarkdac1d172014-06-17 05:15:38 -07004567 drawBox(pos++, "rgba(0,63,0, 0.7)", "white",
4568 (new Array('Q', 'Q', 'C', 'QC', 'Qc', 'Cq'))[draw_computed],
4569 draw_computed != 0, computedKey);
4570 drawBox(pos++, "green", "black", step_limit, drawSomething, '');
4571 drawBox(pos++, "green", "black", stepMax, drawSomething, '');
4572 drawBox(pos++, "rgba(255,0,0, 0.6)", "black", lastIndex, drawSomething & draw_log, '');
4573 drawBox(pos++, "rgba(255,0,0, 0.6)", "black", test.length - 1, drawSomething & draw_log, '');
4574 if (curve_t) {
4575 drawCurveTControl();
4576 }
4577 ctx.font = "normal 20px Arial";
4578 ctx.fillStyle = "rgba(0,0,0, 0.3)";
4579 ctx.textAlign = "right";
4580 ctx.fillText(scale.toFixed(decimal_places) + 'x' , screenWidth - 10, screenHeight - 5);
4581 }
4582 if (draw_hints) {
4583 ctx.font = "normal 10px Arial";
4584 ctx.fillStyle = "rgba(0,0,0, 0.5)";
4585 ctx.textAlign = "right";
4586 var y = 4;
4587 ctx.fillText("control lines : " + controlLinesKey, ctx.screenWidthwidth - 10, pos * 50 + y++ * 10);
4588 ctx.fillText("curve t : " + curveTKey, screenWidth - 10, pos * 50 + y++ * 10);
4589 ctx.fillText("deriviatives : " + deriviativesKey, screenWidth - 10, pos * 50 + y++ * 10);
4590 ctx.fillText("intersect t : " + intersectTKey, screenWidth - 10, pos * 50 + y++ * 10);
caryclarkdac1d172014-06-17 05:15:38 -07004591 ctx.fillText("log : " + logKey, screenWidth - 10, pos * 50 + y++ * 10);
4592 ctx.fillText("log curve : " + logCurvesKey, screenWidth - 10, pos * 50 + y++ * 10);
4593 ctx.fillText("mid point : " + midpointKey, screenWidth - 10, pos * 50 + y++ * 10);
4594 ctx.fillText("points : " + ptsKey, screenWidth - 10, pos * 50 + y++ * 10);
4595 ctx.fillText("sequence : " + sequenceKey, screenWidth - 10, pos * 50 + y++ * 10);
4596 ctx.fillText("xy : " + xyKey, screenWidth - 10, pos * 50 + y++ * 10);
4597 }
4598}
4599
4600function drawBox(y, backC, foreC, str, enable, label) {
4601 ctx.beginPath();
4602 ctx.fillStyle = backC;
4603 ctx.rect(screenWidth - 40, y * 50 + 10, 40, 30);
4604 ctx.fill();
4605 ctx.font = "normal 16px Arial";
4606 ctx.fillStyle = foreC;
4607 ctx.textAlign = "center";
4608 ctx.fillText(str, screenWidth - 20, y * 50 + 32);
4609 if (!enable) {
4610 ctx.fillStyle = "rgba(255,255,255, 0.5)";
4611 ctx.fill();
4612 }
4613 if (label != '') {
4614 ctx.font = "normal 9px Arial";
4615 ctx.fillStyle = "black";
4616 ctx.fillText(label, screenWidth - 47, y * 50 + 40);
4617 }
4618}
4619
4620function drawCurveTControl() {
4621 ctx.lineWidth = 2;
4622 ctx.strokeStyle = "rgba(0,0,0, 0.3)";
4623 ctx.beginPath();
4624 ctx.rect(screenWidth - 80, 40, 28, screenHeight - 80);
4625 ctx.stroke();
4626 var ty = 40 + curveT * (screenHeight - 80);
4627 ctx.beginPath();
4628 ctx.moveTo(screenWidth - 80, ty);
4629 ctx.lineTo(screenWidth - 85, ty - 5);
4630 ctx.lineTo(screenWidth - 85, ty + 5);
4631 ctx.lineTo(screenWidth - 80, ty);
4632 ctx.fillStyle = "rgba(0,0,0, 0.6)";
4633 ctx.fill();
4634 var num = curveT.toFixed(decimal_places);
4635 ctx.font = "normal 10px Arial";
4636 ctx.textAlign = "left";
4637 ctx.fillText(num, screenWidth - 78, ty);
4638}
4639
4640function ptInTControl() {
4641 var e = window.event;
caryclark55888e42016-07-18 10:01:36 -07004642 var tgt = e.target || e.srcElement;
caryclarkdac1d172014-06-17 05:15:38 -07004643 var left = tgt.offsetLeft;
4644 var top = tgt.offsetTop;
4645 var x = (e.clientX - left);
4646 var y = (e.clientY - top);
4647 if (x < screenWidth - 80 || x > screenWidth - 50) {
4648 return false;
4649 }
4650 if (y < 40 || y > screenHeight - 80) {
4651 return false;
4652 }
4653 curveT = (y - 40) / (screenHeight - 120);
4654 if (curveT < 0 || curveT > 1) {
4655 throw "stop execution";
4656 }
4657 return true;
4658}
4659
4660function drawTop() {
4661 if (tests[testIndex] == null) {
4662 var str = testDivs[testIndex].textContent;
4663 parse_all(str);
4664 var title = testDivs[testIndex].id.toString();
4665 testTitles[testIndex] = title;
4666 }
4667 init(tests[testIndex]);
4668 redraw();
4669}
4670
4671function redraw() {
4672 if (focus_on_selection) {
4673 collect_bounds = true;
4674 draw(tests[testIndex], testLines[testIndex], testTitles[testIndex]);
4675 collect_bounds = false;
4676 if (focusXmin < focusXmax && focusYmin < focusYmax) {
4677 setScale(focusXmin, focusXmax, focusYmin, focusYmax);
4678 }
4679 }
4680 ctx.beginPath();
4681 ctx.fillStyle = "white";
4682 ctx.rect(0, 0, screenWidth, screenHeight);
4683 ctx.fill();
4684 draw(tests[testIndex], testLines[testIndex], testTitles[testIndex]);
4685}
4686
4687function dumpCurvePartial(test, id, t0, t1) {
4688 var curve = curveByID(test, id);
4689 var name = ["line", "quad", "cubic"][curve.length / 2 - 2];
4690 console.log("id=" + id + " " + name + "=" + curveToString(curve)
4691 + " t0=" + t0 + " t1=" + t1
4692 + " partial=" + curveToString(curvePartialByID(test, id, t0, t1)));
4693}
4694
4695function dumpAngleTest(test, id, t0, t1) {
4696 var curve = curveByID(test, id);
caryclark55888e42016-07-18 10:01:36 -07004697 console.log(" { {" + curveToString(curve) + "}, "
caryclarkdac1d172014-06-17 05:15:38 -07004698 + curve.length / 2 + ", " + t0 + ", " + t1 + ", {} }, //");
4699}
4700
4701function dumpLogToConsole() {
4702 if (logStart < 0) {
4703 return;
4704 }
4705 var test = tests[testIndex];
4706 var recType = REC_TYPE_UNKNOWN;
4707 var records;
4708 for (var index = 0; index < test.length; index += 3) {
4709 var lastLineNo = test[index + 1];
4710 if (lastLineNo >= logStart && lastLineNo < logStart + logRange) {
4711 recType = test[index];
4712 records = test[index + 2];
4713 break;
4714 }
4715 }
4716 if (recType == REC_TYPE_UNKNOWN) {
4717 return;
4718 }
4719 var lines = testLines[testIndex];
4720 for (var idx = 0; idx < logRange; ++idx) {
4721 var line = lines[logStart + idx];
4722 console.log(line);
4723 for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
4724 var fragType = records[recordIndex];
4725 var frags = records[recordIndex + 1];
4726 if (recType == REC_TYPE_ANGLE && fragType == ANGLE_AFTER) {
caryclarkdac1d172014-06-17 05:15:38 -07004727 dumpCurvePartial(test, frags[0], frags[4], frags[5]);
4728 dumpCurvePartial(test, frags[6], frags[10], frags[11]);
4729 dumpCurvePartial(test, frags[12], frags[16], frags[17]);
4730 console.log("\nstatic IntersectData intersectDataSet[] = { //");
4731 dumpAngleTest(test, frags[0], frags[4], frags[5]);
4732 dumpAngleTest(test, frags[6], frags[10], frags[11]);
4733 dumpAngleTest(test, frags[12], frags[16], frags[17]);
4734 console.log("}; //");
4735 }
4736 }
4737 }
4738}
4739
4740var activeKey = 'a';
4741var pathKey = 'b';
4742var pathBackKey = 'B';
4743var centerKey = 'c';
caryclark624637c2015-05-11 07:21:27 -07004744var coincidenceKey = 'C';
caryclarkdac1d172014-06-17 05:15:38 -07004745var addKey = 'd';
4746var deriviativesKey = 'f';
4747var angleKey = 'g';
4748var angleBackKey = 'G';
caryclarkdac1d172014-06-17 05:15:38 -07004749var intersectionKey = 'i';
4750var intersectionBackKey = 'I';
4751var sequenceKey = 'j';
4752var midpointKey = 'k';
4753var logKey = 'l';
4754var logToConsoleKey = 'L';
4755var markKey = 'm';
4756var sortKey = 'o';
4757var opKey = 'p';
4758var opBackKey = 'P';
4759var computedKey = 'q';
4760var computedBackKey = 'Q';
Cary Clarkff114282016-12-14 11:56:16 -05004761var directionKey = 'r';
caryclarkdac1d172014-06-17 05:15:38 -07004762var stepKey = 's';
4763var stepBackKey = 'S';
4764var intersectTKey = 't';
caryclark03b03ca2015-04-23 09:13:37 -07004765var topKey = 'T';
caryclarkdac1d172014-06-17 05:15:38 -07004766var curveTKey = 'u';
4767var controlLinesBackKey = 'V';
4768var controlLinesKey = 'v';
4769var ptsKey = 'x';
4770var xyKey = 'y';
4771var logCurvesKey = 'z';
4772var focusKey = '`';
4773var idKey = '.';
4774var retinaKey = '\\';
4775
4776function doKeyPress(evt) {
4777 var char = String.fromCharCode(evt.charCode);
4778 var focusWasOn = false;
4779 switch (char) {
4780 case '0':
4781 case '1':
4782 case '2':
4783 case '3':
4784 case '4':
4785 case '5':
4786 case '6':
4787 case '7':
4788 case '8':
4789 case '9':
4790 decimal_places = char - '0';
4791 redraw();
4792 break;
4793 case activeKey:
4794 draw_active ^= true;
caryclark55888e42016-07-18 10:01:36 -07004795 redraw();
caryclarkdac1d172014-06-17 05:15:38 -07004796 break;
4797 case addKey:
4798 draw_add ^= true;
caryclark55888e42016-07-18 10:01:36 -07004799 redraw();
caryclarkdac1d172014-06-17 05:15:38 -07004800 break;
4801 case angleKey:
caryclark54359292015-03-26 07:52:43 -07004802 draw_angle = (draw_angle + 1) % 4;
caryclarkdac1d172014-06-17 05:15:38 -07004803 redraw();
4804 break;
4805 case angleBackKey:
4806 draw_angle = (draw_angle + 2) % 3;
4807 redraw();
4808 break;
4809 case centerKey:
4810 setScale(xmin, xmax, ymin, ymax);
caryclark55888e42016-07-18 10:01:36 -07004811 redraw();
caryclarkdac1d172014-06-17 05:15:38 -07004812 break;
caryclark624637c2015-05-11 07:21:27 -07004813 case coincidenceKey:
4814 draw_coincidence ^= true;
4815 redraw();
4816 break;
caryclarkdac1d172014-06-17 05:15:38 -07004817 case controlLinesBackKey:
4818 control_lines = (control_lines + 3) % 4;
caryclark55888e42016-07-18 10:01:36 -07004819 redraw();
caryclarkdac1d172014-06-17 05:15:38 -07004820 break;
4821 case controlLinesKey:
4822 control_lines = (control_lines + 1) % 4;
caryclark55888e42016-07-18 10:01:36 -07004823 redraw();
caryclarkdac1d172014-06-17 05:15:38 -07004824 break;
4825 case computedBackKey:
4826 draw_computed = (draw_computed + 5) % 6;
caryclark55888e42016-07-18 10:01:36 -07004827 redraw();
caryclarkdac1d172014-06-17 05:15:38 -07004828 break;
4829 case computedKey:
4830 draw_computed = (draw_computed + 1) % 6;
caryclark55888e42016-07-18 10:01:36 -07004831 redraw();
caryclarkdac1d172014-06-17 05:15:38 -07004832 break;
4833 case curveTKey:
4834 curve_t ^= true;
4835 if (curve_t) {
4836 draw_legend = true;
4837 }
4838 redraw();
4839 break;
4840 case deriviativesKey:
4841 draw_deriviatives = (draw_deriviatives + 1) % 3;
4842 redraw();
4843 break;
Cary Clarkff114282016-12-14 11:56:16 -05004844 case directionKey:
4845 draw_direction ^= true;
4846 redraw();
4847 break;
caryclarkdac1d172014-06-17 05:15:38 -07004848 case focusKey:
4849 focus_on_selection ^= true;
4850 setScale(xmin, xmax, ymin, ymax);
4851 redraw();
4852 break;
caryclarkdac1d172014-06-17 05:15:38 -07004853 case idKey:
4854 draw_id ^= true;
4855 redraw();
4856 break;
4857 case intersectionBackKey:
4858 draw_intersection = (draw_intersection + 3) % 4;
caryclark55888e42016-07-18 10:01:36 -07004859 redraw();
caryclarkdac1d172014-06-17 05:15:38 -07004860 break;
4861 case intersectionKey:
4862 draw_intersection = (draw_intersection + 1) % 4;
caryclark55888e42016-07-18 10:01:36 -07004863 redraw();
caryclarkdac1d172014-06-17 05:15:38 -07004864 break;
4865 case intersectTKey:
4866 draw_intersectT ^= true;
4867 redraw();
4868 break;
4869 case logCurvesKey:
4870 logCurves(tests[testIndex]);
4871 break;
4872 case logKey:
4873 draw_log ^= true;
4874 redraw();
4875 break;
4876 case logToConsoleKey:
4877 if (draw_log) {
4878 dumpLogToConsole();
4879 }
4880 break;
4881 case markKey:
4882 draw_mark ^= true;
4883 redraw();
4884 break;
4885 case midpointKey:
4886 draw_midpoint ^= true;
4887 redraw();
4888 break;
4889 case opKey:
4890 draw_op = (draw_op + 1) % 3;
4891 redraw();
4892 break;
4893 case opBackKey:
4894 draw_op = (draw_op + 2) % 3;
4895 redraw();
4896 break;
4897 case pathKey:
caryclark26ad22a2015-10-16 09:03:38 -07004898 draw_path = (draw_path + 1) % (4 + (hasAlignedPath ? 3 : 0));
caryclark55888e42016-07-18 10:01:36 -07004899 redraw();
caryclarkdac1d172014-06-17 05:15:38 -07004900 break;
4901 case pathBackKey:
caryclark26ad22a2015-10-16 09:03:38 -07004902 draw_path = (draw_path + 3 + (hasAlignedPath ? 3 : 0)) % (4 + (hasAlignedPath ? 3 : 0));
caryclark55888e42016-07-18 10:01:36 -07004903 redraw();
caryclarkdac1d172014-06-17 05:15:38 -07004904 break;
4905 case ptsKey:
4906 pt_labels = (pt_labels + 1) % 3;
4907 redraw();
4908 break;
4909 case retinaKey:
4910 retina_scale ^= true;
4911 drawTop();
4912 break;
4913 case sequenceKey:
4914 draw_sequence ^= true;
4915 redraw();
4916 break;
4917 case sortKey:
4918 draw_sort = (draw_sort + 1) % 3;
4919 drawTop();
4920 break;
4921 case stepKey:
4922 step_limit++;
4923 if (step_limit > stepMax) {
4924 step_limit = stepMax;
4925 }
4926 redraw();
4927 break;
4928 case stepBackKey:
4929 step_limit--;
4930 if (step_limit < 0) {
4931 step_limit = 0;
4932 }
4933 redraw();
4934 break;
caryclark03b03ca2015-04-23 09:13:37 -07004935 case topKey:
4936 draw_top ^= true;
4937 redraw();
4938 break;
caryclarkdac1d172014-06-17 05:15:38 -07004939 case xyKey:
4940 debug_xy = (debug_xy + 1) % 3;
4941 redraw();
4942 break;
4943 case '-':
4944 focusWasOn = focus_on_selection;
4945 if (focusWasOn) {
4946 focus_on_selection = false;
4947 scale /= 1.2;
4948 } else {
4949 scale /= 2;
4950 calcLeftTop();
4951 }
4952 redraw();
4953 focus_on_selection = focusWasOn;
4954 break;
4955 case '=':
4956 case '+':
4957 focusWasOn = focus_on_selection;
4958 if (focusWasOn) {
4959 focus_on_selection = false;
4960 scale *= 1.2;
4961 } else {
4962 scale *= 2;
4963 calcLeftTop();
4964 }
4965 redraw();
4966 focus_on_selection = focusWasOn;
4967 break;
4968 case '?':
4969 draw_hints ^= true;
4970 if (draw_hints && !draw_legend) {
4971 draw_legend = true;
4972 }
4973 redraw();
4974 break;
4975 case '/':
4976 draw_legend ^= true;
4977 redraw();
4978 break;
4979 }
4980}
4981
4982function doKeyDown(evt) {
4983 var char = evt.keyCode;
4984 var preventDefault = false;
4985 switch (char) {
4986 case 37: // left arrow
4987 if (evt.shiftKey) {
4988 testIndex -= 9;
4989 }
4990 if (--testIndex < 0)
4991 testIndex = tests.length - 1;
4992 drawTop();
4993 preventDefault = true;
4994 break;
4995 case 39: // right arrow
4996 if (evt.shiftKey) {
4997 testIndex += 9;
4998 }
4999 if (++testIndex >= tests.length)
5000 testIndex = 0;
5001 drawTop();
5002 preventDefault = true;
5003 break;
5004 }
5005 if (preventDefault) {
5006 evt.preventDefault();
5007 return false;
5008 }
5009 return true;
5010}
5011
5012(function() {
5013 var hidden = "hidden";
5014
5015 // Standards:
5016 if (hidden in document)
5017 document.addEventListener("visibilitychange", onchange);
5018 else if ((hidden = "mozHidden") in document)
5019 document.addEventListener("mozvisibilitychange", onchange);
5020 else if ((hidden = "webkitHidden") in document)
5021 document.addEventListener("webkitvisibilitychange", onchange);
5022 else if ((hidden = "msHidden") in document)
5023 document.addEventListener("msvisibilitychange", onchange);
5024 // IE 9 and lower:
5025 else if ('onfocusin' in document)
5026 document.onfocusin = document.onfocusout = onchange;
5027 // All others:
5028 else
caryclark55888e42016-07-18 10:01:36 -07005029 window.onpageshow = window.onpagehide
caryclarkdac1d172014-06-17 05:15:38 -07005030 = window.onfocus = window.onblur = onchange;
5031
5032 function onchange (evt) {
5033 var v = 'visible', h = 'hidden',
caryclark55888e42016-07-18 10:01:36 -07005034 evtMap = {
5035 focus:v, focusin:v, pageshow:v, blur:h, focusout:h, pagehide:h
caryclarkdac1d172014-06-17 05:15:38 -07005036 };
5037
5038 evt = evt || window.event;
5039 if (evt.type in evtMap)
5040 document.body.className = evtMap[evt.type];
caryclark55888e42016-07-18 10:01:36 -07005041 else
caryclarkdac1d172014-06-17 05:15:38 -07005042 document.body.className = this[hidden] ? "hidden" : "visible";
5043 }
5044})();
5045
5046function calcXY() {
5047 var e = window.event;
caryclark55888e42016-07-18 10:01:36 -07005048 var tgt = e.target || e.srcElement;
caryclarkdac1d172014-06-17 05:15:38 -07005049 var left = tgt.offsetLeft;
5050 var top = tgt.offsetTop;
5051 mouseX = (e.clientX - left) / scale + srcLeft;
5052 mouseY = (e.clientY - top) / scale + srcTop;
5053}
5054
5055function calcLeftTop() {
5056 srcLeft = mouseX - screenWidth / 2 / scale;
5057 srcTop = mouseY - screenHeight / 2 / scale;
5058}
5059
5060var disableClick = false;
5061
5062function handleMouseClick() {
5063 if (disableClick) {
5064 return;
5065 }
5066 if (!curve_t || !ptInTControl()) {
5067 calcXY();
5068 calcLeftTop();
5069 }
5070 redraw();
5071// if (!curve_t || !ptInTControl()) {
5072// mouseX = screenWidth / 2 / scale + srcLeft;
5073// mouseY = screenHeight / 2 / scale + srcTop;
5074// }
5075}
5076
5077function handleMouseOver() {
5078 calcXY();
5079 if (debug_xy != 2) {
5080 return;
5081 }
5082 var num = mouseX.toFixed(decimal_places) + ", " + mouseY.toFixed(decimal_places);
5083 ctx.beginPath();
5084 ctx.rect(300,100,num.length * 6,10);
5085 ctx.fillStyle="white";
5086 ctx.fill();
5087 ctx.font = "normal 10px Arial";
5088 ctx.fillStyle="black";
5089 ctx.textAlign = "left";
5090 ctx.fillText(num, 300, 108);
5091}
5092
5093function start() {
5094 for (var i = 0; i < testDivs.length; ++i) {
5095 tests[i] = null;
5096 }
5097 testIndex = 0;
5098 drawTop();
5099 window.addEventListener('keypress', doKeyPress, true);
5100 window.addEventListener('keydown', doKeyDown, true);
5101 window.onresize = function() {
5102 drawTop();
5103 }
5104 /*
5105 window.onpagehide = function() {
5106 disableClick = true;
5107 }
5108 */
5109 window.onpageshow = function () {
5110 disableClick = false;
5111 }
5112}
5113
5114</script>
5115</head>
5116
5117<body onLoad="start();">
5118<canvas id="canvas" width="750" height="500"
5119 onmousemove="handleMouseOver()"
5120 onclick="handleMouseClick()"
5121 ></canvas >
5122</body>
5123</html>