source: node_modules/d3-shape/src/curve/monotone.js@ e4c61dd

Last change on this file since e4c61dd was e4c61dd, checked in by istevanoska <ilinastevanoska@…>, 6 months ago

Prototype 1.1

  • Property mode set to 100644
File size: 3.1 KB
Line 
1function sign(x) {
2 return x < 0 ? -1 : 1;
3}
4
5// Calculate the slopes of the tangents (Hermite-type interpolation) based on
6// the following paper: Steffen, M. 1990. A Simple Method for Monotonic
7// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.
8// NOV(II), P. 443, 1990.
9function slope3(that, x2, y2) {
10 var h0 = that._x1 - that._x0,
11 h1 = x2 - that._x1,
12 s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),
13 s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),
14 p = (s0 * h1 + s1 * h0) / (h0 + h1);
15 return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;
16}
17
18// Calculate a one-sided slope.
19function slope2(that, t) {
20 var h = that._x1 - that._x0;
21 return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;
22}
23
24// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations
25// "you can express cubic Hermite interpolation in terms of cubic Bézier curves
26// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1".
27function point(that, t0, t1) {
28 var x0 = that._x0,
29 y0 = that._y0,
30 x1 = that._x1,
31 y1 = that._y1,
32 dx = (x1 - x0) / 3;
33 that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);
34}
35
36function MonotoneX(context) {
37 this._context = context;
38}
39
40MonotoneX.prototype = {
41 areaStart: function() {
42 this._line = 0;
43 },
44 areaEnd: function() {
45 this._line = NaN;
46 },
47 lineStart: function() {
48 this._x0 = this._x1 =
49 this._y0 = this._y1 =
50 this._t0 = NaN;
51 this._point = 0;
52 },
53 lineEnd: function() {
54 switch (this._point) {
55 case 2: this._context.lineTo(this._x1, this._y1); break;
56 case 3: point(this, this._t0, slope2(this, this._t0)); break;
57 }
58 if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
59 this._line = 1 - this._line;
60 },
61 point: function(x, y) {
62 var t1 = NaN;
63
64 x = +x, y = +y;
65 if (x === this._x1 && y === this._y1) return; // Ignore coincident points.
66 switch (this._point) {
67 case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
68 case 1: this._point = 2; break;
69 case 2: this._point = 3; point(this, slope2(this, t1 = slope3(this, x, y)), t1); break;
70 default: point(this, this._t0, t1 = slope3(this, x, y)); break;
71 }
72
73 this._x0 = this._x1, this._x1 = x;
74 this._y0 = this._y1, this._y1 = y;
75 this._t0 = t1;
76 }
77}
78
79function MonotoneY(context) {
80 this._context = new ReflectContext(context);
81}
82
83(MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {
84 MonotoneX.prototype.point.call(this, y, x);
85};
86
87function ReflectContext(context) {
88 this._context = context;
89}
90
91ReflectContext.prototype = {
92 moveTo: function(x, y) { this._context.moveTo(y, x); },
93 closePath: function() { this._context.closePath(); },
94 lineTo: function(x, y) { this._context.lineTo(y, x); },
95 bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }
96};
97
98export function monotoneX(context) {
99 return new MonotoneX(context);
100}
101
102export function monotoneY(context) {
103 return new MonotoneY(context);
104}
Note: See TracBrowser for help on using the repository browser.