Simplify convex hull algorithm by returning lists of points rather than lines.

We can avoid some data redundancy that way at no performance cost.
This commit is contained in:
Jürg Lehni 2013-05-26 17:18:54 -07:00
parent 9540b7f6a9
commit 9edab9c3aa

View file

@ -1218,7 +1218,7 @@ new function() { // Scope for methods that require numerical integration
// If the fatlines don't overlap, we have no intersections! // If the fatlines don't overlap, we have no intersections!
if (dmin > maxdist || dmax < mindist) if (dmin > maxdist || dmax < mindist)
return 0; return 0;
var Dt = getConvexHull(dq0, dq1, dq2, dq3), var hull = getConvexHull(dq0, dq1, dq2, dq3),
tmp; tmp;
if (dq3 < dq0) { if (dq3 < dq0) {
tmp = dmin; tmp = dmin;
@ -1232,31 +1232,29 @@ new function() { // Scope for methods that require numerical integration
var tmaxdmin = -Infinity, var tmaxdmin = -Infinity,
tmin = Infinity, tmin = Infinity,
tmax = -Infinity; tmax = -Infinity;
for (var i = 0, l = Dt.length; i < l; i++) { for (var i = 0, l = hull.length; i < l; i++) {
var Dtl = Dt[i], var p1 = hull[i],
dtlx1 = Dtl[0], p2 = hull[(i + 1) % l];
dtly1 = Dtl[1], if (p2[1] < p1[1]) {
dtlx2 = Dtl[2], tmp = p2;
dtly2 = Dtl[3]; p2 = p1;
if (dtly2 < dtly1) { p1 = tmp;
tmp = dtly2;
dtly2 = dtly1;
dtly1 = tmp;
tmp = dtlx2;
dtlx2 = dtlx1;
dtlx1 = tmp;
} }
// We know that (dtlx2 - dtlx1) is never 0 var x1 = p1[0],
var inv = (dtly2 - dtly1) / (dtlx2 - dtlx1); y1 = p1[1],
if (dmin >= dtly1 && dmin <= dtly2) { x2 = p2[0],
var ixdx = dtlx1 + (dmin - dtly1) / inv; y2 = p2[1];
// We know that (x2 - x1) is never 0
var inv = (y2 - y1) / (x2 - x1);
if (dmin >= y1 && dmin <= y2) {
var ixdx = x1 + (dmin - y1) / inv;
if (ixdx < tmin) if (ixdx < tmin)
tmin = ixdx; tmin = ixdx;
if (ixdx > tmaxdmin) if (ixdx > tmaxdmin)
tmaxdmin = ixdx; tmaxdmin = ixdx;
} }
if (dmax >= dtly1 && dmax <= dtly2) { if (dmax >= y1 && dmax <= y2) {
var ixdx = dtlx1 + (dmax - dtly1) / inv; var ixdx = x1 + (dmax - y1) / inv;
if (ixdx > tmax) if (ixdx > tmax)
tmax = ixdx; tmax = ixdx;
if (ixdx < tmin) if (ixdx < tmin)
@ -1311,10 +1309,10 @@ new function() { // Scope for methods that require numerical integration
// a quadrilateral and line [0, q0, 1, q3] is NOT part of the hull // a quadrilateral and line [0, q0, 1, q3] is NOT part of the hull
// so we are pretty much done here. // so we are pretty much done here.
return [ return [
[ 0, dq0, 1 / 3, dq1 ], [ 2 / 3, dq2 ],
[ 1 / 3, dq1, 1, dq3 ], [ 0, dq0 ],
[ 2 / 3, dq2, 0, dq0 ], [ 1 / 3, dq1 ],
[ 1, dq3, 2 / 3, dq2 ] [ 1, dq3 ]
]; ];
} }
// dq1 and dq2 lie on the same sides on [0, q0, 1, q3]. The hull can be // dq1 and dq2 lie on the same sides on [0, q0, 1, q3]. The hull can be
@ -1350,22 +1348,21 @@ new function() { // Scope for methods that require numerical integration
} }
// Compare cross products of these vectors to determine, if // Compare cross products of these vectors to determine, if
// point is in triangles [ dq3, dqMax, dq0 ] or [ dq0, dqMax, dq3 ] // point is in triangles [ dq3, dqMax, dq0 ] or [ dq0, dqMax, dq3 ]
var a1a2_a1Min = vqa1a2X * vqa1MinY - vqa1a2Y * vqa1MinX, return (vqa1a2X * vqa1MinY - vqa1a2Y * vqa1MinX)
a1Max_a1Min = vqa1MaxX * vqa1MinY - vqa1MaxY * vqa1MinX; * (vqa1MaxX * vqa1MinY - vqa1MaxY * vqa1MinX) < 0
return a1a2_a1Min * a1Max_a1Min < 0
// Point [2/3, dq2] is inside the triangle, hull is a triangle. // Point [2/3, dq2] is inside the triangle, hull is a triangle.
? [ ? [
[ 0, dq0, dqMaxX, dqMaxY ], [ 0, dq0 ],
[ dqMaxX, dqMaxY, 1, dq3 ], [ dqMaxX, dqMaxY ],
[ 1, dq3, 0, dq0 ] [ 1, dq3 ]
] ]
// Convexhull is a quadrilateral and we need all lines in the // Convexhull is a quadrilateral and we need all lines in the
// correct order where line [0, q0, 1, q3] is part of the hull. // correct order where line [0, q0, 1, q3] is part of the hull.
: [ : [
[ 0, dq0, 1 / 3, dq1 ], [ 0, dq0 ],
[ 1 / 3, dq1, 2 / 3, dq2 ], [ 1 / 3, dq1 ],
[ 2 / 3, dq2, 1, dq3 ], [ 2 / 3, dq2 ],
[ 1, dq3, 0, dq0 ] [ 1, dq3 ]
]; ];
} }
/*#*/ } // options.fatline /*#*/ } // options.fatline