Resolve some bad clipping

This commit is contained in:
hkrish 2013-05-19 16:22:15 +02:00
parent e6a98b4f18
commit 3a881e3a14
2 changed files with 167 additions and 159 deletions

View file

@ -200,8 +200,8 @@ function _clipBezierFatLine( v1, v2, v2t ){
if( dq3 < dq0 ){
tmp = dmin; dmin = dmax; dmax = tmp;
}
// Calculate the convex hull for non-parametric bezier curve D(ti, di(t))
var Dt = _convexhull( dq0, dq1, dq2, dq3 );
// Calculate the convex hull for non-parametric bezier curve D(ti, di(t))
// Now we clip the convex hulls for D(ti, di(t)) with dmin and dmax
// for the coorresponding t values (tmin, tmax):
// Portions of curve v2 before tmin and after tmax can safely be clipped away
@ -230,6 +230,14 @@ function _clipBezierFatLine( v1, v2, v2t ){
// Return the parameter values for v2 for which we can be sure that the
// intersection with v1 lies within.
if(tmin !== Infinity && tmax !== -Infinity){
var mindmin = Math.min(dmin, dmax);
var mindmax = Math.max(dmin, dmax);
if( dq3 > mindmin && dq3 < mindmax ){
tmax = 1;
}
if( dq0 > mindmin && dq0 < mindmax ){
tmin = 0;
}
if( tmaxdmin > tmax ){ tmax = 1; }
// Debug: Plot the non-parametric graph and hull
// plotD_vs_t( 500, 110, Dt, [dq0, dq1, dq2, dq3], v1, dmin, dmax, tmin, tmax, 1.0 / ( tmax - tmin + 0.3 ) )

View file

@ -46,32 +46,32 @@ function runTests() {
return caption;
}
// var caption = document.createElement('h3');
// caption.appendChild(document.createTextNode("Randomised tests (may take a while...)"));
// container.appendChild(caption);
// var canvas = document.createElement('CANVAS');
// container.appendChild( canvas );
// paper.setup( canvas );
// doRandomTests( randomtestdata );
// window.d = randomtestdata;
// container.removeChild( canvas );
var caption = document.createElement('h3');
caption.appendChild(document.createTextNode("Randomised tests (may take a while...)"));
container.appendChild(caption);
var canvas = document.createElement('CANVAS');
container.appendChild( canvas );
paper.setup( canvas );
doRandomTests( randomtestdata );
window.d = randomtestdata;
container.removeChild( canvas );
runTest('random', function(){
pathA = getRandomPath(5);
pathB = getRandomPath(5);
pathA = getRandomPath(10);
pathB = getRandomPath(10);
return [pathA, pathB];
});
// runTest('failcase 1', function(){
// group = paper.project.importSVG( document.getElementById( 'svgrandom1' ) );
// pathA = group.children[0];
// pathB = group.children[1];
// pathA.style = pathB.style = null;
// var np1 = new Path( [pathA.segments[0], pathA.segments[1]] );
// var np2 = new Path( [pathB.segments[0], pathB.segments[1]] );
// return [pathA, pathB];
// return [np1, np2];
// });
runTest('failcase 1', function(){
group = paper.project.importSVG( document.getElementById( 'svgrandom1' ) );
pathA = group.children[0];
pathB = group.children[1];
pathA.style = pathB.style = null;
var np1 = new Path( [pathA.segments[0], pathA.segments[1]] );
var np2 = new Path( [pathB.segments[0], pathB.segments[1]] );
return [pathA, pathB];
// return [np1, np2];
});
// runTest('failcase 2', function(){
// group = paper.project.importSVG( document.getElementById( 'svgrandom2' ) );
@ -84,162 +84,162 @@ function runTests() {
// return [np1, np2];
// });
// runTest('Overlapping circles', function(){
// pathA = new Path.Circle(new Point(80, 110), 50);
// pathB = new Path.Circle(new Point(150, 110), 70);
runTest('Overlapping circles', function(){
pathA = new Path.Circle(new Point(80, 110), 50);
pathB = new Path.Circle(new Point(150, 110), 70);
return [pathA, pathB];
});
// runTest('Polygon and square', function(){
// pathA = new Path.RegularPolygon(new Point(80, 110), 12, 80);
// pathB = new Path.Rectangle(new Point(100, 80), [80, 80] );
// return [pathA, pathB];
// });
// // runTest('Polygon and square', function(){
// // pathA = new Path.RegularPolygon(new Point(80, 110), 12, 80);
// // pathB = new Path.Rectangle(new Point(100, 80), [80, 80] );
// // return [pathA, pathB];
// // });
// // runTest('Circle and square (overlaps exactly on existing segments)', function(){
// // pathA = new Path.Circle(new Point(110, 110), 80);
// // pathB = new Path.Rectangle(new Point(110, 110), [80, 80] );
// // return [pathA, pathB];
// // });
// // runTest('Circle and square (existing segments overlaps on curves)', function(){
// // pathA = new Path.Circle(new Point(110, 110), 80);
// // pathB = new Path.Rectangle(new Point(110, 110), [100, 100] );
// // return [pathA, pathB];
// // });
// // runTest('Square and square (one segment overlaps on a line)', function(){
// // pathA = new Path.Rectangle(new Point(80, 125), [50, 50] );
// // pathA.rotate( 45 );
// // pathB = new Path.Rectangle(new Point(pathA.segments[2].point.x, 110), [80, 80] );
// // return [pathA, pathB];
// // });
// // runTest('Rectangle and rectangle (overlaps exactly on existing curves)', function(){
// // pathA = new Path.Rectangle(new Point(30.5, 50.5), [100, 150]);
// // pathB = new Path.Rectangle(new Point(130.5, 60.5), [100, 150]);
// // return [pathA, pathB];
// // });
// // runTest('Overlapping stars 1', function(){
// // pathA = new Path.Star(new Point(80, 110), 10, 20, 80);
// // pathB = new Path.Star(new Point(120, 110), 10, 30, 100);
// // return [pathA, pathB];
// // });
// // runTest('Overlapping stars 2', function(){
// // pathA = new Path.Star(new Point(110, 110), 20, 20, 80);
// // pathB = new Path.Star(new Point(110, 110), 6, 30, 100);
// // return [pathA, pathB];
// // });
// runTest('Circle and banana (multiple intersections within same curve segment)', function(){
// pathA = new Path.Circle(new Point(80, 110), 80);
// pathB = new Path.Circle(new Point(130, 110), 80 );
// pathB.segments[3].point = pathB.segments[3].point.add( [ 0, -120 ] );
// runTest('Circle and square (overlaps exactly on existing segments)', function(){
// pathA = new Path.Circle(new Point(110, 110), 80);
// pathB = new Path.Rectangle(new Point(110, 110), [80, 80] );
// return [pathA, pathB];
// });
// runTest('Maximum possible intersections between 2 cubic bezier curve segments - 9', function(){
// pathA = new Path();
// pathA.add( new Segment( [173, 44], [-281, 268], [-86, 152] ) );
// pathA.add( new Segment( [47, 93], [-89, 100], [240, -239] ) );
// pathA.closed = true;
// pathB = pathA.clone();
// pathB.rotate( -90 );
// pathA.translate( [-10,0] );
// pathB.translate( [10,0] );
// runTest('Circle and square (existing segments overlaps on curves)', function(){
// pathA = new Path.Circle(new Point(110, 110), 80);
// pathB = new Path.Rectangle(new Point(110, 110), [100, 100] );
// return [pathA, pathB];
// });
// runTest('SVG gears', function(){
// group = paper.project.importSVG( document.getElementById( 'svggears' ) );
// pathA = group.children[0];
// pathB = group.children[1];
// return [pathA, pathB];
// });
// runTest('Glyphs imported from SVG', function(){
// group = paper.project.importSVG( document.getElementById( 'glyphsys' ) );
// pathA = group.children[0];
// pathB = group.children[1];
// runTest('Square and square (one segment overlaps on a line)', function(){
// pathA = new Path.Rectangle(new Point(80, 125), [50, 50] );
// pathA.rotate( 45 );
// pathB = new Path.Rectangle(new Point(pathA.segments[2].point.x, 110), [80, 80] );
// return [pathA, pathB];
// });
// runTest('CompoundPaths 1', function(){
// group = paper.project.importSVG( document.getElementById( 'glyphsacirc' ) );
// pathA = group.children[0];
// pathB = group.children[1];
// runTest('Rectangle and rectangle (overlaps exactly on existing curves)', function(){
// pathA = new Path.Rectangle(new Point(30.5, 50.5), [100, 150]);
// pathB = new Path.Rectangle(new Point(130.5, 60.5), [100, 150]);
// return [pathA, pathB];
// });
// runTest('CompoundPaths 2 - holes', function(){
// group = paper.project.importSVG( document.getElementById( 'glyphsacirc' ) );
// pathA = group.children[0];
// runTest('Overlapping stars 1', function(){
// pathA = new Path.Star(new Point(80, 110), 10, 20, 80);
// pathB = new Path.Star(new Point(120, 110), 10, 30, 100);
// return [pathA, pathB];
// });
// runTest('Overlapping stars 2', function(){
// pathA = new Path.Star(new Point(110, 110), 20, 20, 80);
// pathB = new Path.Star(new Point(110, 110), 6, 30, 100);
// return [pathA, pathB];
// });
runTest('Circle and banana (multiple intersections within same curve segment)', function(){
pathA = new Path.Circle(new Point(80, 110), 80);
pathB = new Path.Circle(new Point(130, 110), 80 );
pathB.segments[3].point = pathB.segments[3].point.add( [ 0, -120 ] );
return [pathA, pathB];
});
runTest('Maximum possible intersections between 2 cubic bezier curve segments - 9', function(){
pathA = new Path();
pathA.add( new Segment( [173, 44], [-281, 268], [-86, 152] ) );
pathA.add( new Segment( [47, 93], [-89, 100], [240, -239] ) );
pathA.closed = true;
pathB = pathA.clone();
pathB.rotate( -90 );
pathA.translate( [-10,0] );
pathB.translate( [10,0] );
return [pathA, pathB];
});
runTest('SVG gears', function(){
group = paper.project.importSVG( document.getElementById( 'svggears' ) );
pathA = group.children[0];
pathB = group.children[1];
return [pathA, pathB];
});
runTest('Glyphs imported from SVG', function(){
group = paper.project.importSVG( document.getElementById( 'glyphsys' ) );
pathA = group.children[0];
pathB = group.children[1];
return [pathA, pathB];
});
runTest('CompoundPaths 1', function(){
group = paper.project.importSVG( document.getElementById( 'glyphsacirc' ) );
pathA = group.children[0];
pathB = group.children[1];
return [pathA, pathB];
});
runTest('CompoundPaths 2 - holes', function(){
group = paper.project.importSVG( document.getElementById( 'glyphsacirc' ) );
pathA = group.children[0];
pathB = new CompoundPath();
group.children[1].clockwise = true;
pathB.addChild(group.children[1]);
var npath = new Path.Circle([110, 110], 30);
pathB.addChild( npath );
return [pathA, pathB];
});
runTest('CompoundPaths 3 !', function(){
group = paper.project.importSVG( document.getElementById( 'svggreenland' ) );
pathA = group.children[0];
pathB = group.children[1];
pathB.scale( 0.5, 1 ).translate( [25.5, 0] );
// pathA.scale( 2 );
// pathB.scale( 2 );
return [pathA, pathB];
});
runTest('CompoundPaths 4 - holes and islands 1', function(){
group = paper.project.importSVG( document.getElementById( 'glyphsacirc' ) );
pathA = group.children[0];
pathB = new CompoundPath();
group.children[1].clockwise = true;
pathB.addChild(group.children[1]);
var npath = new Path.Circle([40, 80], 20);
pathB.addChild( npath );
return [pathA, pathB];
});
runTest('CompoundPaths 5 - holes and islands 2', function(){
group = paper.project.importSVG( document.getElementById( 'glyphsacirc' ) );
pathA = group.children[0];
pathB = new CompoundPath();
group.children[1].clockwise = true;
pathB.addChild(group.children[1]);
var npath = new Path.Circle([40, 80], 20);
pathB.addChild( npath );
npath = new Path.Circle([120, 110], 30);
pathB.addChild( npath );
return [pathA, pathB];
});
runTest('CompoundPaths 6 - holes and islands 3', function(){
group = paper.project.importSVG( document.getElementById( 'glyphsacirc' ) );
pathA = group.children[0];
pathB = new CompoundPath();
var npath = new Path.Circle([110, 110], 100);
pathB.addChild( npath );
npath = new Path.Circle([110, 110], 60);
pathB.addChild( npath );
npath = new Path.Circle([110, 110], 30);
pathB.addChild( npath );
return [pathA, pathB];
});
// runTest('CompoundPaths 6 - holes and islands 4 (curves overlap exactly on existing curves)', function(){
// pathA = new Path.Rectangle(new Point(50.5, 50.5), [100, 120]);
// pathB = new CompoundPath();
// group.children[1].clockwise = true;
// pathB.addChild(group.children[1]);
// var npath = new Path.Circle([110, 110], 30);
// pathB.addChild( npath );
// pathB.addChild( new Path.Rectangle(new Point(140.5, 30.5), [100, 150]) );
// pathB.addChild( new Path.Rectangle(new Point(150.5, 65.5), [50, 100]) );
// // pathB = new Path.Rectangle(new Point(150.5, 80.5), [80, 80] );
// return [pathA, pathB];
// });
// runTest('CompoundPaths 3 !', function(){
// group = paper.project.importSVG( document.getElementById( 'svggreenland' ) );
// pathA = group.children[0];
// pathB = group.children[1];
// pathB.scale( 0.5, 1 ).translate( [25.5, 0] );
// // pathA.scale( 2 );
// // pathB.scale( 2 );
// return [pathA, pathB];
// });
// runTest('CompoundPaths 4 - holes and islands 1', function(){
// group = paper.project.importSVG( document.getElementById( 'glyphsacirc' ) );
// pathA = group.children[0];
// pathB = new CompoundPath();
// group.children[1].clockwise = true;
// pathB.addChild(group.children[1]);
// var npath = new Path.Circle([40, 80], 20);
// pathB.addChild( npath );
// return [pathA, pathB];
// });
// runTest('CompoundPaths 5 - holes and islands 2', function(){
// group = paper.project.importSVG( document.getElementById( 'glyphsacirc' ) );
// pathA = group.children[0];
// pathB = new CompoundPath();
// group.children[1].clockwise = true;
// pathB.addChild(group.children[1]);
// var npath = new Path.Circle([40, 80], 20);
// pathB.addChild( npath );
// npath = new Path.Circle([120, 110], 30);
// pathB.addChild( npath );
// return [pathA, pathB];
// });
// runTest('CompoundPaths 6 - holes and islands 3', function(){
// group = paper.project.importSVG( document.getElementById( 'glyphsacirc' ) );
// pathA = group.children[0];
// pathB = new CompoundPath();
// var npath = new Path.Circle([110, 110], 100);
// pathB.addChild( npath );
// npath = new Path.Circle([110, 110], 60);
// pathB.addChild( npath );
// npath = new Path.Circle([110, 110], 30);
// pathB.addChild( npath );
// return [pathA, pathB];
// });
// // runTest('CompoundPaths 6 - holes and islands 4 (curves overlap exactly on existing curves)', function(){
// // pathA = new Path.Rectangle(new Point(50.5, 50.5), [100, 120]);
// // pathB = new CompoundPath();
// // pathB.addChild( new Path.Rectangle(new Point(140.5, 30.5), [100, 150]) );
// // pathB.addChild( new Path.Rectangle(new Point(150.5, 65.5), [50, 100]) );
// // // pathB = new Path.Rectangle(new Point(150.5, 80.5), [80, 80] );
// // return [pathA, pathB];
// // });
// Plot the run times
function plotData(){