| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883 |
- /* eslint no-console: ["error", { allow: ["log"] }] */
- /* eslint-env browser,node */
- import {isoBandOptions} from './options.js';
- import {cell2Polygons, traceBandPaths} from './polygons.js';
- import {QuadTree} from './quadtree.js';
- /*
- * lookup table to generate polygon paths or edges required to
- * trace the full polygon(s)
- */
- var shapeCoordinates = {
- square: function(cell, x0, x1, x2, x3, opt) {
- if (opt.polygons)
- cell.polygons.push([ [0,0], [0, 1], [1, 1], [1, 0] ]);
- },
- triangle_bl: function(cell, x0, x1, x2, x3, opt) {
- var bottomleft = opt.interpolate(x0, x1, opt.minV, opt.maxV);
- var leftbottom = opt.interpolate(x0, x3, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.lb = {
- path: [ [0, leftbottom], [bottomleft, 0] ],
- move: {
- x: 0,
- y: -1,
- enter: 'tl'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [0, leftbottom], [bottomleft, 0], [0, 0] ]);
- },
- triangle_br: function(cell, x0, x1, x2, x3, opt) {
- var bottomright = opt.interpolate(x0, x1, opt.minV, opt.maxV);
- var rightbottom = opt.interpolate(x1, x2, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.br = {
- path: [ [bottomright, 0], [1, rightbottom] ],
- move: {
- x: 1,
- y: 0,
- enter: 'lb'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [bottomright, 0], [1, rightbottom], [1, 0] ]);
- },
- triangle_tr: function(cell, x0, x1, x2, x3, opt) {
- var righttop = opt.interpolate(x1, x2, opt.minV, opt.maxV);
- var topright = opt.interpolate(x3, x2, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.rt = {
- path: [ [1, righttop], [topright, 1] ],
- move: {
- x: 0,
- y: 1,
- enter: 'br'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [1, righttop], [topright, 1], [1, 1] ]);
- },
- triangle_tl: function(cell, x0, x1, x2, x3, opt) {
- var topleft = opt.interpolate(x3, x2, opt.minV, opt.maxV);
- var lefttop = opt.interpolate(x0, x3, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.tl = {
- path: [ [topleft, 1], [0, lefttop] ],
- move: {
- x: -1,
- y: 0,
- enter: 'rt'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [0, lefttop], [0, 1], [topleft, 1] ]);
- },
- tetragon_t: function(cell, x0, x1, x2, x3, opt) {
- var righttop = opt.interpolate(x1, x2, opt.minV, opt.maxV);
- var lefttop = opt.interpolate(x0, x3, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.rt = {
- path: [ [1, righttop], [0, lefttop] ],
- move: {
- x: -1,
- y: 0,
- enter: 'rt'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [0, lefttop], [0, 1], [1, 1], [1, righttop] ]);
- },
- tetragon_r: function(cell, x0, x1, x2, x3, opt) {
- var bottomright = opt.interpolate(x0, x1, opt.minV, opt.maxV);
- var topright = opt.interpolate(x3, x2, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.br = {
- path: [ [bottomright, 0], [topright, 1] ],
- move: {
- x: 0,
- y: 1,
- enter: 'br'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [bottomright, 0], [topright, 1], [1, 1], [1, 0] ]);
- },
- tetragon_b: function(cell, x0, x1, x2, x3, opt) {
- var leftbottom = opt.interpolate(x0, x3, opt.minV, opt.maxV);
- var rightbottom = opt.interpolate(x1, x2, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.lb = {
- path: [ [0, leftbottom], [1, rightbottom] ],
- move: {
- x: 1,
- y: 0,
- enter: 'lb'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [0, 0], [0, leftbottom], [1, rightbottom], [1, 0] ]);
- },
- tetragon_l: function(cell, x0, x1, x2, x3, opt) {
- var topleft = opt.interpolate(x3, x2, opt.minV, opt.maxV);
- var bottomleft = opt.interpolate(x0, x1, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.tl = {
- path: [ [topleft, 1], [bottomleft, 0] ],
- move: {
- x: 0,
- y: -1,
- enter: 'tl'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [0, 0], [0, 1], [topleft, 1], [bottomleft, 0] ]);
- },
- tetragon_bl: function(cell, x0, x1, x2, x3, opt) {
- var bottomleft = opt.interpolate_a(x0, x1, opt.minV, opt.maxV);
- var bottomright = opt.interpolate_b(x0, x1, opt.minV, opt.maxV);
- var leftbottom = opt.interpolate_a(x0, x3, opt.minV, opt.maxV);
- var lefttop = opt.interpolate_b(x0, x3, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.bl = {
- path: [ [bottomleft, 0], [0, leftbottom] ],
- move: {
- x: -1,
- y: 0,
- enter: 'rb'
- }
- };
- cell.edges.lt = {
- path: [ [0, lefttop], [bottomright, 0] ],
- move: {
- x: 0,
- y: -1,
- enter: 'tr'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [bottomleft, 0], [0, leftbottom], [0, lefttop], [bottomright, 0] ]);
- },
- tetragon_br: function(cell, x0, x1, x2, x3, opt) {
- var bottomleft = opt.interpolate_a(x0, x1, opt.minV, opt.maxV);
- var bottomright = opt.interpolate_b(x0, x1, opt.minV, opt.maxV);
- var rightbottom = opt.interpolate_a(x1, x2, opt.minV, opt.maxV);
- var righttop = opt.interpolate_b(x1, x2, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.bl = {
- path: [ [bottomleft, 0], [1, righttop] ],
- move: {
- x: 1,
- y: 0,
- enter: 'lt'
- }
- };
- cell.edges.rb = {
- path: [ [1, rightbottom], [bottomright, 0] ],
- move: {
- x: 0,
- y: -1,
- enter: 'tr'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [bottomleft, 0], [1, righttop], [1, rightbottom], [bottomright, 0] ]);
- },
- tetragon_tr: function(cell, x0, x1, x2, x3, opt) {
- var topleft = opt.interpolate_a(x3, x2, opt.minV, opt.maxV);
- var topright = opt.interpolate_b(x3, x2, opt.minV, opt.maxV);
- var righttop = opt.interpolate_b(x1, x2, opt.minV, opt.maxV);
- var rightbottom = opt.interpolate_a(x1, x2, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.rb = {
- path: [ [1, rightbottom], [topleft, 1] ],
- move: {
- x: 0,
- y: 1,
- enter: 'bl'
- }
- };
- cell.edges.tr = {
- path: [ [topright, 1], [1, righttop] ],
- move: {
- x: 1,
- y: 0,
- enter: 'lt'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [1, rightbottom], [topleft, 1], [topright, 1], [1, righttop] ]);
- },
- tetragon_tl: function(cell, x0, x1, x2, x3, opt) {
- var topleft = opt.interpolate_a(x3, x2, opt.minV, opt.maxV);
- var topright = opt.interpolate_b(x3, x2, opt.minV, opt.maxV);
- var lefttop = opt.interpolate_b(x0, x3, opt.minV, opt.maxV);
- var leftbottom = opt.interpolate_a(x0, x3, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.tr = {
- path: [ [topright, 1], [0, leftbottom] ],
- move: {
- x: -1,
- y: 0,
- enter: 'rb'
- }
- };
- cell.edges.lt = {
- path: [ [0, lefttop], [topleft, 1] ],
- move: {
- x: 0,
- y: 1,
- enter: 'bl'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [topright, 1], [0, leftbottom], [0, lefttop], [topleft, 1] ]);
- },
- tetragon_lr: function(cell, x0, x1, x2, x3, opt) {
- var leftbottom = opt.interpolate_a(x0, x3, opt.minV, opt.maxV);
- var lefttop = opt.interpolate_b(x0, x3, opt.minV, opt.maxV);
- var righttop = opt.interpolate_b(x1, x2, opt.minV, opt.maxV);
- var rightbottom = opt.interpolate_a(x1, x2, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.lt = {
- path: [ [0, lefttop], [1, righttop] ],
- move: {
- x: 1,
- y: 0,
- enter: 'lt'
- }
- };
- cell.edges.rb = {
- path: [ [1, rightbottom], [0, leftbottom] ],
- move: {
- x: -1,
- y: 0,
- enter: 'rb'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [0, leftbottom], [0, lefttop], [1, righttop], [1, rightbottom] ]);
- },
- tetragon_tb: function(cell, x0, x1, x2, x3, opt) {
- var topleft = opt.interpolate_a(x3, x2, opt.minV, opt.maxV);
- var topright = opt.interpolate_b(x3, x2, opt.minV, opt.maxV);
- var bottomright = opt.interpolate_b(x0, x1, opt.minV, opt.maxV);
- var bottomleft = opt.interpolate_a(x0, x1, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.tr = {
- path: [ [topright, 1], [bottomright, 0] ],
- move: {
- x: 0,
- y: -1,
- enter: 'tr'
- }
- };
- cell.edges.bl = {
- path: [ [bottomleft, 0], [topleft, 1] ],
- move: {
- x: 0,
- y: 1,
- enter: 'bl'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [bottomleft, 0], [topleft, 1], [topright, 1], [bottomright, 0] ]);
- },
- pentagon_tr: function(cell, x0, x1, x2, x3, opt) {
- var topleft = opt.interpolate(x3, x2, opt.minV, opt.maxV);
- var rightbottom = opt.interpolate(x1, x2, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.tl = {
- path: [[topleft, 1], [1, rightbottom]],
- move: {
- x: 1,
- y: 0,
- enter: 'lb'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [0, 0], [0, 1], [topleft, 1], [1, rightbottom], [1, 0] ]);
- },
- pentagon_tl: function(cell, x0, x1, x2, x3, opt) {
- var leftbottom = opt.interpolate(x0, x3, opt.minV, opt.maxV);
- var topright = opt.interpolate(x3, x2, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.lb = {
- path: [ [0, leftbottom], [topright, 1] ],
- move: {
- x: 0,
- y: 1,
- enter: 'br'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [0, 0], [0, leftbottom], [topright, 1], [1, 1], [1, 0] ]);
- },
- pentagon_br: function(cell, x0, x1, x2, x3, opt) {
- var bottomleft = opt.interpolate(x0, x1, opt.minV, opt.maxV);
- var righttop = opt.interpolate(x1, x2, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.rt = {
- path: [ [1, righttop], [bottomleft, 0] ],
- move: {
- x: 0,
- y: -1,
- enter: 'tl'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [0, 0], [0, 1], [1, 1], [1, righttop], [bottomleft, 0] ]);
- },
- pentagon_bl: function(cell, x0, x1, x2, x3, opt) {
- var lefttop = opt.interpolate(x0, x3, opt.minV, opt.maxV);
- var bottomright = opt.interpolate(x0, x1, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.br = {
- path: [ [bottomright, 0], [0, lefttop] ],
- move: {
- x: -1,
- y: 0,
- enter: 'rt'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [0, lefttop], [0, 1], [1, 1], [1, 0], [bottomright, 0] ]);
- },
- pentagon_tr_rl: function(cell, x0, x1, x2, x3, opt) {
- var lefttop = opt.interpolate(x0, x3, opt.minV, opt.maxV);
- var topleft = opt.interpolate(x3, x2, opt.minV, opt.maxV);
- var righttop = opt.interpolate_b(x1, x2, opt.minV, opt.maxV);
- var rightbottom = opt.interpolate_a(x1, x2, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.tl = {
- path: [ [topleft, 1], [1, righttop] ],
- move: {
- x: 1,
- y: 0,
- enter: 'lt'
- }
- };
- cell.edges.rb = {
- path: [ [1, rightbottom], [0, lefttop] ],
- move: {
- x: -1,
- y: 0,
- enter: 'rt'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [0, lefttop], [0, 1], [topleft, 1], [1, righttop], [1, rightbottom] ]);
- },
- pentagon_rb_bt: function(cell, x0, x1, x2, x3, opt) {
- var righttop = opt.interpolate(x1, x2, opt.minV, opt.maxV);
- var bottomright = opt.interpolate_b(x0, x1, opt.minV, opt.maxV);
- var bottomleft = opt.interpolate_a(x0, x1, opt.minV, opt.maxV);
- var topright = opt.interpolate(x3, x2, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.rt = {
- path: [ [1, righttop], [bottomright, 0] ],
- move: {
- x: 0,
- y: -1,
- enter: 'tr'
- }
- };
- cell.edges.bl = {
- path: [ [bottomleft, 0], [topright, 1] ],
- move: {
- x: 0,
- y: 1,
- enter: 'br'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [topright, 1], [1, 1], [1, righttop], [bottomright, 0], [bottomleft, 0] ]);
- },
- pentagon_bl_lr: function(cell, x0, x1, x2, x3, opt) {
- var bottomright = opt.interpolate(x0, x1, opt.minV, opt.maxV);
- var leftbottom = opt.interpolate_a(x0, x3, opt.minV, opt.maxV);
- var lefttop = opt.interpolate_b(x0, x3, opt.minV, opt.maxV);
- var rightbottom = opt.interpolate(x1, x2, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.br = {
- path: [ [bottomright, 0], [0, leftbottom] ],
- move: {
- x: -1,
- y: 0,
- enter: 'rb'
- }
- };
- cell.edges.lt = {
- path: [ [0, lefttop], [1, rightbottom] ],
- move: {
- x: 1,
- y: 0,
- enter: 'lb'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [bottomright, 0], [0, leftbottom], [0, lefttop], [1, rightbottom], [1, 0] ]);
- },
- pentagon_lt_tb: function(cell, x0, x1, x2, x3, opt) {
- var leftbottom = opt.interpolate(x0, x3, opt.minV, opt.maxV);
- var topleft = opt.interpolate_a(x3, x2, opt.minV, opt.maxV);
- var topright = opt.interpolate_b(x3, x2, opt.minV, opt.maxV);
- var bottomleft = opt.interpolate(x0, x1, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.lb = {
- path: [ [0, leftbottom], [topleft, 1] ],
- move: {
- x: 0,
- y: 1,
- enter: 'bl'
- }
- };
- cell.edges.tr = {
- path: [ [topright, 1], [bottomleft, 0] ],
- move: {
- x: 0,
- y: -1,
- enter: 'tl'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [0, 0], [0, leftbottom], [topleft, 1], [topright, 1], [bottomleft, 0] ]);
- },
- pentagon_bl_tb: function(cell, x0, x1, x2, x3, opt) {
- var lefttop = opt.interpolate(x0, x3, opt.minV, opt.maxV);
- var topleft = opt.interpolate(x3, x2, opt.minV, opt.maxV);
- var bottomright = opt.interpolate_b(x0, x1, opt.minV, opt.maxV);
- var bottomleft = opt.interpolate_a(x0, x1, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.bl = {
- path: [ [bottomleft, 0], [0, lefttop] ],
- move: {
- x: -1,
- y: 0,
- enter: 'rt'
- }
- };
- cell.edges.tl = {
- path: [ [ topleft, 1], [bottomright, 0] ],
- move: {
- x: 0,
- y: -1,
- enter: 'tr'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [0, lefttop], [0, 1], [topleft, 1], [bottomright, 0], [bottomleft, 0] ]);
- },
- pentagon_lt_rl: function(cell, x0, x1, x2, x3, opt) {
- var leftbottom = opt.interpolate_a(x0, x3, opt.minV, opt.maxV);
- var lefttop = opt.interpolate_b(x0, x3, opt.minV, opt.maxV);
- var topright = opt.interpolate(x3, x2, opt.minV, opt.maxV);
- var righttop = opt.interpolate(x1, x3, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.lt = {
- path: [ [0, lefttop], [topright, 1] ],
- move: {
- x: 0,
- y: 1,
- enter: 'br'
- }
- };
- cell.edges.rt = {
- path: [ [1, righttop], [0, leftbottom] ],
- move: {
- x: -1,
- y: 0,
- enter: 'rb'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [0, leftbottom], [0, lefttop], [topright, 1], [1, 1], [1, righttop] ]);
- },
- pentagon_tr_bt: function(cell, x0, x1, x2, x3, opt) {
- var topleft = opt.interpolate_a(x3, x2, opt.minV, opt.maxV);
- var topright = opt.interpolate_b(x3, x2, opt.minV, opt.maxV);
- var rightbottom = opt.interpolate(x1, x2, opt.minV, opt.maxV);
- var bottomright = opt.interpolate(x0, x1, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.br = {
- path: [ [bottomright, 0], [topleft, 1] ],
- move: {
- x: 0,
- y: 1,
- enter: 'bl'
- }
- };
- cell.edges.tr = {
- path: [ [topright, 1], [1, rightbottom] ],
- move: {
- x: 1,
- y: 0,
- enter: 'lb'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [topleft, 1], [topright, 1], [1, rightbottom], [1, 0], [bottomright, 0] ]);
- },
- pentagon_rb_lr: function(cell, x0, x1, x2, x3, opt) {
- var leftbottom = opt.interpolate(x0, x3, opt.minV, opt.maxV);
- var righttop = opt.interpolate_b(x1, x2, opt.minV, opt.maxV);
- var rightbottom = opt.interpolate_a(x1, x2, opt.minV, opt.maxV);
- var bottomleft = opt.interpolate(x0, x1, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.lb = {
- path: [ [0, leftbottom], [1, righttop] ],
- move: {
- x: 1,
- y: 0,
- enter: 'lt'
- }
- };
- cell.edges.rb = {
- path: [ [1, rightbottom], [bottomleft, 0] ],
- move: {
- x: 0,
- y: -1,
- enter: 'tl'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [0, 0], [0, leftbottom], [1, righttop], [1, rightbottom], [bottomleft, 0] ]);
- },
- hexagon_lt_tr: function(cell, x0, x1, x2, x3, opt) {
- var leftbottom = opt.interpolate(x0, x3, opt.minV, opt.maxV);
- var topleft = opt.interpolate_a(x3, x2, opt.minV, opt.maxV);
- var topright = opt.interpolate_b(x3, x2, opt.minV, opt.maxV);
- var rightbottom = opt.interpolate(x1, x2, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.lb = {
- path: [ [0, leftbottom], [topleft, 1] ],
- move: {
- x: 0,
- y: 1,
- enter: 'bl'
- }
- };
- cell.edges.tr = {
- path: [ [topright, 1], [1, rightbottom] ],
- move: {
- x: 1,
- y: 0,
- enter: 'lb'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [0, 0], [0, leftbottom], [topleft, 1], [topright, 1], [1, rightbottom], [1, 0] ]);
- },
- hexagon_bl_lt: function(cell, x0, x1, x2, x3, opt) {
- var bottomright = opt.interpolate(x0, x1, opt.minV, opt.maxV);
- var leftbottom = opt.interpolate_a(x0, x3, opt.minV, opt.maxV);
- var lefttop = opt.interpolate_b(x0, x3, opt.minV, opt.maxV);
- var topright = opt.interpolate(x3, x2, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.br = {
- path: [ [bottomright, 0], [0, leftbottom] ],
- move: {
- x: -1,
- y: 0,
- enter: 'rb'
- }
- };
- cell.edges.lt = {
- path: [ [0, lefttop], [topright, 1] ],
- move: {
- x: 0,
- y: 1,
- enter: 'br'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [bottomright, 0], [0, leftbottom], [0, lefttop], [topright, 1], [1, 1], [1, 0] ]);
- },
- hexagon_bl_rb: function(cell, x0, x1, x2, x3, opt) {
- var bottomleft = opt.interpolate_a(x0, x1, opt.minV, opt.maxV);
- var bottomright = opt.interpolate_b(x0, x1, opt.minV, opt.maxV);
- var lefttop = opt.interpolate(x0, x3, opt.minV, opt.maxV);
- var righttop = opt.interpolate(x1, x2, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.bl = {
- path: [ [bottomleft, 0], [0, lefttop] ],
- move: {
- x: -1,
- y: 0,
- enter: 'rt'
- }
- };
- cell.edges.rt = {
- path: [ [1, righttop], [bottomright, 0] ],
- move: {
- x: 0,
- y: -1,
- enter: 'tr'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [bottomleft, 0], [0, lefttop], [0, 1], [1, 1], [1, righttop], [bottomright, 0] ]);
- },
- hexagon_tr_rb: function(cell, x0, x1, x2, x3, opt) {
- var bottomleft = opt.interpolate(x0, x1, opt.minV, opt.maxV);
- var topleft = opt.interpolate(x3, x2, opt.minV, opt.maxV);
- var righttop = opt.interpolate_b(x1, x2, opt.minV, opt.maxV);
- var rightbottom = opt.interpolate_a(x1, x2, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.tl = {
- path: [ [topleft, 1], [1, righttop] ],
- move: {
- x: 1,
- y: 0,
- enter: 'lt'
- }
- };
- cell.edges.rb = {
- path: [ [1, rightbottom], [bottomleft, 0] ],
- move: {
- x: 0,
- y: -1,
- enter: 'tl'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [0, 0], [0, 1], [topleft, 1], [1, righttop], [1, rightbottom], [bottomleft, 0] ]);
- },
- hexagon_lt_rb: function(cell, x0, x1, x2, x3, opt) {
- var leftbottom = opt.interpolate(x0, x3, opt.minV, opt.maxV);
- var topright = opt.interpolate(x3, x2, opt.minV, opt.maxV);
- var righttop = opt.interpolate(x1, x2, opt.minV, opt.maxV);
- var bottomleft = opt.interpolate(x0, x1, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.lb = {
- path: [ [0, leftbottom], [topright, 1] ],
- move: {
- x: 0,
- y: 1,
- enter: 'br'
- }
- };
- cell.edges.rt = {
- path: [ [1, righttop], [bottomleft, 0] ],
- move: {
- x: 0,
- y: -1,
- enter: 'tl'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [0, 0], [0, leftbottom], [topright, 1], [1, 1], [1, righttop], [bottomleft, 0] ]);
- },
- hexagon_bl_tr: function(cell, x0, x1, x2, x3, opt) {
- var bottomright = opt.interpolate(x0, x1, opt.minV, opt.maxV);
- var lefttop = opt.interpolate(x0, x3, opt.minV, opt.maxV);
- var topleft = opt.interpolate(x3, x2, opt.minV, opt.maxV);
- var rightbottom = opt.interpolate(x1, x2, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.br = {
- path: [ [bottomright, 0], [0, lefttop] ],
- move: {
- x: -1,
- y: 0,
- enter: 'rt'
- }
- };
- cell.edges.tl = {
- path: [ [topleft, 1], [1, rightbottom] ],
- move: {
- x: 1,
- y: 0,
- enter: 'lb'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [bottomright, 0], [0, lefttop], [0, 1], [topleft, 1], [1, rightbottom], [1, 0] ]);
- },
- heptagon_tr: function(cell, x0, x1, x2, x3, opt) {
- var bottomleft = opt.interpolate_a(x0, x1, opt.minV, opt.maxV);
- var bottomright = opt.interpolate_b(x0, x1, opt.minV, opt.maxV);
- var leftbottom = opt.interpolate_a(x0, x3, opt.minV, opt.maxV);
- var lefttop = opt.interpolate_b(x0, x3, opt.minV, opt.maxV);
- var topright = opt.interpolate(x3, x2, opt.minV, opt.maxV);
- var righttop = opt.interpolate(x1, x2, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.bl = {
- path: [ [bottomleft, 0], [0, leftbottom] ],
- move: {
- x: -1,
- y: 0,
- enter: 'rb'
- }
- };
- cell.edges.lt = {
- path: [ [0, lefttop], [topright, 1] ],
- move: {
- x: 0,
- y: 1,
- enter: 'br'
- }
- };
- cell.edges.rt = {
- path: [ [1, righttop], [bottomright, 0] ],
- move: {
- x: 0,
- y: -1,
- enter: 'tr'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [bottomleft, 0], [0, leftbottom], [0, lefttop], [topright, 1], [1, 1], [1, righttop], [bottomright, 0] ]);
- },
- heptagon_bl: function(cell, x0, x1, x2, x3, opt) {
- var bottomleft = opt.interpolate(x0, x1, opt.minV, opt.maxV);
- var leftbottom = opt.interpolate(x0, x3, opt.minV, opt.maxV);
- var topleft = opt.interpolate_a(x3, x2, opt.minV, opt.maxV);
- var topright = opt.interpolate_b(x3, x2, opt.minV, opt.maxV);
- var righttop = opt.interpolate_b(x1, x2, opt.minV, opt.maxV);
- var rightbottom = opt.interpolate_a(x1, x2, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.lb = {
- path: [ [0, leftbottom], [topleft, 1] ],
- move: {
- x: 0,
- y: 1,
- enter: 'bl'
- }
- };
- cell.edges.tr = {
- path: [ [topright, 1], [1, righttop] ],
- move: {
- x: 1,
- y: 0,
- enter: 'lt'
- }
- };
- cell.edges.rb = {
- path: [ [1, rightbottom], [bottomleft, 0] ],
- move: {
- x: 0,
- y: -1,
- enter: 'tl'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [0, 0], [0, leftbottom], [topleft, 1], [topright, 1], [1, righttop], [1, rightbottom], [bottomleft, 0] ]);
- },
- heptagon_tl: function(cell, x0, x1, x2, x3, opt) {
- var bottomleft = opt.interpolate_a(x0, x1, opt.minV, opt.maxV);
- var bottomright = opt.interpolate_b(x0, x1, opt.minV, opt.maxV);
- var lefttop = opt.interpolate(x0, x3, opt.minV, opt.maxV);
- var topleft = opt.interpolate(x3, x2, opt.minV, opt.maxV);
- var righttop = opt.interpolate_b(x1, x2, opt.minV, opt.maxV);
- var rightbottom = opt.interpolate_a(x1, x2, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.bl = {
- path: [ [bottomleft, 0], [0, lefttop] ],
- move: {
- x: -1,
- y: 0,
- enter: 'rt'
- }
- };
- cell.edges.tl = {
- path: [ [topleft, 1], [1, righttop] ],
- move: {
- x: 1,
- y: 0,
- enter: 'lt'
- }
- };
- cell.edges.rb = {
- path: [ [1, rightbottom], [bottomright, 0] ],
- move: {
- x: 0,
- y: -1,
- enter: 'tr'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [bottomleft, 0], [0, lefttop], [0, 1], [topleft, 1], [1, righttop], [1, rightbottom], [bottomright, 0] ]);
- },
- heptagon_br: function(cell, x0, x1, x2, x3, opt) {
- var bottomright = opt.interpolate(x0, x1, opt.minV, opt.maxV);
- var leftbottom = opt.interpolate_a(x0, x3, opt.minV, opt.maxV);
- var lefttop = opt.interpolate_b(x0, x3, opt.minV, opt.maxV);
- var topleft = opt.interpolate_a(x3, x2, opt.minV, opt.maxV);
- var topright = opt.interpolate_b(x3, x2, opt.minV, opt.maxV);
- var rightbottom = opt.interpolate(x1, x2, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.br = {
- path: [ [bottomright, 0], [0, leftbottom] ],
- move: {
- x: -1,
- y: 0,
- enter: 'rb'
- }
- };
- cell.edges.lt = {
- path: [ [0, lefttop], [topleft, 1] ],
- move: {
- x: 0,
- y: 1,
- enter: 'bl'
- }
- };
- cell.edges.tr = {
- path: [ [topright, 1], [1, rightbottom] ],
- move: {
- x: 1,
- y: 0,
- enter: 'lb'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [bottomright,0], [0, leftbottom], [0, lefttop], [topleft, 1], [topright, 1], [1, rightbottom], [1, 0] ]);
- },
- octagon: function(cell, x0, x1, x2, x3, opt) {
- var bottomleft = opt.interpolate_a(x0, x1, opt.minV, opt.maxV);
- var bottomright = opt.interpolate_b(x0, x1, opt.minV, opt.maxV);
- var leftbottom = opt.interpolate_a(x0, x3, opt.minV, opt.maxV);
- var lefttop = opt.interpolate_b(x0, x3, opt.minV, opt.maxV);
- var topleft = opt.interpolate_a(x3, x2, opt.minV, opt.maxV);
- var topright = opt.interpolate_b(x3, x2, opt.minV, opt.maxV);
- var righttop = opt.interpolate_b(x1, x2, opt.minV, opt.maxV);
- var rightbottom = opt.interpolate_a(x1, x2, opt.minV, opt.maxV);
- if (opt.polygons_full) {
- cell.edges.bl = {
- path: [ [bottomleft, 0], [0, leftbottom] ],
- move: {
- x: -1,
- y: 0,
- enter: 'rb'
- }
- };
- cell.edges.lt = {
- path: [ [0, lefttop], [topleft, 1] ],
- move: {
- x: 0,
- y: 1,
- enter: 'bl'
- }
- };
- cell.edges.tr = {
- path: [ [topright, 1], [1, righttop] ],
- move: {
- x: 1,
- y: 0,
- enter: 'lt'
- }
- };
- cell.edges.rb = {
- path: [ [1, rightbottom], [bottomright, 0] ],
- move: {
- x: 0,
- y: -1,
- enter: 'tr'
- }
- };
- }
- if (opt.polygons)
- cell.polygons.push([ [bottomleft, 0], [0, leftbottom], [0, lefttop], [topleft, 1], [topright, 1], [1, righttop], [1, rightbottom], [bottomright, 0] ]);
- }
- };
- /*
- * Compute isobands(s) for a scalar 2D field given a certain
- * threshold and a bandwidth by applying the Marching Squares
- * Algorithm. The function returns a list of path coordinates
- * either for individual polygons within each grid cell, or the
- * outline of connected polygons.
- */
- function isoBands(input, minV, bandWidth, options) {
- var i,
- j,
- settings,
- useQuadTree = false,
- tree = null,
- root = null,
- data = null,
- cellGrid = null,
- multiBand = false,
- bw = [],
- bandPolygons = [],
- ret = [];
- /* basic input validation */
- if (!input) throw new Error('data is required');
- if (minV === undefined || minV === null) throw new Error('lowerBound is required');
- if (bandWidth === undefined || bandWidth === null) throw new Error('bandWidth is required');
- if ((!!options) && (typeof options !== 'object')) throw new Error('options must be an object');
- settings = isoBandOptions(options);
- /* check for input data */
- if (input instanceof QuadTree) {
- tree = input;
- root = input.root;
- data = input.data;
- if (!settings.noQuadTree)
- useQuadTree = true;
- } else if (Array.isArray(input) && Array.isArray(input[0])) {
- data = input;
- } else {
- throw new Error('input is neither array of arrays nor object retrieved from \'QuadTree()\'');
- }
- /* check and prepare input thresholds */
- if (Array.isArray(minV)) {
- multiBand = true;
- /* activate QuadTree optimization if not explicitly forbidden by user settings */
- if (!settings.noQuadTree)
- useQuadTree = true;
- /* check if all minV are numbers */
- for (i = 0; i < minV.length; i++)
- if (isNaN(+minV[i]))
- throw new Error('lowerBound[' + i + '] is not a number');
- if (Array.isArray(bandWidth)) {
- if (minV.length !== bandWidth.length)
- throw new Error('lowerBound and bandWidth have unequal lengths');
- /* check bandwidth values */
- for (i = 0; i < bandWidth.length; i++)
- if (isNaN(+bandWidth[i]))
- throw new Error('bandWidth[' + i + '] is not a number');
- } else {
- if (isNaN(+bandWidth))
- throw new Error('bandWidth must be a number');
- bw = [];
- for (i = 0; i < minV.length; i++) {
- bw.push(bandWidth);
- }
- bandWidth = bw;
- }
- } else {
- if (isNaN(+minV))
- throw new Error('lowerBound must be a number');
- minV = [ minV ];
- if (isNaN(+bandWidth))
- throw new Error('bandWidth must be a number');
- bandWidth = [ bandWidth ];
- }
- /* create QuadTree root node if not already present */
- if ((useQuadTree) && (!root)) {
- tree = new QuadTree(data);
- root = tree.root;
- data = tree.data;
- }
- if (settings.verbose) {
- if(settings.polygons)
- console.log('MarchingSquaresJS-isoBands: returning single polygons for each grid cell');
- else
- console.log('MarchingSquaresJS-isoBands: returning polygon paths for entire data grid');
- if (multiBand)
- console.log('MarchingSquaresJS-isoBands: multiple bands requested, returning array of band polygons instead of polygons for a single band');
- }
- /* Done with all input validation, now let's start computing stuff */
- /* loop over all minV values */
- minV.forEach(function(lowerBound, b) {
- bandPolygons = [];
- /* store bounds for current computation in settings object */
- settings.minV = lowerBound;
- settings.maxV = lowerBound + bandWidth[b];
- if(settings.verbose)
- console.log('MarchingSquaresJS-isoBands: computing isobands for [' + lowerBound + ':' + (lowerBound + bandWidth[b]) + ']');
- if (settings.polygons) {
- /* compose list of polygons for each single cell */
- if (useQuadTree) {
- /* go through list of cells retrieved from QuadTree */
- root
- .cellsInBand(settings.minV, settings.maxV, true)
- .forEach(function(c) {
- bandPolygons = bandPolygons.concat(
- cell2Polygons(
- prepareCell(data,
- c.x,
- c.y,
- settings),
- c.x,
- c.y,
- settings
- ));
- });
- } else {
- /* go through entire array of input data */
- for (j = 0; j < data.length - 1; ++j) {
- for (i = 0; i < data[0].length - 1; ++i)
- bandPolygons = bandPolygons.concat(
- cell2Polygons(
- prepareCell(data,
- i,
- j,
- settings),
- i,
- j,
- settings
- ));
- }
- }
- } else {
- /* sparse grid of input data cells */
- cellGrid = [];
- for (i = 0; i < data[0].length - 1; ++i)
- cellGrid[i] = [];
- /* compose list of polygons for entire input grid */
- if (useQuadTree) {
- /* collect the cells */
- root
- .cellsInBand(settings.minV, settings.maxV, false)
- .forEach(function(c) {
- cellGrid[c.x][c.y] = prepareCell(data,
- c.x,
- c.y,
- settings);
- });
- } else {
- /* prepare cells */
- for (i = 0; i < data[0].length - 1; ++i) {
- for (j = 0; j < data.length - 1; ++j) {
- cellGrid[i][j] = prepareCell(data,
- i,
- j,
- settings);
- }
- }
- }
- bandPolygons = traceBandPaths(data, cellGrid, settings);
- }
- /* finally, add polygons to output array */
- if (multiBand)
- ret.push(bandPolygons);
- else
- ret = bandPolygons;
- if(typeof settings.successCallback === 'function')
- settings.successCallback(ret, lowerBound, bandWidth[b]);
- });
- return ret;
- }
- /*
- * Thats all for the public interface, below follows the actual
- * implementation
- */
- /*
- * For isoBands, each square is defined by the three states
- * of its corner points. However, since computers use power-2
- * values, we use 2bits per trit, i.e.:
- *
- * 00 ... below minV
- * 01 ... between minV and maxV
- * 10 ... above maxV
- *
- * Hence we map the 4-trit configurations as follows:
- *
- * 0000 => 0
- * 0001 => 1
- * 0002 => 2
- * 0010 => 4
- * 0011 => 5
- * 0012 => 6
- * 0020 => 8
- * 0021 => 9
- * 0022 => 10
- * 0100 => 16
- * 0101 => 17
- * 0102 => 18
- * 0110 => 20
- * 0111 => 21
- * 0112 => 22
- * 0120 => 24
- * 0121 => 25
- * 0122 => 26
- * 0200 => 32
- * 0201 => 33
- * 0202 => 34
- * 0210 => 36
- * 0211 => 37
- * 0212 => 38
- * 0220 => 40
- * 0221 => 41
- * 0222 => 42
- * 1000 => 64
- * 1001 => 65
- * 1002 => 66
- * 1010 => 68
- * 1011 => 69
- * 1012 => 70
- * 1020 => 72
- * 1021 => 73
- * 1022 => 74
- * 1100 => 80
- * 1101 => 81
- * 1102 => 82
- * 1110 => 84
- * 1111 => 85
- * 1112 => 86
- * 1120 => 88
- * 1121 => 89
- * 1122 => 90
- * 1200 => 96
- * 1201 => 97
- * 1202 => 98
- * 1210 => 100
- * 1211 => 101
- * 1212 => 102
- * 1220 => 104
- * 1221 => 105
- * 1222 => 106
- * 2000 => 128
- * 2001 => 129
- * 2002 => 130
- * 2010 => 132
- * 2011 => 133
- * 2012 => 134
- * 2020 => 136
- * 2021 => 137
- * 2022 => 138
- * 2100 => 144
- * 2101 => 145
- * 2102 => 146
- * 2110 => 148
- * 2111 => 149
- * 2112 => 150
- * 2120 => 152
- * 2121 => 153
- * 2122 => 154
- * 2200 => 160
- * 2201 => 161
- * 2202 => 162
- * 2210 => 164
- * 2211 => 165
- * 2212 => 166
- * 2220 => 168
- * 2221 => 169
- * 2222 => 170
- */
- /*
- * ####################################
- * Some small helper functions
- * ####################################
- */
- function computeCenterAverage(bl, br, tr, tl, minV, maxV) {
- var average = (tl + tr + br + bl) / 4;
- if (average > maxV)
- return 2; /* above isoband limits */
- if (average < minV)
- return 0; /* below isoband limits */
- return 1; /* within isoband limits */
- }
- function prepareCell(grid, x, y, opt) {
- var cell,
- center_avg;
- /* compose the 4-trit corner representation */
- var cval = 0;
- var x3 = grid[y + 1][x];
- var x2 = grid[y + 1][x + 1];
- var x1 = grid[y][x + 1];
- var x0 = grid[y][x];
- var minV = opt.minV;
- var maxV = opt.maxV;
- /*
- * Note that missing data within the grid will result
- * in horribly failing to trace full polygon paths
- */
- if(isNaN(x0) || isNaN(x1) || isNaN(x2) || isNaN(x3)) {
- return;
- }
- /*
- * Here we detect the type of the cell
- *
- * x3 ---- x2
- * | |
- * | |
- * x0 ---- x1
- *
- * with edge points
- *
- * x0 = (x,y),
- * x1 = (x + 1, y),
- * x2 = (x + 1, y + 1), and
- * x3 = (x, y + 1)
- *
- * and compute the polygon intersections with the edges
- * of the cell. Each edge value may be (i) below, (ii) within,
- * or (iii) above the values of the isoband limits. We
- * encode this property using 2 bits of information, where
- *
- * 00 ... below,
- * 01 ... within, and
- * 10 ... above
- *
- * Then we store the cells value as vector
- *
- * cval = (x0, x1, x2, x3)
- *
- * where x0 are the two least significant bits (0th, 1st),
- * x1 the 2nd and 3rd bit, and so on. This essentially
- * enables us to work with a single integer number
- */
- cval |= (x3 < minV) ? 0 : (x3 > maxV) ? 128 : 64;
- cval |= (x2 < minV) ? 0 : (x2 > maxV) ? 32 : 16;
- cval |= (x1 < minV) ? 0 : (x1 > maxV) ? 8 : 4;
- cval |= (x0 < minV) ? 0 : (x0 > maxV) ? 2 : 1;
- /* make sure cval is a number */
- cval = +cval;
- /*
- * cell center average trit for ambiguous cases, where
- * 0 ... below iso band
- * 1 ... within iso band
- * 2 ... above isoband
- */
- center_avg = 0;
- cell = {
- cval: cval,
- polygons: [],
- edges: {},
- x0: x0,
- x1: x1,
- x2: x2,
- x3: x3,
- x: x,
- y: y
- };
- /*
- * Compute interpolated intersections of the polygon(s)
- * with the cell borders and (i) add edges for polygon
- * trace-back, or (ii) a list of small closed polygons
- * according to look-up table
- */
- switch (cval) {
- case 85: /* 1111 */
- shapeCoordinates.square(cell, x0, x1, x2, x3, opt);
- /* fall through */
- case 0: /* 0000 */
- /* fall through */
- case 170: /* 2222 */
- break;
- /* single triangle cases */
- case 169: /* 2221 */
- shapeCoordinates.triangle_bl(cell, x0, x1, x2, x3, opt);
- break;
- case 166: /* 2212 */
- shapeCoordinates.triangle_br(cell, x0, x1, x2, x3, opt);
- break;
- case 154: /* 2122 */
- shapeCoordinates.triangle_tr(cell, x0, x1, x2, x3, opt);
- break;
- case 106: /* 1222 */
- shapeCoordinates.triangle_tl(cell, x0, x1, x2, x3, opt);
- break;
- case 1: /* 0001 */
- shapeCoordinates.triangle_bl(cell, x0, x1, x2, x3, opt);
- break;
- case 4: /* 0010 */
- shapeCoordinates.triangle_br(cell, x0, x1, x2, x3, opt);
- break;
- case 16: /* 0100 */
- shapeCoordinates.triangle_tr(cell, x0, x1, x2, x3, opt);
- break;
- case 64: /* 1000 */
- shapeCoordinates.triangle_tl(cell, x0, x1, x2, x3, opt);
- break;
- /* single trapezoid cases */
- case 168: /* 2220 */
- shapeCoordinates.tetragon_bl(cell, x0, x1, x2, x3, opt);
- break;
- case 162: /* 2202 */
- shapeCoordinates.tetragon_br(cell, x0, x1, x2, x3, opt);
- break;
- case 138: /* 2022 */
- shapeCoordinates.tetragon_tr(cell, x0, x1, x2, x3, opt);
- break;
- case 42: /* 0222 */
- shapeCoordinates.tetragon_tl(cell, x0, x1, x2, x3, opt);
- break;
- case 2: /* 0002 */
- shapeCoordinates.tetragon_bl(cell, x0, x1, x2, x3, opt);
- break;
- case 8: /* 0020 */
- shapeCoordinates.tetragon_br(cell, x0, x1, x2, x3, opt);
- break;
- case 32: /* 0200 */
- shapeCoordinates.tetragon_tr(cell, x0, x1, x2, x3, opt);
- break;
- case 128: /* 2000 */
- shapeCoordinates.tetragon_tl(cell, x0, x1, x2, x3, opt);
- break;
- /* single rectangle cases */
- case 5: /* 0011 */
- shapeCoordinates.tetragon_b(cell, x0, x1, x2, x3, opt);
- break;
- case 20: /* 0110 */
- shapeCoordinates.tetragon_r(cell, x0, x1, x2, x3, opt);
- break;
- case 80: /* 1100 */
- shapeCoordinates.tetragon_t(cell, x0, x1, x2, x3, opt);
- break;
- case 65: /* 1001 */
- shapeCoordinates.tetragon_l(cell, x0, x1, x2, x3, opt);
- break;
- case 165: /* 2211 */
- shapeCoordinates.tetragon_b(cell, x0, x1, x2, x3, opt);
- break;
- case 150: /* 2112 */
- shapeCoordinates.tetragon_r(cell, x0, x1, x2, x3, opt);
- break;
- case 90: /* 1122 */
- shapeCoordinates.tetragon_t(cell, x0, x1, x2, x3, opt);
- break;
- case 105: /* 1221 */
- shapeCoordinates.tetragon_l(cell, x0, x1, x2, x3, opt);
- break;
- case 160: /* 2200 */
- shapeCoordinates.tetragon_lr(cell, x0, x1, x2, x3, opt);
- break;
- case 130: /* 2002 */
- shapeCoordinates.tetragon_tb(cell, x0, x1, x2, x3, opt);
- break;
- case 10: /* 0022 */
- shapeCoordinates.tetragon_lr(cell, x0, x1, x2, x3, opt);
- break;
- case 40: /* 0220 */
- shapeCoordinates.tetragon_tb(cell, x0, x1, x2, x3, opt);
- break;
- /* single pentagon cases */
- case 101: /* 1211 */
- shapeCoordinates.pentagon_tr(cell, x0, x1, x2, x3, opt);
- break;
- case 149: /* 2111 */
- shapeCoordinates.pentagon_tl(cell, x0, x1, x2, x3, opt);
- break;
- case 86: /* 1112 */
- shapeCoordinates.pentagon_bl(cell, x0, x1, x2, x3, opt);
- break;
- case 89: /* 1121 */
- shapeCoordinates.pentagon_br(cell, x0, x1, x2, x3, opt);
- break;
- case 69: /* 1011 */
- shapeCoordinates.pentagon_tr(cell, x0, x1, x2, x3, opt);
- break;
- case 21: /* 0111 */
- shapeCoordinates.pentagon_tl(cell, x0, x1, x2, x3, opt);
- break;
- case 84: /* 1110 */
- shapeCoordinates.pentagon_bl(cell, x0, x1, x2, x3, opt);
- break;
- case 81: /* 1101 */
- shapeCoordinates.pentagon_br(cell, x0, x1, x2, x3, opt);
- break;
- case 96: /* 1200 */
- shapeCoordinates.pentagon_tr_rl(cell, x0, x1, x2, x3, opt);
- break;
- case 24: /* 0120 */
- shapeCoordinates.pentagon_rb_bt(cell, x0, x1, x2, x3, opt);
- break;
- case 6: /* 0012 */
- shapeCoordinates.pentagon_bl_lr(cell, x0, x1, x2, x3, opt);
- break;
- case 129: /* 2001 */
- shapeCoordinates.pentagon_lt_tb(cell, x0, x1, x2, x3, opt);
- break;
- case 74: /* 1022 */
- shapeCoordinates.pentagon_tr_rl(cell, x0, x1, x2, x3, opt);
- break;
- case 146: /* 2102 */
- shapeCoordinates.pentagon_rb_bt(cell, x0, x1, x2, x3, opt);
- break;
- case 164: /* 2210 */
- shapeCoordinates.pentagon_bl_lr(cell, x0, x1, x2, x3, opt);
- break;
- case 41: /* 0221 */
- shapeCoordinates.pentagon_lt_tb(cell, x0, x1, x2, x3, opt);
- break;
- case 66: /* 1002 */
- shapeCoordinates.pentagon_bl_tb(cell, x0, x1, x2, x3, opt);
- break;
- case 144: /* 2100 */
- shapeCoordinates.pentagon_lt_rl(cell, x0, x1, x2, x3, opt);
- break;
- case 36: /* 0210 */
- shapeCoordinates.pentagon_tr_bt(cell, x0, x1, x2, x3, opt);
- break;
- case 9: /* 0021 */
- shapeCoordinates.pentagon_rb_lr(cell, x0, x1, x2, x3, opt);
- break;
- case 104: /* 1220 */
- shapeCoordinates.pentagon_bl_tb(cell, x0, x1, x2, x3, opt);
- break;
- case 26: /* 0122 */
- shapeCoordinates.pentagon_lt_rl(cell, x0, x1, x2, x3, opt);
- break;
- case 134: /* 2012 */
- shapeCoordinates.pentagon_tr_bt(cell, x0, x1, x2, x3, opt);
- break;
- case 161: /* 2201 */
- shapeCoordinates.pentagon_rb_lr(cell, x0, x1, x2, x3, opt);
- break;
- /* single hexagon cases */
- case 37: /* 0211 */
- shapeCoordinates.hexagon_lt_tr(cell, x0, x1, x2, x3, opt);
- break;
- case 148: /* 2110 */
- shapeCoordinates.hexagon_bl_lt(cell, x0, x1, x2, x3, opt);
- break;
- case 82: /* 1102 */
- shapeCoordinates.hexagon_bl_rb(cell, x0, x1, x2, x3, opt);
- break;
- case 73: /* 1021 */
- shapeCoordinates.hexagon_tr_rb(cell, x0, x1, x2, x3, opt);
- break;
- case 133: /* 2011 */
- shapeCoordinates.hexagon_lt_tr(cell, x0, x1, x2, x3, opt);
- break;
- case 22: /* 0112 */
- shapeCoordinates.hexagon_bl_lt(cell, x0, x1, x2, x3, opt);
- break;
- case 88: /* 1120 */
- shapeCoordinates.hexagon_bl_rb(cell, x0, x1, x2, x3, opt);
- break;
- case 97: /* 1201 */
- shapeCoordinates.hexagon_tr_rb(cell, x0, x1, x2, x3, opt);
- break;
- case 145: /* 2101 */
- shapeCoordinates.hexagon_lt_rb(cell, x0, x1, x2, x3, opt);
- break;
- case 25: /* 0121 */
- shapeCoordinates.hexagon_lt_rb(cell, x0, x1, x2, x3, opt);
- break;
- case 70: /* 1012 */
- shapeCoordinates.hexagon_bl_tr(cell, x0, x1, x2, x3, opt);
- break;
- case 100: /* 1210 */
- shapeCoordinates.hexagon_bl_tr(cell, x0, x1, x2, x3, opt);
- break;
- /* 6-sided saddles */
- case 17: /* 0101 */
- center_avg = computeCenterAverage(x0, x1, x2, x3, minV, maxV);
- /* should never be center_avg === 2 */
- if (center_avg === 0) {
- shapeCoordinates.triangle_bl(cell, x0, x1, x2, x3, opt);
- shapeCoordinates.triangle_tr(cell, x0, x1, x2, x3, opt);
- } else {
- shapeCoordinates.hexagon_lt_rb(cell, x0, x1, x2, x3, opt);
- }
- break;
- case 68: /* 1010 */
- center_avg = computeCenterAverage(x0, x1, x2, x3, minV, maxV);
- /* should never be center_avg === 2 */
- if (center_avg === 0) {
- shapeCoordinates.triangle_tl(cell, x0, x1, x2, x3, opt);
- shapeCoordinates.triangle_br(cell, x0, x1, x2, x3, opt);
- } else {
- shapeCoordinates.hexagon_bl_tr(cell, x0, x1, x2, x3, opt);
- }
- break;
- case 153: /* 2121 */
- center_avg = computeCenterAverage(x0, x1, x2, x3, minV, maxV);
- /* should never be center_avg === 0 */
- if (center_avg === 2) {
- shapeCoordinates.triangle_bl(cell, x0, x1, x2, x3, opt);
- shapeCoordinates.triangle_tr(cell, x0, x1, x2, x3, opt);
- } else {
- shapeCoordinates.hexagon_lt_rb(cell, x0, x1, x2, x3, opt);
- }
- break;
- case 102: /* 1212 */
- center_avg = computeCenterAverage(x0, x1, x2, x3, minV, maxV);
- /* should never be center_avg === 0 */
- if (center_avg === 2) {
- shapeCoordinates.triangle_tl(cell, x0, x1, x2, x3, opt);
- shapeCoordinates.triangle_br(cell, x0, x1, x2, x3, opt);
- } else {
- shapeCoordinates.hexagon_bl_tr(cell, x0, x1, x2, x3, opt);
- }
- break;
- /* 7-sided saddles */
- case 152: /* 2120 */
- center_avg = computeCenterAverage(x0, x1, x2, x3, minV, maxV);
- /* should never be center_avg === 0 */
- if (center_avg === 2) {
- shapeCoordinates.triangle_tr(cell, x0, x1, x2, x3, opt);
- shapeCoordinates.tetragon_bl(cell, x0, x1, x2, x3, opt);
- } else {
- shapeCoordinates.heptagon_tr(cell, x0, x1, x2, x3, opt);
- }
- break;
- case 137: /* 2021 */
- center_avg = computeCenterAverage(x0, x1, x2, x3, minV, maxV);
- /* should never be center_avg === 0 */
- if (center_avg === 2) {
- shapeCoordinates.triangle_bl(cell, x0, x1, x2, x3, opt);
- shapeCoordinates.tetragon_tr(cell, x0, x1, x2, x3, opt);
- } else {
- shapeCoordinates.heptagon_bl(cell, x0, x1, x2, x3, opt);
- }
- break;
- case 98: /* 1202 */
- center_avg = computeCenterAverage(x0, x1, x2, x3, minV, maxV);
- /* should never be center_avg === 0 */
- if (center_avg === 2) {
- shapeCoordinates.triangle_tl(cell, x0, x1, x2, x3, opt);
- shapeCoordinates.tetragon_br(cell, x0, x1, x2, x3, opt);
- } else {
- shapeCoordinates.heptagon_tl(cell, x0, x1, x2, x3, opt);
- }
- break;
- case 38: /* 0212 */
- center_avg = computeCenterAverage(x0, x1, x2, x3, minV, maxV);
- /* should never be center_avg === 0 */
- if (center_avg === 2) {
- shapeCoordinates.triangle_br(cell, x0, x1, x2, x3, opt);
- shapeCoordinates.tetragon_tl(cell, x0, x1, x2, x3, opt);
- } else {
- shapeCoordinates.heptagon_br(cell, x0, x1, x2, x3, opt);
- }
- break;
- case 18: /* 0102 */
- center_avg = computeCenterAverage(x0, x1, x2, x3, minV, maxV);
- /* should never be center_avg === 2 */
- if (center_avg === 0) {
- shapeCoordinates.triangle_tr(cell, x0, x1, x2, x3, opt);
- shapeCoordinates.tetragon_bl(cell, x0, x1, x2, x3, opt);
- } else {
- shapeCoordinates.heptagon_tr(cell, x0, x1, x2, x3, opt);
- }
- break;
- case 33: /* 0201 */
- center_avg = computeCenterAverage(x0, x1, x2, x3, minV, maxV);
- /* should never be center_avg === 2 */
- if (center_avg === 0) {
- shapeCoordinates.triangle_bl(cell, x0, x1, x2, x3, opt);
- shapeCoordinates.tetragon_tr(cell, x0, x1, x2, x3, opt);
- } else {
- shapeCoordinates.heptagon_bl(cell, x0, x1, x2, x3, opt);
- }
- break;
- case 72: /* 1020 */
- center_avg = computeCenterAverage(x0, x1, x2, x3, minV, maxV);
- /* should never be center_avg === 2 */
- if (center_avg === 0) {
- shapeCoordinates.triangle_tl(cell, x0, x1, x2, x3, opt);
- shapeCoordinates.tetragon_br(cell, x0, x1, x2, x3, opt);
- } else {
- shapeCoordinates.heptagon_tl(cell, x0, x1, x2, x3, opt);
- }
- break;
- case 132: /* 2010 */
- center_avg = computeCenterAverage(x0, x1, x2, x3, minV, maxV);
- /* should never be center_avg === 2 */
- if (center_avg === 0) {
- shapeCoordinates.triangle_br(cell, x0, x1, x2, x3, opt);
- shapeCoordinates.tetragon_tl(cell, x0, x1, x2, x3, opt);
- } else {
- shapeCoordinates.heptagon_br(cell, x0, x1, x2, x3, opt);
- }
- break;
- /* 8-sided saddles */
- case 136: /* 2020 */
- center_avg = computeCenterAverage(x0, x1, x2, x3, minV, maxV);
- if (center_avg === 0) {
- shapeCoordinates.tetragon_tl(cell, x0, x1, x2, x3, opt);
- shapeCoordinates.tetragon_br(cell, x0, x1, x2, x3, opt);
- } else if (center_avg === 1) {
- shapeCoordinates.octagon(cell, x0, x1, x2, x3, opt);
- } else {
- shapeCoordinates.tetragon_bl(cell, x0, x1, x2, x3, opt);
- shapeCoordinates.tetragon_tr(cell, x0, x1, x2, x3, opt);
- }
- break;
- case 34: /* 0202 */
- center_avg = computeCenterAverage(x0, x1, x2, x3, minV, maxV);
- if (center_avg === 0) {
- shapeCoordinates.tetragon_bl(cell, x0, x1, x2, x3, opt);
- shapeCoordinates.tetragon_tr(cell, x0, x1, x2, x3, opt);
- } else if (center_avg === 1) {
- shapeCoordinates.octagon(cell, x0, x1, x2, x3, opt);
- } else {
- shapeCoordinates.tetragon_tl(cell, x0, x1, x2, x3, opt);
- shapeCoordinates.tetragon_br(cell, x0, x1, x2, x3, opt);
- }
- break;
- }
- return cell;
- }
- export {isoBands};
|