- 总路径长度:SVG API:
path.getTotalLength()
- 沿路径的长度:SVG API:
path.getPointAtLength(...),您可能希望基于总长度
- 一个点的曲率半径:API 中没有烘焙,因此您将不得不通过简单地将一个圆拟合到您的点以及它之前和之后的点来滚动自己。
我们构造三个点:
var p1 = path.getPointAtLength(n - e),
p2 = path.getPointAtLength(n),
p3 = path.getPointAtLength(n + e);
e 是一个很小的值。然后,我们知道通过所有三个点的圆在圆上的每个点都具有相同的距离(显然),并且我们还知道如果我们在点之间构造和弦,那么通过这些弦的中心的线(垂直于它们)将在圆的中心相交。
这就是通过任意三个点找到圆的方法:我们需要找到和弦p1--p2 和p2--p3,找到它们的中点,通过这些中点构造一些垂直于每个弦的线,然后它们的交点就是我们圈子的中心,我们就完成了。我们将知道原点的曲率半径。所以:
// chords p1--p2 and p2--p3
var dx1 = (p2.x - p1.x), dy1 = (p2.y - p1.y),
dx2 = (p3.x - p2.x), dy2 = (p3.y - p2.y);
// chord midpoints
var mx1 = (p1.x + p2.x)/2, my1 = (p1.y + p2.y)/2,
mx2 = (p2.x + p3.x)/2, my2 = (p2.y + p3.y)/2;
// chord normals
var nx1 = -dy1, ny1 = dx1
nx2 = -dy2, ny2 = dx2;
// chord midpoint offsets along the normals
var ox1 = mx1 + dx1p, oy1 = my1 + dy1p,
ox2 = mx2 + dx2p, oy2 = my2 + dy2p;
然后我们可以使用公共线相交测试找到圆的中点:
// line-line-intersection using a flat 8 coordinate values
function lli8(x1,y1,x2,y2,x3,y3,x4,y4) {
var nx=(x1*y2-y1*x2)*(x3-x4)-(x1-x2)*(x3*y4-y3*x4),
ny=(x1*y2-y1*x2)*(y3-y4)-(y1-y2)*(x3*y4-y3*x4),
d=(x1-x2)*(y3-y4)-(y1-y2)*(x3-x4);
if(d==0) { return false; }
return { x: nx/d, y: ny/d };
}
我们称之为lli8(mx1, my1, ox1, oy1, mx2, my2, ox2, oy2),因为我们通过这三个点知道圆的中心,所以我们得到了我们最初感兴趣的点的半径。