Do not pre-calculate numeric values, count on optimizing JS engines to do that for us.

This commit is contained in:
Jürg Lehni 2013-05-24 17:14:23 -07:00
parent aac8bf83fd
commit ed572e7d48

View file

@ -73,8 +73,10 @@ paper.Curve.getIntersections2 = function(v1, v2, curve1, curve2, locations, _v1t
(Math.abs(v1t.t2 - v1t.t1) > TOLERANCE || Math.abs(v2t.t2 - v2t.t1) > TOLERANCE)) {
++iterate;
// First we clip v2 with v1's fat-line
tmpt.t1 = v2t.t1; tmpt.t2 = v2t.t2;
var intersects1 = _clipBezierFatLine(_v1, _v2, tmpt);
tmpt.t1 = v2t.t1;
tmpt.t2 = v2t.t2;
var intersects1 = _clipBezierFatLine(_v1, _v2, tmpt),
intersects2 = 0;
// Stop if there are no possible intersections
if (intersects1 === 0) {
return;
@ -86,7 +88,7 @@ paper.Curve.getIntersections2 = function(v1, v2, curve1, curve2, locations, _v1t
// markCurve(_v2, '#0ff', false);
// Next we clip v1 with nuv2's fat-line
tmpt.t1 = v1t.t1; tmpt.t2 = v1t.t2;
var intersects2 = _clipBezierFatLine(_v2, _v1, tmpt);
intersects2 = _clipBezierFatLine(_v2, _v1, tmpt);
// Stop if there are no possible intersections
if (intersects2 === 0) {
return;
@ -144,8 +146,8 @@ paper.Curve.getIntersections2 = function(v1, v2, curve1, curve2, locations, _v1t
locations.push(new CurveLocation(curve1, v1t.t1, curve1.getPointAt(v1t.t1, true), curve2));
return;
} else {
var curve1Flat = Curve.isFlatEnough(_v1, /*#=*/ TOLERANCE);
var curve2Flat = Curve.isFlatEnough(_v2, /*#=*/ TOLERANCE);
var curve1Flat = Curve.isFlatEnough(_v1, TOLERANCE);
var curve2Flat = Curve.isFlatEnough(_v2, TOLERANCE);
if (curve1Flat && curve2Flat) {
_getLineLineIntersection(_v1, _v2, curve1, curve2, locations);
return;
@ -178,13 +180,11 @@ function _clipBezierFatLine(v1, v2, v2t) {
var d2 = _getSignedDist(p0x, p0y, p3x, p3y, p2x, p2y) || 0;
var dmin, dmax;
if (d1 * d2 > 0) {
// 3/4 * min{0, d1, d2}
dmin = 0.75 * Math.min(0, d1, d2);
dmax = 0.75 * Math.max(0, d1, d2);
dmin = 3 / 4 * Math.min(0, d1, d2);
dmax = 3 / 4 * Math.max(0, d1, d2);
} else {
// 4/9 * min{0, d1, d2}
dmin = 0.4444444444444444 * Math.min(0, d1, d2);
dmax = 0.4444444444444444 * Math.max(0, d1, d2);
dmin = 4 / 9 * Math.min(0, d1, d2);
dmax = 4 / 9 * Math.max(0, d1, d2);
}
// Calculate non-parametric bezier curve D(ti, di(t)) -
// di(t) is the distance of Q from the baseline l of the fat-line,
@ -245,7 +245,7 @@ function _clipBezierFatLine(v1, v2, v2t) {
}
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))
// plotD_vs_t(500, 110, Dt, [dq0, dq1, dq2, dq3], v1, dmin, dmax, tmin, tmax, 1 / (tmax - tmin + 0.3))
// tmin and tmax are within the range (0, 1). We need to project it to the original
// parameter range for v2.
var v2tmin = v2t.t1;
@ -274,18 +274,18 @@ function _clipBezierFatLine(v1, v2, v2t) {
* much easier than a set of arbitrary points.
*/
function _convexhull(dq0, dq1, dq2, dq3) {
var distq1 = _getSignedDist(0.0, dq0, 1.0, dq3, 0.3333333333333333, dq1);
var distq2 = _getSignedDist(0.0, dq0, 1.0, dq3, 0.6666666666666666, dq2);
var distq1 = _getSignedDist(0, dq0, 1, dq3, 1 / 3, dq1);
var distq2 = _getSignedDist(0, dq0, 1, dq3, 2 / 3, 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) {
// dq1 and dq2 lie on different sides on [0, q0, 1, q3]
// Convexhull is a quadrilateral and line [0, q0, 1, q3] is NOT part of the convexhull
// so we are pretty much done here.
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 ]
[ 0, dq0, 1 / 3, dq1 ],
[ 1 / 3, dq1, 1, dq3 ],
[ 2 / 3, dq2, 0, dq0 ],
[ 1, dq3, 2 / 3, dq2 ]
];
} else {
// dq1 and dq2 lie on the same sides on [0, q0, 1, q3]
@ -297,30 +297,30 @@ function _convexhull(dq0, dq1, dq2, dq3) {
distq2 = Math.abs(distq2);
var vqa1a2x, vqa1a2y, vqa1Maxx, vqa1Maxy, vqa1Minx, vqa1Miny;
if (distq1 > distq2) {
dqmin = [ 0.6666666666666666, dq2 ];
dqmax = [ 0.3333333333333333, dq1 ];
dqmin = [ 2 / 3, dq2 ];
dqmax = [ 1 / 3, dq1 ];
// apex is dq3 and the other apex point is dq0
// vector dqapex->dqapex2 or the base vector which is already part of c-hull
vqa1a2x = 1.0;
vqa1a2x = 1;
vqa1a2y = dq3 - dq0;
// vector dqapex->dqmax
vqa1Maxx = 0.6666666666666666;
vqa1Maxx = 2 / 3;
vqa1Maxy = dq3 - dq1;
// vector dqapex->dqmin
vqa1Minx = 0.3333333333333333;
vqa1Minx = 1 / 3;
vqa1Miny = dq3 - dq2;
} else {
dqmin = [ 0.3333333333333333, dq1 ];
dqmax = [ 0.6666666666666666, dq2 ];
dqmin = [ 1 / 3, dq1 ];
dqmax = [ 2 / 3, dq2 ];
// apex is dq0 in this case, and the other apex point is dq3
// vector dqapex->dqapex2 or the base vector which is already part of c-hull
vqa1a2x = -1.0;
vqa1a2x = -1;
vqa1a2y = dq0 - dq3;
// vector dqapex->dqmax
vqa1Maxx = -0.6666666666666666;
vqa1Maxx = -2 / 3;
vqa1Maxy = dq0 - dq2;
// vector dqapex->dqmin
vqa1Minx = -0.3333333333333333;
vqa1Minx = -1 / 3;
vqa1Miny = dq0 - dq1;
}
// compare cross products of these vectors to determine, if
@ -330,18 +330,18 @@ function _convexhull(dq0, dq1, dq2, dq3) {
if (vcrossa1Max_a1Min * vcrossa1a2_a1Min < 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 ]
[ 0, dq0, dqmax[0], dqmax[1] ],
[ dqmax[0], dqmax[1], 1, dq3 ],
[ 1, dq3, 0, dq0 ]
];
} else {
// Convexhull is a quadrilateral and we need all lines in the correct order where
// line [0, q0, 1, q3] is part of the convex hull
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 ]
[ 0, dq0, 1 / 3, dq1 ],
[ 1 / 3, dq1, 2 / 3, dq2 ],
[ 2 / 3, dq2, 1, dq3 ],
[ 1, dq3, 0, dq0 ]
];
}
}
@ -408,8 +408,8 @@ var _getCurveLineIntersection = function(v1, v2, curve1, curve2, locations, _oth
var _getLineLineIntersection = function(v1, v2, curve1, curve2, locations) {
var point = Line.intersect(
v1[0], v1[1], v1[6], v1[7],
v2[0], v2[1], v2[6], v2[7], false);
v1[0], v1[1], v1[6], v1[7],
v2[0], v2[1], v2[6], v2[7], false);
if (point) {
// Avoid duplicates when hitting segments (closed paths too)
var first = locations[0],