pathops_visualizer.htm 202 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635
  1. <html>
  2. <head>
  3. <div height="0" hidden="true">
  4. <div id="bug8380">
  5. SkDCubic::ComplexBreak
  6. {{{126, 9.396100044250488281}, {125.6320571899414063, 9.295844078063964844}, {125.1227340698242188, 9.337338447570800781}, {124.6031646728515625, 9.379667282104492188}}},
  7. inflectionsTs[0]=0.999997776 {{{126.1618761931709827, 9.252680507258252973}, {123.04446008475567, 9.506653492188940291}}},
  8. SkDCubic::ComplexBreak
  9. {{{124.6031646728515625, 9.379667282104492188}, {124.1427383422851563, 9.417178153991699219}, {123.6742630004882813, 9.45534515380859375}, {123.28900146484375, 9.396100044250488281}}},
  10. inflectionsTs[0]=4.14921088e-06 {{{125.984438133710114, 9.267135117035042668}, {123.2218797495565639, 9.492200381017113386}}},
  11. maxCurvature[0]=0.0817322831 {{{125.8735553329735666, 9.277935394706121386}, {123.1067608854740314, 9.499713475347833835}}},
  12. SkDCubic::ComplexBreak
  13. {{{126, 9.396200180053710938}, {125.305999755859375, 9.206999778747558594}, {124.1090011596679688, 9.522199630737304688}, {123.28900146484375, 9.396200180053710938}}},
  14. inflectionsTs[0]=0.530286644 {{{127.5428560571536707, 9.140180090182106198}, {121.6628069847287179, 9.619260454379688241}}},
  15. maxCurvature[0]=0.568563182 {{{127.4346914043237859, 9.15278490094694952}, {121.5456828946143446, 9.624913158409162506}}},
  16. seg=1 {{{0, 353.891998f}, {126, 9.39610004f}}}
  17. seg=2 {{{126, 9.39610004f}, {125.632057f, 9.29584408f}, {125.122734f, 9.33733845f}, {124.603165f, 9.37966728f}}}
  18. seg=3 {{{124.603165f, 9.37966728f}, {124.142731f, 9.41717815f}, {123.674263f, 9.45534515f}, {123.289001f, 9.39610004f}}}
  19. seg=4 {{{123.289001f, 9.39610004f}, {118.119003f, 8.07219982f}}}
  20. seg=5 {{{118.119003f, 8.07219982f}, {8.17210007f, 104.212997f}}}
  21. seg=6 {{{8.17210007f, 104.212997f}, {0, 259.298737f}}}
  22. seg=7 {{{0, 259.298737f}, {0, 353.891998f}}}
  23. op sect
  24. seg=8 {{{8.17210007f, 104.212997f}, {-5.82350016f, 369.813995f}}}
  25. seg=9 {{{-5.82350016f, 369.813995f}, {126, 9.39620018f}}}
  26. seg=10 {{{126, 9.39620018f}, {125.631981f, 9.29586983f}, {125.12252f, 9.3373785f}, {124.602829f, 9.37972069f}}}
  27. seg=11 {{{124.602829f, 9.37972069f}, {124.142509f, 9.41722488f}, {123.674164f, 9.45538425f}, {123.289001f, 9.39620018f}}}
  28. seg=12 {{{123.289001f, 9.39620018f}, {118.119003f, 8.07219982f}}}
  29. seg=13 {{{118.119003f, 8.07219982f}, {8.17210007f, 104.212997f}}}
  30. debugShowLineIntersection wtTs[0]=1 {{{8.17210007,104.212997}, {-5.82350016,369.813995}}} {{-5.82350016,369.813995}} wnTs[0]=0 {{{-5.82350016,369.813995}, {126,9.39620018}}}
  31. debugShowLineIntersection wtTs[0]=0 {{{8.17210007,104.212997}, {-5.82350016,369.813995}}} {{8.17210007,104.212997}} wnTs[0]=1 {{{118.119003,8.07219982}, {8.17210007,104.212997}}}
  32. debugShowCubicLineIntersection wtTs[0]=0 {{{126,9.39620018}, {125.631981,9.29586983}, {125.12252,9.3373785}, {124.602829,9.37972069}}} {{126,9.39620018}} wnTs[0]=1 {{{-5.82350016,369.813995}, {126,9.39620018}}}
  33. debugShowCubicLineIntersection no intersect {{{124.602829,9.37972069}, {124.142509,9.41722488}, {123.674164,9.45538425}, {123.289001,9.39620018}}} {{{-5.82350016,369.813995}, {126,9.39620018}}}
  34. debugShowLineIntersection no intersect {{{-5.82350016,369.813995}, {126,9.39620018}}} {{{123.289001,9.39620018}, {118.119003,8.07219982}}}
  35. debugShowLineIntersection no intersect {{{-5.82350016,369.813995}, {126,9.39620018}}} {{{118.119003,8.07219982}, {8.17210007,104.212997}}}
  36. debugShowCubicIntersection wtTs[0]=1 {{{126,9.39620018}, {125.631981,9.29586983}, {125.12252,9.3373785}, {124.602829,9.37972069}}} {{124.602829,9.37972069}} wnTs[0]=0 {{{124.602829,9.37972069}, {124.142509,9.41722488}, {123.674164,9.45538425}, {123.289001,9.39620018}}}
  37. debugShowCubicLineIntersection wtTs[0]=1 {{{124.602829,9.37972069}, {124.142509,9.41722488}, {123.674164,9.45538425}, {123.289001,9.39620018}}} {{123.289001,9.39620018}} wnTs[0]=0 {{{123.289001,9.39620018}, {118.119003,8.07219982}}}
  38. debugShowLineIntersection wtTs[0]=1 {{{123.289001,9.39620018}, {118.119003,8.07219982}}} {{118.119003,8.07219982}} wnTs[0]=0 {{{118.119003,8.07219982}, {8.17210007,104.212997}}}
  39. debugShowLineIntersection no intersect {{{8.17210007,104.212997}, {-5.82350016,369.813995}}} {{{0,353.891998}, {126,9.39610004}}}
  40. debugShowLineIntersection wtTs[0]=0 {{{8.17210007,104.212997}, {-5.82350016,369.813995}}} {{8.17210007,104.212997}} wnTs[0]=1 {{{118.119003,8.07219982}, {8.17210007,104.212997}}}
  41. debugShowLineIntersection wtTs[0]=0 {{{8.17210007,104.212997}, {-5.82350016,369.813995}}} {{8.17210007,104.212997}} wtTs[1]=0.583904956 {{0,259.298737}} wnTs[0]=0 {{{8.17210007,104.212997}, {0,259.298737}}} wnTs[1]=1
  42. SkOpSegment::addT insert t=0.583904956 segID=8 spanID=27
  43. debugShowLineIntersection wtTs[0]=0.583904956 {{{8.17210007,104.212997}, {-5.82350016,369.813995}}} {{0,259.298737}} wnTs[0]=0 {{{0,259.298737}, {0,353.891998}}}
  44. debugShowLineIntersection wtTs[0]=0.0441765002 {{{-5.82350016,369.813995}, {126,9.39620018}}} {{0,353.891998}} wtTs[1]=1 {{126,9.39620018}} wnTs[0]=0 {{{0,353.891998}, {126,9.39610004}}} wnTs[1]=0.999999744
  45. SkOpSegment::addT insert t=0.0441765002 segID=9 spanID=28
  46. debugShowCubicLineIntersection no intersect {{{124.603165,9.37966728}, {124.142731,9.41717815}, {123.674263,9.45534515}, {123.289001,9.39610004}}} {{{-5.82350016,369.813995}, {126,9.39620018}}}
  47. debugShowLineIntersection no intersect {{{-5.82350016,369.813995}, {126,9.39620018}}} {{{118.119003,8.07219982}, {8.17210007,104.212997}}}
  48. debugShowLineIntersection no intersect {{{-5.82350016,369.813995}, {126,9.39620018}}} {{{8.17210007,104.212997}, {0,259.298737}}}
  49. debugShowLineIntersection wtTs[0]=0.0441765002 {{{-5.82350016,369.813995}, {126,9.39620018}}} {{0,353.891998}} wnTs[0]=1 {{{0,259.298737}, {0,353.891998}}}
  50. debugShowCubicLineIntersection wtTs[0]=0 {{{126,9.39620018}, {125.631981,9.29586983}, {125.12252,9.3373785}, {124.602829,9.37972069}}} {{126,9.39620018}} wnTs[0]=1 {{{0,353.891998}, {126,9.39610004}}}
  51. -1=(0.375,0.5) [-1]
  52. SkTSect::addForPerp addBounded span=-1 opp=-1
  53. -1=(0.5,0.625) [-1]
  54. SkTSect::addForPerp addBounded span=-1 opp=-1
  55. -1=(0.625,0.75) [-1]
  56. SkTSect::addForPerp addBounded span=-1 opp=-1
  57. -1=(0.75,0.8125) [-1]
  58. SkTSect::addForPerp addBounded span=-1 opp=-1
  59. -1=(0.8125,0.875) [-1]
  60. SkTSect::addForPerp addBounded span=-1 opp=-1
  61. -1=(0.875,0.9375) [-1]
  62. SkTSect::addForPerp addBounded span=-1 opp=-1
  63. SkTSect::addForPerp priorSpan=-1 t=0.937702598 opp=-1
  64. -1=(0.9375,1) []
  65. SkTSect::addForPerp addBounded span=-1 opp=-1
  66. debugShowCubicIntersection wtTs[0]=0.307128906 {{{126,9.39620018}, {125.631981,9.29586983}, {125.12252,9.3373785}, {124.602829,9.37972069}}} {{125.624687,9.33981037}} wtTs[1]=0.9375 {{124.700119,9.37182617}} wnTs[0]=0.307191 {{{126,9.39610004}, {125.632057,9.29584408}, {125.122734,9.33733845}, {124.603165,9.37966728}}} wnTs[1]=0.937702598
  67. SkOpSegment::addT insert t=0.307128906 segID=10 spanID=29
  68. SkOpSegment::addT insert t=0.307190555 segID=2 spanID=30
  69. SkOpSegment::addT insert t=0.9375 segID=10 spanID=31
  70. SkOpSegment::addT insert t=0.937702598 segID=2 spanID=32
  71. debugShowCubicIntersection no intersect {{{126,9.39620018}, {125.631981,9.29586983}, {125.12252,9.3373785}, {124.602829,9.37972069}}} {{{124.603165,9.37966728}, {124.142731,9.41717815}, {123.674263,9.45534515}, {123.289001,9.39610004}}}
  72. debugShowCubicLineIntersection no intersect {{{124.602829,9.37972069}, {124.142509,9.41722488}, {123.674164,9.45538425}, {123.289001,9.39620018}}} {{{0,353.891998}, {126,9.39610004}}}
  73. -1=(0.125,0.1875) [-1]
  74. SkTSect::addForPerp addBounded span=-1 opp=-1
  75. -1=(0.1875,0.25) [-1]
  76. SkTSect::addForPerp addBounded span=-1 opp=-1
  77. -1=(0.25,0.375) [-1]
  78. SkTSect::addForPerp addBounded span=-1 opp=-1
  79. -1=(0.375,0.5) [-1]
  80. SkTSect::addForPerp addBounded span=-1 opp=-1
  81. -1=(0.5,0.625) [-1]
  82. SkTSect::addForPerp addBounded span=-1 opp=-1
  83. -1=(0.625,0.75) [-1]
  84. SkTSect::addForPerp addBounded span=-1 opp=-1
  85. debugShowCubicIntersection wtTs[0]=0.0625 {{{124.602829,9.37972069}, {124.142509,9.41722488}, {123.674164,9.45538425}, {123.289001,9.39620018}}} {{124.516449,9.38673687}} wtTs[1]=0.625 {{123.752594,9.4268837}} wnTs[0]=0.0627287 {{{124.603165,9.37966728}, {124.142731,9.41717815}, {123.674263,9.45534515}, {123.289001,9.39610004}}} wnTs[1]=0.625091708
  86. SkOpSegment::addT insert t=0.0625 segID=11 spanID=33
  87. SkOpSegment::addT insert t=0.0627286673 segID=3 spanID=34
  88. SkOpSegment::addT insert t=0.625 segID=11 spanID=35
  89. SkOpSegment::addT insert t=0.625091708 segID=3 spanID=36
  90. debugShowCubicLineIntersection no intersect {{{124.602829,9.37972069}, {124.142509,9.41722488}, {123.674164,9.45538425}, {123.289001,9.39620018}}} {{{123.289001,9.39610004}, {118.119003,8.07219982}}}
  91. debugShowLineIntersection no intersect {{{123.289001,9.39620018}, {118.119003,8.07219982}}} {{{0,353.891998}, {126,9.39610004}}}
  92. debugShowCubicLineIntersection wtTs[0]=0.999978653 {{{124.603165,9.37966728}, {124.142731,9.41717815}, {123.674263,9.45534515}, {123.289001,9.39610004}}} {{123.289001,9.39620018}} wnTs[0]=0 {{{123.289001,9.39620018}, {118.119003,8.07219982}}}
  93. debugShowLineIntersection wtTs[0]=4.65488731e-06 {{{123.289001,9.39620018}, {118.119003,8.07219982}}} {{123.289001,9.39610004}} wtTs[1]=1 {{118.119003,8.07219982}} wnTs[0]=0 {{{123.289001,9.39610004}, {118.119003,8.07219982}}} wnTs[1]=1
  94. debugShowLineIntersection wtTs[0]=1 {{{123.289001,9.39620018}, {118.119003,8.07219982}}} {{118.119003,8.07219982}} wnTs[0]=0 {{{118.119003,8.07219982}, {8.17210007,104.212997}}}
  95. debugShowLineIntersection no intersect {{{118.119003,8.07219982}, {8.17210007,104.212997}}} {{{0,353.891998}, {126,9.39610004}}}
  96. debugShowLineIntersection wtTs[0]=0 {{{118.119003,8.07219982}, {8.17210007,104.212997}}} {{118.119003,8.07219982}} wnTs[0]=1 {{{123.289001,9.39610004}, {118.119003,8.07219982}}}
  97. debugShowLineIntersection wtTs[0]=0 {{{118.119003,8.07219982}, {8.17210007,104.212997}}} {{118.119003,8.07219982}} wtTs[1]=1 {{8.17210007,104.212997}} wnTs[0]=0 {{{118.119003,8.07219982}, {8.17210007,104.212997}}} wnTs[1]=1
  98. debugShowLineIntersection wtTs[0]=1 {{{118.119003,8.07219982}, {8.17210007,104.212997}}} {{8.17210007,104.212997}} wnTs[0]=0 {{{8.17210007,104.212997}, {0,259.298737}}}
  99. debugShowCubicLineIntersection wtTs[0]=0 {{{126,9.39610004}, {125.632057,9.29584408}, {125.122734,9.33733845}, {124.603165,9.37966728}}} {{126,9.39610004}} wnTs[0]=1 {{{0,353.891998}, {126,9.39610004}}}
  100. debugShowCubicLineIntersection no intersect {{{124.603165,9.37966728}, {124.142731,9.41717815}, {123.674263,9.45534515}, {123.289001,9.39610004}}} {{{0,353.891998}, {126,9.39610004}}}
  101. debugShowLineIntersection no intersect {{{0,353.891998}, {126,9.39610004}}} {{{123.289001,9.39610004}, {118.119003,8.07219982}}}
  102. debugShowLineIntersection no intersect {{{0,353.891998}, {126,9.39610004}}} {{{118.119003,8.07219982}, {8.17210007,104.212997}}}
  103. debugShowLineIntersection no intersect {{{0,353.891998}, {126,9.39610004}}} {{{8.17210007,104.212997}, {0,259.298737}}}
  104. debugShowLineIntersection wtTs[0]=0 {{{0,353.891998}, {126,9.39610004}}} {{0,353.891998}} wnTs[0]=1 {{{0,259.298737}, {0,353.891998}}}
  105. debugShowCubicIntersection wtTs[0]=1 {{{126,9.39610004}, {125.632057,9.29584408}, {125.122734,9.33733845}, {124.603165,9.37966728}}} {{124.603165,9.37966728}} wnTs[0]=0 {{{124.603165,9.37966728}, {124.142731,9.41717815}, {123.674263,9.45534515}, {123.289001,9.39610004}}}
  106. debugShowCubicLineIntersection wtTs[0]=1 {{{124.603165,9.37966728}, {124.142731,9.41717815}, {123.674263,9.45534515}, {123.289001,9.39610004}}} {{123.289001,9.39610004}} wnTs[0]=0 {{{123.289001,9.39610004}, {118.119003,8.07219982}}}
  107. debugShowLineIntersection wtTs[0]=1 {{{123.289001,9.39610004}, {118.119003,8.07219982}}} {{118.119003,8.07219982}} wnTs[0]=0 {{{118.119003,8.07219982}, {8.17210007,104.212997}}}
  108. debugShowLineIntersection wtTs[0]=1 {{{118.119003,8.07219982}, {8.17210007,104.212997}}} {{8.17210007,104.212997}} wnTs[0]=0 {{{8.17210007,104.212997}, {0,259.298737}}}
  109. debugShowLineIntersection wtTs[0]=1 {{{8.17210007,104.212997}, {0,259.298737}}} {{0,259.298737}} wnTs[0]=0 {{{0,259.298737}, {0,353.891998}}}
  110. ----------------x-x--x-x-------------- addExpanded
  111. 00: coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
  112. 01: coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
  113. 02: coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
  114. 03: coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
  115. 04: coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
  116. 05: coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
  117. 06: coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
  118. 07: coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
  119. 08: coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
  120. 09: coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
  121. 10: coinSeg/Span/PtT=11/33/33 endSpan=6 oppSeg/Span/PtT=11/22/22 oppEndSpan=6 ExpandCoin
  122. 11: coinSeg/Span/PtT=2/30/30 endSpan=19 oppSeg/Span/PtT=2/3/3 oppEndSpan=19 ExpandCoin
  123. 12: seg/base=13/25 seg/base=5/9 MarkCoinStart
  124. 13: seg/base=13/26 seg/base=5/10 MarkCoinEnd
  125. 14: seg/base=4/7 seg/base=12/23 MarkCoinStart
  126. 15: seg/base=4/8 seg/base=12/24 MarkCoinEnd
  127. 16: seg/base=11/33 seg/base=3/34 MarkCoinStart
  128. 17: seg/base=11/35 seg/base=3/36 MarkCoinEnd
  129. 18: seg/base=2/30 seg/base=10/29 MarkCoinStart
  130. 19: seg/base=2/32 seg/base=10/31 MarkCoinEnd
  131. 20: seg/base=9/28 seg/base=1/1 MarkCoinStart
  132. 21: seg/base=9/18 seg/base=1/2 MarkCoinEnd
  133. 22: seg/base=8/15 seg/base=6/11 MarkCoinStart
  134. 23: seg/base=8/27 seg/base=6/12 MarkCoinEnd
  135. SkOpSegment::debugShowActiveSpans id=8 (8.17210007,104.212997 -2.71619996e-07,259.298737) t=0 tEnd=0.583904956 windSum=? windValue=1
  136. SkOpSegment::debugShowActiveSpans id=8 (-2.71619996e-07,259.298737 -5.82350016,369.813995) t=0.583904956 tEnd=1 windSum=? windValue=1
  137. SkOpSegment::debugShowActiveSpans id=9 (-5.82350016,369.813995 7.26031715e-07,353.891998) t=0 tEnd=0.0441765002 windSum=? windValue=1
  138. SkOpSegment::debugShowActiveSpans id=9 (7.26031715e-07,353.891998 126,9.39620018) t=0.0441765002 tEnd=1 windSum=? windValue=1
  139. SkOpSegment::debugShowActiveSpans id=10 (126,9.39620018 125.886971,9.36538583 125.760599,9.34795095 125.624687,9.33981037) t=0 tEnd=0.307128906 windSum=? windValue=1
  140. SkOpSegment::debugShowActiveSpans id=10 (125.624687,9.33981037 125.345733,9.32310212 125.026588,9.34554777 124.700119,9.37182617) t=0.307128906 tEnd=0.9375 windSum=? windValue=1
  141. SkOpSegment::debugShowActiveSpans id=10 (124.700119,9.37182617 124.66775,9.37443162 124.63531,9.3770743 124.602829,9.37972069) t=0.9375 tEnd=1 windSum=? windValue=1
  142. SkOpSegment::debugShowActiveSpans id=11 (124.602829,9.37972069 124.574059,9.3820647 124.545259,9.38441166 124.516449,9.38673687) t=0 tEnd=0.0625 windSum=? windValue=1
  143. SkOpSegment::debugShowActiveSpans id=11 (124.516449,9.38673687 124.257155,9.40766372 123.997126,9.42685982 123.752594,9.4268837) t=0.0625 tEnd=0.625 windSum=? windValue=1
  144. SkOpSegment::debugShowActiveSpans id=11 (123.752594,9.4268837 123.589573,9.42689962 123.433437,9.41839421 123.289001,9.39620018) t=0.625 tEnd=1 windSum=? windValue=1
  145. SkOpSegment::debugShowActiveSpans id=12 (123.289001,9.39620018 118.119003,8.07219982) t=0 tEnd=1 windSum=? windValue=1
  146. SkOpSegment::debugShowActiveSpans id=13 (118.119003,8.07219982 8.17210007,104.212997) t=0 tEnd=1 windSum=? windValue=1
  147. SkOpSegment::debugShowActiveSpans id=1 (0,353.891998 126,9.39610004) t=0 tEnd=1 windSum=? windValue=1
  148. SkOpSegment::debugShowActiveSpans id=2 (126,9.39610004 125.886971,9.36530236 125.760605,9.34788101 125.624695,9.33975124) t=0 tEnd=0.307190555 windSum=? windValue=1
  149. SkOpSegment::debugShowActiveSpans id=2 (125.624695,9.33975124 125.345738,9.3230648 125.026588,9.34552196 124.700119,9.37180042) t=0.307190555 tEnd=0.937702598 windSum=? windValue=1
  150. SkOpSegment::debugShowActiveSpans id=2 (124.700119,9.37180042 124.667862,9.37439685 124.635532,9.37703031 124.603165,9.37966728) t=0.937702598 tEnd=1 windSum=? windValue=1
  151. SkOpSegment::debugShowActiveSpans id=3 (124.603165,9.37966728 124.574282,9.38202029 124.545364,9.3843762 124.516441,9.38671017) t=0 tEnd=0.0627286673 windSum=? windValue=1
  152. SkOpSegment::debugShowActiveSpans id=3 (124.516441,9.38671017 124.257145,9.40763418 123.997124,9.42681973 123.752594,9.42682648) t=0.0627286673 tEnd=0.625091708 windSum=? windValue=1
  153. SkOpSegment::debugShowActiveSpans id=3 (123.752594,9.42682648 123.589574,9.42683098 123.433439,9.41831153 123.289001,9.39610004) t=0.625091708 tEnd=1 windSum=? windValue=1
  154. SkOpSegment::debugShowActiveSpans id=4 (123.289001,9.39610004 118.119003,8.07219982) t=0 tEnd=1 windSum=? windValue=1
  155. SkOpSegment::debugShowActiveSpans id=5 (118.119003,8.07219982 8.17210007,104.212997) t=0 tEnd=1 windSum=? windValue=1
  156. SkOpSegment::debugShowActiveSpans id=6 (8.17210007,104.212997 0,259.298737) t=0 tEnd=1 windSum=? windValue=1
  157. SkOpSegment::debugShowActiveSpans id=7 (0,259.298737 0,353.891998) t=0 tEnd=1 windSum=? windValue=1
  158. ----------------x-x--x-x-------------- move_multiples
  159. 00: coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
  160. 01: coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
  161. 02: coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
  162. 03: coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
  163. 04: coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
  164. 05: coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
  165. 06: coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
  166. 07: coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
  167. 08: coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
  168. 09: coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
  169. 10: coinSeg/Span/PtT=11/33/33 endSpan=6 oppSeg/Span/PtT=11/22/22 oppEndSpan=6 ExpandCoin
  170. 11: coinSeg/Span/PtT=2/30/30 endSpan=19 oppSeg/Span/PtT=2/3/3 oppEndSpan=19 ExpandCoin
  171. 12: seg/base=13/25 seg/base=5/9 MarkCoinStart
  172. 13: seg/base=13/26 seg/base=5/10 MarkCoinEnd
  173. 14: seg/base=4/7 seg/base=12/23 MarkCoinStart
  174. 15: seg/base=4/8 seg/base=12/24 MarkCoinEnd
  175. 16: seg/base=11/33 seg/base=3/34 MarkCoinStart
  176. 17: seg/base=11/35 seg/base=3/36 MarkCoinEnd
  177. 18: seg/base=2/30 seg/base=10/29 MarkCoinStart
  178. 19: seg/base=2/32 seg/base=10/31 MarkCoinEnd
  179. 20: seg/base=9/28 seg/base=1/1 MarkCoinStart
  180. 21: seg/base=9/18 seg/base=1/2 MarkCoinEnd
  181. 22: seg/base=8/15 seg/base=6/11 MarkCoinStart
  182. 23: seg/base=8/27 seg/base=6/12 MarkCoinEnd
  183. ----------------x-x--x-x-------------- move_nearby
  184. 00: coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
  185. 01: coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
  186. 02: coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
  187. 03: coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
  188. 04: coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
  189. 05: coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
  190. 06: coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
  191. 07: coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
  192. 08: coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
  193. 09: coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
  194. 10: coinSeg/Span/PtT=11/33/33 endSpan=6 oppSeg/Span/PtT=11/22/22 oppEndSpan=6 ExpandCoin
  195. 11: coinSeg/Span/PtT=2/30/30 endSpan=19 oppSeg/Span/PtT=2/3/3 oppEndSpan=19 ExpandCoin
  196. 12: seg/base=13/25 seg/base=5/9 MarkCoinStart
  197. 13: seg/base=13/26 seg/base=5/10 MarkCoinEnd
  198. 14: seg/base=4/7 seg/base=12/23 MarkCoinStart
  199. 15: seg/base=4/8 seg/base=12/24 MarkCoinEnd
  200. 16: seg/base=11/33 seg/base=3/34 MarkCoinStart
  201. 17: seg/base=11/35 seg/base=3/36 MarkCoinEnd
  202. 18: seg/base=2/30 seg/base=10/29 MarkCoinStart
  203. 19: seg/base=2/32 seg/base=10/31 MarkCoinEnd
  204. 20: seg/base=9/28 seg/base=1/1 MarkCoinStart
  205. 21: seg/base=9/18 seg/base=1/2 MarkCoinEnd
  206. 22: seg/base=8/15 seg/base=6/11 MarkCoinStart
  207. 23: seg/base=8/27 seg/base=6/12 MarkCoinEnd
  208. ----------------x-x--x-x-------------- correctEnds
  209. 00: coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
  210. 01: coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
  211. 02: coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
  212. 03: coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
  213. 04: coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
  214. 05: coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
  215. 06: coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
  216. 07: coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
  217. 08: coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
  218. 09: coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
  219. 10: coinSeg/Span/PtT=11/33/33 endSpan=6 oppSeg/Span/PtT=11/22/22 oppEndSpan=6 ExpandCoin
  220. 11: coinSeg/Span/PtT=2/30/30 endSpan=19 oppSeg/Span/PtT=2/3/3 oppEndSpan=19 ExpandCoin
  221. 12: seg/base=13/25 seg/base=5/9 MarkCoinStart
  222. 13: seg/base=13/26 seg/base=5/10 MarkCoinEnd
  223. 14: seg/base=4/7 seg/base=12/23 MarkCoinStart
  224. 15: seg/base=4/8 seg/base=12/24 MarkCoinEnd
  225. 16: seg/base=11/33 seg/base=3/34 MarkCoinStart
  226. 17: seg/base=11/35 seg/base=3/36 MarkCoinEnd
  227. 18: seg/base=2/30 seg/base=10/29 MarkCoinStart
  228. 19: seg/base=2/32 seg/base=10/31 MarkCoinEnd
  229. 20: seg/base=9/28 seg/base=1/1 MarkCoinStart
  230. 21: seg/base=9/18 seg/base=1/2 MarkCoinEnd
  231. 22: seg/base=8/15 seg/base=6/11 MarkCoinStart
  232. 23: seg/base=8/27 seg/base=6/12 MarkCoinEnd
  233. ----------------x-x--x-x-------------- addEndMovedSpans
  234. 00: coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
  235. 01: coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
  236. 02: coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
  237. 03: coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
  238. 04: coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
  239. 05: coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
  240. 06: coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
  241. 07: coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
  242. 08: coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
  243. 09: coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
  244. 10: coinSeg/Span/PtT=11/33/33 endSpan=6 oppSeg/Span/PtT=11/22/22 oppEndSpan=6 ExpandCoin
  245. 11: coinSeg/Span/PtT=2/30/30 endSpan=19 oppSeg/Span/PtT=2/3/3 oppEndSpan=19 ExpandCoin
  246. 12: seg/base=13/25 seg/base=5/9 MarkCoinStart
  247. 13: seg/base=13/26 seg/base=5/10 MarkCoinEnd
  248. 14: seg/base=4/7 seg/base=12/23 MarkCoinStart
  249. 15: seg/base=4/8 seg/base=12/24 MarkCoinEnd
  250. 16: seg/base=11/33 seg/base=3/34 MarkCoinStart
  251. 17: seg/base=11/35 seg/base=3/36 MarkCoinEnd
  252. 18: seg/base=2/30 seg/base=10/29 MarkCoinStart
  253. 19: seg/base=2/32 seg/base=10/31 MarkCoinEnd
  254. 20: seg/base=9/28 seg/base=1/1 MarkCoinStart
  255. 21: seg/base=9/18 seg/base=1/2 MarkCoinEnd
  256. 22: seg/base=8/15 seg/base=6/11 MarkCoinStart
  257. 23: seg/base=8/27 seg/base=6/12 MarkCoinEnd
  258. ----------------x-x--x-x-------------- expand
  259. 00: coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
  260. 01: coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
  261. 02: coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
  262. 03: coinSeg/Span/PtT=2/3/3 endSpan=30 oppSeg/Span/PtT=10/19/19 oppEndSpan=29 MissingCoin
  263. 04: coinSeg/Span/PtT=3/36/36 endSpan=6 oppSeg/Span/PtT=11/35/35 oppEndSpan=22 MissingCoin
  264. 05: coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
  265. 06: coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
  266. 07: coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
  267. 08: coinSeg/Span/PtT=10/19/19 endSpan=29 oppSeg/Span/PtT=2/3/3 oppEndSpan=30 MissingCoin
  268. 09: coinSeg/Span/PtT=11/35/35 endSpan=22 oppSeg/Span/PtT=3/36/36 oppEndSpan=6 MissingCoin
  269. 10: coinSeg/Span/PtT=11/33/33 endSpan=6 oppSeg/Span/PtT=11/22/22 oppEndSpan=6 ExpandCoin
  270. 11: coinSeg/Span/PtT=2/30/30 endSpan=19 oppSeg/Span/PtT=2/3/3 oppEndSpan=19 ExpandCoin
  271. 12: seg/base=13/25 seg/base=5/9 MarkCoinStart
  272. 13: seg/base=13/26 seg/base=5/10 MarkCoinEnd
  273. 14: seg/base=4/7 seg/base=12/23 MarkCoinStart
  274. 15: seg/base=4/8 seg/base=12/24 MarkCoinEnd
  275. 16: seg/base=11/33 seg/base=3/34 MarkCoinStart
  276. 17: seg/base=11/35 seg/base=3/36 MarkCoinEnd
  277. 18: seg/base=2/30 seg/base=10/29 MarkCoinStart
  278. 19: seg/base=2/32 seg/base=10/31 MarkCoinEnd
  279. 20: seg/base=9/28 seg/base=1/1 MarkCoinStart
  280. 21: seg/base=9/18 seg/base=1/2 MarkCoinEnd
  281. 22: seg/base=8/15 seg/base=6/11 MarkCoinStart
  282. 23: seg/base=8/27 seg/base=6/12 MarkCoinEnd
  283. ------------------xx-x-x-------------- addExpanded
  284. 00: coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
  285. 01: coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
  286. 02: seg/base=13/25 seg/base=5/9 MarkCoinStart
  287. 03: seg/base=13/26 seg/base=5/10 MarkCoinEnd
  288. 04: seg/base=4/7 seg/base=12/23 MarkCoinStart
  289. 05: seg/base=4/8 seg/base=12/24 MarkCoinEnd
  290. 06: seg/base=11/33 seg/base=3/34 MarkCoinStart
  291. 07: seg/base=11/22 seg/base=3/6 MarkCoinEnd
  292. 08: seg/base=3/36 MarkCoinInsert
  293. 09: seg/base=11/35 MarkCoinInsert
  294. 10: seg/base=2/3 seg/base=10/19 MarkCoinStart
  295. 11: seg/base=2/32 seg/base=10/31 MarkCoinEnd
  296. 12: seg/base=10/29 MarkCoinInsert
  297. 13: seg/base=2/30 MarkCoinInsert
  298. 14: seg/base=9/28 seg/base=1/1 MarkCoinStart
  299. 15: seg/base=9/18 seg/base=1/2 MarkCoinEnd
  300. 16: seg/base=8/15 seg/base=6/11 MarkCoinStart
  301. 17: seg/base=8/27 seg/base=6/12 MarkCoinEnd
  302. ------------------xx-x-x-------------- move_multiples
  303. 00: coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
  304. 01: coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
  305. 02: seg/base=13/25 seg/base=5/9 MarkCoinStart
  306. 03: seg/base=13/26 seg/base=5/10 MarkCoinEnd
  307. 04: seg/base=4/7 seg/base=12/23 MarkCoinStart
  308. 05: seg/base=4/8 seg/base=12/24 MarkCoinEnd
  309. 06: seg/base=11/33 seg/base=3/34 MarkCoinStart
  310. 07: seg/base=11/22 seg/base=3/6 MarkCoinEnd
  311. 08: seg/base=3/36 MarkCoinInsert
  312. 09: seg/base=11/35 MarkCoinInsert
  313. 10: seg/base=2/3 seg/base=10/19 MarkCoinStart
  314. 11: seg/base=2/32 seg/base=10/31 MarkCoinEnd
  315. 12: seg/base=10/29 MarkCoinInsert
  316. 13: seg/base=2/30 MarkCoinInsert
  317. 14: seg/base=9/28 seg/base=1/1 MarkCoinStart
  318. 15: seg/base=9/18 seg/base=1/2 MarkCoinEnd
  319. 16: seg/base=8/15 seg/base=6/11 MarkCoinStart
  320. 17: seg/base=8/27 seg/base=6/12 MarkCoinEnd
  321. ------------------xx-x-x-------------- move_nearby
  322. 00: coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
  323. 01: coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
  324. 02: seg/base=13/25 seg/base=5/9 MarkCoinStart
  325. 03: seg/base=13/26 seg/base=5/10 MarkCoinEnd
  326. 04: seg/base=4/7 seg/base=12/23 MarkCoinStart
  327. 05: seg/base=4/8 seg/base=12/24 MarkCoinEnd
  328. 06: seg/base=11/33 seg/base=3/34 MarkCoinStart
  329. 07: seg/base=11/22 seg/base=3/6 MarkCoinEnd
  330. 08: seg/base=3/36 MarkCoinInsert
  331. 09: seg/base=11/35 MarkCoinInsert
  332. 10: seg/base=2/3 seg/base=10/19 MarkCoinStart
  333. 11: seg/base=2/32 seg/base=10/31 MarkCoinEnd
  334. 12: seg/base=10/29 MarkCoinInsert
  335. 13: seg/base=2/30 MarkCoinInsert
  336. 14: seg/base=9/28 seg/base=1/1 MarkCoinStart
  337. 15: seg/base=9/18 seg/base=1/2 MarkCoinEnd
  338. 16: seg/base=8/15 seg/base=6/11 MarkCoinStart
  339. 17: seg/base=8/27 seg/base=6/12 MarkCoinEnd
  340. ------------------xx-x-x-------------- addExpanded
  341. 00: coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
  342. 01: coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
  343. 02: seg/base=13/25 seg/base=5/9 MarkCoinStart
  344. 03: seg/base=13/26 seg/base=5/10 MarkCoinEnd
  345. 04: seg/base=4/7 seg/base=12/23 MarkCoinStart
  346. 05: seg/base=4/8 seg/base=12/24 MarkCoinEnd
  347. 06: seg/base=11/33 seg/base=3/34 MarkCoinStart
  348. 07: seg/base=11/22 seg/base=3/6 MarkCoinEnd
  349. 08: seg/base=3/36 MarkCoinInsert
  350. 09: seg/base=11/35 MarkCoinInsert
  351. 10: seg/base=2/3 seg/base=10/19 MarkCoinStart
  352. 11: seg/base=2/32 seg/base=10/31 MarkCoinEnd
  353. 12: seg/base=10/29 MarkCoinInsert
  354. 13: seg/base=2/30 MarkCoinInsert
  355. 14: seg/base=9/28 seg/base=1/1 MarkCoinStart
  356. 15: seg/base=9/18 seg/base=1/2 MarkCoinEnd
  357. 16: seg/base=8/15 seg/base=6/11 MarkCoinStart
  358. 17: seg/base=8/27 seg/base=6/12 MarkCoinEnd
  359. ------------------xx-x-x-------------- mark
  360. 00: coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
  361. 01: coinSeg/Span/PtT=5/9/9 endSpan=10 oppSeg/Span/PtT=13/25/25 oppEndSpan=26 MissingCoin
  362. 02: seg/base=13/25 seg/base=5/9 MarkCoinStart
  363. 03: seg/base=13/26 seg/base=5/10 MarkCoinEnd
  364. 04: seg/base=4/7 seg/base=12/23 MarkCoinStart
  365. 05: seg/base=4/8 seg/base=12/24 MarkCoinEnd
  366. 06: seg/base=11/33 seg/base=3/34 MarkCoinStart
  367. 07: seg/base=11/22 seg/base=3/6 MarkCoinEnd
  368. 08: seg/base=3/36 MarkCoinInsert
  369. 09: seg/base=11/35 MarkCoinInsert
  370. 10: seg/base=2/3 seg/base=10/19 MarkCoinStart
  371. 11: seg/base=2/32 seg/base=10/31 MarkCoinEnd
  372. 12: seg/base=10/29 MarkCoinInsert
  373. 13: seg/base=2/30 MarkCoinInsert
  374. 14: seg/base=9/28 seg/base=1/1 MarkCoinStart
  375. 15: seg/base=9/18 seg/base=1/2 MarkCoinEnd
  376. 16: seg/base=8/15 seg/base=6/11 MarkCoinStart
  377. 17: seg/base=8/27 seg/base=6/12 MarkCoinEnd
  378. -------------------------------------- missing_coincidence
  379. -------------------------------------- expand
  380. -------------------------------------- expand
  381. -------------------------------------- apply
  382. SkOpSegment::markDone id=5 (118.119003,8.07219982 8.17210007,104.212997) t=0 [9] (118.119003,8.07219982) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
  383. SkOpSegment::markDone id=12 (123.289001,9.39620018 118.119003,8.07219982) t=0 [23] (123.289001,9.39620018) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
  384. SkOpSegment::markDone id=3 (124.603165,9.37966728 124.142731,9.41717815 123.674263,9.45534515 123.289001,9.39610004) t=0.0627286673 [34] (124.516441,9.38671017) tEnd=0.625091708 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
  385. SkOpSegment::markDone id=3 (124.603165,9.37966728 124.142731,9.41717815 123.674263,9.45534515 123.289001,9.39610004) t=0.625091708 [36] (123.752594,9.42682648) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
  386. SkOpSegment::markDone id=10 (126,9.39620018 125.631981,9.29586983 125.12252,9.3373785 124.602829,9.37972069) t=0 [19] (126,9.39620018) tEnd=0.307128906 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
  387. SkOpSegment::markDone id=10 (126,9.39620018 125.631981,9.29586983 125.12252,9.3373785 124.602829,9.37972069) t=0.307128906 [29] (125.624687,9.33981037) tEnd=0.9375 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
  388. SkOpSegment::markDone id=1 (0,353.891998 126,9.39610004) t=0 [1] (0,353.891998) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
  389. SkOpSegment::markDone id=6 (8.17210007,104.212997 0,259.298737) t=0 [11] (8.17210007,104.212997) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
  390. -------------------------------------- findOverlaps
  391. SkOpSegment::debugShowActiveSpans id=8 (8.17210007,104.212997 -2.71619996e-07,259.298737) t=0 tEnd=0.583904956 windSum=? oppSum=? windValue=1 oppValue=1
  392. SkOpSegment::debugShowActiveSpans id=8 (-2.71619996e-07,259.298737 -5.82350016,369.813995) t=0.583904956 tEnd=1 windSum=? windValue=1
  393. SkOpSegment::debugShowActiveSpans id=9 (-5.82350016,369.813995 7.26031715e-07,353.891998) t=0 tEnd=0.0441765002 windSum=? windValue=1
  394. SkOpSegment::debugShowActiveSpans id=9 (7.26031715e-07,353.891998 126,9.39620018) t=0.0441765002 tEnd=1 windSum=? oppSum=? windValue=1 oppValue=1
  395. SkOpSegment::debugShowActiveSpans id=10 (124.700119,9.37182617 124.66775,9.37443162 124.63531,9.3770743 124.602829,9.37972069) t=0.9375 tEnd=1 windSum=? windValue=1
  396. SkOpSegment::debugShowActiveSpans id=11 (124.602829,9.37972069 124.574059,9.3820647 124.545259,9.38441166 124.516449,9.38673687) t=0 tEnd=0.0625 windSum=? windValue=1
  397. SkOpSegment::debugShowActiveSpans id=11 (124.516449,9.38673687 124.257155,9.40766372 123.997126,9.42685982 123.752594,9.4268837) t=0.0625 tEnd=0.625 windSum=? oppSum=? windValue=1 oppValue=1
  398. SkOpSegment::debugShowActiveSpans id=11 (123.752594,9.4268837 123.589573,9.42689962 123.433437,9.41839421 123.289001,9.39620018) t=0.625 tEnd=1 windSum=? oppSum=? windValue=1 oppValue=1
  399. SkOpSegment::debugShowActiveSpans id=13 (118.119003,8.07219982 8.17210007,104.212997) t=0 tEnd=1 windSum=? oppSum=? windValue=1 oppValue=1
  400. SkOpSegment::debugShowActiveSpans id=2 (126,9.39610004 125.886971,9.36530236 125.760605,9.34788101 125.624695,9.33975124) t=0 tEnd=0.307190555 windSum=? oppSum=? windValue=1 oppValue=1
  401. SkOpSegment::debugShowActiveSpans id=2 (125.624695,9.33975124 125.345738,9.3230648 125.026588,9.34552196 124.700119,9.37180042) t=0.307190555 tEnd=0.937702598 windSum=? oppSum=? windValue=1 oppValue=1
  402. SkOpSegment::debugShowActiveSpans id=2 (124.700119,9.37180042 124.667862,9.37439685 124.635532,9.37703031 124.603165,9.37966728) t=0.937702598 tEnd=1 windSum=? windValue=1
  403. SkOpSegment::debugShowActiveSpans id=3 (124.603165,9.37966728 124.574282,9.38202029 124.545364,9.3843762 124.516441,9.38671017) t=0 tEnd=0.0627286673 windSum=? windValue=1
  404. SkOpSegment::debugShowActiveSpans id=4 (123.289001,9.39610004 118.119003,8.07219982) t=0 tEnd=1 windSum=? oppSum=? windValue=1 oppValue=1
  405. SkOpSegment::debugShowActiveSpans id=7 (0,259.298737 0,353.891998) t=0 tEnd=1 windSum=? windValue=1
  406. -------------------------------------- calc_angles
  407. SkOpSegment::sortAngles [8] tStart=0 [15]
  408. SkOpSegment::sortAngles [8] tStart=0.583904956 [27]
  409. SkOpAngle::after [8/2] 5/5 tStart=0.583904956 tEnd=0 < [7/23] 23/23 tStart=0 tEnd=1 < [8/3] 21/21 tStart=0.583904956 tEnd=1 F 4
  410. SkOpAngle::afterPart {{{0,259.298737}, {8.17210034,104.212997}}} id=8
  411. SkOpAngle::afterPart {{{0,259.298737}, {0,353.891998}}} id=7
  412. SkOpAngle::afterPart {{{0,259.298737}, {-5.82349988,369.813995}}} id=8
  413. SkOpSegment::sortAngles [9] tStart=0.0441765002 [28]
  414. SkOpAngle::after [9/4] 21/21 tStart=0.0441765002 tEnd=0 < [7/24] 7/7 tStart=1 tEnd=0 < [9/5] 5/5 tStart=0.0441765002 tEnd=1 F 4
  415. SkOpAngle::afterPart {{{0,353.891998}, {-5.82350088,369.813995}}} id=9
  416. SkOpAngle::afterPart {{{0,353.891998}, {0,259.298737}}} id=7
  417. SkOpAngle::afterPart {{{0,353.891998}, {125.999999,9.39620018}}} id=9
  418. SkOpSegment::sortAngles [9] tStart=1 [18]
  419. SkOpSegment::sortAngles [10] tStart=0.9375 [31]
  420. SkOpAngle::after [10/7] 17/17 tStart=0.9375 tEnd=1 < [2/19] 17/17 tStart=0.937702598 tEnd=1 < [2/18] 1/1 tStart=0.937702598 tEnd=0.307190555 T 12
  421. SkOpAngle::afterPart {{{124.700119,9.37180042}, {124.66775,9.37440587}, {124.63531,9.37704855}, {124.602829,9.37969494}}} id=10
  422. SkOpAngle::afterPart {{{124.700119,9.37180042}, {124.667862,9.37439685}, {124.635532,9.37703031}, {124.603165,9.37966728}}} id=2
  423. SkOpAngle::afterPart {{{124.700119,9.37180042}, {125.026588,9.34552196}, {125.345738,9.3230648}, {125.624695,9.33975124}}} id=2
  424. SkOpSegment::sortAngles [11] tStart=0.0625 [33]
  425. SkOpAngle::after [11/8] 1/1 tStart=0.0625 tEnd=0 < [3/20] 1/1 tStart=0.0627286673 tEnd=0 < [11/9] 17/17 tStart=0.0625 tEnd=0.625 T 12
  426. SkOpAngle::afterPart {{{124.516441,9.38671017}, {124.545252,9.38438496}, {124.574051,9.382038}, {124.602821,9.37969398}}} id=11
  427. SkOpAngle::afterPart {{{124.516441,9.38671017}, {124.545364,9.3843762}, {124.574282,9.38202029}, {124.603165,9.37966728}}} id=3
  428. SkOpAngle::afterPart {{{124.516441,9.38671017}, {124.257148,9.40763702}, {123.997118,9.42683311}, {123.752586,9.42685699}}} id=11
  429. SkOpSegment::sortAngles [11] tStart=0.625 [35]
  430. SkOpSegment::sortAngles [11] tStart=1 [22]
  431. SkOpSegment::sortAngles [13] tStart=0 [25]
  432. SkOpSegment::sortAngles [13] tStart=1 [26]
  433. SkOpSegment::sortAngles [2] tStart=0 [3]
  434. SkOpSegment::sortAngles [2] tStart=0.307190555 [30]
  435. SkOpSegment::sortAngles [2] tStart=0.937702598 [32]
  436. SkOpSegment::sortAngles [3] tStart=0.0627286673 [34]
  437. SkOpSegment::sortAngles [4] tStart=0 [7]
  438. SkOpSegment::sortAngles [4] tStart=1 [8]
  439. SkOpSegment::sortAngles [7] tStart=0 [13]
  440. SkOpSegment::sortAngles [7] tStart=1 [14]
  441. coinSpan - id=13 t=0 tEnd=1
  442. coinSpan + id=5 t=0 tEnd=1
  443. coinSpan - id=4 t=0 tEnd=1
  444. coinSpan + id=12 t=0 tEnd=1
  445. coinSpan - id=11 t=0.0625 tEnd=1
  446. coinSpan + id=3 t=0.0627286673 tEnd=1
  447. coinSpan - id=2 t=0 tEnd=0.937702598
  448. coinSpan + id=10 t=0 tEnd=0.9375
  449. coinSpan - id=9 t=0.0441765002 tEnd=1
  450. coinSpan + id=1 t=0 tEnd=1
  451. coinSpan - id=8 t=0 tEnd=0.583904956
  452. coinSpan + id=6 t=0 tEnd=1
  453. SkOpSpan::sortableTop dir=kLeft seg=8 t=0.291952478 pt=(4.08605003,181.755859)
  454. SkOpSpan::sortableTop [0] valid=1 operand=1 span=15 ccw=0 seg=8 {{{8.17210007f, 104.212997f}, {-5.82350016f, 369.813995f}}} t=0.291952478 pt=(4.08605003,181.755859) slope=(-13.9956002,265.600998)
  455. SkOpSegment::markWinding id=8 (8.17210007,104.212997 -5.82350016,369.813995) t=0 [15] (8.17210007,104.212997) tEnd=0.583904956 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=1
  456. SkOpSegment::markWinding id=8 (8.17210007,104.212997 -5.82350016,369.813995) t=0 [15] (8.17210007,104.212997) tEnd=0.583904956 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=1
  457. SkOpSegment::markWinding id=13 (118.119003,8.07219982 8.17210007,104.212997) t=0 [25] (118.119003,8.07219982) tEnd=1 newWindSum=1 newOppSum=1 oppSum=? windSum=? windValue=1 oppValue=1
  458. SkOpSegment::markWinding id=4 (123.289001,9.39610004 118.119003,8.07219982) t=0 [7] (123.289001,9.39610004) tEnd=1 newWindSum=1 newOppSum=1 oppSum=? windSum=? windValue=1 oppValue=1
  459. SkOpSegment::markWinding id=11 (124.602829,9.37972069 124.142509,9.41722488 123.674164,9.45538425 123.289001,9.39620018) t=0.625 [35] (123.752594,9.4268837) tEnd=1 newWindSum=1 newOppSum=1 oppSum=? windSum=? windValue=1 oppValue=1
  460. SkOpSegment::markWinding id=11 (124.602829,9.37972069 124.142509,9.41722488 123.674164,9.45538425 123.289001,9.39620018) t=0.0625 [33] (124.516449,9.38673687) tEnd=0.625 newWindSum=1 newOppSum=1 oppSum=? windSum=? windValue=1 oppValue=1
  461. SkOpSegment::activeOp id=8 t=0.583904956 tEnd=0 op=sect miFrom=1 miTo=0 suFrom=1 suTo=0 result=1
  462. SkOpSegment::findNextOp simple
  463. SkOpSegment::markDone id=8 (8.17210007,104.212997 -5.82350016,369.813995) t=0 [15] (8.17210007,104.212997) tEnd=0.583904956 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=1
  464. bridgeOp current id=8 from=(-2.71619996e-07,259.298737) to=(8.17210007,104.212997)
  465. SkOpSegment::findNextOp simple
  466. SkOpSegment::markDone id=13 (118.119003,8.07219982 8.17210007,104.212997) t=0 [25] (118.119003,8.07219982) tEnd=1 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=1
  467. bridgeOp current id=13 from=(8.17210007,104.212997) to=(118.119003,8.07219982)
  468. path.moveTo(-2.71619996e-07,259.298737);
  469. path.lineTo(8.17210007,104.212997);
  470. SkOpSegment::findNextOp simple
  471. SkOpSegment::markDone id=4 (123.289001,9.39610004 118.119003,8.07219982) t=0 [7] (123.289001,9.39610004) tEnd=1 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=1
  472. bridgeOp current id=4 from=(118.119003,8.07219982) to=(123.289001,9.39610004)
  473. path.lineTo(118.119003,8.07219982);
  474. SkOpSegment::findNextOp simple
  475. SkOpSegment::markDone id=11 (124.602829,9.37972069 124.142509,9.41722488 123.674164,9.45538425 123.289001,9.39620018) t=0.625 [35] (123.752594,9.4268837) tEnd=1 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=1
  476. bridgeOp current id=11 from=(123.289001,9.39620018) to=(123.752594,9.4268837)
  477. path.lineTo(123.289001,9.39610004);
  478. path.cubicTo(123.433441,9.41839409, 123.589569,9.42689991, 123.752594,9.4268837);
  479. SkOpSegment::markWinding id=11 (124.602829,9.37972069 124.142509,9.41722488 123.674164,9.45538425 123.289001,9.39620018) t=0 [21] (124.602829,9.37972069) tEnd=0.0625 newWindSum=1 newOppSum=1 oppSum=? windSum=? windValue=1 oppValue=0
  480. SkOpSegment::markWinding id=10 (126,9.39620018 125.631981,9.29586983 125.12252,9.3373785 124.602829,9.37972069) t=0.9375 [31] (124.700119,9.37182617) tEnd=1 newWindSum=1 newOppSum=1 oppSum=? windSum=? windValue=1 oppValue=0
  481. SkOpSegment::markAngle last segment=10 span=31 windSum=1
  482. SkOpSegment::markWinding id=3 (124.603165,9.37966728 124.142731,9.41717815 123.674263,9.45534515 123.289001,9.39610004) t=0 [5] (124.603165,9.37966728) tEnd=0.0627286673 newWindSum=1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
  483. SkOpSegment::markWinding id=2 (126,9.39610004 125.632057,9.29584408 125.122734,9.33733845 124.603165,9.37966728) t=0.937702598 [32] (124.700119,9.37180042) tEnd=1 newWindSum=1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
  484. SkOpSegment::markAngle last segment=2 span=32 windSum=1
  485. SkOpSegment::findNextOp
  486. SkOpAngle::dumpOne [11/9] next=11/8 sect=17/17 s=0.0625 [33] e=0.625 [35] sgn=-1 windVal=1 windSum=1 oppVal=1 oppSum=1 operand
  487. SkOpAngle::dumpOne [11/8] next=3/20 sect=1/1 s=0.0625 [33] e=0 [21] sgn=1 windVal=1 windSum=1 oppVal=0 oppSum=1 operand
  488. SkOpAngle::dumpOne [3/20] next=11/9 sect=1/1 s=0.0627286673 [34] e=0 [5] sgn=1 windVal=1 windSum=1 oppVal=0 oppSum=0
  489. SkOpSegment::activeOp id=11 t=0.0625 tEnd=0 op=sect miFrom=1 miTo=1 suFrom=1 suTo=0 result=1
  490. SkOpSegment::findNextOp chase.append segment=10 span=31 windSum=1
  491. SkOpSegment::activeOp id=3 t=0.0627286673 tEnd=0 op=sect miFrom=1 miTo=0 suFrom=0 suTo=0 result=0
  492. SkOpSegment::markDone id=3 (124.603165,9.37966728 124.142731,9.41717815 123.674263,9.45534515 123.289001,9.39610004) t=0 [5] (124.603165,9.37966728) tEnd=0.0627286673 newWindSum=1 newOppSum=0 oppSum=0 windSum=1 windValue=1 oppValue=0
  493. SkOpSegment::markDone id=2 (126,9.39610004 125.632057,9.29584408 125.122734,9.33733845 124.603165,9.37966728) t=0.937702598 [32] (124.700119,9.37180042) tEnd=1 newWindSum=1 newOppSum=0 oppSum=0 windSum=1 windValue=1 oppValue=0
  494. SkOpSegment::findNextOp chase.append segment=2 span=32 windSum=1
  495. SkOpSegment::markDone id=11 (124.602829,9.37972069 124.142509,9.41722488 123.674164,9.45538425 123.289001,9.39620018) t=0.0625 [33] (124.516449,9.38673687) tEnd=0.625 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=1
  496. SkOpSegment::findNextOp from:[11] to:[11] start=-1132576784 end=-1353716568
  497. bridgeOp current id=11 from=(123.752594,9.4268837) to=(124.516449,9.38673687)
  498. path.cubicTo(123.997124,9.42685986, 124.257156,9.40766335, 124.516449,9.38673687);
  499. SkOpSegment::findNextOp simple
  500. SkOpSegment::markDone id=11 (124.602829,9.37972069 124.142509,9.41722488 123.674164,9.45538425 123.289001,9.39620018) t=0 [21] (124.602829,9.37972069) tEnd=0.0625 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=0
  501. bridgeOp current id=11 from=(124.516449,9.38673687) to=(124.602829,9.37972069)
  502. path.cubicTo(124.545258,9.38441181, 124.574059,9.38206482, 124.602829,9.37972069);
  503. SkOpSegment::markWinding id=2 (126,9.39610004 125.632057,9.29584408 125.122734,9.33733845 124.603165,9.37966728) t=0.307190555 [30] (125.624695,9.33975124) tEnd=0.937702598 newWindSum=1 newOppSum=-1 oppSum=? windSum=? windValue=1 oppValue=1
  504. SkOpSegment::markWinding id=2 (126,9.39610004 125.632057,9.29584408 125.122734,9.33733845 124.603165,9.37966728) t=0 [3] (126,9.39610004) tEnd=0.307190555 newWindSum=1 newOppSum=-1 oppSum=? windSum=? windValue=1 oppValue=1
  505. SkOpSegment::markWinding id=9 (-5.82350016,369.813995 126,9.39620018) t=0.0441765002 [28] (7.26031715e-07,353.891998) tEnd=1 newWindSum=-1 newOppSum=1 oppSum=? windSum=? windValue=1 oppValue=1
  506. SkOpSegment::markAngle last segment=9 span=28 windSum=-1
  507. SkOpSegment::findNextOp
  508. SkOpAngle::dumpOne [10/7] next=2/19 sect=17/17 s=0.9375 [31] e=1 [20] sgn=-1 windVal=1 windSum=1 oppVal=0 oppSum=1 operand
  509. SkOpAngle::dumpOne [2/19] next=2/18 sect=17/17 s=0.937702598 [32] e=1 [4] sgn=-1 windVal=1 windSum=1 oppVal=0 oppSum=0 done
  510. SkOpAngle::dumpOne [2/18] next=10/7 sect=1/1 s=0.937702598 [32] e=0.307190555 [30] sgn=1 windVal=1 windSum=1 oppVal=1 oppSum=-1
  511. SkOpSegment::activeOp id=2 t=0.937702598 tEnd=1 op=sect = result=1
  512. SkOpSegment::activeOp id=2 t=0.937702598 tEnd=0.307190555 op=sect miFrom=0 miTo=1 suFrom=1 suTo=0 result=0
  513. SkOpSegment::markDone id=2 (126,9.39610004 125.632057,9.29584408 125.122734,9.33733845 124.603165,9.37966728) t=0.307190555 [30] (125.624695,9.33975124) tEnd=0.937702598 newWindSum=1 newOppSum=-1 oppSum=-1 windSum=1 windValue=1 oppValue=1
  514. SkOpSegment::markDone id=2 (126,9.39610004 125.632057,9.29584408 125.122734,9.33733845 124.603165,9.37966728) t=0 [3] (126,9.39610004) tEnd=0.307190555 newWindSum=1 newOppSum=-1 oppSum=-1 windSum=1 windValue=1 oppValue=1
  515. SkOpSegment::markDone id=9 (-5.82350016,369.813995 126,9.39620018) t=0.0441765002 [28] (7.26031715e-07,353.891998) tEnd=1 newWindSum=-1 newOppSum=1 oppSum=1 windSum=-1 windValue=1 oppValue=1
  516. SkOpSegment::findNextOp chase.append segment=9 span=28 windSum=-1
  517. SkOpSegment::markDone id=10 (126,9.39620018 125.631981,9.29586983 125.12252,9.3373785 124.602829,9.37972069) t=0.9375 [31] (124.700119,9.37182617) tEnd=1 newWindSum=1 newOppSum=1 oppSum=1 windSum=1 windValue=1 oppValue=0
  518. SkOpSegment::findNextOp from:[10] to:[2] start=-1132576976 end=-1353719496
  519. bridgeOp current id=10 from=(124.602829,9.37972069) to=(124.700119,9.37182617)
  520. path.cubicTo(124.635307,9.37707424, 124.667747,9.37443161, 124.700119,9.37182617);
  521. SkOpSegment::markWinding id=7 (0,259.298737 0,353.891998) t=0 [13] (0,259.298737) tEnd=1 newWindSum=1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
  522. SkOpSegment::markWinding id=9 (-5.82350016,369.813995 126,9.39620018) t=0 [17] (-5.82350016,369.813995) tEnd=0.0441765002 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
  523. SkOpSegment::markWinding id=8 (8.17210007,104.212997 -5.82350016,369.813995) t=0.583904956 [27] (-2.71619996e-07,259.298737) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
  524. SkOpSegment::debugShowActiveSpans id=8 (-2.71619996e-07,259.298737 -5.82350016,369.813995) t=0.583904956 tEnd=1 windSum=-1 oppSum=0 windValue=1 oppValue=0
  525. SkOpSegment::debugShowActiveSpans id=9 (-5.82350016,369.813995 7.26031715e-07,353.891998) t=0 tEnd=0.0441765002 windSum=-1 oppSum=0 windValue=1 oppValue=0
  526. SkOpSegment::debugShowActiveSpans id=7 (0,259.298737 0,353.891998) t=0 tEnd=1 windSum=1 oppSum=0 windValue=1 oppValue=0
  527. SkOpSegment::activeOp id=7 t=1 tEnd=0 op=sect miFrom=1 miTo=0 suFrom=0 suTo=0 result=0
  528. SkOpSegment::markDone id=7 (0,259.298737 0,353.891998) t=0 [13] (0,259.298737) tEnd=1 newWindSum=1 newOppSum=0 oppSum=0 windSum=1 windValue=1 oppValue=0
  529. bridgeOp chase.append id=7 windSum=1
  530. SkOpSegment::debugShowActiveSpans id=8 (-2.71619996e-07,259.298737 -5.82350016,369.813995) t=0.583904956 tEnd=1 windSum=-1 oppSum=0 windValue=1 oppValue=0
  531. SkOpSegment::debugShowActiveSpans id=9 (-5.82350016,369.813995 7.26031715e-07,353.891998) t=0 tEnd=0.0441765002 windSum=-1 oppSum=0 windValue=1 oppValue=0
  532. SkOpSegment::activeOp id=8 t=0.583904956 tEnd=1 op=sect miFrom=0 miTo=0 suFrom=1 suTo=0 result=0
  533. SkOpSegment::markDone id=8 (8.17210007,104.212997 -5.82350016,369.813995) t=0.583904956 [27] (-2.71619996e-07,259.298737) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
  534. SkOpSegment::markDone id=9 (-5.82350016,369.813995 126,9.39620018) t=0 [17] (-5.82350016,369.813995) tEnd=0.0441765002 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
  535. </div>
  536. </div>
  537. <script type="text/javascript">
  538. var testDivs = [
  539. bug8380,
  540. ];
  541. var decimal_places = 3; // make this 3 to show more precision
  542. var tests = [];
  543. var testLines = [];
  544. var testTitles = [];
  545. var testIndex = 0;
  546. var ctx;
  547. var xmin, xmax, focusXmin, focusXmax;
  548. var ymin, ymax, focusYmin, focusYmax;
  549. var scale;
  550. var mouseX, mouseY;
  551. var srcLeft, srcTop;
  552. var screenWidth, screenHeight;
  553. var drawnPts, drawnLines, drawnQuads, drawnConics, drawnCubics;
  554. var curveT = 0;
  555. var pt_labels = 2;
  556. var collect_bounds = false;
  557. var control_lines = 0;
  558. var curve_t = false;
  559. var debug_xy = 1;
  560. var focus_enabled = false;
  561. var focus_on_selection = false;
  562. var step_limit = 0;
  563. var draw_active = false;
  564. var draw_add = false;
  565. var draw_angle = 0;
  566. var draw_coincidence = false;
  567. var draw_deriviatives = 0;
  568. var draw_direction = false;
  569. var draw_hints = false;
  570. var draw_id = false;
  571. var draw_intersection = 0;
  572. var draw_intersectT = false;
  573. var draw_legend = true;
  574. var draw_log = false;
  575. var draw_mark = false;
  576. var draw_midpoint = false;
  577. var draw_op = 0;
  578. var draw_sequence = false;
  579. var draw_sort = 0;
  580. var draw_top = false;
  581. var draw_path = 3;
  582. var draw_computed = 0;
  583. var retina_scale = !!window.devicePixelRatio;
  584. var activeCount = 0;
  585. var addCount = 0;
  586. var angleCount = 0;
  587. var coinCount = 0;
  588. var opCount = 0;
  589. var sectCount = 0;
  590. var sortCount = 0;
  591. var topCount = 0;
  592. var markCount = 0;
  593. var activeMax = 0;
  594. var addMax = 0;
  595. var angleMax = 0;
  596. var coinMax = 0;
  597. var sectMax = 0;
  598. var sectMax2 = 0;
  599. var sortMax = 0;
  600. var topMax = 0;
  601. var markMax = 0;
  602. var opMax = 0;
  603. var stepMax = 0;
  604. var lastIndex = 0;
  605. var hasPath = false;
  606. var hasAlignedPath = false;
  607. var hasComputedPath = false;
  608. var angleBetween = false;
  609. var afterIndex = 0;
  610. var firstActiveSpan = -1;
  611. var logStart = -1;
  612. var logRange = 0;
  613. var SPAN_ID = 0;
  614. var SPAN_X1 = SPAN_ID + 1;
  615. var SPAN_Y1 = SPAN_X1 + 1;
  616. var SPAN_X2 = SPAN_Y1 + 1;
  617. var SPAN_Y2 = SPAN_X2 + 1;
  618. var SPAN_L_TX = SPAN_Y2 + 1;
  619. var SPAN_L_TY = SPAN_L_TX + 1;
  620. var SPAN_L_OTHER = SPAN_L_TY + 1;
  621. var SPAN_L_OTHERT = SPAN_L_OTHER + 1;
  622. var SPAN_L_OTHERI = SPAN_L_OTHERT + 1;
  623. var SPAN_L_SUM = SPAN_L_OTHERI + 1;
  624. var SPAN_L_VAL = SPAN_L_SUM + 1;
  625. var SPAN_L_OPP = SPAN_L_VAL + 1;
  626. var SPAN_X3 = SPAN_Y2 + 1;
  627. var SPAN_Y3 = SPAN_X3 + 1;
  628. var SPAN_Q_TX = SPAN_Y3 + 1;
  629. var SPAN_Q_TY = SPAN_Q_TX + 1;
  630. var SPAN_Q_OTHER = SPAN_Q_TY + 1;
  631. var SPAN_Q_OTHERT = SPAN_Q_OTHER + 1;
  632. var SPAN_Q_OTHERI = SPAN_Q_OTHERT + 1;
  633. var SPAN_Q_SUM = SPAN_Q_OTHERI + 1;
  634. var SPAN_Q_VAL = SPAN_Q_SUM + 1;
  635. var SPAN_Q_OPP = SPAN_Q_VAL + 1;
  636. var SPAN_K_W = SPAN_Y3 + 1;
  637. var SPAN_K_TX = SPAN_K_W + 1;
  638. var SPAN_K_TY = SPAN_K_TX + 1;
  639. var SPAN_K_OTHER = SPAN_K_TY + 1;
  640. var SPAN_K_OTHERT = SPAN_K_OTHER + 1;
  641. var SPAN_K_OTHERI = SPAN_K_OTHERT + 1;
  642. var SPAN_K_SUM = SPAN_K_OTHERI + 1;
  643. var SPAN_K_VAL = SPAN_K_SUM + 1;
  644. var SPAN_K_OPP = SPAN_K_VAL + 1;
  645. var SPAN_X4 = SPAN_Y3 + 1;
  646. var SPAN_Y4 = SPAN_X4 + 1;
  647. var SPAN_C_TX = SPAN_Y4 + 1;
  648. var SPAN_C_TY = SPAN_C_TX + 1;
  649. var SPAN_C_OTHER = SPAN_C_TY + 1;
  650. var SPAN_C_OTHERT = SPAN_C_OTHER + 1;
  651. var SPAN_C_OTHERI = SPAN_C_OTHERT + 1;
  652. var SPAN_C_SUM = SPAN_C_OTHERI + 1;
  653. var SPAN_C_VAL = SPAN_C_SUM + 1;
  654. var SPAN_C_OPP = SPAN_C_VAL + 1;
  655. var ACTIVE_LINE_SPAN = 1;
  656. var ACTIVE_QUAD_SPAN = ACTIVE_LINE_SPAN + 1;
  657. var ACTIVE_CONIC_SPAN = ACTIVE_QUAD_SPAN + 1;
  658. var ACTIVE_CUBIC_SPAN = ACTIVE_CONIC_SPAN + 1;
  659. var ADD_MOVETO = ACTIVE_CUBIC_SPAN + 1;
  660. var ADD_LINETO = ADD_MOVETO + 1;
  661. var ADD_QUADTO = ADD_LINETO + 1;
  662. var ADD_CONICTO = ADD_QUADTO + 1;
  663. var ADD_CUBICTO = ADD_CONICTO + 1;
  664. var ADD_CLOSE = ADD_CUBICTO + 1;
  665. var ADD_FILL = ADD_CLOSE + 1;
  666. var PATH_LINE = ADD_FILL + 1;
  667. var PATH_QUAD = PATH_LINE + 1;
  668. var PATH_CONIC = PATH_QUAD + 1;
  669. var PATH_CUBIC = PATH_CONIC + 1;
  670. var INTERSECT_LINE = PATH_CUBIC + 1;
  671. var INTERSECT_LINE_2 = INTERSECT_LINE + 1;
  672. var INTERSECT_LINE_NO = INTERSECT_LINE_2 + 1;
  673. var INTERSECT_QUAD_LINE = INTERSECT_LINE_NO + 1;
  674. var INTERSECT_QUAD_LINE_2 = INTERSECT_QUAD_LINE + 1;
  675. var INTERSECT_QUAD_LINE_NO = INTERSECT_QUAD_LINE_2 + 1;
  676. var INTERSECT_QUAD = INTERSECT_QUAD_LINE_NO + 1;
  677. var INTERSECT_QUAD_2 = INTERSECT_QUAD + 1;
  678. var INTERSECT_QUAD_NO = INTERSECT_QUAD_2 + 1;
  679. var INTERSECT_CONIC_LINE = INTERSECT_QUAD_NO + 1;
  680. var INTERSECT_CONIC_LINE_2 = INTERSECT_CONIC_LINE + 1;
  681. var INTERSECT_CONIC_LINE_NO = INTERSECT_CONIC_LINE_2 + 1;
  682. var INTERSECT_CONIC_QUAD = INTERSECT_CONIC_LINE_NO + 1;
  683. var INTERSECT_CONIC_QUAD_2 = INTERSECT_CONIC_QUAD + 1;
  684. var INTERSECT_CONIC_QUAD_3 = INTERSECT_CONIC_QUAD_2 + 1;
  685. var INTERSECT_CONIC_QUAD_4 = INTERSECT_CONIC_QUAD_3 + 1;
  686. var INTERSECT_CONIC_QUAD_NO = INTERSECT_CONIC_QUAD_4 + 1;
  687. var INTERSECT_CONIC = INTERSECT_CONIC_QUAD_NO + 1;
  688. var INTERSECT_CONIC_2 = INTERSECT_CONIC + 1;
  689. var INTERSECT_CONIC_NO = INTERSECT_CONIC_2 + 1;
  690. var INTERSECT_SELF_CUBIC = INTERSECT_CONIC_NO + 1;
  691. var INTERSECT_SELF_CUBIC_NO = INTERSECT_SELF_CUBIC + 1;
  692. var INTERSECT_CUBIC_LINE = INTERSECT_SELF_CUBIC_NO + 1;
  693. var INTERSECT_CUBIC_LINE_2 = INTERSECT_CUBIC_LINE + 1;
  694. var INTERSECT_CUBIC_LINE_3 = INTERSECT_CUBIC_LINE_2 + 1;
  695. var INTERSECT_CUBIC_LINE_NO = INTERSECT_CUBIC_LINE_3 + 1;
  696. var INTERSECT_CUBIC_QUAD = INTERSECT_CUBIC_LINE_NO + 1;
  697. var INTERSECT_CUBIC_QUAD_2 = INTERSECT_CUBIC_QUAD + 1;
  698. var INTERSECT_CUBIC_QUAD_3 = INTERSECT_CUBIC_QUAD_2 + 1;
  699. var INTERSECT_CUBIC_QUAD_4 = INTERSECT_CUBIC_QUAD_3 + 1;
  700. var INTERSECT_CUBIC_QUAD_NO = INTERSECT_CUBIC_QUAD_4 + 1;
  701. var INTERSECT_CUBIC = INTERSECT_CUBIC_QUAD_NO + 1;
  702. var INTERSECT_CUBIC_2 = INTERSECT_CUBIC + 1;
  703. var INTERSECT_CUBIC_3 = INTERSECT_CUBIC_2 + 1;
  704. var INTERSECT_CUBIC_4 = INTERSECT_CUBIC_3 + 1;
  705. // FIXME: add cubic 5- 9
  706. var INTERSECT_CUBIC_NO = INTERSECT_CUBIC_4 + 1;
  707. var SORT_UNARY = INTERSECT_CUBIC_NO + 1;
  708. var SORT_BINARY = SORT_UNARY + 1;
  709. var OP_DIFFERENCE = SORT_BINARY + 1;
  710. var OP_INTERSECT = OP_DIFFERENCE + 1;
  711. var OP_UNION = OP_INTERSECT + 1;
  712. var OP_XOR = OP_UNION + 1;
  713. var MARK_LINE = OP_XOR + 1;
  714. var MARK_QUAD = MARK_LINE + 1;
  715. var MARK_CONIC = MARK_QUAD + 1;
  716. var MARK_CUBIC = MARK_CONIC + 1;
  717. var MARK_DONE_LINE = MARK_CUBIC + 1;
  718. var MARK_DONE_QUAD = MARK_DONE_LINE + 1;
  719. var MARK_DONE_CONIC = MARK_DONE_QUAD + 1;
  720. var MARK_DONE_CUBIC = MARK_DONE_CONIC + 1;
  721. var MARK_UNSORTABLE_LINE = MARK_DONE_CUBIC + 1;
  722. var MARK_UNSORTABLE_QUAD = MARK_UNSORTABLE_LINE + 1;
  723. var MARK_UNSORTABLE_CONIC = MARK_UNSORTABLE_QUAD + 1;
  724. var MARK_UNSORTABLE_CUBIC = MARK_UNSORTABLE_CONIC + 1;
  725. var MARK_SIMPLE_LINE = MARK_UNSORTABLE_CUBIC + 1;
  726. var MARK_SIMPLE_QUAD = MARK_SIMPLE_LINE + 1;
  727. var MARK_SIMPLE_CONIC = MARK_SIMPLE_QUAD + 1;
  728. var MARK_SIMPLE_CUBIC = MARK_SIMPLE_CONIC + 1;
  729. var MARK_SIMPLE_DONE_LINE = MARK_SIMPLE_CUBIC + 1;
  730. var MARK_SIMPLE_DONE_QUAD = MARK_SIMPLE_DONE_LINE + 1;
  731. var MARK_SIMPLE_DONE_CONIC = MARK_SIMPLE_DONE_QUAD + 1;
  732. var MARK_SIMPLE_DONE_CUBIC = MARK_SIMPLE_DONE_CONIC + 1;
  733. var MARK_DONE_UNARY_LINE = MARK_SIMPLE_DONE_CUBIC + 1;
  734. var MARK_DONE_UNARY_QUAD = MARK_DONE_UNARY_LINE + 1;
  735. var MARK_DONE_UNARY_CONIC = MARK_DONE_UNARY_QUAD + 1;
  736. var MARK_DONE_UNARY_CUBIC = MARK_DONE_UNARY_CONIC + 1;
  737. var MARK_ANGLE_LAST = MARK_DONE_UNARY_CUBIC + 1;
  738. var COMPUTED_SET_1 = MARK_ANGLE_LAST + 1;
  739. var COMPUTED_SET_2 = COMPUTED_SET_1 + 1;
  740. var ANGLE_AFTER = COMPUTED_SET_2 + 1;
  741. var ANGLE_AFTERPART = ANGLE_AFTER + 1;
  742. var ACTIVE_OP = ANGLE_AFTERPART + 1;
  743. var COIN_MAIN_SPAN = ACTIVE_OP + 1;
  744. var COIN_OPP_SPAN = COIN_MAIN_SPAN + 1;
  745. var FRAG_TYPE_LAST = COIN_OPP_SPAN;
  746. var REC_TYPE_UNKNOWN = -1;
  747. var REC_TYPE_PATH = 0;
  748. var REC_TYPE_PATH2 = 1;
  749. var REC_TYPE_SECT = 2;
  750. var REC_TYPE_ACTIVE = 3;
  751. var REC_TYPE_ADD = 4;
  752. var REC_TYPE_SORT = 5;
  753. var REC_TYPE_OP = 6;
  754. var REC_TYPE_MARK = 7;
  755. var REC_TYPE_COMPUTED = 8;
  756. var REC_TYPE_COIN = 9;
  757. var REC_TYPE_ANGLE = 10;
  758. var REC_TYPE_ACTIVE_OP = 11;
  759. var REC_TYPE_AFTERPART = 12;
  760. var REC_TYPE_TOP = 13;
  761. var REC_TYPE_COINCIDENCE = 14;
  762. var REC_TYPE_ALIGNED = 15;
  763. var REC_TYPE_LAST = REC_TYPE_ALIGNED;
  764. function strs_to_nums(strs) {
  765. var result = [];
  766. for (var idx = 1; idx < strs.length; ++idx) {
  767. var str = strs[idx];
  768. var num = parseFloat(str);
  769. if (isNaN(num)) {
  770. result.push(str);
  771. } else {
  772. result.push(num);
  773. }
  774. }
  775. return result;
  776. }
  777. function filter_str_by(id, str, regex, array) {
  778. if (regex.test(str)) {
  779. var strs = regex.exec(str);
  780. var result = strs_to_nums(strs);
  781. array.push(id);
  782. array.push(result);
  783. return true;
  784. }
  785. return false;
  786. }
  787. function construct_regexp2(pattern) {
  788. var escape = pattern.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
  789. escape = escape.replace(/UNSORTABLE/g, "\\*\\*\\* UNSORTABLE \\*\\*\\*");
  790. escape = escape.replace(/CUBIC_VAL/g, "\\(P_VAL P_VAL P_VAL P_VAL\\)");
  791. escape = escape.replace(/CONIC_VAL/g, "\\(P_VAL P_VAL P_VAL W_VAL\\)");
  792. escape = escape.replace(/QUAD_VAL/g, "\\(P_VAL P_VAL P_VAL\\)");
  793. escape = escape.replace(/LINE_VAL/g, "\\(P_VAL P_VAL\\)");
  794. escape = escape.replace(/FILL_TYPE/g, "SkPath::k[a-zA-Z]+_FillType");
  795. escape = escape.replace(/PTR_VAL/g, "0x[0-9A-F]+");
  796. escape = escape.replace(/PT_VAL/g, "\\(P_VAL\\)");
  797. escape = escape.replace(/P_VAL/g, "(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)[Ff]?, ?(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)[Ff]?");
  798. escape = escape.replace(/T_VAL/g, "(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)");
  799. escape = escape.replace(/W_VAL/g, "(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)[Ff]?");
  800. escape = escape.replace(/PATH/g, "pathB?");
  801. escape = escape.replace(/IDX/g, "(-?\\d+)");
  802. escape = escape.replace(/NUM/g, "(-?\\d+)");
  803. escape = escape.replace(/OPT/g, "(\\?|-?\\d+)");
  804. return new RegExp(escape, 'i');
  805. }
  806. function construct_regexp2c(pattern) {
  807. var escape = pattern.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
  808. escape = escape.replace(/UNSORTABLE/g, "\\*\\*\\* UNSORTABLE \\*\\*\\*");
  809. escape = escape.replace(/CUBIC_VAL/g, "(?:\\$\\d = )?\\{\\{\\{P_VAL\\}, \\{P_VAL\\}, \\{P_VAL\\}, \\{P_VAL\\}\\}\\}");
  810. escape = escape.replace(/CONIC_VAL/g, "(?:\\$\\d = )?\\{\\{\\{\\{P_VAL\\}, \\{P_VAL\\}, \\{P_VAL\\}\\}\\}, W_VAL\\}");
  811. escape = escape.replace(/QUAD_VAL/g, "(?:\\$\\d = )?\\{\\{\\{P_VAL\\}, \\{P_VAL\\}, \\{P_VAL\\}\\}\\}");
  812. escape = escape.replace(/LINE_VAL/g, "(?:\\$\\d = )?\\{\\{\\{P_VAL\\}, \\{P_VAL\\}\\}\\}");
  813. escape = escape.replace(/FILL_TYPE/g, "SkPath::k[a-zA-Z]+_FillType");
  814. escape = escape.replace(/PTR_VAL/g, "0x[0-9A-F]+");
  815. escape = escape.replace(/PT_VAL/g, "\\{\\{P_VAL\\}\\}");
  816. escape = escape.replace(/P_VAL/g, "(?:f?[xX] = )?(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)[Ff]?, *(?: f?[yY] = )?(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)[Ff]?");
  817. escape = escape.replace(/T_VAL/g, "(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)");
  818. escape = escape.replace(/W_VAL/g, "(-?\\d+\\.?\\d*(?:e[+-]?\\d+)?)[Ff]?");
  819. escape = escape.replace(/OPER/g, "[a-z]+");
  820. escape = escape.replace(/PATH/g, "pathB?");
  821. escape = escape.replace(/T_F/g, "([TF])");
  822. escape = escape.replace(/IDX/g, "(-?\\d+)");
  823. escape = escape.replace(/NUM/g, "(-?\\d+)");
  824. escape = escape.replace(/OPT/g, "(\\?|-?\\d+)");
  825. return new RegExp(escape, 'i');
  826. }
  827. function match_regexp(str, lineNo, array, id, pattern) {
  828. var regex = construct_regexp2(pattern);
  829. if (filter_str_by(id, str, regex, array)) {
  830. return true;
  831. }
  832. regex = construct_regexp2c(pattern);
  833. return filter_str_by(id, str, regex, array);
  834. }
  835. function endsWith(str, suffix) {
  836. return str.indexOf(suffix, str.length - suffix.length) !== -1;
  837. }
  838. function parse_all(test) {
  839. var lines = test.match(/[^\r\n]+/g);
  840. var records = []; // a rec can be the original paths, a set of intersections, a set of active spans, a sort, or a path add
  841. var record = [];
  842. var recType = REC_TYPE_UNKNOWN;
  843. var lastLineNo;
  844. var moveX, moveY;
  845. for (var lineNo = 0; lineNo < lines.length; ++lineNo) {
  846. var line = lines[lineNo];
  847. if (line.length == 0) {
  848. continue;
  849. }
  850. var opStart = "SkOpSegment::";
  851. if (line.lastIndexOf(opStart, 0) === 0) {
  852. line = line.substr(opStart.length);
  853. }
  854. var angleStart = "SkOpAngle::";
  855. if (line.lastIndexOf(angleStart, 0) === 0) {
  856. line = line.substr(angleStart.length);
  857. }
  858. var coinStart = "SkOpCoincidence::";
  859. if (line.lastIndexOf(coinStart, 0) === 0) {
  860. line = line.substr(coinStart.length);
  861. }
  862. var type = line.lastIndexOf("debugShowActiveSpans", 0) === 0 ? REC_TYPE_ACTIVE
  863. : line.lastIndexOf("debugShowCoincidence", 0) === 0 ? REC_TYPE_COINCIDENCE
  864. : line.lastIndexOf("((SkOpSegment*)", 0) === 0 ? REC_TYPE_PATH2
  865. : line.lastIndexOf("debugShowTs", 0) === 0 ? REC_TYPE_COIN
  866. : line.lastIndexOf("afterPart", 0) === 0 ? REC_TYPE_AFTERPART
  867. : line.lastIndexOf("debugShow", 0) === 0 ? REC_TYPE_SECT
  868. : line.lastIndexOf("activeOp", 0) === 0 ? REC_TYPE_ACTIVE_OP
  869. : line.lastIndexOf("computed", 0) === 0 ? REC_TYPE_COMPUTED
  870. : line.lastIndexOf("debugOne", 0) === 0 ? REC_TYPE_SORT
  871. : line.lastIndexOf("aligned=", 0) === 0 ? REC_TYPE_ALIGNED
  872. : line.lastIndexOf("dumpOne", 0) === 0 ? REC_TYPE_SORT
  873. : line.lastIndexOf("findTop", 0) === 0 ? REC_TYPE_TOP
  874. : line.lastIndexOf("pathB.", 0) === 0 ? REC_TYPE_ADD
  875. : line.lastIndexOf("path.", 0) === 0 ? REC_TYPE_ADD
  876. : line.lastIndexOf("after", 0) === 0 ? REC_TYPE_ANGLE
  877. : line.lastIndexOf("mark", 0) === 0 ? REC_TYPE_MARK
  878. : line.lastIndexOf(" {{", 0) === 0 ? REC_TYPE_COMPUTED
  879. : line.lastIndexOf("seg=", 0) === 0 ? REC_TYPE_PATH
  880. : line.lastIndexOf("op", 0) === 0 ? REC_TYPE_OP
  881. : line.lastIndexOf("$", 0) === 0 ? REC_TYPE_PATH
  882. : REC_TYPE_UNKNOWN;
  883. if (recType != type || recType == REC_TYPE_ADD || recType == REC_TYPE_SECT
  884. || recType == REC_TYPE_ACTIVE_OP || recType == REC_TYPE_ANGLE) {
  885. if (recType != REC_TYPE_UNKNOWN) {
  886. records.push(recType);
  887. records.push(lastLineNo);
  888. records.push(record);
  889. }
  890. record = [];
  891. recType = type;
  892. lastLineNo = lineNo;
  893. }
  894. var found = false;
  895. switch (recType) {
  896. case REC_TYPE_ACTIVE:
  897. found = match_regexp(line, lineNo, record, ACTIVE_LINE_SPAN, "debugShowActiveSpans" +
  898. " id=IDX LINE_VAL t=T_VAL tEnd=T_VAL windSum=OPT windValue=IDX"
  899. ) || match_regexp(line, lineNo, record, ACTIVE_QUAD_SPAN, "debugShowActiveSpans" +
  900. " id=IDX QUAD_VAL t=T_VAL tEnd=T_VAL windSum=OPT windValue=IDX"
  901. ) || match_regexp(line, lineNo, record, ACTIVE_CONIC_SPAN, "debugShowActiveSpans" +
  902. " id=IDX CONIC_VAL t=T_VAL tEnd=T_VAL windSum=OPT windValue=IDX"
  903. ) || match_regexp(line, lineNo, record, ACTIVE_CUBIC_SPAN, "debugShowActiveSpans" +
  904. " id=IDX CUBIC_VAL t=T_VAL tEnd=T_VAL windSum=OPT windValue=IDX"
  905. ) || match_regexp(line, lineNo, record, ACTIVE_LINE_SPAN, "debugShowActiveSpans" +
  906. " id=IDX LINE_VAL t=T_VAL tEnd=T_VAL windSum=OPT oppSum=OPT windValue=IDX oppValue=NUM"
  907. ) || match_regexp(line, lineNo, record, ACTIVE_QUAD_SPAN, "debugShowActiveSpans" +
  908. " id=IDX QUAD_VAL t=T_VAL tEnd=T_VAL windSum=OPT oppSum=OPT windValue=IDX oppValue=NUM"
  909. ) || match_regexp(line, lineNo, record, ACTIVE_CONIC_SPAN, "debugShowActiveSpans" +
  910. " id=IDX CONIC_VAL t=T_VAL tEnd=T_VAL windSum=OPT oppSum=OPT windValue=IDX oppValue=NUM"
  911. ) || match_regexp(line, lineNo, record, ACTIVE_CUBIC_SPAN, "debugShowActiveSpans" +
  912. " id=IDX CUBIC_VAL t=T_VAL tEnd=T_VAL windSum=OPT oppSum=OPT windValue=IDX oppValue=NUM"
  913. );
  914. break;
  915. case REC_TYPE_ACTIVE_OP:
  916. found = match_regexp(line, lineNo, record, ACTIVE_OP, "activeOp" +
  917. " id=IDX t=T_VAL tEnd=T_VAL op=OPER miFrom=NUM miTo=NUM suFrom=NUM suTo=NUM result=IDX"
  918. );
  919. break;
  920. case REC_TYPE_ADD:
  921. if (match_regexp(line, lineNo, record, ADD_MOVETO, "PATH.moveTo(P_VAL);")) {
  922. moveX = record[1][0];
  923. moveY = record[1][1];
  924. found = true;
  925. } else if (match_regexp(line, lineNo, record, ADD_LINETO, "PATH.lineTo(P_VAL);")) {
  926. record[1].unshift(moveY);
  927. record[1].unshift(moveX);
  928. moveX = record[1][2];
  929. moveY = record[1][3];
  930. found = true;
  931. } else if (match_regexp(line, lineNo, record, ADD_QUADTO, "PATH.quadTo(P_VAL, P_VAL);")) {
  932. record[1].unshift(moveY);
  933. record[1].unshift(moveX);
  934. moveX = record[1][4];
  935. moveY = record[1][5];
  936. found = true;
  937. } else if (match_regexp(line, lineNo, record, ADD_CONICTO, "PATH.conicTo(P_VAL, P_VAL, T_VAL);")) {
  938. record[1].unshift(moveY);
  939. record[1].unshift(moveX);
  940. moveX = record[1][4];
  941. moveY = record[1][5];
  942. found = true;
  943. } else if (match_regexp(line, lineNo, record, ADD_CUBICTO, "PATH.cubicTo(P_VAL, P_VAL, P_VAL);")) {
  944. record[1].unshift(moveY);
  945. record[1].unshift(moveX);
  946. moveX = record[1][6];
  947. moveY = record[1][7];
  948. found = true;
  949. } else if (match_regexp(line, lineNo, record, ADD_FILL, "PATH.setFillType(FILL_TYPE);")) {
  950. found = true;
  951. } else {
  952. found = match_regexp(line, lineNo, record, ADD_CLOSE, "PATH.close();");
  953. }
  954. break;
  955. case REC_TYPE_AFTERPART:
  956. found = match_regexp(line, lineNo, record, PATH_LINE, "afterPart LINE_VAL id=IDX")
  957. || match_regexp(line, lineNo, record, PATH_QUAD, "afterPart QUAD_VAL id=IDX")
  958. || match_regexp(line, lineNo, record, PATH_CONIC, "afterPart CONIC_VAL id=IDX")
  959. || match_regexp(line, lineNo, record, PATH_CUBIC, "afterPart CUBIC_VAL id=IDX")
  960. break;
  961. case REC_TYPE_ALIGNED:
  962. found = match_regexp(line, lineNo, record, PATH_LINE, "aligned=IDX LINE_VAL"
  963. ) || match_regexp(line, lineNo, record, PATH_QUAD, "aligned=IDX QUAD_VAL"
  964. ) || match_regexp(line, lineNo, record, PATH_CONIC, "aligned=IDX CONIC_VAL"
  965. ) || match_regexp(line, lineNo, record, PATH_CUBIC, "aligned=IDX CUBIC_VAL"
  966. );
  967. break;
  968. case REC_TYPE_ANGLE:
  969. found = match_regexp(line, lineNo, record, ANGLE_AFTER, "after " +
  970. "[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");
  971. break;
  972. case REC_TYPE_COIN:
  973. found = true;
  974. break;
  975. case REC_TYPE_COINCIDENCE:
  976. found = match_regexp(line, lineNo, record, COIN_MAIN_SPAN, "debugShowCoincidence" +
  977. " + id=IDX t=T_VAL tEnd=T_VAL"
  978. ) || match_regexp(line, lineNo, record, COIN_OPP_SPAN, "debugShowCoincidence" +
  979. " - id=IDX t=T_VAL tEnd=T_VAL"
  980. );
  981. break;
  982. case REC_TYPE_COMPUTED:
  983. found = line == "computed quadratics given"
  984. || match_regexp(line, lineNo, record, COMPUTED_SET_1, "computed quadratics set 1"
  985. ) || match_regexp(line, lineNo, record, COMPUTED_SET_2, "computed quadratics set 2"
  986. ) || match_regexp(line, lineNo, record, PATH_QUAD, " QUAD_VAL,"
  987. ) || match_regexp(line, lineNo, record, PATH_CONIC, " CONIC_VAL,"
  988. ) || match_regexp(line, lineNo, record, PATH_CUBIC, " CUBIC_VAL,"
  989. );
  990. break;
  991. case REC_TYPE_PATH:
  992. found = match_regexp(line, lineNo, record, PATH_LINE, "seg=IDX LINE_VAL"
  993. ) || match_regexp(line, lineNo, record, PATH_QUAD, "seg=IDX QUAD_VAL"
  994. ) || match_regexp(line, lineNo, record, PATH_CONIC, "seg=IDX CONIC_VAL"
  995. ) || match_regexp(line, lineNo, record, PATH_CUBIC, "seg=IDX CUBIC_VAL"
  996. );
  997. break;
  998. case REC_TYPE_PATH2:
  999. found = match_regexp(line, lineNo, record, PATH_LINE, "((SkOpSegment*) PTR_VAL) [IDX] {LINE_VAL}"
  1000. ) || match_regexp(line, lineNo, record, PATH_QUAD, "((SkOpSegment*) PTR_VAL) [IDX] {QUAD_VAL}"
  1001. ) || match_regexp(line, lineNo, record, PATH_CONIC, "((SkOpSegment*) PTR_VAL) [IDX] {CONIC_VAL}"
  1002. ) || match_regexp(line, lineNo, record, PATH_CUBIC, "((SkOpSegment*) PTR_VAL) [IDX] {CUBIC_VAL}"
  1003. );
  1004. break;
  1005. case REC_TYPE_SECT:
  1006. found = match_regexp(line, lineNo, record, INTERSECT_LINE, "debugShowLineIntersection" +
  1007. " wtTs[0]=T_VAL LINE_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL"
  1008. ) || match_regexp(line, lineNo, record, INTERSECT_LINE_2, "debugShowLineIntersection" +
  1009. " wtTs[0]=T_VAL LINE_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL wnTs[1]=T_VAL"
  1010. ) || match_regexp(line, lineNo, record, INTERSECT_LINE_NO, "debugShowLineIntersection" +
  1011. " no intersect LINE_VAL LINE_VAL"
  1012. ) || match_regexp(line, lineNo, record, INTERSECT_QUAD_LINE, "debugShowQuadLineIntersection" +
  1013. " wtTs[0]=T_VAL QUAD_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL"
  1014. ) || match_regexp(line, lineNo, record, INTERSECT_QUAD_LINE_2, "debugShowQuadLineIntersection" +
  1015. " wtTs[0]=T_VAL QUAD_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL wnTs[1]=T_VAL"
  1016. ) || match_regexp(line, lineNo, record, INTERSECT_QUAD_LINE_NO, "debugShowQuadLineIntersection" +
  1017. " no intersect QUAD_VAL LINE_VAL"
  1018. ) || match_regexp(line, lineNo, record, INTERSECT_QUAD, "debugShowQuadIntersection" +
  1019. " wtTs[0]=T_VAL QUAD_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL"
  1020. ) || match_regexp(line, lineNo, record, INTERSECT_QUAD_2, "debugShowQuadIntersection" +
  1021. " wtTs[0]=T_VAL QUAD_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL wnTs[1]=T_VAL"
  1022. ) || match_regexp(line, lineNo, record, INTERSECT_QUAD_NO, "debugShowQuadIntersection" +
  1023. " no intersect QUAD_VAL QUAD_VAL"
  1024. ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_LINE, "debugShowConicLineIntersection" +
  1025. " wtTs[0]=T_VAL CONIC_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL"
  1026. ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_LINE_2, "debugShowConicLineIntersection" +
  1027. " wtTs[0]=T_VAL CONIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL wnTs[1]=T_VAL"
  1028. ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_LINE_NO, "debugShowConicLineIntersection" +
  1029. " no intersect CONIC_VAL LINE_VAL"
  1030. ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_QUAD, "debugShowConicQuadIntersection" +
  1031. " wtTs[0]=T_VAL CONIC_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL"
  1032. ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_QUAD_2, "debugShowConicQuadIntersection" +
  1033. " wtTs[0]=T_VAL CONIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL wnTs[1]=T_VAL"
  1034. ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_QUAD_3, "debugShowConicQuadIntersection" +
  1035. " 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"
  1036. ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_QUAD_4, "debugShowConicQuadIntersection" +
  1037. " 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"
  1038. ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_QUAD_NO, "debugShowConicQuadIntersection" +
  1039. " no intersect CONIC_VAL QUAD_VAL"
  1040. ) || match_regexp(line, lineNo, record, INTERSECT_CONIC, "debugShowConicIntersection" +
  1041. " wtTs[0]=T_VAL CONIC_VAL PT_VAL wnTs[0]=T_VAL CONIC_VAL"
  1042. ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_2, "debugShowConicIntersection" +
  1043. " wtTs[0]=T_VAL CONIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL CONIC_VAL wnTs[1]=T_VAL"
  1044. ) || match_regexp(line, lineNo, record, INTERSECT_CONIC_NO, "debugShowConicIntersection" +
  1045. " no intersect CONIC_VAL CONIC_VAL"
  1046. ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_LINE, "debugShowCubicLineIntersection" +
  1047. " wtTs[0]=T_VAL CUBIC_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL"
  1048. ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_LINE_2, "debugShowCubicLineIntersection" +
  1049. " wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL LINE_VAL wnTs[1]=T_VAL"
  1050. ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_LINE_3, "debugShowCubicLineIntersection" +
  1051. " 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"
  1052. ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_LINE_NO, "debugShowCubicLineIntersection" +
  1053. " no intersect CUBIC_VAL LINE_VAL"
  1054. ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_QUAD, "debugShowCubicQuadIntersection" +
  1055. " wtTs[0]=T_VAL CUBIC_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL"
  1056. ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_QUAD_2, "debugShowCubicQuadIntersection" +
  1057. " wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL QUAD_VAL wnTs[1]=T_VAL"
  1058. ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_QUAD_3, "debugShowCubicQuadIntersection" +
  1059. " 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"
  1060. ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_QUAD_4, "debugShowCubicQuadIntersection" +
  1061. " 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"
  1062. ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_QUAD_NO, "debugShowCubicQuadIntersection" +
  1063. " no intersect CUBIC_VAL QUAD_VAL"
  1064. ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC, "debugShowCubicIntersection" +
  1065. " wtTs[0]=T_VAL CUBIC_VAL PT_VAL wnTs[0]=T_VAL CUBIC_VAL"
  1066. ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_2, "debugShowCubicIntersection" +
  1067. " wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL PT_VAL wnTs[0]=T_VAL CUBIC_VAL wnTs[1]=T_VAL"
  1068. ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_3, "debugShowCubicIntersection" +
  1069. " 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"
  1070. ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_4, "debugShowCubicIntersection" +
  1071. " 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"
  1072. ) || match_regexp(line, lineNo, record, INTERSECT_CUBIC_NO, "debugShowCubicIntersection" +
  1073. " no intersect CUBIC_VAL CUBIC_VAL"
  1074. ) || match_regexp(line, lineNo, record, INTERSECT_SELF_CUBIC, "debugShowCubicIntersection" +
  1075. " wtTs[0]=T_VAL CUBIC_VAL PT_VAL wtTs[1]=T_VAL"
  1076. ) || match_regexp(line, lineNo, record, INTERSECT_SELF_CUBIC_NO, "debugShowCubicIntersection" +
  1077. " no self intersect CUBIC_VAL"
  1078. );
  1079. break;
  1080. case REC_TYPE_SORT:
  1081. var hasDone = / done/.test(line);
  1082. var hasUnorderable = / unorderable/.test(line);
  1083. var hasSmall = / small/.test(line);
  1084. var hasTiny = / tiny/.test(line);
  1085. var hasOperand = / operand/.test(line);
  1086. var hasStop = / stop/.test(line);
  1087. line.replace(/[ a-z]+$/, "");
  1088. found = match_regexp(line, lineNo, record, SORT_UNARY, "debugOne" +
  1089. " [IDX/IDX] next=IDX/IDX sect=IDX/IDX s=T_VAL [IDX] e=T_VAL [IDX] sgn=NUM windVal=IDX windSum=OPT"
  1090. ) || match_regexp(line, lineNo, record, SORT_BINARY, "debugOne" +
  1091. " [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"
  1092. ) || match_regexp(line, lineNo, record, SORT_UNARY, "dumpOne" +
  1093. " [IDX/IDX] next=IDX/IDX sect=NUM/NUM s=T_VAL [IDX] e=T_VAL [IDX] sgn=NUM windVal=IDX windSum=OPT"
  1094. ) || match_regexp(line, lineNo, record, SORT_BINARY, "dumpOne" +
  1095. " [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"
  1096. );
  1097. if (found) {
  1098. record[1].push(hasDone);
  1099. record[1].push(hasUnorderable);
  1100. record[1].push(hasSmall);
  1101. record[1].push(hasTiny);
  1102. record[1].push(hasOperand);
  1103. record[1].push(hasStop);
  1104. }
  1105. break;
  1106. case REC_TYPE_TOP:
  1107. found = match_regexp(line, lineNo, record, ACTIVE_OP, "findTop" +
  1108. " id=IDX s=T_VAL e=T_VAL cw=NUM swap=NUM inflections=NUM monotonic=NUM"
  1109. ) || match_regexp(line, lineNo, record, ACTIVE_OP, "findTop" +
  1110. " id=IDX s=T_VAL e=T_VAL (-) cw=NUM swap=NUM inflections=NUM monotonic=NUM"
  1111. ) || match_regexp(line, lineNo, record, ACTIVE_OP, "findTop" +
  1112. " id=IDX s=T_VAL e=T_VAL (+) cw=NUM swap=NUM inflections=NUM monotonic=NUM"
  1113. );
  1114. break;
  1115. case REC_TYPE_MARK:
  1116. found = match_regexp(line, lineNo, record, MARK_LINE, "markWinding" +
  1117. " id=IDX LINE_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX"
  1118. ) || match_regexp(line, lineNo, record, MARK_QUAD, "markWinding" +
  1119. " id=IDX QUAD_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX"
  1120. ) || match_regexp(line, lineNo, record, MARK_CONIC, "markWinding" +
  1121. " id=IDX CONIC_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX"
  1122. ) || match_regexp(line, lineNo, record, MARK_CUBIC, "markWinding" +
  1123. " id=IDX CUBIC_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM newOppSum=OPT oppSum=OPT windSum=OPT windValue=IDX"
  1124. ) || match_regexp(line, lineNo, record, MARK_DONE_LINE, "markDone" +
  1125. " 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"
  1126. ) || match_regexp(line, lineNo, record, MARK_DONE_QUAD, "markDone" +
  1127. " 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"
  1128. ) || match_regexp(line, lineNo, record, MARK_DONE_CONIC, "markDone" +
  1129. " 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"
  1130. ) || match_regexp(line, lineNo, record, MARK_DONE_CUBIC, "markDone" +
  1131. " 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"
  1132. ) || match_regexp(line, lineNo, record, MARK_SIMPLE_LINE, "markWinding" +
  1133. " id=IDX LINE_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM windSum=OPT windValue=IDX"
  1134. ) || match_regexp(line, lineNo, record, MARK_SIMPLE_QUAD, "markWinding" +
  1135. " id=IDX QUAD_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM windSum=OPT windValue=IDX"
  1136. ) || match_regexp(line, lineNo, record, MARK_SIMPLE_CONIC, "markWinding" +
  1137. " id=IDX CONIC_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM windSum=OPT windValue=IDX"
  1138. ) || match_regexp(line, lineNo, record, MARK_SIMPLE_CUBIC, "markWinding" +
  1139. " id=IDX CUBIC_VAL t=T_VAL [IDX] PT_VAL tEnd=T_VAL newWindSum=NUM windSum=OPT windValue=IDX"
  1140. ) || match_regexp(line, lineNo, record, MARK_ANGLE_LAST, "markAngle" +
  1141. " last segment=IDX span=IDX"
  1142. ) || match_regexp(line, lineNo, record, MARK_ANGLE_LAST, "markAngle" +
  1143. " last seg=IDX span=IDX"
  1144. ) || match_regexp(line, lineNo, record, MARK_ANGLE_LAST, "markAngle" +
  1145. " last segment=IDX span=IDX windSum=OPT"
  1146. ) || match_regexp(line, lineNo, record, MARK_ANGLE_LAST, "markAngle" +
  1147. " last seg=IDX span=IDX windSum=OPT"
  1148. );
  1149. break;
  1150. case REC_TYPE_OP:
  1151. if (line.lastIndexOf("oppSign oppSign=", 0) === 0
  1152. || line.lastIndexOf("operator<", 0) === 0) {
  1153. found = true;
  1154. break;
  1155. }
  1156. found = match_regexp(line, lineNo, record, OP_DIFFERENCE, "op diff"
  1157. ) || match_regexp(line, lineNo, record, OP_INTERSECT, "op intersect"
  1158. ) || match_regexp(line, lineNo, record, OP_INTERSECT, "op sect"
  1159. ) || match_regexp(line, lineNo, record, OP_UNION, "op union"
  1160. ) || match_regexp(line, lineNo, record, OP_XOR, "op xor"
  1161. );
  1162. break;
  1163. case REC_TYPE_UNKNOWN:
  1164. found = true;
  1165. break;
  1166. }
  1167. if (!found) {
  1168. console.log(line + " [" + lineNo + "] of type " + type + " not found");
  1169. }
  1170. }
  1171. if (recType != REC_TYPE_UNKNOWN) {
  1172. records.push(recType);
  1173. records.push(lastLineNo);
  1174. records.push(record);
  1175. }
  1176. if (records.length >= 1) {
  1177. tests[testIndex] = records;
  1178. testLines[testIndex] = lines;
  1179. }
  1180. }
  1181. function init(test) {
  1182. var canvas = document.getElementById('canvas');
  1183. if (!canvas.getContext) return;
  1184. ctx = canvas.getContext('2d');
  1185. var resScale = retina_scale && window.devicePixelRatio ? window.devicePixelRatio : 1;
  1186. var unscaledWidth = window.innerWidth - 20;
  1187. var unscaledHeight = window.innerHeight - 20;
  1188. screenWidth = unscaledWidth;
  1189. screenHeight = unscaledHeight;
  1190. canvas.width = unscaledWidth * resScale;
  1191. canvas.height = unscaledHeight * resScale;
  1192. canvas.style.width = unscaledWidth + 'px';
  1193. canvas.style.height = unscaledHeight + 'px';
  1194. if (resScale != 1) {
  1195. ctx.scale(resScale, resScale);
  1196. }
  1197. xmin = Infinity;
  1198. xmax = -Infinity;
  1199. ymin = Infinity;
  1200. ymax = -Infinity;
  1201. hasPath = hasAlignedPath = hasComputedPath = false;
  1202. firstActiveSpan = -1;
  1203. for (var tIndex = 0; tIndex < test.length; tIndex += 3) {
  1204. var recType = test[tIndex];
  1205. if (!typeof recType == 'number' || recType < REC_TYPE_UNKNOWN || recType > REC_TYPE_LAST) {
  1206. console.log("unknown rec type: " + recType);
  1207. throw "stop execution";
  1208. }
  1209. var records = test[tIndex + 2];
  1210. for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
  1211. var fragType = records[recordIndex];
  1212. if (!typeof fragType == 'number' || fragType < 1 || fragType > FRAG_TYPE_LAST) {
  1213. console.log("unknown in range frag type: " + fragType);
  1214. throw "stop execution";
  1215. }
  1216. var frags = records[recordIndex + 1];
  1217. var first = 0;
  1218. var last = -1;
  1219. var first2 = 0;
  1220. var last2 = 0;
  1221. switch (recType) {
  1222. case REC_TYPE_ALIGNED:
  1223. hasAlignedPath = true;
  1224. case REC_TYPE_COMPUTED:
  1225. if (fragType == COMPUTED_SET_1 || fragType == COMPUTED_SET_2) {
  1226. break;
  1227. }
  1228. if (REC_TYPE_COMPUTED == recType) {
  1229. hasComputedPath = true;
  1230. }
  1231. case REC_TYPE_PATH:
  1232. first = 1;
  1233. switch (fragType) {
  1234. case PATH_LINE:
  1235. last = 5;
  1236. break;
  1237. case PATH_CONIC:
  1238. case PATH_QUAD:
  1239. last = 7;
  1240. break;
  1241. case PATH_CUBIC:
  1242. last = 9;
  1243. break;
  1244. default:
  1245. console.log("unknown " + (recType == REC_TYPE_PATH ? "REC_TYPE_PATH"
  1246. : "REC_TYPE_COMPUTED") + " frag type:" + fragType);
  1247. throw "stop execution";
  1248. }
  1249. if (recType == REC_TYPE_PATH) {
  1250. hasPath = true;
  1251. }
  1252. break;
  1253. case REC_TYPE_PATH2:
  1254. first = 1;
  1255. switch (fragType) {
  1256. case PATH_LINE:
  1257. last = 5;
  1258. break;
  1259. case PATH_CONIC:
  1260. case PATH_QUAD:
  1261. last = 7;
  1262. break;
  1263. case PATH_CUBIC:
  1264. last = 9;
  1265. break;
  1266. default:
  1267. console.log("unknown " + (recType == REC_TYPE_PATH2 ? "REC_TYPE_PATH2"
  1268. : "REC_TYPE_COMPUTED") + " frag type:" + fragType);
  1269. throw "stop execution";
  1270. }
  1271. if (recType == REC_TYPE_PATH2) {
  1272. hasPath = true;
  1273. }
  1274. break;
  1275. case REC_TYPE_ACTIVE:
  1276. if (firstActiveSpan < 0) {
  1277. firstActiveSpan = tIndex;
  1278. }
  1279. first = 1;
  1280. switch (fragType) {
  1281. case ACTIVE_LINE_SPAN:
  1282. last = 5;
  1283. break;
  1284. case ACTIVE_CONIC_SPAN:
  1285. case ACTIVE_QUAD_SPAN:
  1286. last = 7;
  1287. break;
  1288. case ACTIVE_CUBIC_SPAN:
  1289. last = 9;
  1290. break;
  1291. default:
  1292. console.log("unknown REC_TYPE_ACTIVE frag type: " + fragType);
  1293. throw "stop execution";
  1294. }
  1295. break;
  1296. case REC_TYPE_ADD:
  1297. switch (fragType) {
  1298. case ADD_MOVETO:
  1299. break;
  1300. case ADD_LINETO:
  1301. last = 4;
  1302. break;
  1303. case ADD_CONICTO:
  1304. case ADD_QUADTO:
  1305. last = 6;
  1306. break;
  1307. case ADD_CUBICTO:
  1308. last = 8;
  1309. break;
  1310. case ADD_CLOSE:
  1311. case ADD_FILL:
  1312. break;
  1313. default:
  1314. console.log("unknown REC_TYPE_ADD frag type: " + fragType);
  1315. throw "stop execution";
  1316. }
  1317. break;
  1318. case REC_TYPE_AFTERPART:
  1319. switch (fragType) {
  1320. case PATH_LINE:
  1321. last = 4;
  1322. break;
  1323. case PATH_CONIC:
  1324. case PATH_QUAD:
  1325. last = 6;
  1326. break;
  1327. case PATH_CUBIC:
  1328. last = 8;
  1329. break;
  1330. default:
  1331. console.log("unknown REC_TYPE_ACTIVEPART frag type: " + fragType);
  1332. throw "stop execution";
  1333. }
  1334. break;
  1335. case REC_TYPE_SECT:
  1336. switch (fragType) {
  1337. case INTERSECT_LINE:
  1338. first = 1; last = 5; first2 = 8; last2 = 12;
  1339. break;
  1340. case INTERSECT_LINE_2:
  1341. first = 1; last = 5; first2 = 11; last2 = 15;
  1342. break;
  1343. case INTERSECT_LINE_NO:
  1344. first = 0; last = 4; first2 = 4; last2 = 8;
  1345. break;
  1346. case INTERSECT_CONIC_LINE:
  1347. first = 1; last = 7; first2 = 11; last2 = 15;
  1348. break;
  1349. case INTERSECT_QUAD_LINE:
  1350. first = 1; last = 7; first2 = 10; last2 = 14;
  1351. break;
  1352. case INTERSECT_CONIC_LINE_2:
  1353. first = 1; last = 7; first2 = 14; last2 = 18;
  1354. break;
  1355. case INTERSECT_QUAD_LINE_2:
  1356. first = 1; last = 7; first2 = 13; last2 = 17;
  1357. break;
  1358. case INTERSECT_CONIC_LINE_NO:
  1359. first = 0; last = 6; first2 = 7; last2 = 11;
  1360. break;
  1361. case INTERSECT_QUAD_LINE_NO:
  1362. first = 0; last = 6; first2 = 6; last2 = 10;
  1363. break;
  1364. case INTERSECT_CONIC:
  1365. first = 1; last = 7; first2 = 11; last2 = 17;
  1366. break;
  1367. case INTERSECT_QUAD:
  1368. first = 1; last = 7; first2 = 10; last2 = 16;
  1369. break;
  1370. case INTERSECT_CONIC_2:
  1371. first = 1; last = 7; first2 = 14; last2 = 20;
  1372. break;
  1373. case INTERSECT_QUAD_2:
  1374. first = 1; last = 7; first2 = 13; last2 = 19;
  1375. break;
  1376. case INTERSECT_CONIC_NO:
  1377. first = 0; last = 6; first2 = 7; last2 = 13;
  1378. break;
  1379. case INTERSECT_QUAD_NO:
  1380. first = 0; last = 6; first2 = 6; last2 = 12;
  1381. break;
  1382. case INTERSECT_SELF_CUBIC:
  1383. first = 1; last = 9;
  1384. break;
  1385. case INTERSECT_SELF_CUBIC_NO:
  1386. first = 0; last = 8;
  1387. break;
  1388. case INTERSECT_CUBIC_LINE:
  1389. first = 1; last = 9; first2 = 12; last2 = 16;
  1390. break;
  1391. case INTERSECT_CUBIC_LINE_2:
  1392. first = 1; last = 9; first2 = 15; last2 = 19;
  1393. break;
  1394. case INTERSECT_CUBIC_LINE_3:
  1395. first = 1; last = 9; first2 = 18; last2 = 22;
  1396. break;
  1397. case INTERSECT_CUBIC_LINE_NO:
  1398. first = 0; last = 8; first2 = 8; last2 = 12;
  1399. break;
  1400. case INTERSECT_CONIC_QUAD:
  1401. first = 1; last = 7; first2 = 11; last2 = 17;
  1402. break;
  1403. case INTERSECT_CONIC_QUAD_2:
  1404. first = 1; last = 7; first2 = 14; last2 = 20;
  1405. break;
  1406. case INTERSECT_CONIC_QUAD_3:
  1407. first = 1; last = 7; first2 = 17; last2 = 23;
  1408. break;
  1409. case INTERSECT_CONIC_QUAD_4:
  1410. first = 1; last = 7; first2 = 20; last2 = 26;
  1411. break;
  1412. case INTERSECT_CONIC_QUAD_NO:
  1413. first = 0; last = 6; first2 = 7; last2 = 13;
  1414. break;
  1415. case INTERSECT_CUBIC_QUAD:
  1416. first = 1; last = 9; first2 = 12; last2 = 18;
  1417. break;
  1418. case INTERSECT_CUBIC_QUAD_2:
  1419. first = 1; last = 9; first2 = 15; last2 = 21;
  1420. break;
  1421. case INTERSECT_CUBIC_QUAD_3:
  1422. first = 1; last = 9; first2 = 18; last2 = 24;
  1423. break;
  1424. case INTERSECT_CUBIC_QUAD_4:
  1425. first = 1; last = 9; first2 = 21; last2 = 27;
  1426. break;
  1427. case INTERSECT_CUBIC_QUAD_NO:
  1428. first = 0; last = 8; first2 = 8; last2 = 14;
  1429. break;
  1430. case INTERSECT_CUBIC:
  1431. first = 1; last = 9; first2 = 12; last2 = 20;
  1432. break;
  1433. case INTERSECT_CUBIC_2:
  1434. first = 1; last = 9; first2 = 15; last2 = 23;
  1435. break;
  1436. case INTERSECT_CUBIC_3:
  1437. first = 1; last = 9; first2 = 18; last2 = 26;
  1438. break;
  1439. case INTERSECT_CUBIC_4:
  1440. first = 1; last = 9; first2 = 21; last2 = 29;
  1441. break;
  1442. case INTERSECT_CUBIC_NO:
  1443. first = 0; last = 8; first2 = 8; last2 = 16;
  1444. break;
  1445. default:
  1446. console.log("unknown REC_TYPE_SECT frag type: " + fragType);
  1447. throw "stop execution";
  1448. }
  1449. break;
  1450. default:
  1451. continue;
  1452. }
  1453. for (var idx = first; idx < last; idx += 2) {
  1454. xmin = Math.min(xmin, frags[idx]);
  1455. xmax = Math.max(xmax, frags[idx]);
  1456. ymin = Math.min(ymin, frags[idx + 1]);
  1457. ymax = Math.max(ymax, frags[idx + 1]);
  1458. }
  1459. for (var idx = first2; idx < last2; idx += 2) {
  1460. xmin = Math.min(xmin, frags[idx]);
  1461. xmax = Math.max(xmax, frags[idx]);
  1462. ymin = Math.min(ymin, frags[idx + 1]);
  1463. ymax = Math.max(ymax, frags[idx + 1]);
  1464. }
  1465. }
  1466. }
  1467. var angleBounds = [Infinity, Infinity, -Infinity, -Infinity];
  1468. for (var tIndex = 0; tIndex < test.length; tIndex += 3) {
  1469. var recType = test[tIndex];
  1470. var records = test[tIndex + 2];
  1471. for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
  1472. var fragType = records[recordIndex];
  1473. var frags = records[recordIndex + 1];
  1474. switch (recType) {
  1475. case REC_TYPE_ACTIVE_OP:
  1476. if (!draw_op) {
  1477. break;
  1478. }
  1479. {
  1480. var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
  1481. curve_extremes(curve, angleBounds);
  1482. }
  1483. break;
  1484. case REC_TYPE_ANGLE:
  1485. if (!draw_angle) {
  1486. break;
  1487. }
  1488. {
  1489. var curve = curvePartialByID(test, frags[0], frags[4], frags[5]);
  1490. curve_extremes(curve, angleBounds);
  1491. curve = curvePartialByID(test, frags[6], frags[10], frags[11]);
  1492. curve_extremes(curve, angleBounds);
  1493. curve = curvePartialByID(test, frags[12], frags[16], frags[17]);
  1494. }
  1495. break;
  1496. case REC_TYPE_COINCIDENCE:
  1497. if (!draw_coincidence) {
  1498. break;
  1499. }
  1500. {
  1501. var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
  1502. curve_extremes(curve, angleBounds);
  1503. }
  1504. break;
  1505. case REC_TYPE_SORT:
  1506. if (!draw_sort) {
  1507. break;
  1508. }
  1509. if (fragType == SORT_UNARY || fragType == SORT_BINARY) {
  1510. var curve = curvePartialByID(test, frags[0], frags[6], frags[8]);
  1511. curve_extremes(curve, angleBounds);
  1512. }
  1513. break;
  1514. case REC_TYPE_TOP:
  1515. if (!draw_top) {
  1516. break;
  1517. }
  1518. {
  1519. var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
  1520. curve_extremes(curve, angleBounds);
  1521. }
  1522. break;
  1523. }
  1524. }
  1525. }
  1526. xmin = Math.min(xmin, angleBounds[0]);
  1527. ymin = Math.min(ymin, angleBounds[1]);
  1528. xmax = Math.max(xmax, angleBounds[2]);
  1529. ymax = Math.max(ymax, angleBounds[3]);
  1530. setScale(xmin, xmax, ymin, ymax);
  1531. if (hasPath == false && hasComputedPath == true && !draw_computed) {
  1532. draw_computed = 7; // show quadratics, conics, and cubics
  1533. }
  1534. if (hasPath == true && hasComputedPath == false && draw_computed) {
  1535. draw_computed = 0;
  1536. }
  1537. }
  1538. function curveByIDMatch(test, id, recMatch) {
  1539. var tIndex = -3;
  1540. while ((tIndex += 3) < test.length) {
  1541. var recType = test[tIndex];
  1542. if (recType == REC_TYPE_OP) {
  1543. continue;
  1544. }
  1545. if (recType != recMatch) {
  1546. return [];
  1547. }
  1548. var records = test[tIndex + 2];
  1549. for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
  1550. var fragType = records[recordIndex];
  1551. var frags = records[recordIndex + 1];
  1552. if (frags[0] == id) {
  1553. switch (fragType) {
  1554. case PATH_LINE:
  1555. return [frags[1], frags[2], frags[3], frags[4]];
  1556. case PATH_QUAD:
  1557. return [frags[1], frags[2], frags[3], frags[4],
  1558. frags[5], frags[6]];
  1559. case PATH_CONIC:
  1560. return [frags[1], frags[2], frags[3], frags[4],
  1561. frags[5], frags[6], frags[7]];
  1562. case PATH_CUBIC:
  1563. return [frags[1], frags[2], frags[3], frags[4],
  1564. frags[5], frags[6], frags[7], frags[8]];
  1565. }
  1566. }
  1567. }
  1568. }
  1569. return [];
  1570. }
  1571. function curveByID(test, id) {
  1572. var result = draw_path >= 4 ? curveByIDMatch(test, id, REC_TYPE_ALIGNED) : [];
  1573. if (!result.length) {
  1574. result = curveByIDMatch(test, id, REC_TYPE_PATH);
  1575. }
  1576. return result;
  1577. }
  1578. function curvePartialByIDMatch(test, id, t0, t1, recMatch) {
  1579. var tIndex = -3;
  1580. while ((tIndex += 3) < test.length) {
  1581. var recType = test[tIndex];
  1582. if (recType == REC_TYPE_OP) {
  1583. continue;
  1584. }
  1585. if (recType != recMatch) {
  1586. return [];
  1587. }
  1588. var records = test[tIndex + 2];
  1589. for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
  1590. var fragType = records[recordIndex];
  1591. var frags = records[recordIndex + 1];
  1592. if (frags[0] == id) {
  1593. switch (fragType) {
  1594. case PATH_LINE:
  1595. return linePartial(frags[1], frags[2], frags[3], frags[4], t0, t1);
  1596. case PATH_QUAD:
  1597. return quadPartial(frags[1], frags[2], frags[3], frags[4],
  1598. frags[5], frags[6], t0, t1);
  1599. case PATH_CONIC:
  1600. return conicPartial(frags[1], frags[2], frags[3], frags[4],
  1601. frags[5], frags[6], frags[7], t0, t1);
  1602. case PATH_CUBIC:
  1603. return cubicPartial(frags[1], frags[2], frags[3], frags[4],
  1604. frags[5], frags[6], frags[7], frags[8], t0, t1);
  1605. }
  1606. }
  1607. }
  1608. }
  1609. return [];
  1610. }
  1611. function curvePartialByID(test, id, t0, t1) {
  1612. var result = draw_path >= 4 ? curvePartialByIDMatch(test, id, t0, t1, REC_TYPE_ALIGNED) : [];
  1613. if (!result.length) {
  1614. result = curvePartialByIDMatch(test, id, t0, t1, REC_TYPE_PATH);
  1615. }
  1616. return result;
  1617. }
  1618. function idByCurveIDMatch(test, frag, type, recMatch) {
  1619. var tIndex = 0;
  1620. while (tIndex < test.length) {
  1621. var recType = test[tIndex];
  1622. if (recType != recMatch) {
  1623. ++tIndex;
  1624. continue;
  1625. }
  1626. var records = test[tIndex + 2];
  1627. for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
  1628. var fragType = records[recordIndex];
  1629. var frags = records[recordIndex + 1];
  1630. if (frag.length != frags.length - 1) {
  1631. continue;
  1632. }
  1633. switch (fragType) {
  1634. case PATH_LINE:
  1635. if (frag[0] != frags[1] || frag[1] != frags[2]
  1636. || frag[2] != frags[3] || frag[3] != frags[4]) {
  1637. continue;
  1638. }
  1639. return frags[0];
  1640. case PATH_QUAD:
  1641. if (frag[0] != frags[1] || frag[1] != frags[2]
  1642. || frag[2] != frags[3] || frag[3] != frags[4]
  1643. || frag[4] != frags[5] || frag[5] != frags[6]) {
  1644. continue;
  1645. }
  1646. return frags[0];
  1647. case PATH_CONIC:
  1648. if (frag[0] != frags[1] || frag[1] != frags[2]
  1649. || frag[2] != frags[3] || frag[3] != frags[4]
  1650. || frag[4] != frags[5] || frag[5] != frags[6]
  1651. || frag[6] != frags[7]) {
  1652. continue;
  1653. }
  1654. return frags[0];
  1655. case PATH_CUBIC:
  1656. if (frag[0] != frags[1] || frag[1] != frags[2]
  1657. || frag[2] != frags[3] || frag[3] != frags[4]
  1658. || frag[4] != frags[5] || frag[5] != frags[6]
  1659. || frag[6] != frags[7] || frag[7] != frags[8]) {
  1660. continue;
  1661. }
  1662. return frags[0];
  1663. }
  1664. }
  1665. ++tIndex;
  1666. }
  1667. return -1;
  1668. }
  1669. function idByCurve(test, frag, type) {
  1670. var result = draw_path >= 4 ? idByCurveIDMatch(test, frag, type, REC_TYPE_ALIGNED) : [];
  1671. if (!result.length) {
  1672. result = idByCurveIDMatch(test, frag, type, REC_TYPE_PATH);
  1673. }
  1674. return result;
  1675. }
  1676. function curve_extremes(curve, bounds) {
  1677. var length = curve.length == 7 ? 6 : curve.length;
  1678. for (var index = 0; index < length; index += 2) {
  1679. var x = curve[index];
  1680. var y = curve[index + 1];
  1681. bounds[0] = Math.min(bounds[0], x);
  1682. bounds[1] = Math.min(bounds[1], y);
  1683. bounds[2] = Math.max(bounds[2], x);
  1684. bounds[3] = Math.max(bounds[3], y);
  1685. }
  1686. }
  1687. function setScale(x0, x1, y0, y1) {
  1688. var srcWidth = x1 - x0;
  1689. var srcHeight = y1 - y0;
  1690. var usableWidth = screenWidth;
  1691. var xDigits = Math.ceil(Math.log(Math.abs(xmax)) / Math.log(10));
  1692. var yDigits = Math.ceil(Math.log(Math.abs(ymax)) / Math.log(10));
  1693. usableWidth -= (xDigits + yDigits) * 10;
  1694. usableWidth -= decimal_places * 10;
  1695. if (draw_legend) {
  1696. usableWidth -= 40;
  1697. }
  1698. var hscale = usableWidth / srcWidth;
  1699. var vscale = screenHeight / srcHeight;
  1700. scale = Math.min(hscale, vscale);
  1701. var invScale = 1 / scale;
  1702. var sxmin = x0 - invScale * 5;
  1703. var symin = y0 - invScale * 10;
  1704. var sxmax = x1 + invScale * (6 * decimal_places + 10);
  1705. var symax = y1 + invScale * 10;
  1706. srcWidth = sxmax - sxmin;
  1707. srcHeight = symax - symin;
  1708. hscale = usableWidth / srcWidth;
  1709. vscale = screenHeight / srcHeight;
  1710. scale = Math.min(hscale, vscale);
  1711. srcLeft = sxmin;
  1712. srcTop = symin;
  1713. }
  1714. function drawArc(curve, op, from, to) {
  1715. var type = PATH_LINE + (curve.length / 2 - 2);
  1716. var pt = pointAtT(curve, type, op ? 0.4 : 0.6);
  1717. var dy = pt.y - curve[1];
  1718. var dx = pt.x - curve[0];
  1719. var dist = Math.sqrt(dy * dy + dx * dx);
  1720. var _dist = dist * scale;
  1721. var angle = Math.atan2(dy, dx);
  1722. var _px = (curve[0] - srcLeft) * scale;
  1723. var _py = (curve[1] - srcTop) * scale;
  1724. var divisor = 4;
  1725. var endDist;
  1726. do {
  1727. var ends = [];
  1728. for (var index = -1; index <= 1; index += 2) {
  1729. var px = Math.cos(index * Math.PI / divisor);
  1730. var py = Math.sin(index * Math.PI / divisor);
  1731. ends.push(px);
  1732. ends.push(py);
  1733. }
  1734. var endDx = (ends[2] - ends[0]) * scale * dist;
  1735. var endDy = (ends[3] - ends[1]) * scale * dist;
  1736. endDist = Math.sqrt(endDx * endDx + endDy * endDy);
  1737. if (endDist < 100) {
  1738. break;
  1739. }
  1740. divisor *= 2;
  1741. } while (true);
  1742. if (endDist < 30) {
  1743. return;
  1744. }
  1745. if (op) {
  1746. divisor *= 2;
  1747. }
  1748. ctx.strokeStyle = op ? "rgba(210,0,45, 0.4)" : "rgba(90,90,90, 0.5)";
  1749. ctx.beginPath();
  1750. ctx.arc(_px, _py, _dist, angle - Math.PI / divisor, angle + Math.PI / divisor, false);
  1751. ctx.stroke();
  1752. var saveAlign = ctx.textAlign;
  1753. var saveStyle = ctx.fillStyle;
  1754. var saveFont = ctx.font;
  1755. ctx.textAlign = "center";
  1756. ctx.fillStyle = "black";
  1757. ctx.font = "normal 24px Arial";
  1758. divisor *= 0.8;
  1759. for (var index = -1; index <= 1; index += 2) {
  1760. var px = curve[0] + Math.cos(angle + index * Math.PI / divisor) * dist;
  1761. var py = curve[1] + Math.sin(angle + index * Math.PI / divisor) * dist;
  1762. var _px = (px - srcLeft) * scale;
  1763. var _py = (py - srcTop) * scale;
  1764. ctx.fillText(index < 0 ? to.toString() : from.toString(), _px, _py + 8);
  1765. }
  1766. ctx.textAlign = saveAlign;
  1767. ctx.fillStyle = saveStyle;
  1768. ctx.font = saveFont;
  1769. }
  1770. function drawPoint(px, py, end) {
  1771. var length = drawnPts.length == 7 ? 6 : drawnPts.length;
  1772. for (var pts = 0; pts < length; pts += 2) {
  1773. var x = drawnPts[pts];
  1774. var y = drawnPts[pts + 1];
  1775. if (px == x && py == y) {
  1776. return;
  1777. }
  1778. }
  1779. drawnPts.push(px);
  1780. drawnPts.push(py);
  1781. var label = px.toFixed(decimal_places) + ", " + py.toFixed(decimal_places);
  1782. var _px = (px - srcLeft) * scale;
  1783. var _py = (py - srcTop) * scale;
  1784. ctx.beginPath();
  1785. ctx.arc(_px, _py, 3, 0, Math.PI*2, true);
  1786. ctx.closePath();
  1787. if (end) {
  1788. ctx.fill();
  1789. } else {
  1790. ctx.stroke();
  1791. }
  1792. if (debug_xy) {
  1793. ctx.textAlign = "left";
  1794. ctx.fillText(label, _px + 5, _py);
  1795. }
  1796. }
  1797. function coordCount(curveType) {
  1798. switch (curveType) {
  1799. case PATH_LINE:
  1800. return 4;
  1801. case PATH_QUAD:
  1802. return 6;
  1803. case PATH_CONIC:
  1804. return 6;
  1805. case PATH_CUBIC:
  1806. return 8;
  1807. }
  1808. return -1;
  1809. }
  1810. function drawPoints(ptArray, curveType, drawControls) {
  1811. var count = coordCount(curveType);
  1812. for (var idx = 0; idx < count; idx += 2) {
  1813. if (!drawControls && idx != 0 && idx != count - 2) {
  1814. continue;
  1815. }
  1816. drawPoint(ptArray[idx], ptArray[idx + 1], idx == 0 || idx == count - 2);
  1817. }
  1818. }
  1819. function drawControlLines(curve, curveType, drawEnd) {
  1820. if (curveType == PATH_LINE) {
  1821. return;
  1822. }
  1823. ctx.strokeStyle = "rgba(0,0,0, 0.3)";
  1824. drawLine(curve[0], curve[1], curve[2], curve[3]);
  1825. drawLine(curve[2], curve[3], curve[4], curve[5]);
  1826. if (curveType == PATH_CUBIC) {
  1827. drawLine(curve[4], curve[5], curve[6], curve[7]);
  1828. if (drawEnd > 1) {
  1829. drawLine(curve[6], curve[7], curve[0], curve[1]);
  1830. if (drawEnd > 2) {
  1831. drawLine(curve[0], curve[1], curve[4], curve[5]);
  1832. drawLine(curve[6], curve[7], curve[2], curve[3]);
  1833. }
  1834. }
  1835. } else if (drawEnd > 1) {
  1836. drawLine(curve[4], curve[5], curve[0], curve[1]);
  1837. }
  1838. }
  1839. function pointAtT(curve, curveType, t) {
  1840. var xy = {};
  1841. switch (curveType) {
  1842. case PATH_LINE:
  1843. var a = 1 - t;
  1844. var b = t;
  1845. xy.x = a * curve[0] + b * curve[2];
  1846. xy.y = a * curve[1] + b * curve[3];
  1847. break;
  1848. case PATH_QUAD:
  1849. var one_t = 1 - t;
  1850. var a = one_t * one_t;
  1851. var b = 2 * one_t * t;
  1852. var c = t * t;
  1853. xy.x = a * curve[0] + b * curve[2] + c * curve[4];
  1854. xy.y = a * curve[1] + b * curve[3] + c * curve[5];
  1855. break;
  1856. case PATH_CONIC:
  1857. var one_t = 1 - t;
  1858. var a = one_t * one_t;
  1859. var b = 2 * one_t * t;
  1860. var c = t * t;
  1861. xy.x = a * curve[0] + b * curve[2] * curve[6] + c * curve[4];
  1862. xy.y = a * curve[1] + b * curve[3] * curve[6] + c * curve[5];
  1863. var d = a + b * curve[6] + c;
  1864. xy.x /= d;
  1865. xy.y /= d;
  1866. break;
  1867. case PATH_CUBIC:
  1868. var one_t = 1 - t;
  1869. var one_t2 = one_t * one_t;
  1870. var a = one_t2 * one_t;
  1871. var b = 3 * one_t2 * t;
  1872. var t2 = t * t;
  1873. var c = 3 * one_t * t2;
  1874. var d = t2 * t;
  1875. xy.x = a * curve[0] + b * curve[2] + c * curve[4] + d * curve[6];
  1876. xy.y = a * curve[1] + b * curve[3] + c * curve[5] + d * curve[7];
  1877. break;
  1878. }
  1879. return xy;
  1880. }
  1881. function drawPointAtT(curve, curveType) {
  1882. var x, y;
  1883. var xy = pointAtT(curve, curveType, curveT);
  1884. drawPoint(xy.x, xy.y, true);
  1885. if (!draw_intersectT) {
  1886. return;
  1887. }
  1888. ctx.fillStyle = "red";
  1889. drawTAtPointUp(xy.x, xy.y, curveT);
  1890. }
  1891. function drawTAtPointUp(px, py, t) {
  1892. var label = t.toFixed(decimal_places);
  1893. var _px = (px - srcLeft)* scale;
  1894. var _py = (py - srcTop) * scale;
  1895. ctx.fillText(label, _px + 5, _py - 10);
  1896. }
  1897. function drawTAtPointDown(px, py, t) {
  1898. var label = t.toFixed(decimal_places);
  1899. var _px = (px - srcLeft)* scale;
  1900. var _py = (py - srcTop) * scale;
  1901. ctx.fillText(label, _px + 5, _py + 10);
  1902. }
  1903. function alreadyDrawnLine(x1, y1, x2, y2) {
  1904. if (collect_bounds) {
  1905. if (focus_enabled) {
  1906. focusXmin = Math.min(focusXmin, x1, x2);
  1907. focusYmin = Math.min(focusYmin, y1, y2);
  1908. focusXmax = Math.max(focusXmax, x1, x2);
  1909. focusYmax = Math.max(focusYmax, y1, y2);
  1910. }
  1911. return true;
  1912. }
  1913. for (var pts = 0; pts < drawnLines.length; pts += 4) {
  1914. if (x1 == drawnLines[pts] && y1 == drawnLines[pts + 1]
  1915. && x2 == drawnLines[pts + 2] && y2 == drawnLines[pts + 3]) {
  1916. return true;
  1917. }
  1918. }
  1919. drawnLines.push(x1);
  1920. drawnLines.push(y1);
  1921. drawnLines.push(x2);
  1922. drawnLines.push(y2);
  1923. return false;
  1924. }
  1925. function drawLine(x1, y1, x2, y2) {
  1926. if (alreadyDrawnLine(x1, y1, x2, y2)) {
  1927. return;
  1928. }
  1929. ctx.beginPath();
  1930. ctx.moveTo((x1 - srcLeft) * scale,
  1931. (y1 - srcTop) * scale);
  1932. ctx.lineTo((x2 - srcLeft) * scale,
  1933. (y2 - srcTop) * scale);
  1934. ctx.stroke();
  1935. }
  1936. function linePartial(x1, y1, x2, y2, t1, t2) {
  1937. var dx = x1 - x2;
  1938. var dy = y1 - y2;
  1939. var array = [
  1940. x1 - t1 * dx,
  1941. y1 - t1 * dy,
  1942. x1 - t2 * dx,
  1943. y1 - t2 * dy
  1944. ];
  1945. return array;
  1946. }
  1947. function drawLinePartial(x1, y1, x2, y2, t1, t2) {
  1948. var a = linePartial(x1, y1, x2, y2, t1, t2);
  1949. var ax = a[0];
  1950. var ay = a[1];
  1951. var bx = a[2];
  1952. var by = a[3];
  1953. if (alreadyDrawnLine(ax, ay, bx, by)) {
  1954. return;
  1955. }
  1956. ctx.beginPath();
  1957. ctx.moveTo((ax - srcLeft) * scale,
  1958. (ay - srcTop) * scale);
  1959. ctx.lineTo((bx - srcLeft) * scale,
  1960. (by - srcTop) * scale);
  1961. ctx.stroke();
  1962. }
  1963. function alreadyDrawnQuad(x1, y1, x2, y2, x3, y3) {
  1964. if (collect_bounds) {
  1965. if (focus_enabled) {
  1966. focusXmin = Math.min(focusXmin, x1, x2, x3);
  1967. focusYmin = Math.min(focusYmin, y1, y2, y3);
  1968. focusXmax = Math.max(focusXmax, x1, x2, x3);
  1969. focusYmax = Math.max(focusYmax, y1, y2, y3);
  1970. }
  1971. return true;
  1972. }
  1973. for (var pts = 0; pts < drawnQuads.length; pts += 6) {
  1974. if (x1 == drawnQuads[pts] && y1 == drawnQuads[pts + 1]
  1975. && x2 == drawnQuads[pts + 2] && y2 == drawnQuads[pts + 3]
  1976. && x3 == drawnQuads[pts + 4] && y3 == drawnQuads[pts + 5]) {
  1977. return true;
  1978. }
  1979. }
  1980. drawnQuads.push(x1);
  1981. drawnQuads.push(y1);
  1982. drawnQuads.push(x2);
  1983. drawnQuads.push(y2);
  1984. drawnQuads.push(x3);
  1985. drawnQuads.push(y3);
  1986. return false;
  1987. }
  1988. function drawQuad(x1, y1, x2, y2, x3, y3) {
  1989. if (alreadyDrawnQuad(x1, y1, x2, y2, x3, y3)) {
  1990. return;
  1991. }
  1992. ctx.beginPath();
  1993. ctx.moveTo((x1 - srcLeft) * scale,
  1994. (y1 - srcTop) * scale);
  1995. ctx.quadraticCurveTo((x2 - srcLeft) * scale,
  1996. (y2 - srcTop) * scale,
  1997. (x3 - srcLeft) * scale,
  1998. (y3 - srcTop) * scale);
  1999. ctx.stroke();
  2000. }
  2001. function interp(A, B, t) {
  2002. return A + (B - A) * t;
  2003. }
  2004. function interp_quad_coords(x1, x2, x3, t)
  2005. {
  2006. var ab = interp(x1, x2, t);
  2007. var bc = interp(x2, x3, t);
  2008. var abc = interp(ab, bc, t);
  2009. return abc;
  2010. }
  2011. function quadPartial(x1, y1, x2, y2, x3, y3, t1, t2) {
  2012. var ax = interp_quad_coords(x1, x2, x3, t1);
  2013. var ay = interp_quad_coords(y1, y2, y3, t1);
  2014. var dx = interp_quad_coords(x1, x2, x3, (t1 + t2) / 2);
  2015. var dy = interp_quad_coords(y1, y2, y3, (t1 + t2) / 2);
  2016. var cx = interp_quad_coords(x1, x2, x3, t2);
  2017. var cy = interp_quad_coords(y1, y2, y3, t2);
  2018. var bx = 2*dx - (ax + cx)/2;
  2019. var by = 2*dy - (ay + cy)/2;
  2020. var array = [
  2021. ax, ay, bx, by, cx, cy
  2022. ];
  2023. return array;
  2024. }
  2025. function drawQuadPartial(x1, y1, x2, y2, x3, y3, t1, t2) {
  2026. var a = quadPartial(x1, y1, x2, y2, x3, y3, t1, t2);
  2027. var ax = a[0];
  2028. var ay = a[1];
  2029. var bx = a[2];
  2030. var by = a[3];
  2031. var cx = a[4];
  2032. var cy = a[5];
  2033. if (alreadyDrawnQuad(ax, ay, bx, by, cx, cy)) {
  2034. return;
  2035. }
  2036. ctx.beginPath();
  2037. ctx.moveTo((ax - srcLeft) * scale,
  2038. (ay - srcTop) * scale);
  2039. ctx.quadraticCurveTo((bx - srcLeft) * scale,
  2040. (by - srcTop) * scale,
  2041. (cx - srcLeft) * scale,
  2042. (cy - srcTop) * scale);
  2043. ctx.stroke();
  2044. }
  2045. function alreadyDrawnConic(x1, y1, x2, y2, x3, y3, w) {
  2046. if (collect_bounds) {
  2047. if (focus_enabled) {
  2048. focusXmin = Math.min(focusXmin, x1, x2, x3);
  2049. focusYmin = Math.min(focusYmin, y1, y2, y3);
  2050. focusXmax = Math.max(focusXmax, x1, x2, x3);
  2051. focusYmax = Math.max(focusYmax, y1, y2, y3);
  2052. }
  2053. return true;
  2054. }
  2055. for (var pts = 0; pts < drawnConics.length; pts += 8) {
  2056. if (x1 == drawnConics[pts] && y1 == drawnCubics[pts + 1]
  2057. && x2 == drawnCubics[pts + 2] && y2 == drawnCubics[pts + 3]
  2058. && x3 == drawnCubics[pts + 4] && y3 == drawnCubics[pts + 5]
  2059. && w == drawnCubics[pts + 6]) {
  2060. return true;
  2061. }
  2062. }
  2063. drawnConics.push(x1);
  2064. drawnConics.push(y1);
  2065. drawnConics.push(x2);
  2066. drawnConics.push(y2);
  2067. drawnConics.push(x3);
  2068. drawnConics.push(y3);
  2069. drawnCubics.push(w);
  2070. return false;
  2071. }
  2072. var kMaxConicToQuadPOW2 = 5;
  2073. function computeQuadPOW2(curve, tol) {
  2074. var a = curve[6] - 1;
  2075. var k = a / (4 * (2 + a));
  2076. var x = k * (curve[0] - 2 * curve[2] + curve[4]);
  2077. var y = k * (curve[1] - 2 * curve[3] + curve[5]);
  2078. var error = Math.sqrt(x * x + y * y);
  2079. var pow2;
  2080. for (pow2 = 0; pow2 < kMaxConicToQuadPOW2; ++pow2) {
  2081. if (error <= tol) {
  2082. break;
  2083. }
  2084. error *= 0.25;
  2085. }
  2086. return pow2;
  2087. }
  2088. function subdivide_w_value(w) {
  2089. return Math.sqrt(0.5 + w * 0.5);
  2090. }
  2091. function chop(curve, part1, part2) {
  2092. var w = curve[6];
  2093. var scale = 1 / (1 + w);
  2094. part1[0] = curve[0];
  2095. part1[1] = curve[1];
  2096. part1[2] = (curve[0] + curve[2] * w) * scale;
  2097. part1[3] = (curve[1] + curve[3] * w) * scale;
  2098. part1[4] = part2[0] = (curve[0] + (curve[2] * w) * 2 + curve[4]) * scale * 0.5;
  2099. part1[5] = part2[1] = (curve[1] + (curve[3] * w) * 2 + curve[5]) * scale * 0.5;
  2100. part2[2] = (curve[2] * w + curve[4]) * scale;
  2101. part2[3] = (curve[3] * w + curve[5]) * scale;
  2102. part2[4] = curve[4];
  2103. part2[5] = curve[5];
  2104. part1[6] = part2[6] = subdivide_w_value(w);
  2105. }
  2106. function subdivide(curve, level, pts) {
  2107. if (0 == level) {
  2108. pts.push(curve[2]);
  2109. pts.push(curve[3]);
  2110. pts.push(curve[4]);
  2111. pts.push(curve[5]);
  2112. } else {
  2113. var part1 = [], part2 = [];
  2114. chop(curve, part1, part2);
  2115. --level;
  2116. subdivide(part1, level, pts);
  2117. subdivide(part2, level, pts);
  2118. }
  2119. }
  2120. function chopIntoQuadsPOW2(curve, pow2, pts) {
  2121. subdivide(curve, pow2, pts);
  2122. return 1 << pow2;
  2123. }
  2124. function drawConicWithQuads(x1, y1, x2, y2, x3, y3, w) {
  2125. if (alreadyDrawnConic(x1, y1, x2, y2, x3, y3, w)) {
  2126. return;
  2127. }
  2128. ctx.beginPath();
  2129. ctx.moveTo((x1 - srcLeft) * scale,
  2130. (y1 - srcTop) * scale);
  2131. var tol = 1 / scale;
  2132. var curve = [x1, y1, x2, y2, x3, y3, w];
  2133. var pow2 = computeQuadPOW2(curve, tol);
  2134. var pts = [];
  2135. chopIntoQuadsPOW2(curve, pow2, pts);
  2136. for (var i = 0; i < pts.length; i += 4) {
  2137. ctx.quadraticCurveTo(
  2138. (pts[i + 0] - srcLeft) * scale, (pts[i + 1] - srcTop) * scale,
  2139. (pts[i + 2] - srcLeft) * scale, (pts[i + 3] - srcTop) * scale);
  2140. }
  2141. ctx.stroke();
  2142. }
  2143. function conic_eval_numerator(x1, x2, x3, w, t) {
  2144. var src2w = x2 * w;
  2145. var C = x1;
  2146. var A = x3 - 2 * src2w + C;
  2147. var B = 2 * (src2w - C);
  2148. return (A * t + B) * t + C;
  2149. }
  2150. function conic_eval_denominator(w, t) {
  2151. var B = 2 * (w - 1);
  2152. var C = 1;
  2153. var A = -B;
  2154. return (A * t + B) * t + C;
  2155. }
  2156. function conicPartial(x1, y1, x2, y2, x3, y3, w, t1, t2) {
  2157. var ax = conic_eval_numerator(x1, x2, x3, w, t1);
  2158. var ay = conic_eval_numerator(y1, y2, y3, w, t1);
  2159. var az = conic_eval_denominator(w, t1);
  2160. var midT = (t1 + t2) / 2;
  2161. var dx = conic_eval_numerator(x1, x2, x3, w, midT);
  2162. var dy = conic_eval_numerator(y1, y2, y3, w, midT);
  2163. var dz = conic_eval_denominator(w, midT);
  2164. var cx = conic_eval_numerator(x1, x2, x3, w, t2);
  2165. var cy = conic_eval_numerator(y1, y2, y3, w, t2);
  2166. var cz = conic_eval_denominator(w, t2);
  2167. var bx = 2 * dx - (ax + cx) / 2;
  2168. var by = 2 * dy - (ay + cy) / 2;
  2169. var bz = 2 * dz - (az + cz) / 2;
  2170. var dt = t2 - t1;
  2171. var dt_1 = 1 - dt;
  2172. var array = [
  2173. ax / az, ay / az, bx / bz, by / bz, cx / cz, cy / cz, 0
  2174. ];
  2175. var dMidAC = { x:(array[0] + array[4]) / 2, y:(array[1] + array[5]) / 2 };
  2176. var dMid = { x:dx / dz, y:dy / dz };
  2177. var dWNumer = { x:dMidAC.x - dMid.x, y:dMidAC.y - dMid.y };
  2178. var dWDenom = { x:dMid.x - array[2], y:dMid.y - array[3] };
  2179. var partW = Math.sqrt(dWNumer.x * dWNumer.x + dWNumer.y * dWNumer.y)
  2180. / Math.sqrt(dWDenom.x * dWDenom.x + dWDenom.y * dWDenom.y);
  2181. array[6] = partW;
  2182. return array;
  2183. }
  2184. function drawConicPartial(x1, y1, x2, y2, x3, y3, w, t1, t2) {
  2185. var a = conicPartial(x1, y1, x2, y2, x3, y3, w, t1, t2);
  2186. var ax = a[0];
  2187. var ay = a[1];
  2188. var bx = a[2];
  2189. var by = a[3];
  2190. var cx = a[4];
  2191. var cy = a[5];
  2192. var w_ = a[6];
  2193. drawConicWithQuads(ax, ay, bx, by, cx, cy, w_);
  2194. }
  2195. function alreadyDrawnCubic(x1, y1, x2, y2, x3, y3, x4, y4) {
  2196. if (collect_bounds) {
  2197. if (focus_enabled) {
  2198. focusXmin = Math.min(focusXmin, x1, x2, x3, x4);
  2199. focusYmin = Math.min(focusYmin, y1, y2, y3, y4);
  2200. focusXmax = Math.max(focusXmax, x1, x2, x3, x4);
  2201. focusYmax = Math.max(focusYmax, y1, y2, y3, y4);
  2202. }
  2203. return true;
  2204. }
  2205. for (var pts = 0; pts < drawnCubics.length; pts += 8) {
  2206. if (x1 == drawnCubics[pts] && y1 == drawnCubics[pts + 1]
  2207. && x2 == drawnCubics[pts + 2] && y2 == drawnCubics[pts + 3]
  2208. && x3 == drawnCubics[pts + 4] && y3 == drawnCubics[pts + 5]
  2209. && x4 == drawnCubics[pts + 6] && y4 == drawnCubics[pts + 7]) {
  2210. return true;
  2211. }
  2212. }
  2213. drawnCubics.push(x1);
  2214. drawnCubics.push(y1);
  2215. drawnCubics.push(x2);
  2216. drawnCubics.push(y2);
  2217. drawnCubics.push(x3);
  2218. drawnCubics.push(y3);
  2219. drawnCubics.push(x4);
  2220. drawnCubics.push(y4);
  2221. return false;
  2222. }
  2223. function drawCubic(x1, y1, x2, y2, x3, y3, x4, y4) {
  2224. if (alreadyDrawnCubic(x1, y1, x2, y2, x3, y3, x4, y4)) {
  2225. return;
  2226. }
  2227. ctx.beginPath();
  2228. ctx.moveTo((x1 - srcLeft) * scale,
  2229. (y1 - srcTop) * scale);
  2230. ctx.bezierCurveTo((x2 - srcLeft) * scale,
  2231. (y2 - srcTop) * scale,
  2232. (x3 - srcLeft) * scale,
  2233. (y3 - srcTop) * scale,
  2234. (x4 - srcLeft) * scale,
  2235. (y4 - srcTop) * scale);
  2236. ctx.stroke();
  2237. }
  2238. function interp_cubic_coords(x1, x2, x3, x4, t)
  2239. {
  2240. var ab = interp(x1, x2, t);
  2241. var bc = interp(x2, x3, t);
  2242. var cd = interp(x3, x4, t);
  2243. var abc = interp(ab, bc, t);
  2244. var bcd = interp(bc, cd, t);
  2245. var abcd = interp(abc, bcd, t);
  2246. return abcd;
  2247. }
  2248. function cubicPartial(x1, y1, x2, y2, x3, y3, x4, y4, t1, t2) {
  2249. var ax = interp_cubic_coords(x1, x2, x3, x4, t1);
  2250. var ay = interp_cubic_coords(y1, y2, y3, y4, t1);
  2251. var ex = interp_cubic_coords(x1, x2, x3, x4, (t1*2+t2)/3);
  2252. var ey = interp_cubic_coords(y1, y2, y3, y4, (t1*2+t2)/3);
  2253. var fx = interp_cubic_coords(x1, x2, x3, x4, (t1+t2*2)/3);
  2254. var fy = interp_cubic_coords(y1, y2, y3, y4, (t1+t2*2)/3);
  2255. var dx = interp_cubic_coords(x1, x2, x3, x4, t2);
  2256. var dy = interp_cubic_coords(y1, y2, y3, y4, t2);
  2257. var mx = ex * 27 - ax * 8 - dx;
  2258. var my = ey * 27 - ay * 8 - dy;
  2259. var nx = fx * 27 - ax - dx * 8;
  2260. var ny = fy * 27 - ay - dy * 8;
  2261. var bx = (mx * 2 - nx) / 18;
  2262. var by = (my * 2 - ny) / 18;
  2263. var cx = (nx * 2 - mx) / 18;
  2264. var cy = (ny * 2 - my) / 18;
  2265. var array = [
  2266. ax, ay, bx, by, cx, cy, dx, dy
  2267. ];
  2268. return array;
  2269. }
  2270. function drawCubicPartial(x1, y1, x2, y2, x3, y3, x4, y4, t1, t2) {
  2271. var a = cubicPartial(x1, y1, x2, y2, x3, y3, x4, y4, t1, t2);
  2272. var ax = a[0];
  2273. var ay = a[1];
  2274. var bx = a[2];
  2275. var by = a[3];
  2276. var cx = a[4];
  2277. var cy = a[5];
  2278. var dx = a[6];
  2279. var dy = a[7];
  2280. if (alreadyDrawnCubic(ax, ay, bx, by, cx, cy, dx, dy)) {
  2281. return;
  2282. }
  2283. ctx.beginPath();
  2284. ctx.moveTo((ax - srcLeft) * scale,
  2285. (ay - srcTop) * scale);
  2286. ctx.bezierCurveTo((bx - srcLeft) * scale,
  2287. (by - srcTop) * scale,
  2288. (cx - srcLeft) * scale,
  2289. (cy - srcTop) * scale,
  2290. (dx - srcLeft) * scale,
  2291. (dy - srcTop) * scale);
  2292. ctx.stroke();
  2293. }
  2294. function drawCurve(c) {
  2295. switch (c.length) {
  2296. case 4:
  2297. drawLine(c[0], c[1], c[2], c[3]);
  2298. break;
  2299. case 6:
  2300. drawQuad(c[0], c[1], c[2], c[3], c[4], c[5]);
  2301. break;
  2302. case 7:
  2303. drawConicWithQuads(c[0], c[1], c[2], c[3], c[4], c[5], c[6]);
  2304. break;
  2305. case 8:
  2306. drawCubic(c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]);
  2307. break;
  2308. }
  2309. }
  2310. function boundsWidth(pts) {
  2311. var min = pts[0];
  2312. var max = pts[0];
  2313. var length = pts.length == 7 ? 6 : pts.length;
  2314. for (var idx = 2; idx < length; idx += 2) {
  2315. min = Math.min(min, pts[idx]);
  2316. max = Math.max(max, pts[idx]);
  2317. }
  2318. return max - min;
  2319. }
  2320. function boundsHeight(pts) {
  2321. var min = pts[1];
  2322. var max = pts[1];
  2323. var length = pts.length == 7 ? 6 : pts.length;
  2324. for (var idx = 3; idx < length; idx += 2) {
  2325. min = Math.min(min, pts[idx]);
  2326. max = Math.max(max, pts[idx]);
  2327. }
  2328. return max - min;
  2329. }
  2330. function tangent(pts) {
  2331. var dx = pts[2] - pts[0];
  2332. var dy = pts[3] - pts[1];
  2333. if (dx == 0 && dy == 0 && pts.length > 4) {
  2334. dx = pts[4] - pts[0];
  2335. dy = pts[5] - pts[1];
  2336. if (dx == 0 && dy == 0 && pts.length == 8) {
  2337. dx = pts[6] - pts[0];
  2338. dy = pts[7] - pts[1];
  2339. }
  2340. }
  2341. return Math.atan2(-dy, dx);
  2342. }
  2343. function hodograph(cubic) {
  2344. var hodo = [];
  2345. hodo[0] = 3 * (cubic[2] - cubic[0]);
  2346. hodo[1] = 3 * (cubic[3] - cubic[1]);
  2347. hodo[2] = 3 * (cubic[4] - cubic[2]);
  2348. hodo[3] = 3 * (cubic[5] - cubic[3]);
  2349. hodo[4] = 3 * (cubic[6] - cubic[4]);
  2350. hodo[5] = 3 * (cubic[7] - cubic[5]);
  2351. return hodo;
  2352. }
  2353. function hodograph2(cubic) {
  2354. var quad = hodograph(cubic);
  2355. var hodo = [];
  2356. hodo[0] = 2 * (quad[2] - quad[0]);
  2357. hodo[1] = 2 * (quad[3] - quad[1]);
  2358. hodo[2] = 2 * (quad[4] - quad[2]);
  2359. hodo[3] = 2 * (quad[5] - quad[3]);
  2360. return hodo;
  2361. }
  2362. function quadraticRootsReal(A, B, C, s) {
  2363. if (A == 0) {
  2364. if (B == 0) {
  2365. s[0] = 0;
  2366. return C == 0;
  2367. }
  2368. s[0] = -C / B;
  2369. return 1;
  2370. }
  2371. /* normal form: x^2 + px + q = 0 */
  2372. var p = B / (2 * A);
  2373. var q = C / A;
  2374. var p2 = p * p;
  2375. if (p2 < q) {
  2376. return 0;
  2377. }
  2378. var sqrt_D = 0;
  2379. if (p2 > q) {
  2380. sqrt_D = sqrt(p2 - q);
  2381. }
  2382. s[0] = sqrt_D - p;
  2383. s[1] = -sqrt_D - p;
  2384. return 1 + s[0] != s[1];
  2385. }
  2386. function add_valid_ts(s, realRoots, t) {
  2387. var foundRoots = 0;
  2388. for (var index = 0; index < realRoots; ++index) {
  2389. var tValue = s[index];
  2390. if (tValue >= 0 && tValue <= 1) {
  2391. for (var idx2 = 0; idx2 < foundRoots; ++idx2) {
  2392. if (t[idx2] != tValue) {
  2393. t[foundRoots++] = tValue;
  2394. }
  2395. }
  2396. }
  2397. }
  2398. return foundRoots;
  2399. }
  2400. function quadraticRootsValidT(a, b, c, t) {
  2401. var s = [];
  2402. var realRoots = quadraticRootsReal(A, B, C, s);
  2403. var foundRoots = add_valid_ts(s, realRoots, t);
  2404. return foundRoots != 0;
  2405. }
  2406. function find_cubic_inflections(cubic, tValues) {
  2407. var Ax = src[2] - src[0];
  2408. var Ay = src[3] - src[1];
  2409. var Bx = src[4] - 2 * src[2] + src[0];
  2410. var By = src[5] - 2 * src[3] + src[1];
  2411. var Cx = src[6] + 3 * (src[2] - src[4]) - src[0];
  2412. var Cy = src[7] + 3 * (src[3] - src[5]) - src[1];
  2413. return quadraticRootsValidT(Bx * Cy - By * Cx, (Ax * Cy - Ay * Cx),
  2414. Ax * By - Ay * Bx, tValues);
  2415. }
  2416. function dxy_at_t(curve, type, t) {
  2417. var dxy = {};
  2418. if (type == PATH_LINE) {
  2419. dxy.x = curve[2] - curve[0];
  2420. dxy.y = curve[3] - curve[1];
  2421. } else if (type == PATH_QUAD) {
  2422. var a = t - 1;
  2423. var b = 1 - 2 * t;
  2424. var c = t;
  2425. dxy.x = a * curve[0] + b * curve[2] + c * curve[4];
  2426. dxy.y = a * curve[1] + b * curve[3] + c * curve[5];
  2427. } else if (type == PATH_CONIC) {
  2428. var p20x = curve[4] - curve[0];
  2429. var p20y = curve[5] - curve[1];
  2430. var p10xw = (curve[2] - curve[0]) * curve[6];
  2431. var p10yw = (curve[3] - curve[1]) * curve[6];
  2432. var coeff0x = curve[6] * p20x - p20x;
  2433. var coeff0y = curve[6] * p20y - p20y;
  2434. var coeff1x = p20x - 2 * p10xw;
  2435. var coeff1y = p20y - 2 * p10yw;
  2436. dxy.x = t * (t * coeff0x + coeff1x) + p10xw;
  2437. dxy.y = t * (t * coeff0y + coeff1y) + p10yw;
  2438. } else if (type == PATH_CUBIC) {
  2439. var one_t = 1 - t;
  2440. var a = curve[0];
  2441. var b = curve[2];
  2442. var c = curve[4];
  2443. var d = curve[6];
  2444. dxy.x = 3 * ((b - a) * one_t * one_t + 2 * (c - b) * t * one_t + (d - c) * t * t);
  2445. a = curve[1];
  2446. b = curve[3];
  2447. c = curve[5];
  2448. d = curve[7];
  2449. dxy.y = 3 * ((b - a) * one_t * one_t + 2 * (c - b) * t * one_t + (d - c) * t * t);
  2450. }
  2451. return dxy;
  2452. }
  2453. function dpt_at_t(curve, t) {
  2454. var type = PATH_LINE + (curve.length / 2 - 2);
  2455. return dxy_at_t(curve, type, t);
  2456. }
  2457. function drawLabel(num, px, py) {
  2458. ctx.beginPath();
  2459. ctx.arc(px, py, 8, 0, Math.PI*2, true);
  2460. ctx.closePath();
  2461. ctx.strokeStyle = "rgba(0,0,0, 0.4)";
  2462. ctx.lineWidth = num == 0 || num == 3 ? 2 : 1;
  2463. ctx.stroke();
  2464. ctx.fillStyle = "black";
  2465. ctx.font = "normal 10px Arial";
  2466. // ctx.rotate(0.001);
  2467. ctx.fillText(num, px - 2, py + 3);
  2468. // ctx.rotate(-0.001);
  2469. }
  2470. function drawLabelX(ymin, num, loc) {
  2471. var px = (loc - srcLeft) * scale;
  2472. var py = (ymin - srcTop) * scale - 20;
  2473. drawLabel(num, px, py);
  2474. }
  2475. function drawLabelY(xmin, num, loc) {
  2476. var px = (xmin - srcLeft) * scale - 20;
  2477. var py = (loc - srcTop) * scale;
  2478. drawLabel(num, px, py);
  2479. }
  2480. function drawHodoOrigin(hx, hy, hMinX, hMinY, hMaxX, hMaxY) {
  2481. ctx.beginPath();
  2482. ctx.moveTo(hx, hy - 100);
  2483. ctx.lineTo(hx, hy);
  2484. ctx.strokeStyle = hMinY < 0 ? "green" : "blue";
  2485. ctx.stroke();
  2486. ctx.beginPath();
  2487. ctx.moveTo(hx, hy);
  2488. ctx.lineTo(hx, hy + 100);
  2489. ctx.strokeStyle = hMaxY > 0 ? "green" : "blue";
  2490. ctx.stroke();
  2491. ctx.beginPath();
  2492. ctx.moveTo(hx - 100, hy);
  2493. ctx.lineTo(hx, hy);
  2494. ctx.strokeStyle = hMinX < 0 ? "green" : "blue";
  2495. ctx.stroke();
  2496. ctx.beginPath();
  2497. ctx.moveTo(hx, hy);
  2498. ctx.lineTo(hx + 100, hy);
  2499. ctx.strokeStyle = hMaxX > 0 ? "green" : "blue";
  2500. ctx.stroke();
  2501. }
  2502. function scalexy(x, y, mag) {
  2503. var length = Math.sqrt(x * x + y * y);
  2504. return mag / length;
  2505. }
  2506. function drawArrow(x, y, dx, dy, s) {
  2507. var dscale = scalexy(dx, dy, 1 / scale * 100 * s);
  2508. dx *= dscale;
  2509. dy *= dscale;
  2510. ctx.beginPath();
  2511. ctx.moveTo((x - srcLeft) * scale, (y - srcTop) * scale);
  2512. x += dx;
  2513. y += dy;
  2514. ctx.lineTo((x - srcLeft) * scale, (y - srcTop) * scale);
  2515. dx /= 10;
  2516. dy /= 10;
  2517. ctx.lineTo((x - dy - srcLeft) * scale, (y + dx - srcTop) * scale);
  2518. ctx.lineTo((x + dx * 2 - srcLeft) * scale, (y + dy * 2 - srcTop) * scale);
  2519. ctx.lineTo((x + dy - srcLeft) * scale, (y - dx - srcTop) * scale);
  2520. ctx.lineTo((x - srcLeft) * scale, (y - srcTop) * scale);
  2521. ctx.strokeStyle = "rgba(0,75,0, 0.4)";
  2522. ctx.stroke();
  2523. }
  2524. function x_at_t(curve, t) {
  2525. var one_t = 1 - t;
  2526. if (curve.length == 4) {
  2527. return one_t * curve[0] + t * curve[2];
  2528. }
  2529. var one_t2 = one_t * one_t;
  2530. var t2 = t * t;
  2531. if (curve.length == 6) {
  2532. return one_t2 * curve[0] + 2 * one_t * t * curve[2] + t2 * curve[4];
  2533. }
  2534. if (curve.length == 7) {
  2535. return (one_t2 * curve[0] + 2 * one_t * t * curve[2] * curve[6] + t2 * curve[4])
  2536. / (one_t2 +2 * one_t * t * curve[6] + t2);
  2537. }
  2538. var a = one_t2 * one_t;
  2539. var b = 3 * one_t2 * t;
  2540. var c = 3 * one_t * t2;
  2541. var d = t2 * t;
  2542. return a * curve[0] + b * curve[2] + c * curve[4] + d * curve[6];
  2543. }
  2544. function y_at_t(curve, t) {
  2545. var one_t = 1 - t;
  2546. if (curve.length == 4) {
  2547. return one_t * curve[1] + t * curve[3];
  2548. }
  2549. var one_t2 = one_t * one_t;
  2550. var t2 = t * t;
  2551. if (curve.length == 6) {
  2552. return one_t2 * curve[1] + 2 * one_t * t * curve[3] + t2 * curve[5];
  2553. }
  2554. if (curve.length == 7) {
  2555. return (one_t2 * curve[1] + 2 * one_t * t * curve[3] * curve[6] + t2 * curve[5])
  2556. / (one_t2 +2 * one_t * t * curve[6] + t2);
  2557. }
  2558. var a = one_t2 * one_t;
  2559. var b = 3 * one_t2 * t;
  2560. var c = 3 * one_t * t2;
  2561. var d = t2 * t;
  2562. return a * curve[1] + b * curve[3] + c * curve[5] + d * curve[7];
  2563. }
  2564. function pt_at_t(curve, t) {
  2565. var pt = {};
  2566. pt.x = x_at_t(curve, t);
  2567. pt.y = y_at_t(curve, t);
  2568. return pt;
  2569. }
  2570. function drawOrder(curve, t, label) {
  2571. var px = x_at_t(curve, t);
  2572. var py = y_at_t(curve, t);
  2573. var _px = (px - srcLeft) * scale;
  2574. var _py = (py - srcTop) * scale;
  2575. ctx.beginPath();
  2576. ctx.arc(_px, _py, 15, 0, Math.PI * 2, true);
  2577. ctx.closePath();
  2578. ctx.fillStyle = "white";
  2579. ctx.fill();
  2580. if (label == 'L') {
  2581. ctx.strokeStyle = "rgba(255,0,0, 1)";
  2582. ctx.fillStyle = "rgba(255,0,0, 1)";
  2583. } else {
  2584. ctx.strokeStyle = "rgba(0,0,255, 1)";
  2585. ctx.fillStyle = "rgba(0,0,255, 1)";
  2586. }
  2587. ctx.stroke();
  2588. ctx.font = "normal 16px Arial";
  2589. ctx.textAlign = "center";
  2590. ctx.fillText(label, _px, _py + 5);
  2591. ctx.font = "normal 10px Arial";
  2592. }
  2593. function drawVisibleOrder(curve, label) {
  2594. var s = pt_at_t(curve, 0);
  2595. var e = pt_at_t(curve, 1);
  2596. var sOn = ptOnScreen(s);
  2597. var eOn = ptOnScreen(e);
  2598. var defaultT = 0.85;
  2599. if (sOn && eOn)
  2600. return drawOrder(curve, defaultT, label);
  2601. if (sOn || eOn) {
  2602. if (eOn) {
  2603. defaultT = 1 - defaultT;
  2604. }
  2605. var step = sOn ? -defaultT / 2 : (1 - defaultT) / 2;
  2606. var t = defaultT;
  2607. var tries = 16;
  2608. do {
  2609. var mid = pt_at_t(curve, t);
  2610. if (ptOnScreen(mid))
  2611. return drawOrder(curve, t, label);
  2612. t += step;
  2613. step /= 2;
  2614. } while (--tries > 0);
  2615. drawOrder(curve, defaultT, label);
  2616. }
  2617. // scattershot until we find a visible point
  2618. var denom = 2; // visit odd number num / denom to hit unique pts
  2619. var tries = 6; // tries 1/2, 1/4, 3/4, 1/8, 3/8, 5/8, 7/8, 1/16 ...
  2620. do {
  2621. for (var numer = 1; numer < denom; numer += 2) {
  2622. var t = numer / denom + 0.1;
  2623. if (t >= 1) {
  2624. break;
  2625. }
  2626. var mid = pt_at_t(curve, t);
  2627. if (ptOnScreen(mid))
  2628. return drawOrder(curve, t, label);
  2629. }
  2630. denom *= 2;
  2631. } while (--tries > 0);
  2632. drawOrder(curve, defaultT, label);
  2633. }
  2634. function set_length(pt, newLen) {
  2635. var len = Math.sqrt(pt.x * pt.x + pt.y * pt.y);
  2636. var scale = newLen / len;
  2637. var newPt = { x: pt.x * scale, y: pt.y * scale };
  2638. return newPt;
  2639. }
  2640. function drawDirection(curve, t) {
  2641. var d = dpt_at_t(curve, t);
  2642. d = set_length(d, 16);
  2643. var pt = localToGlobal(pt_at_t(curve, t));
  2644. ctx.beginPath();
  2645. ctx.moveTo(pt.x - d.y, pt.y + d.x);
  2646. ctx.lineTo(pt.x + d.x, pt.y + d.y);
  2647. ctx.lineTo(pt.x + d.y, pt.y - d.x);
  2648. ctx.strokeStyle = "rgba(0,75,0, 0.4)";
  2649. ctx.stroke();
  2650. }
  2651. function drawVisibleDirection(curve) {
  2652. var s = pt_at_t(curve, 0);
  2653. var e = pt_at_t(curve, 1);
  2654. var sOn = ptOnScreen(s);
  2655. var eOn = ptOnScreen(e);
  2656. var defaultT = 0.65;
  2657. if (sOn && eOn) {
  2658. return drawDirection(curve, defaultT);
  2659. }
  2660. if (sOn || eOn) {
  2661. if (eOn) {
  2662. defaultT = 1 - defaultT;
  2663. }
  2664. var step = sOn ? -defaultT / 2 : (1 - defaultT) / 2;
  2665. var t = defaultT;
  2666. var tries = 16;
  2667. do {
  2668. var mid = pt_at_t(curve, t);
  2669. if (ptOnScreen(mid))
  2670. return drawDirection(curve, t);
  2671. t += step;
  2672. step /= 2;
  2673. } while (--tries > 0);
  2674. drawDirection(curve, defaultT);
  2675. }
  2676. // scattershot until we find a visible point
  2677. var denom = 2; // visit odd number num / denom to hit unique pts
  2678. var tries = 6; // tries 1/2, 1/4, 3/4, 1/8, 3/8, 5/8, 7/8, 1/16 ...
  2679. do {
  2680. for (var numer = 1; numer < denom; numer += 2) {
  2681. var t = numer / denom + 0.1;
  2682. if (t >= 1) {
  2683. break;
  2684. }
  2685. var mid = pt_at_t(curve, t);
  2686. if (ptOnScreen(mid))
  2687. return drawDirection(curve, t);
  2688. }
  2689. denom *= 2;
  2690. } while (--tries > 0);
  2691. drawDirection(curve, defaultT);
  2692. }
  2693. function drawID(curve, t, id) {
  2694. var px = x_at_t(curve, t);
  2695. var py = y_at_t(curve, t);
  2696. var _px = (px - srcLeft) * scale;
  2697. var _py = (py - srcTop) * scale;
  2698. draw_id_at(id, _px, _py);
  2699. }
  2700. function localToGlobal(local) {
  2701. var global = {};
  2702. global.x = (local.x - srcLeft) * scale;
  2703. global.y = (local.y - srcTop) * scale;
  2704. return global;
  2705. }
  2706. function ptOnScreen(local) {
  2707. var pt = localToGlobal(local);
  2708. return 10 <= pt.x && pt.x <= screenWidth - 10
  2709. && 10 <= pt.y && pt.y <= screenHeight - 10;
  2710. }
  2711. function drawVisibleID(curve, defaultT, id) {
  2712. // determine if either or both ends are visible
  2713. var s = pt_at_t(curve, 0);
  2714. var e = pt_at_t(curve, 1);
  2715. var sOn = ptOnScreen(s);
  2716. var eOn = ptOnScreen(e);
  2717. if (sOn && eOn)
  2718. return drawID(curve, defaultT, id);
  2719. if (sOn || eOn) {
  2720. var step = sOn ? -defaultT / 2 : (1 - defaultT) / 2;
  2721. var t = defaultT;
  2722. var tries = 16;
  2723. do {
  2724. var mid = pt_at_t(curve, t);
  2725. if (ptOnScreen(mid))
  2726. return drawID(curve, t, id);
  2727. t += step;
  2728. step /= 2;
  2729. } while (--tries > 0);
  2730. drawID(curve, defaultT, id);
  2731. }
  2732. // scattershot until we find a visible point
  2733. var denom = 2; // visit odd number num / denom to hit unique pts
  2734. var tries = 6; // tries 1/2, 1/4, 3/4, 1/8, 3/8, 5/8, 7/8, 1/16 ...
  2735. do {
  2736. for (var numer = 1; numer < denom; numer += 2) {
  2737. var t = numer / denom;
  2738. var mid = pt_at_t(curve, t);
  2739. if (ptOnScreen(mid))
  2740. return drawID(curve, t, id);
  2741. }
  2742. denom *= 2;
  2743. } while (--tries > 0);
  2744. drawID(curve, defaultT, id);
  2745. }
  2746. function draw_id_at(id, _px, _py) {
  2747. ctx.beginPath();
  2748. ctx.arc(_px, _py, 15, 0, Math.PI * 2, true);
  2749. ctx.closePath();
  2750. ctx.fillStyle = "white";
  2751. ctx.fill();
  2752. ctx.strokeStyle = "rgba(127,127,0, 1)";
  2753. ctx.fillStyle = "rgba(127,127,0, 1)";
  2754. ctx.stroke();
  2755. ctx.font = "normal 16px Arial";
  2756. ctx.textAlign = "center";
  2757. ctx.fillText(id, _px, _py + 5);
  2758. ctx.font = "normal 10px Arial";
  2759. }
  2760. function drawLinePartialID(id, x1, y1, x2, y2, t1, t2) {
  2761. var curve = [x1, y1, x2, y2];
  2762. drawCurvePartialID(id, curve, t1, t2);
  2763. }
  2764. function drawLineID(id, x1, y1, x2, y2) {
  2765. drawLinePartialID(id, x1, y1, x2, y2, 0, 1);
  2766. }
  2767. function drawQuadPartialID(id, x1, y1, x2, y2, x3, y3, t1, t2) {
  2768. var curve = [x1, y1, x2, y2, x3, y3];
  2769. drawCurvePartialID(id, curve, t1, t2);
  2770. }
  2771. function drawQuadID(id, x1, y1, x2, y2, x3, y3) {
  2772. drawQuadPartialID(id, x1, y1, x2, y2, x3, y3, 0, 1);
  2773. }
  2774. function drawConicPartialID(id, x1, y1, x2, y2, x3, y3, w, t1, t2) {
  2775. var curve = [x1, y1, x2, y2, x3, y3, w];
  2776. drawCurvePartialID(id, curve, t1, t2);
  2777. }
  2778. function drawConicID(id, x1, y1, x2, y2, x3, y3, w) {
  2779. drawConicPartialID(id, x1, y1, x2, y2, x3, y3, w, 0, 1);
  2780. }
  2781. function drawCubicPartialID(id, x1, y1, x2, y2, x3, y3, x4, y4, t1, t2) {
  2782. var curve = [x1, y1, x2, y2, x3, y3, x4, y4];
  2783. drawCurvePartialID(id, curve, t1, t2);
  2784. }
  2785. function drawCubicID(id, x1, y1, x2, y2, x3, y3, x4, y4) {
  2786. drawCubicPartialID(id, x1, y1, x2, y2, x3, y3, x4, y4, 0, 1);
  2787. }
  2788. function drawCurvePartialID(id, curve, t1, t2) {
  2789. drawVisibleID(curve, (t1 + t2) / 2, id);
  2790. }
  2791. function drawCurveSpecials(test, curve, type) {
  2792. if (pt_labels) {
  2793. drawPoints(curve, type, pt_labels == 2);
  2794. }
  2795. if (control_lines != 0) {
  2796. drawControlLines(curve, type, control_lines);
  2797. }
  2798. if (curve_t) {
  2799. drawPointAtT(curve, type);
  2800. }
  2801. if (draw_midpoint) {
  2802. var mid = pointAtT(curve, type, 0.5);
  2803. drawPoint(mid.x, mid.y, true);
  2804. }
  2805. if (draw_id) {
  2806. var id = idByCurve(test, curve, type);
  2807. if (id >= 0) {
  2808. drawVisibleID(curve, 0.5, id);
  2809. }
  2810. }
  2811. if (draw_direction) {
  2812. drawVisibleDirection(curve);
  2813. }
  2814. if (type == PATH_LINE) {
  2815. return;
  2816. }
  2817. if (draw_deriviatives > 0) {
  2818. var d = dxy_at_t(curve, type, 0);
  2819. drawArrow(curve[0], curve[1], d.x, d.y, 1);
  2820. if (draw_deriviatives == 2) {
  2821. d = dxy_at_t(curve, type, 1);
  2822. if (type == PATH_CUBIC) {
  2823. drawArrow(curve[6], curve[7], d.x, d.y, 1);
  2824. } else {
  2825. drawArrow(curve[4], curve[5], d.x, d.y, 1);
  2826. }
  2827. }
  2828. if (draw_midpoint) {
  2829. var mid = pointAtT(curve, type, 0.5);
  2830. d = dxy_at_t(curve, type, 0.5);
  2831. drawArrow(mid.x, mid.y, d.x, d.y, 1);
  2832. }
  2833. }
  2834. if (type != PATH_CUBIC) {
  2835. return;
  2836. }
  2837. if (draw_sequence) {
  2838. var ymin = Math.min(curve[1], curve[3], curve[5], curve[7]);
  2839. for (var i = 0; i < 8; i+= 2) {
  2840. drawLabelX(ymin, i >> 1, curve[i]);
  2841. }
  2842. var xmin = Math.min(curve[0], curve[2], curve[4], curve[6]);
  2843. for (var i = 1; i < 8; i+= 2) {
  2844. drawLabelY(xmin, i >> 1, curve[i]);
  2845. }
  2846. }
  2847. }
  2848. function logCurves(test) {
  2849. for (curves in test) {
  2850. var curve = test[curves];
  2851. dumpCurve(curve);
  2852. }
  2853. }
  2854. function curveToString(curve) {
  2855. var str = "{{";
  2856. var length = curve.length == 7 ? 6 : curve.length;
  2857. if (curve.length == 7) {
  2858. str += "{";
  2859. }
  2860. for (i = 0; i < length; i += 2) {
  2861. str += curve[i].toFixed(decimal_places) + "," + curve[i + 1].toFixed(decimal_places);
  2862. if (i < curve.length - 2) {
  2863. str += "}, {";
  2864. }
  2865. }
  2866. str += "}";
  2867. if (curve.length == 7) {
  2868. str += "}, " + curve[6].toFixed(decimal_places);
  2869. }
  2870. str += "}";
  2871. return str;
  2872. }
  2873. function dumpCurve(curve) {
  2874. console.log(curveToString(curve));
  2875. }
  2876. function draw(test, lines, title) {
  2877. ctx.fillStyle = "rgba(0,0,0, 0.1)";
  2878. ctx.font = "normal 50px Arial";
  2879. ctx.textAlign = "left";
  2880. ctx.fillText(title, 50, 50);
  2881. ctx.font = "normal 10px Arial";
  2882. ctx.lineWidth = "1.001"; "0.999";
  2883. var secondPath = test.length;
  2884. var closeCount = 0;
  2885. logStart = -1;
  2886. logRange = 0;
  2887. // find last active rec type at this step
  2888. var curType = test[0];
  2889. var curStep = 0;
  2890. var hasOp = false;
  2891. var lastActive = 0;
  2892. var lastAdd = 0;
  2893. var lastCoin = 0;
  2894. var lastSect = 0;
  2895. var lastSort = 0;
  2896. var lastMark = 0;
  2897. var lastTop = 0;
  2898. activeCount = 0;
  2899. addCount = 0;
  2900. angleCount = 0;
  2901. opCount = 0;
  2902. sectCount = 0;
  2903. sortCount = 0;
  2904. topCount = 0;
  2905. markCount = 0;
  2906. activeMax = 0;
  2907. addMax = 0;
  2908. angleMax = 0;
  2909. coinMax = 0;
  2910. opMax = 0;
  2911. sectMax = 0;
  2912. sectMax2 = 0;
  2913. sortMax = 0;
  2914. topMax = 0;
  2915. markMax = 0;
  2916. lastIndex = test.length - 3;
  2917. for (var tIndex = 0; tIndex < test.length; tIndex += 3) {
  2918. var recType = test[tIndex];
  2919. if (!typeof recType == 'number' || recType < REC_TYPE_UNKNOWN || recType > REC_TYPE_LAST) {
  2920. console.log("unknown rec type: " + recType);
  2921. throw "stop execution";
  2922. }
  2923. // if (curType == recType && curType != REC_TYPE_ADD) {
  2924. // continue;
  2925. // }
  2926. var inStepRange = step_limit == 0 || curStep < step_limit;
  2927. curType = recType;
  2928. if (recType == REC_TYPE_OP) {
  2929. hasOp = true;
  2930. continue;
  2931. }
  2932. if (recType == REC_TYPE_UNKNOWN) {
  2933. // these types do not advance step
  2934. continue;
  2935. }
  2936. var bumpStep = false;
  2937. var records = test[tIndex + 2];
  2938. var fragType = records[0];
  2939. if (recType == REC_TYPE_ADD) {
  2940. if (records.length != 2) {
  2941. console.log("expect only two elements: " + records.length);
  2942. throw "stop execution";
  2943. }
  2944. if (fragType == ADD_MOVETO || fragType == ADD_CLOSE) {
  2945. continue;
  2946. }
  2947. ++addMax;
  2948. if (!draw_add || !inStepRange) {
  2949. continue;
  2950. }
  2951. lastAdd = tIndex;
  2952. ++addCount;
  2953. bumpStep = true;
  2954. }
  2955. if (recType == REC_TYPE_PATH && hasOp) {
  2956. secondPath = tIndex;
  2957. }
  2958. if (recType == REC_TYPE_PATH2 && hasOp) {
  2959. secondPath = tIndex;
  2960. }
  2961. if (recType == REC_TYPE_ACTIVE) {
  2962. ++activeMax;
  2963. if (!draw_active || !inStepRange) {
  2964. continue;
  2965. }
  2966. lastActive = tIndex;
  2967. ++activeCount;
  2968. bumpStep = true;
  2969. }
  2970. if (recType == REC_TYPE_ACTIVE_OP) {
  2971. ++opMax;
  2972. if (!draw_op || !inStepRange) {
  2973. continue;
  2974. }
  2975. lastOp = tIndex;
  2976. ++opCount;
  2977. bumpStep = true;
  2978. }
  2979. if (recType == REC_TYPE_AFTERPART) {
  2980. if (draw_angle != 3 || !inStepRange) {
  2981. continue;
  2982. }
  2983. lastAngle = tIndex;
  2984. ++angleCount;
  2985. bumpStep = true;
  2986. }
  2987. if (recType == REC_TYPE_ANGLE) {
  2988. ++angleMax;
  2989. if (draw_angle == 0 || draw_angle == 3 || !inStepRange) {
  2990. continue;
  2991. }
  2992. lastAngle = tIndex;
  2993. ++angleCount;
  2994. bumpStep = true;
  2995. }
  2996. if (recType == REC_TYPE_COINCIDENCE) {
  2997. ++coinMax;
  2998. if (!draw_coincidence || !inStepRange) {
  2999. continue;
  3000. }
  3001. lastCoin = tIndex;
  3002. ++coinCount;
  3003. bumpStep = true;
  3004. }
  3005. if (recType == REC_TYPE_SECT) {
  3006. if (records.length != 2) {
  3007. console.log("expect only two elements: " + records.length);
  3008. throw "stop execution";
  3009. }
  3010. ++sectMax;
  3011. var sectBump = 1;
  3012. switch (fragType) {
  3013. case INTERSECT_LINE:
  3014. case INTERSECT_QUAD_LINE:
  3015. case INTERSECT_QUAD:
  3016. case INTERSECT_CONIC_LINE:
  3017. case INTERSECT_CONIC_QUAD:
  3018. case INTERSECT_CONIC:
  3019. case INTERSECT_SELF_CUBIC:
  3020. case INTERSECT_CUBIC_LINE:
  3021. case INTERSECT_CUBIC_QUAD:
  3022. case INTERSECT_CUBIC:
  3023. sectBump = 1;
  3024. break;
  3025. case INTERSECT_LINE_2:
  3026. case INTERSECT_QUAD_LINE_2:
  3027. case INTERSECT_QUAD_2:
  3028. case INTERSECT_CONIC_LINE_2:
  3029. case INTERSECT_CONIC_QUAD_2:
  3030. case INTERSECT_CONIC_2:
  3031. case INTERSECT_CUBIC_LINE_2:
  3032. case INTERSECT_CUBIC_QUAD_2:
  3033. case INTERSECT_CUBIC_2:
  3034. sectBump = 2;
  3035. break;
  3036. case INTERSECT_LINE_NO:
  3037. case INTERSECT_QUAD_LINE_NO:
  3038. case INTERSECT_QUAD_NO:
  3039. case INTERSECT_CONIC_LINE_NO:
  3040. case INTERSECT_CONIC_QUAD_NO:
  3041. case INTERSECT_CONIC_NO:
  3042. case INTERSECT_SELF_CUBIC_NO:
  3043. case INTERSECT_CUBIC_LINE_NO:
  3044. case INTERSECT_CUBIC_QUAD_NO:
  3045. case INTERSECT_CUBIC_NO:
  3046. sectBump = 0;
  3047. break;
  3048. case INTERSECT_CONIC_QUAD_3:
  3049. case INTERSECT_CUBIC_LINE_3:
  3050. case INTERSECT_CUBIC_QUAD_3:
  3051. case INTERSECT_CUBIC_3:
  3052. sectBump = 3;
  3053. break;
  3054. case INTERSECT_CONIC_QUAD_4:
  3055. case INTERSECT_CUBIC_QUAD_4:
  3056. case INTERSECT_CUBIC_4:
  3057. sectBump = 4;
  3058. break;
  3059. default:
  3060. console.log("missing case " + records.length);
  3061. throw "stop execution";
  3062. }
  3063. sectMax2 += sectBump;
  3064. if (draw_intersection <= 1 || !inStepRange) {
  3065. continue;
  3066. }
  3067. lastSect = tIndex;
  3068. sectCount += sectBump;
  3069. bumpStep = true;
  3070. }
  3071. if (recType == REC_TYPE_SORT) {
  3072. ++sortMax;
  3073. if (!draw_sort || !inStepRange) {
  3074. continue;
  3075. }
  3076. lastSort = tIndex;
  3077. ++sortCount;
  3078. bumpStep = true;
  3079. }
  3080. if (recType == REC_TYPE_TOP) {
  3081. ++topMax;
  3082. if (!draw_top || !inStepRange) {
  3083. continue;
  3084. }
  3085. lastTop = tIndex;
  3086. ++topCount;
  3087. bumpStep = true;
  3088. }
  3089. if (recType == REC_TYPE_MARK) {
  3090. ++markMax;
  3091. if (!draw_mark || !inStepRange) {
  3092. continue;
  3093. }
  3094. lastMark = tIndex;
  3095. ++markCount;
  3096. bumpStep = true;
  3097. }
  3098. if (bumpStep) {
  3099. lastIndex = tIndex;
  3100. logStart = test[tIndex + 1];
  3101. logRange = records.length / 2;
  3102. ++curStep;
  3103. }
  3104. }
  3105. stepMax = (draw_add ? addMax : 0)
  3106. + (draw_active ? activeMax : 0)
  3107. + (draw_angle ? angleMax : 0)
  3108. + (draw_coincidence ? coinMax : 0)
  3109. + (draw_op ? opMax : 0)
  3110. + (draw_sort ? sortMax : 0)
  3111. + (draw_top ? topMax : 0)
  3112. + (draw_mark ? markMax : 0)
  3113. + (draw_intersection == 2 ? sectMax : draw_intersection == 3 ? sectMax2 : 0);
  3114. if (stepMax == 0) {
  3115. stepMax = addMax + activeMax + angleMax + coinMax + opMax + sortMax + topMax + markMax;
  3116. }
  3117. drawnPts = [];
  3118. drawnLines = [];
  3119. drawnQuads = [];
  3120. drawnConics = [];
  3121. drawnCubics = [];
  3122. focusXmin = focusYmin = Infinity;
  3123. focusXmax = focusYmax = -Infinity;
  3124. var pathIndex = 0;
  3125. var opLetter = 'S';
  3126. for (var tIndex = lastIndex; tIndex >= 0; tIndex -= 3) {
  3127. var recType = test[tIndex];
  3128. var records = test[tIndex + 2];
  3129. for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
  3130. var fragType = records[recordIndex];
  3131. if (!typeof fragType == 'number' || fragType < 1 || fragType > FRAG_TYPE_LAST) {
  3132. console.log("unknown in range frag type: " + fragType);
  3133. throw "stop execution";
  3134. }
  3135. var frags = records[recordIndex + 1];
  3136. focus_enabled = false;
  3137. switch (recType) {
  3138. case REC_TYPE_COMPUTED:
  3139. if (draw_computed == 0) {
  3140. continue;
  3141. }
  3142. ctx.lineWidth = 1;
  3143. ctx.strokeStyle = pathIndex == 0 ? "black" : "red";
  3144. ctx.fillStyle = "blue";
  3145. var drawThis = false;
  3146. switch (fragType) {
  3147. case PATH_QUAD:
  3148. if ((draw_computed & 0x9) == 1 || ((draw_computed & 8) != 0
  3149. && (draw_computed & 7) == pathIndex)) {
  3150. drawQuad(frags[0], frags[1], frags[2], frags[3],
  3151. frags[4], frags[5]);
  3152. drawThis = true;
  3153. }
  3154. break;
  3155. case PATH_CONIC:
  3156. if ((draw_computed & 0xA) == 2 || ((draw_computed & 8) != 0
  3157. && (draw_computed & 7) == pathIndex)) {
  3158. drawConicWithQuads(frags[0], frags[1], frags[2], frags[3],
  3159. frags[4], frags[5], frags[6]);
  3160. drawThis = true;
  3161. }
  3162. break;
  3163. case PATH_CUBIC:
  3164. if ((draw_computed & 0xC) == 4 || ((draw_computed & 8) != 0
  3165. && (draw_computed & 7) == pathIndex)) {
  3166. drawCubic(frags[0], frags[1], frags[2], frags[3],
  3167. frags[4], frags[5], frags[6], frags[7]);
  3168. drawThis = true;
  3169. }
  3170. ++pathIndex;
  3171. break;
  3172. case COMPUTED_SET_1:
  3173. pathIndex = 0;
  3174. break;
  3175. case COMPUTED_SET_2:
  3176. pathIndex = 1;
  3177. break;
  3178. default:
  3179. console.log("unknown REC_TYPE_COMPUTED frag type: " + fragType);
  3180. throw "stop execution";
  3181. }
  3182. if (!drawThis || collect_bounds) {
  3183. break;
  3184. }
  3185. drawCurveSpecials(test, frags, fragType);
  3186. break;
  3187. case REC_TYPE_ALIGNED:
  3188. if (draw_path < 4) {
  3189. continue;
  3190. }
  3191. case REC_TYPE_PATH:
  3192. case REC_TYPE_PATH2:
  3193. if (REC_TYPE_ALIGNED != recType && draw_path >= 4) {
  3194. continue;
  3195. }
  3196. if (!draw_path) {
  3197. continue;
  3198. }
  3199. var firstPath = tIndex < secondPath;
  3200. if ((draw_path & (firstPath ? 1 : 2)) == 0) {
  3201. continue;
  3202. }
  3203. ctx.lineWidth = 1;
  3204. ctx.strokeStyle = firstPath ? "black" : "red";
  3205. ctx.fillStyle = "blue";
  3206. var frags2 = [];
  3207. switch (fragType) {
  3208. case PATH_LINE:
  3209. for (var i = 0; i < 4; ++ i) { frags2[i] = frags[i + 1]; }
  3210. drawLine(frags2[0], frags2[1], frags2[2], frags2[3]);
  3211. break;
  3212. case PATH_QUAD:
  3213. for (var i = 0; i < 6; ++ i) { frags2[i] = frags[i + 1]; }
  3214. drawQuad(frags2[0], frags2[1], frags2[2], frags2[3],
  3215. frags2[4], frags2[5]);
  3216. break;
  3217. case PATH_CONIC:
  3218. for (var i = 0; i < 7; ++ i) { frags2[i] = frags[i + 1]; }
  3219. drawConicWithQuads(frags2[0], frags2[1], frags2[2], frags2[3],
  3220. frags2[4], frags2[5], frags2[6]);
  3221. break;
  3222. case PATH_CUBIC:
  3223. for (var i = 0; i < 8; ++ i) { frags2[i] = frags[i + 1]; }
  3224. drawCubic(frags2[0], frags2[1], frags2[2], frags2[3],
  3225. frags2[4], frags2[5], frags2[6], frags2[7]);
  3226. break;
  3227. default:
  3228. console.log("unknown " + recType + " frag type: " + fragType);
  3229. throw "stop execution";
  3230. }
  3231. if (collect_bounds) {
  3232. break;
  3233. }
  3234. drawCurveSpecials(test, frags2, fragType);
  3235. break;
  3236. case REC_TYPE_OP:
  3237. switch (fragType) {
  3238. case OP_INTERSECT: opLetter = 'I'; break;
  3239. case OP_DIFFERENCE: opLetter = 'D'; break;
  3240. case OP_UNION: opLetter = 'U'; break;
  3241. case OP_XOR: opLetter = 'X'; break;
  3242. default:
  3243. console.log("unknown REC_TYPE_OP frag type: " + fragType);
  3244. throw "stop execution";
  3245. }
  3246. break;
  3247. case REC_TYPE_ACTIVE:
  3248. if (!draw_active || (step_limit > 0 && tIndex < lastActive)) {
  3249. continue;
  3250. }
  3251. var x1 = frags[SPAN_X1];
  3252. var y1 = frags[SPAN_Y1];
  3253. var x2 = frags[SPAN_X2];
  3254. var y2 = frags[SPAN_Y2];
  3255. var x3, y3, x3, y4, w;
  3256. ctx.lineWidth = 3;
  3257. ctx.strokeStyle = "rgba(0,0,255, 0.3)";
  3258. focus_enabled = true;
  3259. switch (fragType) {
  3260. case ACTIVE_LINE_SPAN:
  3261. drawLine(x1, y1, x2, y2);
  3262. if (draw_id) {
  3263. drawLineID(frags[0], x1, y1, x2, y2);
  3264. }
  3265. if (pt_labels) {
  3266. var curve = [x1, y1, x2, y2];
  3267. ctx.fillStyle = "blue";
  3268. drawPoints(curve, PATH_LINE, pt_labels == 2);
  3269. }
  3270. break;
  3271. case ACTIVE_QUAD_SPAN:
  3272. x3 = frags[SPAN_X3];
  3273. y3 = frags[SPAN_Y3];
  3274. drawQuad(x1, y1, x2, y2, x3, y3);
  3275. if (draw_id) {
  3276. drawQuadID(frags[0], x1, y1, x2, y2, x3, y3);
  3277. }
  3278. if (pt_labels) {
  3279. var curve = [x1, y1, x2, y2, x3, y3];
  3280. ctx.fillStyle = "blue";
  3281. drawPoints(curve, PATH_QUAD, pt_labels == 2);
  3282. }
  3283. break;
  3284. case ACTIVE_CONIC_SPAN:
  3285. x3 = frags[SPAN_X3];
  3286. y3 = frags[SPAN_Y3];
  3287. w = frags[SPAN_K_W];
  3288. drawConicWithQuads(x1, y1, x2, y2, x3, y3, w);
  3289. if (draw_id) {
  3290. drawConicID(frags[0], x1, y1, x2, y2, x3, y3, w);
  3291. }
  3292. if (pt_labels) {
  3293. var curve = [x1, y1, x2, y2, x3, y3, w];
  3294. ctx.fillStyle = "blue";
  3295. drawPoints(curve, PATH_CONIC, pt_labels == 2);
  3296. }
  3297. break;
  3298. case ACTIVE_CUBIC_SPAN:
  3299. x3 = frags[SPAN_X3];
  3300. y3 = frags[SPAN_Y3];
  3301. x4 = frags[SPAN_X4];
  3302. y4 = frags[SPAN_Y4];
  3303. drawCubic(x1, y1, x2, y2, x3, y3, x4, y4);
  3304. if (draw_id) {
  3305. drawCubicID(frags[0], x1, y1, x2, y2, x3, y3, x4, y4);
  3306. }
  3307. if (pt_labels) {
  3308. var curve = [x1, y1, x2, y2, x3, y3, x4, y4];
  3309. ctx.fillStyle = "blue";
  3310. drawPoints(curve, PATH_CUBIC, pt_labels == 2);
  3311. }
  3312. break;
  3313. default:
  3314. console.log("unknown REC_TYPE_ACTIVE frag type: " + fragType);
  3315. throw "stop execution";
  3316. }
  3317. break;
  3318. case REC_TYPE_ACTIVE_OP:
  3319. if (!draw_op || (step_limit > 0 && tIndex < lastOp)) {
  3320. continue;
  3321. }
  3322. focus_enabled = true;
  3323. ctx.lineWidth = 3;
  3324. var activeSpan = frags[7] == "1";
  3325. ctx.strokeStyle = activeSpan ? "rgba(45,160,0, 0.3)" : "rgba(255,45,0, 0.5)";
  3326. var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
  3327. drawCurve(curve);
  3328. if (draw_op > 1) {
  3329. drawArc(curve, false, frags[3], frags[4]);
  3330. drawArc(curve, true, frags[5], frags[6]);
  3331. }
  3332. break;
  3333. case REC_TYPE_ADD:
  3334. if (!draw_add) {
  3335. continue;
  3336. }
  3337. ctx.lineWidth = 3;
  3338. ctx.strokeStyle = closeCount == 0 ? "rgba(0,0,255, 0.3)"
  3339. : closeCount == 1 ? "rgba(0,127,0, 0.3)"
  3340. : closeCount == 2 ? "rgba(0,127,127, 0.3)"
  3341. : closeCount == 3 ? "rgba(127,127,0, 0.3)"
  3342. : "rgba(127,0,127, 0.3)";
  3343. focus_enabled = true;
  3344. switch (fragType) {
  3345. case ADD_MOVETO:
  3346. break;
  3347. case ADD_LINETO:
  3348. if (step_limit == 0 || tIndex >= lastAdd) {
  3349. drawLine(frags[0], frags[1], frags[2], frags[3]);
  3350. }
  3351. break;
  3352. case ADD_QUADTO:
  3353. if (step_limit == 0 || tIndex >= lastAdd) {
  3354. drawQuad(frags[0], frags[1], frags[2], frags[3], frags[4], frags[5]);
  3355. }
  3356. break;
  3357. case ADD_CONICTO:
  3358. if (step_limit == 0 || tIndex >= lastAdd) {
  3359. drawConicWithQuads(frags[0], frags[1], frags[2], frags[3],
  3360. frags[4], frags[5], frags[6]);
  3361. }
  3362. break;
  3363. case ADD_CUBICTO:
  3364. if (step_limit == 0 || tIndex >= lastAdd) {
  3365. drawCubic(frags[0], frags[1], frags[2], frags[3],
  3366. frags[4], frags[5], frags[6], frags[7]);
  3367. }
  3368. break;
  3369. case ADD_CLOSE:
  3370. ++closeCount;
  3371. break;
  3372. case ADD_FILL:
  3373. break;
  3374. default:
  3375. console.log("unknown REC_TYPE_ADD frag type: " + fragType);
  3376. throw "stop execution";
  3377. }
  3378. break;
  3379. case REC_TYPE_ANGLE:
  3380. angleBetween = frags[18] == "T";
  3381. afterIndex = 0;
  3382. if (draw_angle == 0 || draw_angle == 3 || (step_limit > 0 && tIndex < lastAngle)) {
  3383. continue;
  3384. }
  3385. focus_enabled = true;
  3386. ctx.lineWidth = 3;
  3387. ctx.strokeStyle = "rgba(127,45,127, 0.3)";
  3388. var leftCurve = curvePartialByID(test, frags[0], frags[4], frags[5]);
  3389. var midCurve = curvePartialByID(test, frags[6], frags[10], frags[11]);
  3390. var rightCurve = curvePartialByID(test, frags[12], frags[16], frags[17]);
  3391. drawCurve(leftCurve);
  3392. drawCurve(rightCurve);
  3393. ctx.strokeStyle = angleBetween ? "rgba(0,160,45, 0.3)" : "rgba(255,0,45, 0.5)";
  3394. drawCurve(midCurve);
  3395. if (draw_angle > 1) {
  3396. drawVisibleOrder(leftCurve, 'L');
  3397. drawVisibleOrder(rightCurve, 'R');
  3398. }
  3399. if (draw_id) {
  3400. drawVisibleID(leftCurve, 0.5, frags[0]);
  3401. drawVisibleID(midCurve, 0.5, frags[6]);
  3402. drawVisibleID(rightCurve, 0.5, frags[12]);
  3403. }
  3404. break;
  3405. case REC_TYPE_AFTERPART:
  3406. if (draw_angle != 3 || (step_limit > 0 && tIndex < lastAngle)) {
  3407. continue;
  3408. }
  3409. ctx.strokeStyle = afterIndex == 0 ? "rgba(255,0,0, 1.0)"
  3410. : (afterIndex == 1) == angleBetween ? "rgba(0,128,0, 1.0)"
  3411. : "rgba(0,0,255, 1.0)";
  3412. var curve;
  3413. var id;
  3414. switch (fragType) {
  3415. case PATH_LINE:
  3416. curve = [ frags[0], frags[1], frags[2], frags[3] ];
  3417. id = frags[4];
  3418. break;
  3419. case PATH_QUAD:
  3420. curve = [ frags[0], frags[1], frags[2], frags[3],
  3421. frags[4], frags[5] ];
  3422. id = frags[6];
  3423. break;
  3424. case PATH_CONIC:
  3425. curve = [ frags[0], frags[1], frags[2], frags[3],
  3426. frags[4], frags[5], frags[6] ];
  3427. id = frags[7];
  3428. break;
  3429. case PATH_CUBIC:
  3430. curve = [ frags[0], frags[1], frags[2], frags[3],
  3431. frags[4], frags[5], frags[6], frags[7] ];
  3432. id = frags[8];
  3433. break;
  3434. default:
  3435. console.log("unknown REC_TYPE_AFTERPART frag type: " + fragType);
  3436. throw "stop execution";
  3437. }
  3438. drawCurve(curve);
  3439. if (draw_id) {
  3440. drawVisibleID(curve, 0.5, id);
  3441. }
  3442. ++afterIndex;
  3443. break;
  3444. case REC_TYPE_COINCIDENCE:
  3445. if (!draw_coincidence || (step_limit > 0 && tIndex < lastCoin)) {
  3446. continue;
  3447. }
  3448. focus_enabled = true;
  3449. ctx.lineWidth = 3;
  3450. ctx.strokeStyle = "rgba(127,45,63, 0.3)";
  3451. var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
  3452. drawCurve(curve);
  3453. break;
  3454. case REC_TYPE_SECT:
  3455. if (!draw_intersection) {
  3456. continue;
  3457. }
  3458. if (draw_intersection != 1 && (step_limit > 0 && tIndex < lastSect)) {
  3459. continue;
  3460. }
  3461. // draw_intersection == 1 : show all
  3462. // draw_intersection == 2 : step == 0 ? show all : show intersection line #step
  3463. // draw_intersection == 3 : step == 0 ? show all : show intersection #step
  3464. ctx.lineWidth = 1;
  3465. ctx.strokeStyle = "rgba(0,0,255, 0.3)";
  3466. ctx.fillStyle = "blue";
  3467. focus_enabled = true;
  3468. var f = [];
  3469. var c1s;
  3470. var c1l;
  3471. var c2s;
  3472. var c2l;
  3473. switch (fragType) {
  3474. case INTERSECT_LINE:
  3475. f.push(5, 6, 0, 7);
  3476. c1s = 1; c1l = 4; c2s = 8; c2l = 4;
  3477. break;
  3478. case INTERSECT_LINE_2:
  3479. f.push(5, 6, 0, 10);
  3480. f.push(8, 9, 7, 15);
  3481. c1s = 1; c1l = 4; c2s = 11; c2l = 4;
  3482. break;
  3483. case INTERSECT_LINE_NO:
  3484. c1s = 0; c1l = 4; c2s = 4; c2l = 4;
  3485. break;
  3486. case INTERSECT_QUAD_LINE:
  3487. f.push(7, 8, 0, 9);
  3488. c1s = 1; c1l = 6; c2s = 10; c2l = 4;
  3489. break;
  3490. case INTERSECT_QUAD_LINE_2:
  3491. f.push(7, 8, 0, 12);
  3492. f.push(10, 11, 9, 17);
  3493. c1s = 1; c1l = 6; c2s = 13; c2l = 4;
  3494. break;
  3495. case INTERSECT_QUAD_LINE_NO:
  3496. c1s = 0; c1l = 6; c2s = 6; c2l = 4;
  3497. break;
  3498. case INTERSECT_QUAD:
  3499. f.push(7, 8, 0, 9);
  3500. c1s = 1; c1l = 6; c2s = 10; c2l = 6;
  3501. break;
  3502. case INTERSECT_QUAD_2:
  3503. f.push(7, 8, 0, 12);
  3504. f.push(10, 11, 9, 19);
  3505. c1s = 1; c1l = 6; c2s = 13; c2l = 6;
  3506. break;
  3507. case INTERSECT_QUAD_NO:
  3508. c1s = 0; c1l = 6; c2s = 6; c2l = 6;
  3509. break;
  3510. case INTERSECT_CONIC_LINE:
  3511. f.push(8, 9, 0, 10);
  3512. c1s = 1; c1l = 7; c2s = 11; c2l = 4;
  3513. break;
  3514. case INTERSECT_CONIC_LINE_2:
  3515. f.push(8, 9, 0, 12);
  3516. f.push(11, 12, 10, 18);
  3517. c1s = 1; c1l = 7; c2s = 14; c2l = 4;
  3518. break;
  3519. case INTERSECT_CONIC_LINE_NO:
  3520. c1s = 0; c1l = 7; c2s = 7; c2l = 4;
  3521. break;
  3522. case INTERSECT_CONIC_QUAD:
  3523. f.push(8, 9, 0, 10);
  3524. c1s = 1; c1l = 7; c2s = 11; c2l = 6;
  3525. break;
  3526. case INTERSECT_CONIC_QUAD_2:
  3527. f.push(8, 9, 0, 12);
  3528. f.push(11, 12, 10, 18);
  3529. c1s = 1; c1l = 7; c2s = 14; c2l = 6;
  3530. break;
  3531. case INTERSECT_CONIC_QUAD_3:
  3532. f.push(8, 9, 0, 15);
  3533. f.push(11, 12, 10, 21);
  3534. f.push(14, 15, 13, 22);
  3535. c1s = 1; c1l = 7; c2s = 17; c2l = 6;
  3536. break;
  3537. case INTERSECT_CONIC_QUAD_4:
  3538. f.push(8, 9, 0, 18);
  3539. f.push(11, 12, 10, 24);
  3540. f.push(14, 15, 13, 25);
  3541. f.push(17, 18, 16, 26);
  3542. c1s = 1; c1l = 7; c2s = 20; c2l = 6;
  3543. break;
  3544. case INTERSECT_CONIC_QUAD_NO:
  3545. c1s = 0; c1l = 7; c2s = 7; c2l = 6;
  3546. break;
  3547. case INTERSECT_CONIC:
  3548. f.push(8, 9, 0, 10);
  3549. c1s = 1; c1l = 7; c2s = 11; c2l = 7;
  3550. break;
  3551. case INTERSECT_CONIC_2:
  3552. f.push(8, 9, 0, 13);
  3553. f.push(11, 12, 10, 21);
  3554. c1s = 1; c1l = 7; c2s = 14; c2l = 7;
  3555. break;
  3556. case INTERSECT_CONIC_NO:
  3557. c1s = 0; c1l = 7; c2s = 7; c2l = 7;
  3558. break;
  3559. case INTERSECT_SELF_CUBIC:
  3560. f.push(9, 10, 0, 11);
  3561. c1s = 1; c1l = 8; c2s = 0; c2l = 0;
  3562. break;
  3563. case INTERSECT_SELF_CUBIC_NO:
  3564. c1s = 0; c1l = 8; c2s = 0; c2l = 0;
  3565. break;
  3566. case INTERSECT_CUBIC_LINE:
  3567. f.push(9, 10, 0, 11);
  3568. c1s = 1; c1l = 8; c2s = 12; c2l = 4;
  3569. break;
  3570. case INTERSECT_CUBIC_LINE_2:
  3571. f.push(9, 10, 0, 14);
  3572. f.push(12, 13, 11, 19);
  3573. c1s = 1; c1l = 8; c2s = 15; c2l = 4;
  3574. break;
  3575. case INTERSECT_CUBIC_LINE_3:
  3576. f.push(9, 10, 0, 17);
  3577. f.push(12, 13, 11, 22);
  3578. f.push(15, 16, 14, 23);
  3579. c1s = 1; c1l = 8; c2s = 18; c2l = 4;
  3580. break;
  3581. case INTERSECT_CUBIC_QUAD_NO:
  3582. c1s = 0; c1l = 8; c2s = 8; c2l = 6;
  3583. break;
  3584. case INTERSECT_CUBIC_QUAD:
  3585. f.push(9, 10, 0, 11);
  3586. c1s = 1; c1l = 8; c2s = 12; c2l = 6;
  3587. break;
  3588. case INTERSECT_CUBIC_QUAD_2:
  3589. f.push(9, 10, 0, 14);
  3590. f.push(12, 13, 11, 21);
  3591. c1s = 1; c1l = 8; c2s = 15; c2l = 6;
  3592. break;
  3593. case INTERSECT_CUBIC_QUAD_3:
  3594. f.push(9, 10, 0, 17);
  3595. f.push(12, 13, 11, 24);
  3596. f.push(15, 16, 14, 25);
  3597. c1s = 1; c1l = 8; c2s = 18; c2l = 6;
  3598. break;
  3599. case INTERSECT_CUBIC_QUAD_4:
  3600. f.push(9, 10, 0, 20);
  3601. f.push(12, 13, 11, 27);
  3602. f.push(15, 16, 14, 28);
  3603. f.push(18, 19, 17, 29);
  3604. c1s = 1; c1l = 8; c2s = 21; c2l = 6;
  3605. break;
  3606. case INTERSECT_CUBIC_LINE_NO:
  3607. c1s = 0; c1l = 8; c2s = 8; c2l = 4;
  3608. break;
  3609. case INTERSECT_CUBIC:
  3610. f.push(9, 10, 0, 11);
  3611. c1s = 1; c1l = 8; c2s = 12; c2l = 8;
  3612. break;
  3613. case INTERSECT_CUBIC_2:
  3614. f.push(9, 10, 0, 14);
  3615. f.push(12, 13, 11, 23);
  3616. c1s = 1; c1l = 8; c2s = 15; c2l = 8;
  3617. break;
  3618. case INTERSECT_CUBIC_3:
  3619. f.push(9, 10, 0, 17);
  3620. f.push(12, 13, 11, 26);
  3621. f.push(15, 16, 14, 27);
  3622. c1s = 1; c1l = 8; c2s = 18; c2l = 8;
  3623. break;
  3624. case INTERSECT_CUBIC_4:
  3625. f.push(9, 10, 0, 20);
  3626. f.push(12, 13, 11, 29);
  3627. f.push(15, 16, 14, 30);
  3628. f.push(18, 19, 17, 31);
  3629. c1s = 1; c1l = 8; c2s = 21; c2l = 8;
  3630. break;
  3631. case INTERSECT_CUBIC_NO:
  3632. c1s = 0; c1l = 8; c2s = 8; c2l = 8;
  3633. break;
  3634. default:
  3635. console.log("unknown REC_TYPE_SECT frag type: " + fragType);
  3636. throw "stop execution";
  3637. }
  3638. if (draw_intersection != 1) {
  3639. var id = -1;
  3640. var curve;
  3641. switch (c1l) {
  3642. case 4:
  3643. drawLine(frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3]);
  3644. if (draw_id) {
  3645. curve = [frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3]];
  3646. id = idByCurve(test, curve, PATH_LINE);
  3647. }
  3648. break;
  3649. case 6:
  3650. drawQuad(frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
  3651. frags[c1s + 4], frags[c1s + 5]);
  3652. if (draw_id) {
  3653. curve = [frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
  3654. frags[c1s + 4], frags[c1s + 5]];
  3655. id = idByCurve(test, curve, PATH_QUAD);
  3656. }
  3657. break;
  3658. case 7:
  3659. drawConicWithQuads(frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
  3660. frags[c1s + 4], frags[c1s + 5], frags[c1s + 6]);
  3661. if (draw_id) {
  3662. curve = [frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
  3663. frags[c1s + 4], frags[c1s + 5], frags[c1s + 6]];
  3664. id = idByCurve(test, curve, PATH_CONIC);
  3665. }
  3666. break;
  3667. case 8:
  3668. drawCubic(frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
  3669. frags[c1s + 4], frags[c1s + 5], frags[c1s + 6], frags[c1s + 7]);
  3670. if (draw_id) {
  3671. curve = [frags[c1s], frags[c1s + 1], frags[c1s + 2], frags[c1s + 3],
  3672. frags[c1s + 4], frags[c1s + 5], frags[c1s + 6], frags[c1s + 7]];
  3673. id = idByCurve(test, curve, PATH_CUBIC);
  3674. }
  3675. break;
  3676. }
  3677. if (id >= 0) {
  3678. drawVisibleID(curve, 0.5, id);
  3679. }
  3680. id = -1;
  3681. switch (c2l) {
  3682. case 0:
  3683. break;
  3684. case 4:
  3685. drawLine(frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3]);
  3686. if (draw_id) {
  3687. curve = [frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3]];
  3688. id = idByCurve(test, curve, PATH_LINE);
  3689. }
  3690. break;
  3691. case 6:
  3692. drawQuad(frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
  3693. frags[c2s + 4], frags[c2s + 5]);
  3694. if (draw_id) {
  3695. curve = [frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
  3696. frags[c2s + 4], frags[c2s + 5]];
  3697. id = idByCurve(test, curve, PATH_QUAD);
  3698. }
  3699. break;
  3700. case 7:
  3701. drawConicWithQuads(frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
  3702. frags[c2s + 4], frags[c2s + 5], frags[c2s + 6]);
  3703. if (draw_id) {
  3704. curve = [frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
  3705. frags[c2s + 4], frags[c2s + 5], frags[c2s + 6]];
  3706. id = idByCurve(test, curve, PATH_CONIC);
  3707. }
  3708. break;
  3709. case 8:
  3710. drawCubic(frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
  3711. frags[c2s + 4], frags[c2s + 5], frags[c2s + 6], frags[c2s + 7]);
  3712. if (draw_id) {
  3713. curve = [frags[c2s], frags[c2s + 1], frags[c2s + 2], frags[c2s + 3],
  3714. frags[c2s + 4], frags[c2s + 5], frags[c2s + 6], frags[c2s + 7]];
  3715. id = idByCurve(test, curve, PATH_CUBIC);
  3716. }
  3717. break;
  3718. }
  3719. if (id >= 0) {
  3720. drawVisibleID(curve, 0.5, id);
  3721. }
  3722. }
  3723. if (collect_bounds) {
  3724. break;
  3725. }
  3726. if (draw_intersection != 3 || step_limit == 0 || tIndex >= lastSect) {
  3727. for (var idx = 0; idx < f.length; idx += 4) {
  3728. drawPoint(frags[f[idx]], frags[f[idx + 1]], true);
  3729. }
  3730. }
  3731. if (!draw_intersectT) {
  3732. break;
  3733. }
  3734. ctx.fillStyle = "red";
  3735. if (draw_intersection != 3 || step_limit == 0 || tIndex >= lastSect) {
  3736. for (var idx = 0; idx < f.length; idx += 4) {
  3737. drawTAtPointUp(frags[f[idx]], frags[f[idx + 1]], frags[f[idx + 2]]);
  3738. drawTAtPointDown(frags[f[idx]], frags[f[idx + 1]], frags[f[idx + 3]]);
  3739. }
  3740. }
  3741. break;
  3742. case REC_TYPE_SORT:
  3743. if (!draw_sort || (step_limit > 0 && tIndex < lastSort)) {
  3744. continue;
  3745. }
  3746. ctx.lineWidth = 3;
  3747. ctx.strokeStyle = "rgba(127,127,0, 0.5)";
  3748. focus_enabled = true;
  3749. switch (fragType) {
  3750. case SORT_UNARY:
  3751. case SORT_BINARY:
  3752. var curve = curvePartialByID(test, frags[0], frags[6], frags[8]);
  3753. drawCurve(curve);
  3754. break;
  3755. default:
  3756. console.log("unknown REC_TYPE_SORT frag type: " + fragType);
  3757. throw "stop execution";
  3758. }
  3759. break;
  3760. case REC_TYPE_TOP:
  3761. if (!draw_top || (step_limit > 0 && tIndex < lastTop)) {
  3762. continue;
  3763. }
  3764. ctx.lineWidth = 3;
  3765. ctx.strokeStyle = "rgba(127,127,0, 0.5)";
  3766. focus_enabled = true;
  3767. {
  3768. var curve = curvePartialByID(test, frags[0], frags[1], frags[2]);
  3769. drawCurve(curve);
  3770. var type = PATH_LINE + (curve.length / 2 - 2);
  3771. var mid = pointAtT(curve, type, 0.5);
  3772. var d = dxy_at_t(curve, type, 0.5);
  3773. drawArrow(mid.x, mid.y, d.x, d.y, 0.3);
  3774. }
  3775. break;
  3776. case REC_TYPE_MARK:
  3777. if (!draw_mark || (step_limit > 0 && tIndex < lastMark)) {
  3778. continue;
  3779. }
  3780. ctx.lineWidth = 3;
  3781. ctx.strokeStyle = fragType >= MARK_DONE_LINE ?
  3782. "rgba(127,0,127, 0.5)" : "rgba(127,127,0, 0.5)";
  3783. focus_enabled = true;
  3784. switch (fragType) {
  3785. case MARK_LINE:
  3786. case MARK_DONE_LINE:
  3787. case MARK_UNSORTABLE_LINE:
  3788. case MARK_SIMPLE_LINE:
  3789. case MARK_SIMPLE_DONE_LINE:
  3790. case MARK_DONE_UNARY_LINE:
  3791. drawLinePartial(frags[1], frags[2], frags[3], frags[4],
  3792. frags[5], frags[9]);
  3793. if (draw_id) {
  3794. drawLinePartialID(frags[0], frags[1], frags[2], frags[3], frags[4],
  3795. frags[5], frags[9]);
  3796. }
  3797. break;
  3798. case MARK_QUAD:
  3799. case MARK_DONE_QUAD:
  3800. case MARK_UNSORTABLE_QUAD:
  3801. case MARK_SIMPLE_QUAD:
  3802. case MARK_SIMPLE_DONE_QUAD:
  3803. case MARK_DONE_UNARY_QUAD:
  3804. drawQuadPartial(frags[1], frags[2], frags[3], frags[4],
  3805. frags[5], frags[6], frags[7], frags[11]);
  3806. if (draw_id) {
  3807. drawQuadPartialID(frags[0], frags[1], frags[2], frags[3], frags[4],
  3808. frags[5], frags[6], frags[7], frags[11]);
  3809. }
  3810. break;
  3811. case MARK_CUBIC:
  3812. case MARK_DONE_CUBIC:
  3813. case MARK_UNSORTABLE_CUBIC:
  3814. case MARK_SIMPLE_CUBIC:
  3815. case MARK_SIMPLE_DONE_CUBIC:
  3816. case MARK_DONE_UNARY_CUBIC:
  3817. drawCubicPartial(frags[1], frags[2], frags[3], frags[4],
  3818. frags[5], frags[6], frags[7], frags[8], frags[9], frags[13]);
  3819. if (draw_id) {
  3820. drawCubicPartialID(frags[0], frags[1], frags[2], frags[3], frags[4],
  3821. frags[5], frags[6], frags[7], frags[8], frags[9], frags[13]);
  3822. }
  3823. break;
  3824. case MARK_ANGLE_LAST:
  3825. // FIXME: ignored for now
  3826. break;
  3827. default:
  3828. console.log("unknown REC_TYPE_MARK frag type: " + fragType);
  3829. throw "stop execution";
  3830. }
  3831. break;
  3832. default:
  3833. continue;
  3834. }
  3835. }
  3836. switch (recType) {
  3837. case REC_TYPE_SORT:
  3838. if (!draw_sort || (step_limit > 0 && tIndex < lastSort)) {
  3839. break;
  3840. }
  3841. var angles = []; // use tangent lines to describe arcs
  3842. var windFrom = [];
  3843. var windTo = [];
  3844. var opp = [];
  3845. var minXY = Number.MAX_VALUE;
  3846. var partial;
  3847. focus_enabled = true;
  3848. var someUnsortable = false;
  3849. for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
  3850. var fragType = records[recordIndex];
  3851. var frags = records[recordIndex + 1];
  3852. var unsortable = (fragType == SORT_UNARY && frags[14]) ||
  3853. (fragType == SORT_BINARY && frags[16]);
  3854. someUnsortable |= unsortable;
  3855. switch (fragType) {
  3856. case SORT_UNARY:
  3857. case SORT_BINARY:
  3858. partial = curvePartialByID(test, frags[0], frags[6], frags[8]);
  3859. break;
  3860. default:
  3861. console.log("unknown REC_TYPE_SORT frag type: " + fragType);
  3862. throw "stop execution";
  3863. }
  3864. var dx = boundsWidth(partial);
  3865. var dy = boundsHeight(partial);
  3866. minXY = Math.min(minXY, dx * dx + dy * dy);
  3867. if (collect_bounds) {
  3868. continue;
  3869. }
  3870. angles.push(tangent(partial));
  3871. var from = frags[12];
  3872. var to = frags[12];
  3873. var sgn = frags[10];
  3874. if (sgn < 0) {
  3875. from -= frags[11];
  3876. } else if (sgn > 0) {
  3877. to -= frags[11];
  3878. }
  3879. windFrom.push(from + (unsortable ? "!" : ""));
  3880. windTo.push(to + (unsortable ? "!" : ""));
  3881. opp.push(fragType == SORT_BINARY);
  3882. if (draw_sort == 1) {
  3883. drawVisibleOrder(partial, frags[12]);
  3884. } else {
  3885. drawVisibleOrder(partial, (recordIndex / 2) + 1);
  3886. }
  3887. }
  3888. var radius = Math.sqrt(minXY) / 2 * scale;
  3889. radius = Math.min(50, radius);
  3890. var scaledRadius = radius / scale;
  3891. var centerX = partial[0];
  3892. var centerY = partial[1];
  3893. if (collect_bounds) {
  3894. if (focus_enabled) {
  3895. focusXmin = Math.min(focusXmin, centerX - scaledRadius);
  3896. focusYmin = Math.min(focusYmin, centerY - scaledRadius);
  3897. focusXmax = Math.max(focusXmax, centerX + scaledRadius);
  3898. focusYmax = Math.max(focusYmax, centerY + scaledRadius);
  3899. }
  3900. break;
  3901. }
  3902. break;
  3903. default:
  3904. break;
  3905. }
  3906. }
  3907. if (collect_bounds) {
  3908. return;
  3909. }
  3910. if (draw_log && logStart >= 0) {
  3911. ctx.font = "normal 10px Arial";
  3912. ctx.textAlign = "left";
  3913. ctx.beginPath();
  3914. var top = screenHeight - 20 - (logRange + 2) * 10;
  3915. ctx.rect(50, top, screenWidth - 100, (logRange + 2) * 10);
  3916. ctx.fillStyle = "white";
  3917. ctx.fill();
  3918. ctx.fillStyle = "rgba(0,0,0, 0.5)";
  3919. if (logStart > 0) {
  3920. ctx.fillText(lines[logStart - 1], 50, top + 8);
  3921. }
  3922. ctx.fillStyle = "black";
  3923. for (var idx = 0; idx < logRange; ++idx) {
  3924. ctx.fillText(lines[logStart + idx], 50, top + 18 + 10 * idx);
  3925. }
  3926. ctx.fillStyle = "rgba(0,0,0, 0.5)";
  3927. if (logStart + logRange < lines.length) {
  3928. ctx.fillText(lines[logStart + logRange], 50, top + 18 + 10 * logRange);
  3929. }
  3930. }
  3931. if (draw_legend) {
  3932. var pos = 0;
  3933. var drawSomething = draw_add | draw_active | draw_angle | draw_coincidence | draw_sort | draw_mark;
  3934. // drawBox(pos++, "yellow", "black", opLetter, true, '');
  3935. drawBox(pos++, "rgba(0,0,255, 0.3)", "black", draw_intersection > 1 ? sectCount : sectMax2, draw_intersection, intersectionKey);
  3936. drawBox(pos++, "rgba(0,0,255, 0.3)", "black", draw_add ? addCount : addMax, draw_add, addKey);
  3937. drawBox(pos++, "rgba(0,0,255, 0.3)", "black", draw_active ? activeCount : activeMax, draw_active, activeKey);
  3938. drawBox(pos++, "rgba(127,127,0, 0.3)", "black", draw_angle ? angleCount : angleMax, draw_angle, angleKey);
  3939. drawBox(pos++, "rgba(127,127,0, 0.3)", "black", draw_coincidence ? coinCount : coinMax, draw_coincidence, coincidenceKey);
  3940. drawBox(pos++, "rgba(127,127,0, 0.3)", "black", draw_op ? opCount : opMax, draw_op, opKey);
  3941. drawBox(pos++, "rgba(127,127,0, 0.3)", "black", draw_sort ? sortCount : sortMax, draw_sort, sortKey);
  3942. drawBox(pos++, "rgba(127,127,0, 0.3)", "black", draw_top ? topCount : topMax, draw_top, topKey);
  3943. drawBox(pos++, "rgba(127,0,127, 0.3)", "black", draw_mark ? markCount : markMax, draw_mark, markKey);
  3944. drawBox(pos++, "black", "white",
  3945. (new Array('P', 'P1', 'P2', 'P', 'p', 'p1', 'p2'))[draw_path], draw_path != 0, pathKey);
  3946. drawBox(pos++, "rgba(0,63,0, 0.7)", "white",
  3947. (new Array('Q', 'Q', 'C', 'QC', 'Qc', 'Cq'))[draw_computed],
  3948. draw_computed != 0, computedKey);
  3949. drawBox(pos++, "green", "black", step_limit, drawSomething, '');
  3950. drawBox(pos++, "green", "black", stepMax, drawSomething, '');
  3951. drawBox(pos++, "rgba(255,0,0, 0.6)", "black", lastIndex, drawSomething & draw_log, '');
  3952. drawBox(pos++, "rgba(255,0,0, 0.6)", "black", test.length - 1, drawSomething & draw_log, '');
  3953. if (curve_t) {
  3954. drawCurveTControl();
  3955. }
  3956. ctx.font = "normal 20px Arial";
  3957. ctx.fillStyle = "rgba(0,0,0, 0.3)";
  3958. ctx.textAlign = "right";
  3959. ctx.fillText(scale.toFixed(decimal_places) + 'x' , screenWidth - 10, screenHeight - 5);
  3960. }
  3961. if (draw_hints) {
  3962. ctx.font = "normal 10px Arial";
  3963. ctx.fillStyle = "rgba(0,0,0, 0.5)";
  3964. ctx.textAlign = "right";
  3965. var y = 4;
  3966. ctx.fillText("control lines : " + controlLinesKey, ctx.screenWidthwidth - 10, pos * 50 + y++ * 10);
  3967. ctx.fillText("curve t : " + curveTKey, screenWidth - 10, pos * 50 + y++ * 10);
  3968. ctx.fillText("deriviatives : " + deriviativesKey, screenWidth - 10, pos * 50 + y++ * 10);
  3969. ctx.fillText("intersect t : " + intersectTKey, screenWidth - 10, pos * 50 + y++ * 10);
  3970. ctx.fillText("log : " + logKey, screenWidth - 10, pos * 50 + y++ * 10);
  3971. ctx.fillText("log curve : " + logCurvesKey, screenWidth - 10, pos * 50 + y++ * 10);
  3972. ctx.fillText("mid point : " + midpointKey, screenWidth - 10, pos * 50 + y++ * 10);
  3973. ctx.fillText("points : " + ptsKey, screenWidth - 10, pos * 50 + y++ * 10);
  3974. ctx.fillText("sequence : " + sequenceKey, screenWidth - 10, pos * 50 + y++ * 10);
  3975. ctx.fillText("xy : " + xyKey, screenWidth - 10, pos * 50 + y++ * 10);
  3976. }
  3977. }
  3978. function drawBox(y, backC, foreC, str, enable, label) {
  3979. ctx.beginPath();
  3980. ctx.fillStyle = backC;
  3981. ctx.rect(screenWidth - 40, y * 50 + 10, 40, 30);
  3982. ctx.fill();
  3983. ctx.font = "normal 16px Arial";
  3984. ctx.fillStyle = foreC;
  3985. ctx.textAlign = "center";
  3986. ctx.fillText(str, screenWidth - 20, y * 50 + 32);
  3987. if (!enable) {
  3988. ctx.fillStyle = "rgba(255,255,255, 0.5)";
  3989. ctx.fill();
  3990. }
  3991. if (label != '') {
  3992. ctx.font = "normal 9px Arial";
  3993. ctx.fillStyle = "black";
  3994. ctx.fillText(label, screenWidth - 47, y * 50 + 40);
  3995. }
  3996. }
  3997. function drawCurveTControl() {
  3998. ctx.lineWidth = 2;
  3999. ctx.strokeStyle = "rgba(0,0,0, 0.3)";
  4000. ctx.beginPath();
  4001. ctx.rect(screenWidth - 80, 40, 28, screenHeight - 80);
  4002. ctx.stroke();
  4003. var ty = 40 + curveT * (screenHeight - 80);
  4004. ctx.beginPath();
  4005. ctx.moveTo(screenWidth - 80, ty);
  4006. ctx.lineTo(screenWidth - 85, ty - 5);
  4007. ctx.lineTo(screenWidth - 85, ty + 5);
  4008. ctx.lineTo(screenWidth - 80, ty);
  4009. ctx.fillStyle = "rgba(0,0,0, 0.6)";
  4010. ctx.fill();
  4011. var num = curveT.toFixed(decimal_places);
  4012. ctx.font = "normal 10px Arial";
  4013. ctx.textAlign = "left";
  4014. ctx.fillText(num, screenWidth - 78, ty);
  4015. }
  4016. function ptInTControl() {
  4017. var e = window.event;
  4018. var tgt = e.target || e.srcElement;
  4019. var left = tgt.offsetLeft;
  4020. var top = tgt.offsetTop;
  4021. var x = (e.clientX - left);
  4022. var y = (e.clientY - top);
  4023. if (x < screenWidth - 80 || x > screenWidth - 50) {
  4024. return false;
  4025. }
  4026. if (y < 40 || y > screenHeight - 80) {
  4027. return false;
  4028. }
  4029. curveT = (y - 40) / (screenHeight - 120);
  4030. if (curveT < 0 || curveT > 1) {
  4031. throw "stop execution";
  4032. }
  4033. return true;
  4034. }
  4035. function drawTop() {
  4036. if (tests[testIndex] == null) {
  4037. var str = testDivs[testIndex].textContent;
  4038. parse_all(str);
  4039. var title = testDivs[testIndex].id.toString();
  4040. testTitles[testIndex] = title;
  4041. }
  4042. init(tests[testIndex]);
  4043. redraw();
  4044. }
  4045. function redraw() {
  4046. if (focus_on_selection) {
  4047. collect_bounds = true;
  4048. draw(tests[testIndex], testLines[testIndex], testTitles[testIndex]);
  4049. collect_bounds = false;
  4050. if (focusXmin < focusXmax && focusYmin < focusYmax) {
  4051. setScale(focusXmin, focusXmax, focusYmin, focusYmax);
  4052. }
  4053. }
  4054. ctx.beginPath();
  4055. ctx.fillStyle = "white";
  4056. ctx.rect(0, 0, screenWidth, screenHeight);
  4057. ctx.fill();
  4058. draw(tests[testIndex], testLines[testIndex], testTitles[testIndex]);
  4059. }
  4060. function dumpCurvePartial(test, id, t0, t1) {
  4061. var curve = curveByID(test, id);
  4062. var name = ["line", "quad", "cubic"][curve.length / 2 - 2];
  4063. console.log("id=" + id + " " + name + "=" + curveToString(curve)
  4064. + " t0=" + t0 + " t1=" + t1
  4065. + " partial=" + curveToString(curvePartialByID(test, id, t0, t1)));
  4066. }
  4067. function dumpAngleTest(test, id, t0, t1) {
  4068. var curve = curveByID(test, id);
  4069. console.log(" { {" + curveToString(curve) + "}, "
  4070. + curve.length / 2 + ", " + t0 + ", " + t1 + ", {} }, //");
  4071. }
  4072. function dumpLogToConsole() {
  4073. if (logStart < 0) {
  4074. return;
  4075. }
  4076. var test = tests[testIndex];
  4077. var recType = REC_TYPE_UNKNOWN;
  4078. var records;
  4079. for (var index = 0; index < test.length; index += 3) {
  4080. var lastLineNo = test[index + 1];
  4081. if (lastLineNo >= logStart && lastLineNo < logStart + logRange) {
  4082. recType = test[index];
  4083. records = test[index + 2];
  4084. break;
  4085. }
  4086. }
  4087. if (recType == REC_TYPE_UNKNOWN) {
  4088. return;
  4089. }
  4090. var lines = testLines[testIndex];
  4091. for (var idx = 0; idx < logRange; ++idx) {
  4092. var line = lines[logStart + idx];
  4093. console.log(line);
  4094. for (var recordIndex = 0; recordIndex < records.length; recordIndex += 2) {
  4095. var fragType = records[recordIndex];
  4096. var frags = records[recordIndex + 1];
  4097. if (recType == REC_TYPE_ANGLE && fragType == ANGLE_AFTER) {
  4098. dumpCurvePartial(test, frags[0], frags[4], frags[5]);
  4099. dumpCurvePartial(test, frags[6], frags[10], frags[11]);
  4100. dumpCurvePartial(test, frags[12], frags[16], frags[17]);
  4101. console.log("\nstatic IntersectData intersectDataSet[] = { //");
  4102. dumpAngleTest(test, frags[0], frags[4], frags[5]);
  4103. dumpAngleTest(test, frags[6], frags[10], frags[11]);
  4104. dumpAngleTest(test, frags[12], frags[16], frags[17]);
  4105. console.log("}; //");
  4106. }
  4107. }
  4108. }
  4109. }
  4110. var activeKey = 'a';
  4111. var pathKey = 'b';
  4112. var pathBackKey = 'B';
  4113. var centerKey = 'c';
  4114. var coincidenceKey = 'C';
  4115. var addKey = 'd';
  4116. var deriviativesKey = 'f';
  4117. var angleKey = 'g';
  4118. var angleBackKey = 'G';
  4119. var intersectionKey = 'i';
  4120. var intersectionBackKey = 'I';
  4121. var sequenceKey = 'j';
  4122. var midpointKey = 'k';
  4123. var logKey = 'l';
  4124. var logToConsoleKey = 'L';
  4125. var markKey = 'm';
  4126. var sortKey = 'o';
  4127. var opKey = 'p';
  4128. var opBackKey = 'P';
  4129. var computedKey = 'q';
  4130. var computedBackKey = 'Q';
  4131. var directionKey = 'r';
  4132. var stepKey = 's';
  4133. var stepBackKey = 'S';
  4134. var intersectTKey = 't';
  4135. var topKey = 'T';
  4136. var curveTKey = 'u';
  4137. var controlLinesBackKey = 'V';
  4138. var controlLinesKey = 'v';
  4139. var ptsKey = 'x';
  4140. var xyKey = 'y';
  4141. var logCurvesKey = 'z';
  4142. var focusKey = '`';
  4143. var idKey = '.';
  4144. var retinaKey = '\\';
  4145. function doKeyPress(evt) {
  4146. var char = String.fromCharCode(evt.charCode);
  4147. var focusWasOn = false;
  4148. switch (char) {
  4149. case '0':
  4150. case '1':
  4151. case '2':
  4152. case '3':
  4153. case '4':
  4154. case '5':
  4155. case '6':
  4156. case '7':
  4157. case '8':
  4158. case '9':
  4159. decimal_places = char - '0';
  4160. redraw();
  4161. break;
  4162. case activeKey:
  4163. draw_active ^= true;
  4164. redraw();
  4165. break;
  4166. case addKey:
  4167. draw_add ^= true;
  4168. redraw();
  4169. break;
  4170. case angleKey:
  4171. draw_angle = (draw_angle + 1) % 4;
  4172. redraw();
  4173. break;
  4174. case angleBackKey:
  4175. draw_angle = (draw_angle + 2) % 3;
  4176. redraw();
  4177. break;
  4178. case centerKey:
  4179. setScale(xmin, xmax, ymin, ymax);
  4180. redraw();
  4181. break;
  4182. case coincidenceKey:
  4183. draw_coincidence ^= true;
  4184. redraw();
  4185. break;
  4186. case controlLinesBackKey:
  4187. control_lines = (control_lines + 3) % 4;
  4188. redraw();
  4189. break;
  4190. case controlLinesKey:
  4191. control_lines = (control_lines + 1) % 4;
  4192. redraw();
  4193. break;
  4194. case computedBackKey:
  4195. draw_computed = (draw_computed + 5) % 6;
  4196. redraw();
  4197. break;
  4198. case computedKey:
  4199. draw_computed = (draw_computed + 1) % 6;
  4200. redraw();
  4201. break;
  4202. case curveTKey:
  4203. curve_t ^= true;
  4204. if (curve_t) {
  4205. draw_legend = true;
  4206. }
  4207. redraw();
  4208. break;
  4209. case deriviativesKey:
  4210. draw_deriviatives = (draw_deriviatives + 1) % 3;
  4211. redraw();
  4212. break;
  4213. case directionKey:
  4214. draw_direction ^= true;
  4215. redraw();
  4216. break;
  4217. case focusKey:
  4218. focus_on_selection ^= true;
  4219. setScale(xmin, xmax, ymin, ymax);
  4220. redraw();
  4221. break;
  4222. case idKey:
  4223. draw_id ^= true;
  4224. redraw();
  4225. break;
  4226. case intersectionBackKey:
  4227. draw_intersection = (draw_intersection + 3) % 4;
  4228. redraw();
  4229. break;
  4230. case intersectionKey:
  4231. draw_intersection = (draw_intersection + 1) % 4;
  4232. redraw();
  4233. break;
  4234. case intersectTKey:
  4235. draw_intersectT ^= true;
  4236. redraw();
  4237. break;
  4238. case logCurvesKey:
  4239. logCurves(tests[testIndex]);
  4240. break;
  4241. case logKey:
  4242. draw_log ^= true;
  4243. redraw();
  4244. break;
  4245. case logToConsoleKey:
  4246. if (draw_log) {
  4247. dumpLogToConsole();
  4248. }
  4249. break;
  4250. case markKey:
  4251. draw_mark ^= true;
  4252. redraw();
  4253. break;
  4254. case midpointKey:
  4255. draw_midpoint ^= true;
  4256. redraw();
  4257. break;
  4258. case opKey:
  4259. draw_op = (draw_op + 1) % 3;
  4260. redraw();
  4261. break;
  4262. case opBackKey:
  4263. draw_op = (draw_op + 2) % 3;
  4264. redraw();
  4265. break;
  4266. case pathKey:
  4267. draw_path = (draw_path + 1) % (4 + (hasAlignedPath ? 3 : 0));
  4268. redraw();
  4269. break;
  4270. case pathBackKey:
  4271. draw_path = (draw_path + 3 + (hasAlignedPath ? 3 : 0)) % (4 + (hasAlignedPath ? 3 : 0));
  4272. redraw();
  4273. break;
  4274. case ptsKey:
  4275. pt_labels = (pt_labels + 1) % 3;
  4276. redraw();
  4277. break;
  4278. case retinaKey:
  4279. retina_scale ^= true;
  4280. drawTop();
  4281. break;
  4282. case sequenceKey:
  4283. draw_sequence ^= true;
  4284. redraw();
  4285. break;
  4286. case sortKey:
  4287. draw_sort = (draw_sort + 1) % 3;
  4288. drawTop();
  4289. break;
  4290. case stepKey:
  4291. step_limit++;
  4292. if (step_limit > stepMax) {
  4293. step_limit = stepMax;
  4294. }
  4295. redraw();
  4296. break;
  4297. case stepBackKey:
  4298. step_limit--;
  4299. if (step_limit < 0) {
  4300. step_limit = 0;
  4301. }
  4302. redraw();
  4303. break;
  4304. case topKey:
  4305. draw_top ^= true;
  4306. redraw();
  4307. break;
  4308. case xyKey:
  4309. debug_xy = (debug_xy + 1) % 3;
  4310. redraw();
  4311. break;
  4312. case '-':
  4313. focusWasOn = focus_on_selection;
  4314. if (focusWasOn) {
  4315. focus_on_selection = false;
  4316. scale /= 1.2;
  4317. } else {
  4318. scale /= 2;
  4319. calcLeftTop();
  4320. }
  4321. redraw();
  4322. focus_on_selection = focusWasOn;
  4323. break;
  4324. case '=':
  4325. case '+':
  4326. focusWasOn = focus_on_selection;
  4327. if (focusWasOn) {
  4328. focus_on_selection = false;
  4329. scale *= 1.2;
  4330. } else {
  4331. scale *= 2;
  4332. calcLeftTop();
  4333. }
  4334. redraw();
  4335. focus_on_selection = focusWasOn;
  4336. break;
  4337. case '?':
  4338. draw_hints ^= true;
  4339. if (draw_hints && !draw_legend) {
  4340. draw_legend = true;
  4341. }
  4342. redraw();
  4343. break;
  4344. case '/':
  4345. draw_legend ^= true;
  4346. redraw();
  4347. break;
  4348. }
  4349. }
  4350. function doKeyDown(evt) {
  4351. var char = evt.keyCode;
  4352. var preventDefault = false;
  4353. switch (char) {
  4354. case 37: // left arrow
  4355. if (evt.shiftKey) {
  4356. testIndex -= 9;
  4357. }
  4358. if (--testIndex < 0)
  4359. testIndex = tests.length - 1;
  4360. drawTop();
  4361. preventDefault = true;
  4362. break;
  4363. case 39: // right arrow
  4364. if (evt.shiftKey) {
  4365. testIndex += 9;
  4366. }
  4367. if (++testIndex >= tests.length)
  4368. testIndex = 0;
  4369. drawTop();
  4370. preventDefault = true;
  4371. break;
  4372. }
  4373. if (preventDefault) {
  4374. evt.preventDefault();
  4375. return false;
  4376. }
  4377. return true;
  4378. }
  4379. (function() {
  4380. var hidden = "hidden";
  4381. // Standards:
  4382. if (hidden in document)
  4383. document.addEventListener("visibilitychange", onchange);
  4384. else if ((hidden = "mozHidden") in document)
  4385. document.addEventListener("mozvisibilitychange", onchange);
  4386. else if ((hidden = "webkitHidden") in document)
  4387. document.addEventListener("webkitvisibilitychange", onchange);
  4388. else if ((hidden = "msHidden") in document)
  4389. document.addEventListener("msvisibilitychange", onchange);
  4390. // IE 9 and lower:
  4391. else if ('onfocusin' in document)
  4392. document.onfocusin = document.onfocusout = onchange;
  4393. // All others:
  4394. else
  4395. window.onpageshow = window.onpagehide
  4396. = window.onfocus = window.onblur = onchange;
  4397. function onchange (evt) {
  4398. var v = 'visible', h = 'hidden',
  4399. evtMap = {
  4400. focus:v, focusin:v, pageshow:v, blur:h, focusout:h, pagehide:h
  4401. };
  4402. evt = evt || window.event;
  4403. if (evt.type in evtMap)
  4404. document.body.className = evtMap[evt.type];
  4405. else
  4406. document.body.className = this[hidden] ? "hidden" : "visible";
  4407. }
  4408. })();
  4409. function calcXY() {
  4410. var e = window.event;
  4411. var tgt = e.target || e.srcElement;
  4412. var left = tgt.offsetLeft;
  4413. var top = tgt.offsetTop;
  4414. mouseX = (e.clientX - left) / scale + srcLeft;
  4415. mouseY = (e.clientY - top) / scale + srcTop;
  4416. }
  4417. function calcLeftTop() {
  4418. srcLeft = mouseX - screenWidth / 2 / scale;
  4419. srcTop = mouseY - screenHeight / 2 / scale;
  4420. }
  4421. var disableClick = false;
  4422. function handleMouseClick() {
  4423. if (disableClick) {
  4424. return;
  4425. }
  4426. if (!curve_t || !ptInTControl()) {
  4427. calcXY();
  4428. calcLeftTop();
  4429. }
  4430. redraw();
  4431. // if (!curve_t || !ptInTControl()) {
  4432. // mouseX = screenWidth / 2 / scale + srcLeft;
  4433. // mouseY = screenHeight / 2 / scale + srcTop;
  4434. // }
  4435. }
  4436. function handleMouseOver() {
  4437. calcXY();
  4438. if (debug_xy != 2) {
  4439. return;
  4440. }
  4441. var num = mouseX.toFixed(decimal_places) + ", " + mouseY.toFixed(decimal_places);
  4442. ctx.beginPath();
  4443. ctx.rect(300,100,num.length * 6,10);
  4444. ctx.fillStyle="white";
  4445. ctx.fill();
  4446. ctx.font = "normal 10px Arial";
  4447. ctx.fillStyle="black";
  4448. ctx.textAlign = "left";
  4449. ctx.fillText(num, 300, 108);
  4450. }
  4451. function start() {
  4452. for (var i = 0; i < testDivs.length; ++i) {
  4453. tests[i] = null;
  4454. }
  4455. testIndex = 0;
  4456. drawTop();
  4457. window.addEventListener('keypress', doKeyPress, true);
  4458. window.addEventListener('keydown', doKeyDown, true);
  4459. window.onresize = function() {
  4460. drawTop();
  4461. }
  4462. /*
  4463. window.onpagehide = function() {
  4464. disableClick = true;
  4465. }
  4466. */
  4467. window.onpageshow = function () {
  4468. disableClick = false;
  4469. }
  4470. }
  4471. </script>
  4472. </head>
  4473. <body onLoad="start();">
  4474. <canvas id="canvas" width="750" height="500"
  4475. onmousemove="handleMouseOver()"
  4476. onclick="handleMouseClick()"
  4477. ></canvas >
  4478. </body>
  4479. </html>