パスの長さをどのように決定しますか?


11

各プレイヤーに1つの指定されたパスに沿って移動する必要があるゲームがあります。ベジエ曲線を使用してパスを描画します。パスの実際の(直線的ではない)全長と、各プレイヤーが行った距離をどのように決定できますか?(始点とパス上の指定した点の間の距離。)

更新:

パスはデカルト平面(2D)で表されます。


あなたの質問はこの回答の
終わり

回答:


7

以前の答えが言ったように、ベジェ曲線の長さを計算することは困難です(不可能ですか?)。100%のゲームは長さの概算を使用していると思いますが、これはほぼ常に十分正確です。

数か月前に、曲線を「小さな」セグメントに分割して長さを追加するという提案されたアプローチを使用して実装しました。ここに C ++実装の例があります


11

ベジェ曲線の長さを測定することは困難です。わずかな不正確さを気にしない場合、単純な解決策はベジェ曲線を直線で近似し、線の長さの合計を計算することです。作成するセグメントが多いほど、近似が良くなります。


私はそれを検討するかもしれませんが、セグメントの数を決定するにはどうすればよいですか?また、セグメントをマップして、パス上の始点と終点をどのようにマッピングできますか?このテクニックには名前がありますか?(だから私はグーグルでそれを検索する)
バレンティン・ラドゥ

単純なアプローチは、B(0)からB(1)までのポイントの線形分布を使用することです...実際に曲線をプロットするために使用するものとよく似ています。ダンの答えのソースコードを見てください。
bummzack、2011年

私は自分の答えで何を改善できるかを知るために、反対票の説明に感謝します...
bummzack

7

より高次の(つまり、1次よりも大きい)スプライン長のパラメーター化を近似する必要があります。直接表すことはできないため、これに対する直接的な解決策を見つけるのは容易ではありません。

いくつかの現存する実装(コピー貼り付けコード):

著者によれば、チェビシェフ近似を使用すると、曲線のサイズが大きくなるにつれて精度が向上します。pp。7-8の疑似コードを見てください。残りは、無視できるアプローチに基づいた他のアルゴリズムの説明です。オンラインの参考文献の多くは、この方法を優れた方法として言及しています。

これらの簡潔なアプローチも参照してください。


5

これは、@ bummzackの回答に対するコメントへのコメントとして始まりましたが、長くなりすぎました。

必要なセグメント数を決定するにはどうすればよいですか

2つのアプローチがあります。1つ目は、ベジエ曲線をレンダリングするための標準的なアルゴリズムです。制御点は曲線の境界ボックスを形成するため、すべての制御点が始点から終点までの線分のイプシロン内にある場合は、直線として近似します。それ以外の場合は、de Casteljauのアルゴリズムを使用して細分割します。イプシロンは、最終結果で希望するエラーに応じて選択されます。(レンダリングでは通常0.5ピクセルです)。

もう1つのアプローチは、区間演算を使用した改良です。始点から終点までの線の長さを下限とし、制御点を通る線の長さの合計を上限とします。繰り返しになりますが、最終的なエラー要件に応じて細分割してください。

通常1つはt = 0.5で細分割されますが、de Casteljauのアルゴリズムでは任意の点で分割できます。したがって、制御点C_0からC_3までの3次ベジエがあり、C_2がC_1よりも端点間の線分セグメントに非常に近い場合、その分割は1/3または2/3のいずれかがより厳しい境界を与えます。私は代数を使ってどちらが良いかを正当化するために作業していませんが、必要に応じて実験して報告することができます。他に何もない場合、私はオプションがそこにあることを指摘したかったのです。


3

パラメータ化された曲線の長さの計算は、sqrt((dx / dt)²+(dy / dt)²)の積分を取ることで実行できます。ここで、dx / dtは曲線のx成分の導関数であり、dy / dtは、曲線のyコンポーネントの導関数です。ベジェスプラインの場合、方程式は任意の次元に拡張できるため、これら2つは同じです。

3次ベジェスプラインの式は次のとおりです。B(t)=(1-t³)* P0 + 3(1-t)²t* P1 + 3(1-t)t²* P2 +t³P3ここでP0 P3からコントロールポイントです。

Wolfram | Alphaによれば、この式の導関数は次のとおりです:d(B(t))/ dt = 3(t(t(P3-P0)+ P2(2-3t)+ P1(3t²-4t + 1))

これを曲線の長さの方程式に戻し、t = 0からt = 1までの積分を計算できます。残念ながら、これを実行しようとすると、Wolfram | Alphaがタイムアウトします。ただし、数値積分は可能です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.