Commit bfce5d5d by Daniel Goldbach

Refactor isLeft out of clip-extent into trigonometry

parent e4af0902
 ... ... @@ -1176,6 +1176,12 @@ d3 = function() { function d3_sgn(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; } function d3_isCCWTurn(a, b, c) { return d3_cross2d(a, b, c) > 0; } function d3_cross2d(o, a, b) { return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]); } function d3_acos(x) { return x > 1 ? 0 : x < -1 ? π : Math.acos(x); } ... ... @@ -3114,18 +3120,15 @@ d3 = function() { for (var j = 1, v = polygon[i], m = v.length, a = v[0], b; j < m; ++j) { b = v[j]; if (a[1] <= y) { if (b[1] > y && isLeft(a, b, p) > 0) ++wn; if (b[1] > y && d3_isCCWTurn(a, b, p)) ++wn; } else { if (b[1] <= y && isLeft(a, b, p) < 0) --wn; if (b[1] <= y && !d3_isCCWTurn(a, b, p)) --wn; } a = b; } } return wn !== 0; } function isLeft(a, b, c) { return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]); } function interpolate(from, to, direction, listener) { var a = 0, a1 = 0; if (from == null || (a = corner(from, direction)) !== (a1 = corner(to, direction)) || comparePoints(from, to) < 0 ^ direction > 0) { ... ... @@ -4187,20 +4190,17 @@ d3 = function() { if (arguments.length) return hull(vertices); function hull(data) { if (data.length < 3) return []; var fx = d3_functor(x), fy = d3_functor(y), n = data.length, points = [], flipped_points = []; for (var i = 0; i < n; i++) { var fx = d3_functor(x), fy = d3_functor(y), i, n = data.length, points = [], flippedPoints = []; for (i = 0; i < n; i++) { points.push([ +fx.call(this, data[i], i), +fy.call(this, data[i], i), i ]); } points.sort(function(a, b) { return a[0] - b[0] || a[1] - b[1]; }); for (var i = 0; i < n; i++) flipped_points.push([ points[i][0], -points[i][1] ]); var uhull = d3_geom_hull_find_upper_hull(points); var lhull = d3_geom_hull_find_upper_hull(flipped_points); var skip_l = lhull[0] === uhull[0], skip_r = lhull[lhull.length - 1] === uhull[uhull.length - 1], poly = []; for (var i = uhull.length - 1; i >= 0; i--) poly.push(data[points[uhull[i]][2]]); for (var i = +skip_l; i < lhull.length - skip_r; i++) poly.push(data[points[lhull[i]][2]]); return poly; points.sort(d3_geom_hullOrder); for (i = 0; i < n; i++) flippedPoints.push([ points[i][0], -points[i][1] ]); var upper = d3_geom_hullUpper(points), lower = d3_geom_hullUpper(flippedPoints); var skipLeft = lower[0] === upper[0], skipRight = lower[lower.length - 1] === upper[upper.length - 1], polygon = []; for (i = upper.length - 1; i >= 0; --i) polygon.push(data[points[upper[i]][2]]); for (i = +skipLeft; i < lower.length - skipRight; ++i) polygon.push(data[points[lower[i]][2]]); return polygon; } hull.x = function(_) { return arguments.length ? (x = _, hull) : x; ... ... @@ -4210,18 +4210,18 @@ d3 = function() { }; return hull; }; function d3_geom_hull_find_upper_hull(points) { function d3_geom_hullUpper(points) { var n = points.length, hull = [ 0, 1 ], hs = 2; for (var i = 2; i < n; i++) { while (hs > 1 && !d3_geom_hull_CW(points[hull[hs - 2]], points[hull[hs - 1]], points[i])) { while (hs > 1 && d3_isCCWTurn(points[hull[hs - 2]], points[hull[hs - 1]], points[i])) { hs--; } hull[hs++] = i; } return hull.slice(0, hs); } function d3_geom_hull_CW(a, b, c) { return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]) > 0; function d3_geom_hullOrder(a, b) { return a[0] - b[0] || a[1] - b[1]; } d3.geom.polygon = function(coordinates) { d3_subclass(coordinates, d3_geom_polygonPrototype); ... ...
This source diff could not be displayed because it is too large. You can view the blob instead.
 ... ... @@ -79,9 +79,9 @@ function d3_geo_clipExtent(x0, y0, x1, y1) { for (var j = 1, v = polygon[i], m = v.length, a = v[0], b; j < m; ++j) { b = v[j]; if (a[1] <= y) { if (b[1] > y && isLeft(a, b, p) > 0) ++wn; if (b[1] > y && d3_isCCWTurn(a, b, p)) ++wn; } else { if (b[1] <= y && isLeft(a, b, p) < 0) --wn; if (b[1] <= y && !d3_isCCWTurn(a, b, p)) --wn; } a = b; } ... ... @@ -89,10 +89,6 @@ function d3_geo_clipExtent(x0, y0, x1, y1) { return wn !== 0; } function isLeft(a, b, c) { return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]); } function interpolate(from, to, direction, listener) { var a = 0, a1 = 0; if (from == null || ... ...
 import "../core/functor"; import "../math/trigonometry"; import "geom"; import "point"; ... ... @@ -10,8 +11,8 @@ import "point"; * The runtime of this algorithm is O(n log n), where n is the number of input * points. However in practice it outperforms other O(n log n) hulls. * * @param vertices [[x1, y1], [x2, y2], …] * @returns polygon [[x1, y1], [x2, y2], …] * @param vertices [[x1, y1], [x2, y2], ...] * @returns polygon [[x1, y1], [x2, y2], ...] */ d3.geom.hull = function(vertices) { var x = d3_geom_pointX, ... ... @@ -45,7 +46,7 @@ d3.geom.hull = function(vertices) { // construct the polygon, removing possible duplicate endpoints var skipLeft = lower[0] === upper[0], skipRight = lower[lower.length - 1] === upper[upper.length - 1]), skipRight = lower[lower.length - 1] === upper[upper.length - 1], polygon = []; for (i = upper.length - 1; i >= 0; --i) ... ... @@ -76,7 +77,7 @@ function d3_geom_hullUpper(points) { hs = 2; // hull size for (var i = 2; i < n; i++) { while (hs > 1 && !d3_geom_hull_CW(points[hull[hs-2]], points[hull[hs-1]], points[i])) { while (hs > 1 && !d3_isCCWTurn(points[hull[hs-2]], points[hull[hs-1]], points[i])) { hs --; } hull[hs++] = i; ... ... @@ -85,11 +86,5 @@ function d3_geom_hullUpper(points) { return hull.slice(0, hs); } // are three points a, b, c in clockwise order? // i.e. is the sign of (b-a)x(c-a) positive? function d3_geom_hull_CW(a, b, c) { return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]) > 0; } // comparator for ascending sort by x-coord first, y-coord second function d3_geom_hullOrder(a, b) { return a[0] - b[0] || a[1] - b[1]; }
 ... ... @@ -10,6 +10,22 @@ function d3_sgn(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; } // returns true iff the [x,y] points a, b, c form a counter-clockwise turn in // the traditional Cartesian coordinate system (i.e. x value grows from left // to right, y value grows from bottom to top) function d3_isCCWTurn(a, b, c) { return d3_cross2d(a, b, c) > 0; } // 2D cross product of OA and OB vectors, i.e. z-component of their 3D cross // product, in traditional Cartesian coordinate system (x value grows from // left to right, y value grows from bottom to top). Returns a positive value // if OAB makes a counter-clockwise turn, negative for clockwise turn, and // zero if the points are collinear. function d3_cross2d(o, a, b) { return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]); } function d3_acos(x) { return x > 1 ? 0 : x < -1 ? π : Math.acos(x); } ... ...
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment