【问题标题】:Calculating control points for a shorthand/smooth SVG path Bezier curve计算速记/平滑 SVG 路径贝塞尔曲线的控制点
【发布时间】:2011-07-14 08:09:19
【问题描述】:

链接:Official SVG Reference

大家好,我在使用定义为 SVG 路径的速记(由路径数据中的 S 或 s 定义)贝塞尔曲线时遇到了一些问题。具体来说,如何计算第一个控制点。

假设我们有一个带有控制点(X1, Y1)(X2, Y2)、端点(X3, Y3) 和起点(X0, Y0) 的curveto 命令。

接下来是带有第一个控制点(X4, Y4) 和第二个控制点(X5, Y5) 的速记/平滑曲线命令。为简单起见,假设一切都在绝对坐标中。

如何从其他已知点计算未知的第一个控制点(X4, Y4)

【问题讨论】:

标签: path svg bezier


【解决方案1】:

我找到了this。我可以从中引用的最短答案是:

我们用一条线连接开始和结束锚点周围的锚点(我们称之为opposed-lines):

为了使线条平滑,每个控制点的位置必须 相对于它的opposed-line:

  • 控制点位于与opposed-line 平行且与当前锚点相切的线上。
  • 在这条切线上,锚点到控制点的距离取决于opposed-line 的长度和任意smoothing 比率。
  • 起始控制点与opposed-line 的方向相同,而结束控制点向后。
// When 'current' is the first or last point of the array
// 'previous' or 'next' don't exist.
// Replace with 'current'
const p = previous || current
const n = next || current

我的解释:

  • 计算每对“锚点”(实际曲线)点的 2 个控制点。
  • 如果正在计算点 1 (start/end - 1) 和 2 (start + 1/end):
    • 第一个控制点从点 1 (start) 平行于{从点 0 (start - 1) 到点 2 (start + 1) 的线}。
    • 第二个控制点从点 2 (end) 向后延伸,平行于{从点 1 (end - 1) 到点 3 (end + 1) 的线}。
  • 从点 1 或 2 到相应控制点的距离是曲线所需的平滑度变量 (0.0 - 1.0) 与平行线长度的比值。 (您可以使用基本三角函数,即 cos() 和 sin() 作为角度。)
  • 对于端点(在它们之前/之后没有点),将 start - 1 替换为 start 或将 end + 1 替换为 end

【讨论】:

    【解决方案2】:

    您可以将最后一条曲线的最后一个控制点和最后一条曲线的终点(即新曲线中的第一个点)视为一条线,并且镜像控制点应位于该线上一段距离等于最后一个控制点到最后一个端点的距离

    【讨论】:

      【解决方案3】:

      您的第一个点是上一条曲线的最后一个点。在这种情况下,它将是 (x3, y3)。那么你在速记中的第二个点就是速记所代表的曲线长度的终点。

      如果我们要将您的路径翻译成两个完整版本,我们将拥有:

      M X0, Y0 C X1, Y1 X2, Y2 X3, Y3 
      M X3, Y3 C XR, YR X4, Y4 X5, Y5 
      

      其中XR,YR是上一条曲线的最后一个控制点关于当前曲线第一个点的反射。

      XR,YR只是​​P2对P3的反映,所以:

      XR = 2*X3 - X2 and 
      YR = 2*Y3 - Y2
      

      【讨论】:

      • 没有误会,我只是将第二条曲线的第一个控制点称为 (X4,Y4),而您将其称为 (XR,YR)。
      猜你喜欢
      • 2021-09-10
      • 1970-01-01
      • 1970-01-01
      • 2011-04-26
      • 2011-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多