diff --git a/fatline/intersectTests.js b/fatline/intersectTests.js index 29e0d4c9..436c4274 100644 --- a/fatline/intersectTests.js +++ b/fatline/intersectTests.js @@ -13,9 +13,9 @@ function runTests() { // pathA.rotate( 45 ); pathB = new Path.Circle(new Point(160, 110), 50); // pathB.rotate( 45 ); - pathB.segments[3].point = pathB.segments[3].point.add( [10, -120] ); - pathB.segments[0].handleIn = pathB.segments[0].handleIn.add( [-100, 0] ); - // pathB.translate( [ 50, -20 ] ); + // pathB.segments[3].point = pathB.segments[3].point.add( [10, -120] ); + // pathB.segments[0].handleIn = pathB.segments[0].handleIn.add( [-100, 0] ); + pathB.translate( [ -20, -10 ] ); // testIntersection( pathA, pathB, caption ); window.a = pathA; @@ -24,7 +24,7 @@ function runTests() { var _p1U = new Path( pathA.segments[1], pathA.segments[2] ); // var _p1U = new Path( pathA.segments[1], pathA.segments[2] ); // _p1U.reverse(); - var _p2U = new Path( pathB.segments[3], pathB.segments[0] ); + var _p2U = new Path( pathB.segments[0], pathB.segments[1] ); _p1U.style = _p2U.style = pathStyleBoolean; var crvs = _p2U.curves; // for (var i = 0; i < crvs.length; i++) { @@ -32,13 +32,13 @@ function runTests() { drawFatline( crvs[0].getValues() ); // } - var maxCount = 1000, count = maxCount, loc, loc2; + var maxCount = 1, count = maxCount, loc, loc2; var v1 = crvs[0].getValues(), v2 = _p1U.curves[0].getValues(); console.time('fatline'); while( count-- ){ loc = []; - Curve.getIntersections2( v1, v2, crvs[0], _p1U.curves[0], loc ); - // var ret = _clipFatLine( v2, v1, 0, 1, 0, 1, 1, 1, true, crvs[0], _p1U.curves[0], loc ); + // Curve.getIntersections2( v1, v2, crvs[0], _p1U.curves[0], loc ); + var ret = _clipFatLine( v1, v2, 0, 1, 0, 1, 1, 1, true, crvs[0], _p1U.curves[0], loc ); } console.timeEnd('fatline'); @@ -62,6 +62,9 @@ function runTests() { console.log( 'paperjs t = ' + loc2[i].getIntersection().parameter ); } + + convexhull( 20, 20 , 30 , -20 ); + view.draw(); @@ -140,6 +143,92 @@ function markIntersections( ixs ){ } } +function convexhull( dq0, dq1, dq2, dq3 ){ + // Prepare the convex hull for D(ti, di(t)) + var distq1 = _getSignedDist( 0.0, dq0, 1.0, dq3, 0.3333333333333333, dq1 ); + var distq2 = _getSignedDist( 0.0, dq0, 1.0, dq3, 0.6666666666666666, dq2 ); + // Check if [1/3, dq1] and [2/3, dq2] are on the same side of line [0,dq0, 1,dq3] + if( distq1 * distq2 < 0 ) { + Dt = [ + [ 0.0, dq0, 0.3333333333333333, dq1 ], + [ 0.3333333333333333, dq1, 1.0, dq3 ], + [ 0.6666666666666666, dq2, 0.0, dq0 ], + [ 1.0, dq3, 0.6666666666666666, dq2 ] + ]; + } else { + // Check if the hull is a triangle or a quadrilatteral + var dqmin, dqmax, dqapex1, dqapex2; + distq1 = Math.abs(distq1); + distq2 = Math.abs(distq2); + if( distq1 > distq2 ){ + dqapex1 = dq3; + dqapex2 = dq0; + dqmin = [ 0.6666666666666666, dq2 ]; + dqmax = [ 0.3333333333333333, dq1 ]; + } else { + dqapex1 = dq0; + dqapex2 = dq3; + dqmin = [ 0.3333333333333333, dq1 ]; + dqmax = [ 0.6666666666666666, dq2 ]; + } + // vector dq3->dq0 + var vq30x = 1.0, vq30y = dq3 - dq1; + // vector dq3->dqmax + var vq3Maxx = 1 - dqmax[0], vq3Maxy = dq3 - dqmax[1]; + // vector dq3->dqmin + var vq3Minx = 1 - dqmin[0], vq3Miny = dq3 - dqmin[1]; + // vector dq0->dq3 + var vq03x = -vq30x, vq03y = -vq30y; + // vector dq0->dqmax + var vq0Maxx = -dqmax[0], vq0Maxy = dq0 - dqmax[1]; + // vector dq0->dqmin + var vq0Minx = -dqmin[0], vq0Miny = dq0 - dqmin[1]; + // compare cross products of these vectors to determine, if + // point is in triangles [ dq3, dqMax, dq0 ] or [ dq0, dqMax, dq3 ] + var vcross303Max = vq30x * vq3Maxy - vq30y * vq3Maxx; + var vcross3Max3Min = vq3Maxx * vq3Miny - vq3Maxy * vq3Minx; + var vcross030Max = vq03x * vq0Maxy - vq03y * vq0Maxx; + var vcross0Max0Min = vq0Maxx * vq0Miny - vq0Maxy * vq0Minx; + if(( ( distq1 > distq2 ) && vcross303Max * vcross3Max3Min < 0) || (( distq1 <= distq2 ) && vcross030Max * vcross0Max0Min < 0)){ + // Point [2/3, dq2] is inside the triangle and the convex hull is a triangle + Dt = [ + [ 0.0, dq0, dqmax[0], dqmax[1] ], + [ dqmax[0], dqmax[1], 1.0, dq3 ], + [ 1.0, dq3, 0.0, dq0 ] + ]; + } else { + // Convexhull is a quadrilatteral and we need all lines in the correct order + Dt = [ + [ 0.0, dq0, 0.3333333333333333, dq1 ], + [ 0.3333333333333333, dq1, 0.6666666666666666, dq2 ], + [ 0.6666666666666666, dq2, 1.0, dq3 ], + [ 1.0, dq3, 0.0, dq0 ] + ]; + } + } + Dt2 = [ + [ 0.0, dq0, 0.3333333333333333, dq1 ], + [ 0.3333333333333333, dq1, 0.6666666666666666, dq2 ], + [ 0.6666666666666666, dq2, 1.0, dq3 ], + [ 1.0, dq3, 0.0, dq0 ] + ]; + var yscale = 2; + var x = 500, y = 110; + for (var i = 0; i < Dt.length; i++) { + var pth = new Path.Line( new Point( x + Dt[i][0] * 190, y + Dt[i][1] * yscale ), + new Point( x + Dt[i][2] * 190, y + Dt[i][3] * yscale ) ); + pth.style.strokeColor = '#999'; + } + var pnt = []; + for ( i = 0; i < Dt2.length; i++) { + pnt.push( new Point( x + Dt2[i][0] * 190, y + Dt2[i][1] * yscale ) ); + markPoint( pnt[i], " " ); + } + new Path( new Segment(pnt[0], null, pnt[1].subtract(pnt[0])), new Segment( pnt[3], pnt[2].subtract(pnt[3]), null ) ).style.strokeColor = '#f00'; + + return Dt; +} + // ============================================================== // On screen debug helpers function markPoint( pnt, t, c, tc, remove ) {