计算速记/平滑SVG路径贝塞尔曲线的控制点

时间:2011-03-13 05:03:41

标签: path svg bezier

链接:Official SVG Reference

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

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

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

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

3 个答案:

答案 0 :(得分:16)

你的第一点是前一曲线的最后一点。在这种情况下,它将是(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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

  

我们用一条线将围绕起点和终点的锚点连接起来(我们称它们为opposed-lines):

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