Home | History | Annotate | Download | only in Intersection
      1 <!-- bezier clip visualizer -->
      2 <html>
      3 <head>
      4 <div style="height:0">
      5 
      6 <div id="clip1">
      7 (gdb) p smaller
      8 $2 = {{
      9     x = 0.91292418204644155, 
     10     y = 0.41931201426549197
     11   }, {
     12     x = 0.70491388044579517, 
     13     y = 0.64754305977710236
     14   }, {
     15     x = 0, 
     16     y = 1
     17   }}
     18 (gdb) p larger
     19 $3 = {{
     20     x = 0.21875, 
     21     y = 0.765625
     22   }, {
     23     x = 0.125, 
     24     y = 0.875
     25   }, {
     26     x = 0, 
     27     y = 1
     28   }}
     29 (gdb) p distance2y
     30 $1 = {{
     31     x = 0, 
     32     y = 0.080355482722450078
     33   }, {
     34     x = 0.5, 
     35     y = 0.038383741101172597
     36   }, {
     37     x = 1, 
     38     y = 0
     39   }}
     40 </div>
     41 
     42 <div id="quad21a">
     43 bezier_clip q1=(0,0 1,0 0,2) q2=(0.5,0.25 0.5,0.5 0,1) minT=0 maxT=1
     44 </div>
     45 <div id="quad21b">
     46 bezier_clip q1=(0.5,0.25 0.5,0.375 0.375,0.5625) q2=(0,0 1,0 0,2) minT=0.3 maxT=0.78125
     47 </div>
     48 <div id="quad21c">
     49 bezier_clip q1=(0.42,0.18 0.6125,0.46875 0.341796875,1.22070312) q2=(0.5,0.25 0.5,0.375 0.375,0.5625) minT=0 maxT=0.926710098
     50 </div>
     51 <div id="quad21d">
     52 bezier_clip q1=(0.5,0.25 0.5,0.307919381 0.473162762,0.379257381) q2=(0.42,0.18 0.6125,0.46875 0.341796875,1.22070312) minT=0.187231244 maxT=0.729263299
     53 </div>
     54 <div id="quad21e">
     55 bezier_clip q1=(0.475846194,0.304363878 0.53317904,0.507883959 0.454423387,0.847492538) q2=(0.5,0.25 0.5,0.307919381 0.473162762,0.379257381) minT=0 maxT=1
     56 </div>
     57 <div id="quad21f">
     58 bezier_clip q1=(0.493290691,0.311274036 0.486581381,0.343588381 0.473162762,0.379257381) q2=(0.475846194,0.304363878 0.53317904,0.507883959 0.454423387,0.847492538) minT=0.0828748517 maxT=0.150086861
     59 </div>
     60 
     61 <div id="quad21g"> 
     62 (gdb) p smaller
     63 $1 = {{
     64     x = 0.48441440743366754, 
     65     y = 0.33903196011243797
     66   }, {
     67     x = 0.48750982503868118, 
     68     y = 0.35346899178071778
     69   }, {
     70     x = 0.48999046908865357, 
     71     y = 0.368520797004039
     72   }}
     73 (gdb) p larger
     74 $2 = {{
     75     x = 0.49329069058425024, 
     76     y = 0.31127403581536672
     77   }, {
     78     x = 0.48658138116850047, 
     79     y = 0.34358838107698753
     80   }, {
     81     x = 0.47316276233700094, 
     82     y = 0.37925738104648321
     83   }}
     84 </div>
     85 
     86 <div id="quad36">
     87 (gdb) p fQ
     88 $2 = {{
     89     x = 1.8883839294261275, 
     90     y = 2.1108590606904345
     91   }, {
     92     x = 1.888463903363252, 
     93     y = 2.1111576060205435
     94   }, {
     95     x = 1.8885438199983176, 
     96     y = 2.1114561800016824
     97   }}
     98 (gdb) p rh.fQ
     99 $3 = {{
    100     x = 1.8883839294260976, 
    101     y = 2.1108590606903377
    102   }, {
    103     x = 1.8886366953645748, 
    104     y = 2.1109850143489544
    105   }, {
    106     x = 1.8888888888888888, 
    107     y = 2.1111111111111112
    108   }}
    109 (gdb) 
    110 </div>
    111 
    112 <div id="quad37">
    113  {{x = 360.048828125, y = 229.2578125}, {x = 360.048828125, y = 224.4140625}, {x = 362.607421875, y = 221.3671875}}
    114  {{x = 362.607421875, y = 221.3671875}, {x = 365.166015625, y = 218.3203125}, {x = 369.228515625, y = 218.3203125}}
    115 </div>
    116 
    117 <div id="quad38">
    118 $2 = {{fX = 369.969421, fY = 137.94809}, {fX = 383.982849, fY = 121.260353}, {fX = 406.233154, fY = 121.260353}}
    119 $4 = {{fX = 406.232788, fY = 121.260353}, {fX = 409.441956, fY = 121.260353}, {fX = 412.972046, fY = 121.795212}}
    120 </div>
    121 
    122 <div id="quad39">
    123 {{x = 406.233154296875, y = 121.26035308837891}, {x = 406.23153587045397, y = 121.26035308837891}, {x = 406.22991748761177, y = 121.26035317666889}}, 
    124 {{x = 406.23295158013377, y = 121.26035308872596}, {x = 406.2328698329315, y = 121.26035308837889}, {x = 406.2327880859375, y = 121.26035308837891}},
    125 </div>
    126 
    127 </div>
    128 
    129 <script type="text/javascript">
    130 
    131 var testDivs = [
    132     quad56,
    133     quad39,
    134     quad38,
    135     quad37,
    136     quad36,
    137     quad21g,
    138     quad21a,          
    139     quad21b,
    140     quad21c,
    141     quad21d,
    142     quad21e,
    143     quad21f,
    144     clip1,
    145 ];
    146 
    147 var scale, columns, rows, xStart, yStart;
    148 
    149 var ticks = 10;
    150 var at_x = 13 + 0.5;
    151 var at_y = 13 + 0.5;
    152 var init_decimal_places = 1; // make this 3 to show more precision
    153 var decimal_places;
    154 var tests = [];
    155 var testTitles = [];
    156 var testIndex = 0;
    157 var ctx;
    158 var fat1 = true;
    159 var fat2 = false;
    160 var ctl1 = true;
    161 var ctl2 = false;
    162 var ctlPts1 = true;
    163 var ctlPts2 = false;
    164 var minScale = 1;
    165 var subscale = 1;
    166 
    167 function parse(test, title) {
    168     var curveStrs = test.split("{{");
    169     if (curveStrs.length == 1)
    170         curveStrs = test.split("=(");
    171     var pattern = /[a-z$=]?-?\d+\.*\d*/g;
    172     var curves = [];
    173     for (var c in curveStrs) {
    174         var curveStr = curveStrs[c];
    175         var points = curveStr.match(pattern);
    176         var pts = [];
    177         for (var wd in points) {
    178             var num = parseFloat(points[wd]);
    179             if (isNaN(num)) continue;
    180             pts.push(num);
    181         }
    182         if (pts.length > 0)
    183             curves.push(pts);
    184     }
    185     if (curves.length >= 2) {
    186         tests.push(curves);
    187         testTitles.push(title);
    188     }
    189 }
    190 
    191 function init(test) {
    192     var canvas = document.getElementById('canvas');
    193     if (!canvas.getContext) return;
    194     canvas.width = window.innerWidth - at_x;
    195     canvas.height = window.innerHeight - at_y;
    196     ctx = canvas.getContext('2d');
    197     var xmin = Infinity;
    198     var xmax = -Infinity;
    199     var ymin = Infinity;
    200     var ymax = -Infinity;
    201     for (var curves in test) {
    202         var curve = test[curves];
    203         var last = curve.length;
    204         for (var idx = 0; idx < last; idx += 2) {
    205             xmin = Math.min(xmin, curve[idx]);
    206             xmax = Math.max(xmax, curve[idx]);
    207             ymin = Math.min(ymin, curve[idx + 1]);
    208             ymax = Math.max(ymax, curve[idx + 1]);
    209         }
    210     }
    211     subscale = 1;
    212     decimal_places = init_decimal_places;
    213     if (xmax != xmin && ymax != ymin) {
    214         while ((xmax - xmin) * subscale < 0.1 && (ymax - ymin) * subscale < 0.1) {
    215             subscale *= 10;
    216             decimal_places += 1;
    217      //       if (subscale > 100000) {
    218      //           break;
    219      //       }
    220         }
    221     }
    222     columns = Math.ceil(xmax * subscale) - Math.floor(xmin * subscale) + 1;
    223     rows = Math.ceil(ymax * subscale) - Math.floor(ymin * subscale) + 1;
    224     
    225     xStart = Math.floor(xmin * subscale) / subscale;
    226     yStart = Math.floor(ymin * subscale) / subscale;
    227     var hscale = ctx.canvas.width / columns / ticks;
    228     var vscale = ctx.canvas.height / rows / ticks;
    229     minScale = Math.floor(Math.min(hscale, vscale));
    230     scale = minScale * subscale;
    231  //   while (columns < 1000 && rows < 1000) {
    232   //      columns *= 2;
    233  //       rows *= 2;
    234  //   }
    235 }
    236 
    237 function drawPoint(px, py, xoffset, yoffset, unit) {
    238     var label = px.toFixed(decimal_places) + ", " + py.toFixed(decimal_places);
    239     var _px = px * unit + xoffset;
    240     var _py = py * unit + yoffset;
    241     ctx.beginPath();
    242     ctx.arc(_px, _py, 3, 0, Math.PI*2, true);
    243     ctx.closePath();
    244     ctx.fill();
    245     ctx.fillText(label, _px + 5, _py);
    246 }
    247 
    248 function draw(test, title, _at_x, _at_y, scale) {
    249     ctx.fillStyle = "rgba(0,0,0, 0.1)";
    250     ctx.font = "normal 50px Arial";
    251     ctx.fillText(title, 50, 50);
    252     ctx.font = "normal 10px Arial";
    253 
    254     var unit = scale * ticks;
    255     ctx.lineWidth = 1;
    256     var i;
    257     for (i = 0; i <= rows * ticks; ++i) {
    258         ctx.strokeStyle = (i % ticks) != 0 ? "rgb(160,160,160)" : "black";
    259         ctx.beginPath();
    260         ctx.moveTo(_at_x + 0, _at_y + i * minScale);
    261         ctx.lineTo(_at_x + unit * columns, _at_y + i * minScale);
    262         ctx.stroke();
    263     }
    264     for (i = 0; i <= columns * ticks; ++i) {
    265         ctx.strokeStyle = (i % ticks) != 0 ? "rgb(160,160,160)" : "black";
    266         ctx.beginPath();
    267         ctx.moveTo(_at_x + i * minScale, _at_y + 0);
    268         ctx.lineTo(_at_x + i * minScale, _at_y + unit * rows);
    269         ctx.stroke();
    270     }
    271  
    272     var xoffset = xStart * -unit + _at_x;
    273     var yoffset = yStart * -unit + _at_y;
    274 
    275     ctx.fillStyle = "rgb(40,80,60)"
    276     for (i = 0; i <= columns; i += (1 / ticks))
    277     {
    278         num = xStart + i / subscale; 
    279         ctx.fillText(num.toFixed(decimal_places), xoffset + num * unit - 5, 10);
    280     }
    281     for (i = 0; i <= rows; i += (1 / ticks))
    282     {
    283         num = yStart + i / subscale; 
    284         ctx.fillText(num.toFixed(decimal_places), 0, yoffset + num * unit + 0);
    285     }
    286 
    287     // draw curve 1 and 2
    288     var curves, pts;
    289     for (curves in test) {
    290         var curve = test[curves];
    291         ctx.beginPath();
    292         ctx.moveTo(xoffset + curve[0] * unit, yoffset + curve[1] * unit);
    293         switch (curve.length) {
    294             case 6:
    295                 ctx.quadraticCurveTo(
    296                     xoffset + curve[2] * unit, yoffset + curve[3] * unit,
    297                     xoffset + curve[4] * unit, yoffset + curve[5] * unit);
    298                 break;
    299             case 8:
    300                 ctx.bezierCurveTo(
    301                     xoffset + curve[2] * unit, yoffset + curve[3] * unit,
    302                     xoffset + curve[4] * unit, yoffset + curve[5] * unit,
    303                     xoffset + curve[6] * unit, yoffset + curve[7] * unit);
    304                 break;
    305         }
    306         if (curves == 2) ctx.strokeStyle = curves ? "red" : "blue";
    307         ctx.stroke();
    308         ctx.strokeStyle = "rgba(0,0,0, 0.3)";
    309         ctx.beginPath();
    310         ctx.moveTo(xoffset + curve[0] * unit, yoffset + curve[1] * unit);
    311         ctx.lineTo(xoffset + curve[2] * unit, yoffset + curve[3] * unit);
    312         ctx.lineTo(xoffset + curve[4] * unit, yoffset + curve[5] * unit);
    313         if (curve.length == 8)
    314             ctx.lineTo(xoffset + curve[6] * unit, yoffset + curve[7] * unit);
    315         ctx.stroke();
    316     }
    317     // optionally draw fat lines for curve 
    318     if (fat1)
    319         drawFat(test[0], xoffset, yoffset, unit);
    320     if (fat2)
    321         drawFat(test[1], xoffset, yoffset, unit);
    322     if (ctl1)
    323         drawCtl(test[0], xoffset, yoffset, unit);
    324     if (ctl2)
    325         drawCtl(test[1], xoffset, yoffset, unit);
    326     if (ctlPts1)
    327         drawCtlPts(test[0], xoffset, yoffset, unit);
    328     if (ctlPts2)
    329         drawCtlPts(test[1], xoffset, yoffset, unit);
    330 }
    331 
    332 function drawCtl(curve, xoffset, yoffset, unit) {
    333     var last = curve.length - 2;
    334     ctx.strokeStyle = "rgba(0,0,0, 0.5)";
    335     ctx.beginPath();
    336     ctx.moveTo(xoffset + curve[0] * unit, yoffset + curve[1] * unit);
    337     ctx.lineTo(xoffset + curve[2] * unit, yoffset + curve[3] * unit);
    338     ctx.lineTo(xoffset + curve[4] * unit, yoffset + curve[5] * unit);
    339     ctx.stroke();
    340 }
    341 
    342 function drawCtlPts(curve, xoffset, yoffset, unit) {
    343     drawPoint(curve[0], curve[1], xoffset, yoffset, unit);
    344     drawPoint(curve[2], curve[3], xoffset, yoffset, unit);
    345     drawPoint(curve[4], curve[5], xoffset, yoffset, unit);
    346 }
    347 
    348 function drawFat(curve, xoffset, yoffset, unit) {
    349     var last = curve.length - 2;
    350     ctx.strokeStyle = "rgba(0,0,0, 0.5)";
    351     ctx.beginPath();
    352     ctx.moveTo(xoffset + curve[0] * unit, yoffset + curve[1] * unit);
    353     ctx.lineTo(xoffset + curve[last] * unit, yoffset + curve[last + 1] * unit);
    354     ctx.stroke();
    355     // draw line parallel to end points through control points
    356     var dx = curve[last] - curve[0];
    357     var dy = curve[last + 1] - curve[1];
    358     drawParallelLine(curve[2], curve[3], dx, dy, xoffset, yoffset, unit);
    359     if (curve.length == 8)
    360         drawParallelLine(curve[4], curve[5], dx, dy, xoffset, yoffset, unit);
    361 }
    362 
    363 function drawParallelLine(x, y, dx, dy, xoffset, yoffset, unit) {
    364     var x1 = x - dx;
    365     var y1 = y - dy;
    366     var x2 = x + dx;
    367     var y2 = y + dy;
    368     ctx.beginPath();
    369     ctx.moveTo(xoffset + x1 * unit, yoffset + y1 * unit);
    370     ctx.lineTo(xoffset + x2 * unit, yoffset + y2 * unit);
    371     ctx.stroke();
    372 }
    373 
    374 function drawTop() {
    375     init(tests[testIndex]);
    376     redraw();
    377 }
    378 
    379 function redraw() {
    380     ctx.beginPath();
    381     ctx.rect(0, 0, ctx.canvas.width, ctx.canvas.height);
    382     ctx.fillStyle="white";
    383     ctx.fill();
    384     draw(tests[testIndex], testTitles[testIndex], at_x, at_y, scale);
    385 }
    386 
    387 function doKeyPress(evt) {
    388     var char = String.fromCharCode(evt.charCode);
    389     switch (char) {
    390     case 'c':
    391         ctl2 ^= true;
    392         if (ctl2 == false)
    393             ctl1 ^= true;
    394         drawTop();
    395         break;
    396     case 'd':
    397         ctlPts2 ^= true;
    398         if (ctlPts2 == false)
    399             ctlPts1 ^= true;
    400         drawTop();
    401         break;
    402     case 'f':
    403         fat2 ^= true;
    404         if (fat2 == false)
    405             fat1 ^= true;
    406         drawTop();
    407         break;
    408     case 'N':
    409         testIndex += 9;
    410     case 'n':
    411         if (++testIndex >= tests.length)
    412             testIndex = 0;
    413         mouseX = Infinity;
    414         drawTop();
    415         break;
    416     case 'P':
    417         testIndex -= 9;
    418     case 'p':
    419         if (--testIndex < 0)
    420             testIndex = tests.length - 1;
    421         mouseX = Infinity;
    422         drawTop();
    423         break;
    424     }
    425 }
    426 
    427 function handleMouseClick() {
    428 }
    429 
    430 function handleMouseOver() {
    431 }
    432 
    433 function start() {
    434     for (i = 0; i < testDivs.length; ++i) {
    435         var title = testDivs[i].id.toString();
    436         var str = testDivs[i].firstChild.data;
    437         parse(str, title);
    438     }
    439     drawTop();
    440     window.addEventListener('keypress', doKeyPress, true);
    441     window.onresize = function() {
    442         drawTop();
    443     }
    444 }
    445 
    446 </script>
    447 </head>
    448 
    449 <body onLoad="start();">
    450 <canvas id="canvas" width="750" height="500"
    451     onmousemove="handleMouseOver()"
    452     onclick="handleMouseClick()"
    453     ></canvas >
    454 </body>
    455 </html>
    456