2017-12-21 20 views
2

2つの3d点ともう1つの3d点のリストが与えられたら、どの点が半径rの2点間の3d線として定義されている円柱の中にあるかチェックします。 私は遅すぎる正確ではないこれは、そのための数値のソリューションを実装しました:3D点が円柱の中にあるかどうかをチェックする方法

def point_in_cylinder(pt1, pt2, points, r, N=100): 
    dist = np.linalg.norm(pt1 - pt2) 
    ori = (pt2 - pt1)/dist 
    line = np.array([pt1 + ori*t for t in np.linspace(0, dist, N)]) 
    dists = np.min(cdist(line, points), 0) 
    return np.where(dists <= r)[0] 

私はそのためのよりよい解決策があると確信している...

*****編集*****

私はこの機能を高速化行列の乗算と(行が宣言されている)listcompを置き換えることにより、少し:

line = (pt1.reshape(3, 1) + elc_ori.reshape(3, 1) @ np.linspace(0, dist, N).reshape(1, N)).T 

答えて

4

(私の理解に)あなたがレコード生成されていますシリンダ内の均一に離間した点の離散的な(そして非常に大きな)リストをその軸上に配置し、次に試験点と軸点との最小距離がシリンダの半径内にあるかどうかをチェックする。


これらのテストのそれぞれは、それが(後述)O(1)で行うことができ、複雑O(N)を持っているので、これは遅いです。しかし、最も重要なことは:

あなたがテストしている領域がシリンダ全体を満たしていないので、これは間違っています!以下

図は(悪い品質はご容赦下さい)理由を示しています

enter image description here

あなたは円筒の表面付近の白いスペースを見ることができるようにテストで偽陰性を与えます。この不正確さを減らすためには、Nを増やす必要があります。その結果、アルゴリズムの効率が低下します。

[あなたが点の(理論的には)無限の数を使用したとしても、テスト領域は依然としてカプセル、全体ではなくシリンダに収束することになる。]


O(1)方法は次のようになり:

  • テストポイントqを考えると、それを確認してください。

    enter image description here

    これは、qが円柱の2つの円形ファセットの面の間にあることを確認します。

  • 次に確認すること:

    enter image description here

    これはqは円筒の曲面内にあることを確認します。


EDIT:numpyの中に実装するの試み(エラーがある場合は私に知らせてください)

def points_in_cylinder(pt1, pt2, r, q): 
    vec = pt2 - pt1 
    const = r * np.linalg.norm(vec) 
    return np.where(np.dot(q - pt1, vec) >= 0 and np.dot(q - pt2, vec) <= 0 \ 
      and np.linalg.norm(np.cross(q - pt1, vec)) <= const) 
+0

グレート示して!ありがとう! –

関連する問題