Skip to content

Commit 4a40fc7

Browse files
committed
add findPointOnPath geometry2d util function
- to be used to find pt on violin bezier curves
1 parent ad51966 commit 4a40fc7

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

src/lib/geometry2d.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,52 @@ exports.getVisibleSegment = function getVisibleSegment(path, bounds, buffer) {
193193
Math.abs(pt0.y - ptTotal.y) < 0.1
194194
};
195195
};
196+
197+
/**
198+
* Find point on SVG path corresponding to a given constraint coordinate
199+
*
200+
* @param {SVGPathElement} path
201+
* @param {Number} val : constraint coordinate value
202+
* @param {String} coord : 'x' or 'y' the constraint coordinate
203+
* @param {Object} opts :
204+
* - {Number} pathLength : supply total path length before hand
205+
* - {Number} tolerance
206+
* - {Number} iterationLimit
207+
* @return {SVGPoint}
208+
*/
209+
exports.findPointOnPath = function findPointOnPath(path, val, coord, opts) {
210+
opts = opts || {};
211+
212+
var pathLength = opts.pathLength || path.getTotalLength();
213+
var tolerance = opts.tolerance || 1e-3;
214+
var iterationLimit = opts.iterationLimit || 30;
215+
216+
// if path starts at a val greater than the path tail (like on vertical violins),
217+
// we must flip the sign of the compute diff.
218+
var mul = path.getPointAtLength(0)[coord] > path.getPointAtLength(pathLength)[coord] ? -1 : 1;
219+
220+
var i = 0;
221+
var b0 = 0;
222+
var b1 = pathLength;
223+
var mid;
224+
var pt;
225+
var diff;
226+
227+
while(i < iterationLimit) {
228+
mid = (b0 + b1) / 2;
229+
pt = path.getPointAtLength(mid);
230+
diff = pt[coord] - val;
231+
232+
if(Math.abs(diff) < tolerance) {
233+
return pt;
234+
} else {
235+
if(mul * diff > 0) {
236+
b1 = mid;
237+
} else {
238+
b0 = mid;
239+
}
240+
i++;
241+
}
242+
}
243+
return pt;
244+
};

src/lib/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ lib.segmentDistance = geom2dModule.segmentDistance;
8282
lib.getTextLocation = geom2dModule.getTextLocation;
8383
lib.clearLocationCache = geom2dModule.clearLocationCache;
8484
lib.getVisibleSegment = geom2dModule.getVisibleSegment;
85+
lib.findPointOnPath = geom2dModule.findPointOnPath;
8586

8687
var extendModule = require('./extend');
8788
lib.extendFlat = extendModule.extendFlat;

0 commit comments

Comments
 (0)