Detect polygons surrounding clip extent.

Also, fix interpolation for points on the same clip edge that need
interpolating the long way around.
This commit is contained in:
Jason Davies 2013-03-07 23:03:56 +00:00
Родитель f1c8b090da
Коммит 5ed6583eee
4 изменённых файлов: 34 добавлений и 21 удалений

20
d3.js поставляемый
Просмотреть файл

@ -6174,7 +6174,7 @@ d3 = function() {
d3_geo_clipPolygonLinkCircular(subject); d3_geo_clipPolygonLinkCircular(subject);
d3_geo_clipPolygonLinkCircular(clip); d3_geo_clipPolygonLinkCircular(clip);
if (!subject.length) return; if (!subject.length) return;
if (inside) for (var i = 1, e = inside(clip[0].point), n = clip.length; i < n; ++i) { if (inside) for (var i = 1, e = !inside(clip[0].point), n = clip.length; i < n; ++i) {
clip[i].entry = e = !e; clip[i].entry = e = !e;
} }
var start = subject[0], current, points, point; var start = subject[0], current, points, point;
@ -6232,16 +6232,20 @@ d3 = function() {
}, },
polygonEnd: function() { polygonEnd: function() {
listener = listener_; listener = listener_;
if (segments.length) { if ((segments = d3.merge(segments)).length) {
listener.polygonStart(); listener.polygonStart();
d3_geo_clipPolygon(d3.merge(segments), compare, inside, interpolate, listener); d3_geo_clipPolygon(segments, compare, inside, interpolate, listener);
listener.polygonEnd(); listener.polygonEnd();
} else if (insidePolygon([ x0, y0 ])) {
listener.polygonStart(), listener.lineStart();
interpolate(null, null, 1, listener);
listener.lineEnd(), listener.polygonEnd();
} }
segments = polygon = ring = null; segments = polygon = ring = null;
} }
}; };
function inside(point) { function inside(point) {
var a = corner(point, -1), i = !insidePolygon([ a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0 ]); var a = corner(point, -1), i = insidePolygon([ a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0 ]);
return i; return i;
} }
function insidePolygon(p) { function insidePolygon(p) {
@ -6263,8 +6267,8 @@ d3 = function() {
return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]); return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]);
} }
function interpolate(from, to, direction, listener) { function interpolate(from, to, direction, listener) {
var a = corner(from, direction), a1 = corner(to, direction); var a = 0, a1 = 0;
if (a !== a1) { if (from == null || (a = corner(from, direction)) !== (a1 = corner(to, direction)) || comparePoints(from, to) < 0 ^ direction > 0) {
do { do {
listener.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0); listener.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0);
} while ((a = (a + direction + 4) % 4) !== a1); } while ((a = (a + direction + 4) % 4) !== a1);
@ -6326,7 +6330,9 @@ d3 = function() {
return Math.abs(p[0] - x0) < ε ? direction > 0 ? 0 : 3 : Math.abs(p[0] - x1) < ε ? direction > 0 ? 2 : 1 : Math.abs(p[1] - y0) < ε ? direction > 0 ? 1 : 0 : direction > 0 ? 3 : 2; return Math.abs(p[0] - x0) < ε ? direction > 0 ? 0 : 3 : Math.abs(p[0] - x1) < ε ? direction > 0 ? 2 : 1 : Math.abs(p[1] - y0) < ε ? direction > 0 ? 1 : 0 : direction > 0 ? 3 : 2;
} }
function compare(a, b) { function compare(a, b) {
a = a.point, b = b.point; return comparePoints(a.point, b.point);
}
function comparePoints(a, b) {
var ca = corner(a, 1), cb = corner(b, 1); var ca = corner(a, 1), cb = corner(b, 1);
return ca !== cb ? ca - cb : ca === 0 ? b[1] - a[1] : ca === 1 ? a[0] - b[0] : ca === 2 ? a[1] - b[1] : b[0] - a[0]; return ca !== cb ? ca - cb : ca === 0 ? b[1] - a[1] : ca === 1 ? a[0] - b[0] : ca === 2 ? a[1] - b[1] : b[0] - a[0];
} }

10
d3.min.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -36,8 +36,7 @@ function d3_geo_clipPolygon(segments, compare, inside, interpolate, listener) {
d3_geo_clipPolygonLinkCircular(clip); d3_geo_clipPolygonLinkCircular(clip);
if (!subject.length) return; if (!subject.length) return;
// TODO first entry should be computed using point-in-polygon. if (inside) for (var i = 1, e = !inside(clip[0].point), n = clip.length; i < n; ++i) {
if (inside) for (var i = 1, e = inside(clip[0].point), n = clip.length; i < n; ++i) {
clip[i].entry = (e = !e); clip[i].entry = (e = !e);
} }

Просмотреть файл

@ -17,10 +17,14 @@ function d3_geo_clipView(x0, y0, x1, y1) {
}, },
polygonEnd: function() { polygonEnd: function() {
listener = listener_; listener = listener_;
if (segments.length) { if ((segments = d3.merge(segments)).length) {
listener.polygonStart(); listener.polygonStart();
d3_geo_clipPolygon(d3.merge(segments), compare, inside, interpolate, listener); d3_geo_clipPolygon(segments, compare, inside, interpolate, listener);
listener.polygonEnd(); listener.polygonEnd();
} else if (insidePolygon([x0, y0])) {
listener.polygonStart(), listener.lineStart();
interpolate(null, null, 1, listener);
listener.lineEnd(), listener.polygonEnd();
} }
segments = polygon = ring = null; segments = polygon = ring = null;
} }
@ -28,7 +32,7 @@ function d3_geo_clipView(x0, y0, x1, y1) {
function inside(point) { function inside(point) {
var a = corner(point, -1), var a = corner(point, -1),
i = !insidePolygon([a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0]); i = insidePolygon([a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0]);
return i; return i;
} }
@ -56,9 +60,10 @@ function d3_geo_clipView(x0, y0, x1, y1) {
} }
function interpolate(from, to, direction, listener) { function interpolate(from, to, direction, listener) {
var a = corner(from, direction), var a = 0, a1 = 0;
a1 = corner(to, direction); if (from == null ||
if (a !== a1) { (a = corner(from, direction)) !== (a1 = corner(to, direction)) ||
comparePoints(from, to) < 0 ^ direction > 0) {
do { do {
listener.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0); listener.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0);
} while ((a = (a + direction + 4) % 4) !== a1); } while ((a = (a + direction + 4) % 4) !== a1);
@ -139,7 +144,10 @@ function d3_geo_clipView(x0, y0, x1, y1) {
} }
function compare(a, b) { function compare(a, b) {
a = a.point, b = b.point; return comparePoints(a.point, b.point);
}
function comparePoints(a, b) {
var ca = corner(a, 1), var ca = corner(a, 1),
cb = corner(b, 1); cb = corner(b, 1);
return ca !== cb ? ca - cb return ca !== cb ? ca - cb