0

我创建了简单的 JavaScript 应用程序来绘制二次贝塞尔曲线。所有贝塞尔曲线都是一个形状的一部分(第二条贝塞尔曲线从第一条贝塞尔曲线结束的点开始,第三条贝塞尔曲线从第二条贝塞尔曲线结束的点开始,......最后一条曲线在第一条曲线开始的地方结束)。

形状中的贝塞尔曲线数为 2 或更多(未准确指定有多少)。

创建形状后,我有一系列贝塞尔曲线。例如这样的:

array(3): {
   [0]:  object(8): {
      sx:  number: 130
      sy:  number: 175
      cp1x:  number: 119
      cp1y:  number: 151
      cp2x:  number: 175
      cp2y:  number: 120
      ex:  number: 212
      ey:  number: 181
   }
   [1]:  object(8): {
      sx:  number: 212
      sy:  number: 181
      cp1x:  number: 212
      cp1y:  number: 181
      cp2x:  number: 269
      cp2y:  number: 237
      ex:  number: 147
      ey:  number: 226
   }
   [2]:  object(8): {
      sx:  number: 130
      sy:  number: 175
      cp1x:  number: 130
      cp1y:  number: 175
      cp2x:  number: 147
      cp2y:  number: 226
      ex:  number: 147
      ey:  number: 226
   }
} 

我想创建相同的形状,但扩展为 X 像素。例如,如果我的形状是由 2 条贝塞尔曲线创建的半径为 R 的椭圆,我想用半径为 R + X 的相同中间绘制更大的椭圆。我花了 3 天时间试图解决这个问题,但我真的不知道怎么做。

非常感谢您的建议。

4

3 回答 3

1

该死的贝塞尔曲线......我爱他们,我恨他们!

失败#1

一条贝塞尔曲线不能用另一条贝塞尔曲线展开:

维基百科:与给定贝塞尔曲线有固定偏移的曲线,通常称为偏移曲线(与原始曲线“平行”,如铁路轨道中的轨道之间的偏移),不能完全由贝塞尔曲线形成。

失败#2

如果你知道你的曲线形成一个封闭的规则形状(有一个中心 - 质心),你可以使用 context.translate。问题是您的示例贝塞尔集没有质心。事实上,没有多少贝塞尔集有质心。

应该可以……但是数学让人头疼

  1. 沿着构成贝塞尔曲线的路径计算许多 X/Y。
  2. 在每个 X/Y 处,计算曲线的切角。
  3. 计算该切角的垂直角。
  4. 在该垂直线上向外移动要扩展贝塞尔曲线的长度。
  5. 将 X/Y 保存在该扩展点。
  6. 使用 context.lineTo 连接所有扩展点。

就像您扩展了一组封闭的贝塞尔曲线一样简单!

我对此有一些数学计算,但是将其组合成一个完整的解决方案需要时间。如果你试一试,如果你有问题,我会帮助你……</p>

于 2013-11-01T18:35:28.907 回答
0

你不能用另一条曲线偏移一条曲线,但你可以用一条多曲线偏移一条曲线,我在http://pomax.github.io/bezierinfo/#offsetting解释了这通常是如何完成的——代码是处理,但它很容易移植到(未优化的)JavaScript。更重要的部分是,如果您想以“正确”的方式执行此操作,则需要进行一些编程(和理解)。如果您只是想要看起来正确的东西,只需以 X 步(例如 )穿过曲线for(var i=0; i<1; i+=0.01) {...},找到每个点的法线,沿着法线偏移您需要的像素数,然后连接所有这些点。只要曲线不是数千个像素长,线性近似就相当不错。

于 2013-11-02T19:36:38.533 回答
0

我在这里回答了一个类似的问题 如何生成“粗”贝塞尔曲线?

有一篇博客文章解释了如何绘制偏移曲线 http://brunoimbrizi.com/unbox/2015/03/offset-curve/

还有一个用 javascript 编写的交互式示例:http: //codepen.io/brunoimbrizi/pen/VYEWgY

// code is too big to post here, please see the source on codepen
于 2015-03-13T14:29:06.037 回答