1

最初に、英語が下手で、おそらくあまり単純ではない質問をお詫びします。

After Effects にマルチセグメント化された 3 次ベジエ曲線があります。これは、IN 接線と OUT 接線を持つ 5 つの頂点によって定義されます。私の仕事は、Java Script でそれを N 個の小さな線形チャンクに分割することです。

EDITが詳細情報を提出しました。 イン接線とアウト接線を持つ 5 つのポイントで定義されたマルチ セグメント化された 3 次ベジエ スプラインが与えられた場合、その線形表現を取得する必要があります。ここで、N はユーザーが定義する線形セグメントの数です。

3 次ベジエ スプライン:

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法を見てきましたが、理解できるように、1 つのセグメント スプラインで機能します。私の数学のスキルはぼんやりしているので、私の例で de Casteljau を使用できるかどうかはよくわかりません。

4

2 に答える 2

1

これは概念的には簡単ですが、後で説明する理由によりかなりの量のコードが必要になる場合があります。あなたがしようとしているのは、(立方体の) poly-Bezierを平坦化することです。それで始めましょう:

個々の 3 次ベジエ曲線は、始点、始点で接線を決定する制御点、終点、および終点で接線を決定する制御点の 4 つの点によって生成されます。曲線は、3 次ベジエ関数のプロットです。

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³

1 つのベジエ曲線が interval にわたってプロットされるt=[0,1]ため、N セグメントの poly-Bezier が合計 interval にわたってプロットされます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 法は、ベジエ曲線上の点を計算するために使用され、プロセス内の 2 つの分割された曲線の制御点も取得します。したがって、制御点がわかっている場合は、de Cateljau メソッドを使用して、ベジエ曲線上で必要な数の点を評価できるはずです。

あなたが示す写真と、あなたの「3次ベジェスプライン」が入力として接線を出し入れするという事実から、あなたのスプラインは実際には「3次エルミートスプライン」であり、各セグメントは実際に3次ベジエ曲線であると思います。スプラインの各セグメントを 3 次ベジエ曲線に変換し、de Cateljau メソッドを使用して必要な数の点を評価し、これらの点を直線で結ぶことができます。

于 2016-03-06T20:08:16.970 に答える