【问题标题】:SVG curve through predetermined points通过预定点的 SVG 曲线
【发布时间】:2015-02-19 03:01:20
【问题描述】:

我是 SVG 的初学者。

我需要一条通过点列表的 SVG 曲线。它是一个用 C++ 计算的数学函数,输出结果应该写在 SVG 文件中。我的问题是 SVG 中的 path 标签没有通过所有点。相反,它会在中间跳过其中一些,而只是倾向于它们。 SVG 是否有任何工具可以使曲线通过所有点并以自动方式适当地弯曲曲线?

<svg height="400" width="450">
  <path d="M 80 90 C 190 40, 300 60, 380 160" stroke="blue" stroke-width="5" fill="none" />
  <path d="M 80 90 L 190 40, 300 60, 380 160" stroke="green" stroke-width="1" fill="none"/>
  <g stroke="black" stroke-width="3" fill="black">
    <circle id="pointC" cx="80" cy="90" r="3" stroke="black"/>
    <circle id="pointA" cx="190" cy="40" r="3" stroke="green"/>
    <circle id="pointC" cx="300" cy="60" r="3" stroke="red"/>
    <circle id="pointB" cx="380" cy="160" r="3" stroke="blue"/>
  </g>
  Sorry, your browser does not support inline SVG.
</svg>

【问题讨论】:

    标签: math svg curve-fitting


    【解决方案1】:

    如果您只需要通过 4 个点绘制曲线,请查看 at the solution in this topic 和链接的 tinaja 页面。
    如果您必须通过许多点绘制平滑曲线,请考虑构建插值三次样条 (NR book, page 113),而不是 transform these splines to Bezier form(将 bazis 从多项式更改为 Bernstein)

    【讨论】:

      【解决方案2】:

      在 SVG 路径中,贝塞尔曲线是近似值而不是插值,因此它通常不会通过所有控制点。

      Sp做什么:

      1. 使用插值三次曲线并将其转换为贝塞尔曲线

        • 看这里:Interpolation cubic to Bezier cubic(需要这个和你一样的原因) 我在那里使用具有连通性 C1 (位置和一阶导数)的特定插值三次方,那里有贝塞尔曲线的转换,所以你可以使用它来转换控制点......不要忘记首先只使用 3x 倍数以及整个贝塞尔路径的最后一个控制点,而不是每个贝塞尔补丁!!!
      2. 使用多行而不是单个贝塞尔曲线

        这将是粗糙的(取决于线密度)只需插入足够多的点并通过线连接它们

      3. 重复控制点

        如果您有多个控制点 (3x),则 Bezier 将通过该点。所以如果你有曲线点:p0,p1,p2,p3,... 然后像这样从它们做多个贝塞尔曲线:

        p0,p0,p0,p1
        p0,p0,p1,p2
        p0,p1,p2,p3
        p1,p2,p3,p3
        p2,p3,p3,p3
        p3,p3,p3,p4
        p3,p3,p4,p5
        p3,p4,p5,p6
        p4,p5,p6,p6
        p5,p6,p6,p6,...
        

        这将通过点p0,p3,p6,...,因此您仍然需要评估未通过的控制点以确保所需的连通性

      【讨论】:

        【解决方案3】:

        如果您需要通过多个点绘制平滑曲线,请考虑使用 Catmull Rom 样条或 Overhauser 样条。两种算法都将导致在分段连接处具有 C1 连续性的三次样条。此外,它们比实现 C2 B 样条插值更容易实现,因为后者需要您求解线性方程组。您还可以轻松地将 Catmull Rom 样条或 Overhauser 样条转换回 Bezier 形式。

        【讨论】:

        • 如果我正确理解了 catmull-rom,请告诉我。对于P0、P1等端点,控制点为(2/3)P0+(1/3)P1,其余点如Pa、Pb、Pc的结果,Pb之前的控制点为Pb+(1 /6)*(Pa-Pc),Pb后的控制点为Pb+(1/6)*(Pc-Pa)。我说的对吗?
        • @OP:是的。那是正确的。但是,您列出的公式适用于统一的 Catmull Rom 样条,它假定数据点的参数化是统一的(即 t0=0.0、t1=1.0、t2=2.0 等)。使用 Centripetal Catmull Rom spline 会更好(参考 Wiki 页面),当数据点分布不均匀时可以产生更好的结果。
        猜你喜欢
        • 2013-05-05
        • 2013-12-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-11
        • 1970-01-01
        • 2019-10-10
        • 1970-01-01
        相关资源
        最近更新 更多