15

閉じた均一な3次Bスプラインの制御頂点(Dx)である2D点のリストがあります。私は単純な曲線を想定しています(非自己交差、すべての制御点は別個のものです)。

曲線で囲まれた領域を見つけようとしています。

ここに画像の説明を入力してください

結び点(Px)を計算すると、曲線を多角形として扱うことができます。次に、実際の曲線と結び点を結ぶ直線の間の、各セグメントの残りのデルタ領域を「ただ」見つける必要があります。

Bsplineの形状(したがって面積)は回転と平行移動の下で不変であることを理解しています-したがって、各セグメントについて、原点にt = 0ノットを配置するための平行移動と、t=1ノットを配置するための回転を見つけることができます+ x軸上:

ここに画像の説明を入力してください

ポイントを接続して再グループ化することで、曲線の方程式を見つけることができます。

P(t) = (
    (t**3)*(-Dm1 + 3*D0 - 3*D1 + D2)
    + (t**2)*(3*Dm1 - 6*D0 + 3*D1)
    + t*(-3*Dm1 + 3*D1)
    + (Dm1 + 4*D0 + D1)
) / 6.

しかし、私はそれを統合しようとして髪を引き裂いています-私はできます

 1
/
| Py(t) dt
/
t=0

しかし、それは私に領域を与えません。必要なのは

 Px(t=1)
/
| Py(t) (dPx(t) / dt) dt
/
x = Px(t=0)

しかし、先に進む前に、私は本当に知りたいです:

  1. これは面積の正しい計算ですか?理想的には、分析ソリューションが私の一日になります!

  2. この領域を見つけたら、ベースポリゴン(最初の図の赤と緑の領域)に加算または減算する必要があるかどうかをどのように判断できますか?

  3. この計算を行うPythonモジュールはありますか?Numpyには、3次Bスプラインを評価するためのいくつかの方法がありますが、面積を処理する方法はないようです。

  4. これを行う簡単な方法はありますか?t = numpy.arange(0.0, 1.0, 0.05)たぶん、P(t)をたくさんのポイント(のようなもの)で評価し、全体をポリゴンとして扱うことを考えています。与えられたレベルの精度を保証するためにいくつの細分化が必要かという考えはありますか(エラー<1%が欲しい)?

4

3 に答える 3

4

個人的には、スプラインを最大限に活用し、グリーンの定理を使用して面積積分を周回積分として書き直します。

すでに曲線を知っているので、十分な次数のガウス求積法を使用して積分を行うのは簡単です。必要な余分な領域を見積もるシェナニガンはありません。多項式上のガウス求積法は非常に適切に動作するため、計算効率も高くなると思います。キュービックBスプラインはうまく統合されます。

最初と最後のポイントが一致しなければならないような方法でコードを記述します。それは問題の不変量です。

このアプローチは、穴のある領域でも機能します。外側の曲線に沿って積分し、外側と内側の曲線を結ぶ架空の直線を作成し、内側の曲線に沿って積分してから、そこに到達した直線に沿って外側に戻ります。

于 2012-06-03T13:20:45.233 に答える
3
  1. 任意の点をピボットp 0として選択します(例: 原点 (0,0))
  2. 曲線p 1 = (x,y)に沿っていくつかの点をピックします。
  3. その点で曲線を微分して、速度v = < vx,vy >を取得します。
  4. 3 点から三角形を作り、面積を計算しますベクトルp 0 p 1vの間の外積を2 で割ることで最も簡単に実行できます。
  5. この領域をtにわたって0 から 1 まで積分します。

得られる結果は、曲線全体の 1 つのセグメントの面積です。彼らは反対の方向を向いているので、いくつかは否定的です。すべてのセグメントの面積を合計すると、曲線全体の面積が得られます。

結果は次のとおりです。

面積i = (31 x i -1 y i + 28 x i -1 y i +1 + x i -1 y i +2 - 31 x i y i -1 + 183 x i y i +1 + 28 x i y i +2 - 28 x i +1 y i -1 - 183 x i +1 y i + 31 x i +1 y i +2 - x i +2 y i -1 - 28 x i +2 y i - 31 x i +2 y i +1 ) / 720

これを行列形式に変換すると、次のようになります。

領域i = < x i -1   x i   x i +1   x i +2 > · P · < y i -1   y i   y i +1   y i +2 > T

ここで、P

[    0   31   28    1]
[  -31    0  183   28] / 720
[  -28 -183    0   31]
[   -1  -28  -31    0]

コントロール ポイントが の場合[(0,0) (1,0) (1,1) (0,1)]、結果の領域は次のようになります。

[(0,0), (1,0), (1,1), (0,1)] -> 242/720
[(1,0), (1,1), (0,1), (0,0)] -> 242/720
[(1,1), (0,1), (0,0), (1,0)] ->   2/720
[(0,1), (0,0), (1,0), (1,1)] ->   2/720

合計は 488/720 = 61/90 です。

于 2012-06-03T10:42:56.123 に答える
1

うーん...何をすべきかはすでにわかっているようです。

  1. はい、これはセグメントの下の面積を計算する正しい方法です。

    dS=Y*dX=Y*(dX/dt)*dt
    
  2. 加算または減算を気にする必要はありません。常に追加する必要がありますが、一部の積分 (赤いセグメント) は負になります (常に P nを座標の先頭に配置し、P n+1を X 軸の正の方向に配置する場合)。したがって、すべてのセグメントに対して、平行移動と回転を計算してから積分する必要があります (すべて分析的に行われます)。

  3. Python モジュールについてはわかりませんが、このようなモジュールを作成するにはせいぜい 1 日かかるようです。
  4. 分析ソリューションの方が優れていると思いますが、それほど難しくはありません。

とにかくグラフィックが素晴らしい

于 2012-06-03T03:13:53.897 に答える