是否有SVG API允许在生成Bezier和样条曲线点坐标后获取这些坐标?

是否有SVG API允许在生成Bezier和样条曲线点坐标后获取这些坐标?,svg,bezier,spline,Svg,Bezier,Spline,JS中是否有SVGAPI允许在生成Bezier和样条曲线点坐标后获取它们 我想控制一台沿着曲线路径的生产机器。我需要知道: 1) 沿路径的长度,或沿路径的每个部分。 2) 在沿路径的每个指定距离处,了解曲率半径。我可以想象我可以计算曲率半径的一种方法是比较相邻点之间的距离(或路径方向) 但如果我想“阅读”路径曲线规范,我真的需要生成自己的JS来绘制这些曲线吗 在最坏的情况下,我需要收集生成的所有像素的坐标。 感谢路径元素有一个可以调用的getPointAtLength()方法。沿着曲线传递一段长

JS中是否有SVGAPI允许在生成Bezier和样条曲线点坐标后获取它们

我想控制一台沿着曲线路径的生产机器。我需要知道: 1) 沿路径的长度,或沿路径的每个部分。 2) 在沿路径的每个指定距离处,了解曲率半径。我可以想象我可以计算曲率半径的一种方法是比较相邻点之间的距离(或路径方向)

但如果我想“阅读”路径曲线规范,我真的需要生成自己的JS来绘制这些曲线吗

在最坏的情况下,我需要收集生成的所有像素的坐标。
感谢路径元素有一个可以调用的
getPointAtLength()
方法。沿着曲线传递一段长度,它将返回x和y

var path=document.getElementById(“测试”);
var point=path.getPointAtLength(300);
警报(“x=“+point.x+”y=“+point.y”)

  • 总路径长度::
    path.getTotalLength()
  • 沿路径的长度::
    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)
    ,因为我们知道通过这三个点的圆心,所以给出了我们最初感兴趣的点的半径

    有一个API,其中包括获取xy坐标作为长度的函数。您可以使用二进制搜索将其反转,以获得长度作为xy的函数。您还可以使用path元素构建路径,并非常容易地获得每个组件的长度。