あなたが求めているのは、弧長関数の逆関数です。したがって、曲線Bが与えられた場合、0とtの間の曲線の弧長がlenになるように、0と1の間で戻る関数Linv(len)が必要です。
この機能があれば、問題は本当に簡単に解決できます。B(0)を最初の点とします。次の点を見つけるには、B(Linv(w))を計算するだけです。ここで、wは参照する「等しい弧長」です。次のポイントを取得するには、Linv(n * w)が1より大きくなるまで、B(Linv(2 * w))などを評価します。
私は最近この問題に対処しなければなりませんでした。私はいくつかの解決策を思いついた、または見つけましたが、どれも私にとって満足のいくものではありません(しかし、おそらくそれらはあなたのためになるでしょう)。
さて、これは少し複雑なので、最初にソースコードへのリンクを示しましょう:http:
//icedtea.classpath.org/~dlila/webrevs/perfWebrev/webrev/raw_files/new/src/share/classes /sun/java2d/pisces/Dasher.java。必要なのはLengthIteratorクラスです。ファイルの他の部分を調べる必要はありません。別のファイルで定義されているメソッドがたくさんあります。それらに到達するには、/raw_files/からURLの末尾まですべてを切り取ります。これがあなたの使い方です。曲線上のオブジェクトを初期化します。次に、曲線の先頭から弧長Lの点のパラメーターを取得するには、next(L)を呼び出します(実際の点を取得するには、deCasteljauのアルゴリズムまたはzneakの提案を使用して、このパラメーターで曲線を評価します)。next(x)を呼び出すたびに、最後の位置と比較して、曲線に沿ってxの距離だけ移動します。nextは、曲線がなくなると負の数を返します。
コードの説明:したがって、B(0)からB(t)の長さがLEN(LENがわかっている場合)になるような値が必要でした。曲線を平坦化しただけです。したがって、各曲線が線に十分に近づくまで、曲線を再帰的に細分割します(これは、制御ポリゴンの長さと端点を結ぶ線の長さを比較することでテストできます)。このサブカーブの長さは、(controlPolyLength + endPointsSegmentLen)/2として計算できます。これらすべての長さをアキュムレータに追加し、アキュムレータ値が>=LENのときに再帰を停止します。ここで、最後のサブカーブCを呼び出し、[t0、t1]をその定義域とします。必要なtがt0<=t <t1であり、B(0)からB(t0)までの長さがわかっている-この値をL0t0と呼びます。したがって、C(0)からC(t)の長さがLEN-L0t0になるように見つける必要があります。これはまさに私たちが始めた問題です、しかし、小規模です。再帰を使用することもできますが、それはひどく遅いので、代わりにCが非常に平坦な曲線であるという事実を使用します。Cが直線であると仮定し、P = C(0)+((LEN-L0t0)/ length(C))*(C(1)-C(0))を使用してtの点を計算します。この点はC(0)-> C(1)の線上にあるため、実際には曲線上にありませんが、目的の点に非常に近いです。したがって、Bx(t)= PxおよびBy(t)=Pyを解くだけです。これは、クローズドソースソリューションを持つ立方根を見つけるだけですが、私はニュートン法を使用しました。これで必要なtが得られ、実際のポイントであるC(t)を計算できます。tは、C(0)-> C(1)の線上にあるため、実際には曲線上にありますが、目的の点に非常に近いです。したがって、Bx(t)= PxおよびBy(t)=Pyを解くだけです。これは、クローズドソースソリューションを持つ立方根を見つけるだけですが、私はニュートン法を使用しました。これで必要なtが得られ、実際のポイントであるC(t)を計算できます。tは、C(0)-> C(1)の線上にあるため、実際には曲線上にありますが、目的の点に非常に近いです。したがって、Bx(t)= PxおよびBy(t)=Pyを解くだけです。これは、クローズドソースソリューションを持つ立方根を見つけるだけですが、私はニュートン法を使用しました。これで必要なtが得られ、実際のポイントであるC(t)を計算できます。
数ヶ月前に、曲線の自然なパラメータ化への近似を見つけた、これに対する別の解決策を持った論文をざっと読んだことを言及する必要があります。著者はここにそれへのリンクを投稿しました:ベジェ曲線全体の等距離点