Skip to content

Commit

Permalink
Fix monotone bug with infinite slope.
Browse files Browse the repository at this point in the history
If the change in X was zero, the sign of infinity was lost. Now we use the sign
from the other side to compute the correct infinity.
  • Loading branch information
mbostock committed Jan 28, 2016
1 parent 510357d commit cb15448
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/curve/monotone.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ function sign(x) {
function slope3(that, x2, y2) {
var h0 = that._x1 - that._x0,
h1 = x2 - that._x1,
s0 = (that._y1 - that._y0) / h0,
s1 = (y2 - that._y1) / h1,
s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),
s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),
p = (s0 * h1 + s1 * h0) / (h0 + h1);
return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;
}
Expand Down
7 changes: 7 additions & 0 deletions test/curve/monotoneX-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ tape("line.curve(curveMonotoneX)(data) handles duplicate x-values", function(tes
test.end();
});

tape("line.curve(curveMonotoneX)(data) handles segments of infinite slope", function(test) {
var l = shape.line().curve(shape.curveMonotoneX);
test.pathEqual(l([[0, 200], [100, 150], [100, 50], [200, 0]]), "M0,200C33.333333,191.666667,66.666667,183.333333,100,150C100,150,100,50,100,50C133.333333,16.666667,166.666667,8.333333,200,0");
test.pathEqual(l([[200, 0], [100, 50], [100, 150], [0, 200]]), "M200,0C166.666667,8.333333,133.333333,16.666667,100,50C100,50,100,150,100,150C66.666667,183.333333,33.333333,191.666667,0,200");
test.end();
});

tape("line.curve(curveMonotoneX)(data) ignores coincident points", function(test) {
var l = shape.line().curve(shape.curveMonotoneX),
p = l([[0, 200], [50, 200], [100, 100], [150, 0], [200, 0]]);
Expand Down
7 changes: 7 additions & 0 deletions test/curve/monotoneY-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ tape("line.curve(curveMonotoneY)(data) handles duplicate x-values", function(tes
test.end();
});

tape("line.curve(curveMonotoneY)(data) handles segments of infinite slope", function(test) {
var l = shape.line().curve(shape.curveMonotoneY);
test.pathEqual(l([[0, 200], [100, 150], [100, 50], [200, 0]].map(reflect)), "M200,0C191.666667,33.333333,183.333333,66.666667,150,100C150,100,50,100,50,100C16.666667,133.333333,8.333333,166.666667,0,200");
test.pathEqual(l([[200, 0], [100, 50], [100, 150], [0, 200]].map(reflect)), "M0,200C8.333333,166.666667,16.666667,133.333333,50,100C50,100,150,100,150,100C183.333333,66.666667,191.666667,33.333333,200,0");
test.end();
});

tape("line.curve(curveMonotoneY)(data) ignores coincident points", function(test) {
var l = shape.line().curve(shape.curveMonotoneY),
p = l([[0, 200], [50, 200], [100, 100], [150, 0], [200, 0]].map(reflect));
Expand Down

0 comments on commit cb15448

Please sign in to comment.