As referenced here and updated for use with Snap.svg here, I'd like to better understand how the provided gradSearch function actually works (it's a bit over my head), and whether there are any good alternatives to this approach?
gradSearch = function (l0, pt) {
l0 = l0 + totLen;
var l1 = l0,
dist0 = dist(path.getPointAtLength(l0 % totLen), pt),
dist1,
searchDir;
if (dist(path.getPointAtLength((l0 - searchDl) % totLen), pt) >
dist(path.getPointAtLength((l0 + searchDl) % totLen), pt)) {
searchDir = searchDl;
} else {
searchDir = -searchDl;
}
l1 += searchDir;
dist1 = dist(path.getPointAtLength(l1 % totLen), pt);
while (dist1 < dist0) {
dist0 = dist1;
l1 += searchDir;
dist1 = dist(path.getPointAtLength(l1 % totLen), pt);
}
l1 -= searchDir;
return (l1 % totLen);
}
Took me a while to understand the code, but this is how I understand it to be working (trying to keep the explanation simplified):
First the position of the draggable object on the path is recorded as l0
(Note that this is L0
, easy to confuse with the number 10 when first looking at the code).
The distance from the new point (where mouse has dragged to) to the position on the path is recorded as dist0
.
The if
statement then determines which direction to drag in. It does this by adding searchDl
value to the path position (i.e. length along the path), and subtracting the same value and seeing which is closer to the mouse position.
Once it knows which direction to move in, it uses the while
loop to keep adding/subtracting the position by the searchDl
size until the distance between the point on the path and the position of the mouse is as low as it can get.
It then returns the new position on the path.
By changing searchDir
to a larger value you can move in larger increments and it can calculate faster at the expense of precision (If I've understood the code correctly).