1

首先让我为一个糟糕的英语和可能不是很直截了当的问题道歉,因为我不太确定如何称呼它。

我在 After Effects 中有一条多分段三次贝塞尔曲线,它由 5 个带有 IN 和 OUT 切线的顶点定义。我的任务是在 Java Script 中将其细分为 N 个小的线性块。

编辑提交了更多信息。 给定一个由 5 个点定义的多分段三次贝塞尔样条曲线,带有进出切线,我需要得到它的线性表示。其中 N 是用户定义的线性段数。

三次贝塞尔样条曲线:

Segment1: P0, P0out, P1in, P1;
Segment2: P1, P1out, P2in, P2;
Segment3: P2, P2out, P3in, P3;
Segment4: P3, P3out, P4in, P4;

预期输出:

N = 1: linear spline with 2 anchors representing entire shape;
N = 2: linear spline with 3 anchors representing entire shape;
N = 3: linear spline with 4 anchors representing entire shape;
N = 4: linear spline with 5 anchors representing entire shape;
...
N = 8: linear spline with 9 anchors representing entire shape;

distance(L0,L1) = distance(L1,L2) = distance(L2,L3) = ... = distance(L-n, Ln)

在示例图像中,我使用 4 段样条曲线,其中段长度彼此相等 - 这更容易绘制来解释我的任务。但在实际项目中,这些段不会相等,总共会有 4 个以上的段。

我看过de Casteljau方法,但据我所知,它适用于一段样条曲线。我的数学技能很糟糕,所以我不确定我是否可以在我的例子中使用 de Casteljau。

4

2 回答 2

1

这在概念上是直截了当的,尽管由于稍后解释的原因它可能涉及相当多的代码。您要做的是展平(立方)poly-Bezier,所以让我们从它开始:

单个三次贝塞尔曲线由四个点生成:起点、确定起点切线的控制点、终点和确定终点切线的控制点。那么,曲线是三次 Bezier 函数的图:

Bx(t) = p1.x × (1-t)³ + 2 × p2.x × (1-t)² × t + 2 × p3.x × (1-t) × t² + p4.x × t³
By(t) = p1.y × (1-t)³ + 2 × p2.y × (1-t)² × t + 2 × p3.y × (1-t) × t² + p4.y × t³

在区间 上绘制了一条贝塞尔曲线t=[0,1],因此在整个区间上绘制了 N 段的多贝塞尔曲线N × [0,1]

一、简单案例:简单展平。贝塞尔曲线是非线性曲线,因此我们首先不要费心强制“每个线段的长度相同”。给定一个 N 段 poly-Bezier:

S = number of segments we want
points = empty list
for (s = 0):(s = S):(step = S/N):
  v = s * step
  segmentid = floor(v)
  segment = polycurve.segments[segmentid] 
  t = v % 1
  points.push(
    segment.pointAt(t)
  )

我们现在有了我们需要的所有点,我们只需用线将它们连接起来。完毕。

但是,贝塞尔曲线是非线性曲线,因此以这种方式展平不会产生丝毫等距线段。如果我们想这样做,我们需要处理沿曲线的距离而不是t值。

S = number of segments we want
points = empty list
for (s = 0):(s = S):(step = S/N):
  v = s * step
  segmentid = floor(v)
  segment = polycurve.segments[segmentid]
  distanceRatio = v % 1
  t = segment.getTforDistanceRatio(distanceRatio)
  points.push(
    segment.pointAt(t)
  )

这将完全按照您的意愿工作,但这getTforDistanceRatio是困难的部分,因为我们在这里所做的是重新参数化距离而不是时间的曲线,这是一个非常困难的数学问题(不存在一般的符号解决方案)。最便宜的方法是使用查找表(LUT),在上面的链接中解释了“沿曲线的距离”。

于 2016-03-06T20:19:07.827 回答
0

de Casteljau 方法用于计算贝塞尔曲线上的一个点,并在此过程中获得两条细分曲线的控制点。所以,是的,如果您知道控制点,您应该能够使用 de Cateljau 方法在贝塞尔曲线上评估任意数量的点。

从您展示的图片和您的“三次贝塞尔样条”将切线作为输入/输出的事实来看,我认为您的样条实际上是“三次 Hermite 样条”,其中每个段确实是三次贝塞尔曲线。您可以将样条曲线的每一段转换为三次贝塞尔曲线,然后使用 de Cateljau 方法计算所需数量的点,然后用直线连接这些点。

于 2016-03-06T20:08:16.970 回答