2009-04-09 15 views
4

私は線を持っています、私はそれが命中する最も近い線分を見つける必要があります。私は線分を最初にソートするとO(log n)の時間にこれを行うことは可能だと思いますが、ソート方法を覚えていません...何らかの木がうまくいくと思いますが、彼らは開始点と終了点の両方で?可能であれば、このデータ構造にすばやく挿入したいと思います。高速線交差のための線分セグメントコンテナ? (2D)

1つの線と1つの線分のコードがたくさんありますが、1つの線分と多くの線分に何かが必要です...私はどのような用語をGoogleに知らないのですか?

適切な記事へのリンクが良好で、C++コードがさらに優れています。ありがとう! :)

PS:線分は実際にはCCW順序でソートされた非自己交差ポリゴンの辺ですが、別の方法でそれらをソートするといくつかの利点があると思いますか?

これはすべて2Dです。二思想に


、私はこのが可能で完全にはよく分かりません。いくつかの種類の空間パーティショニングが役立つかもしれませんが、そうでなければ、私は線を並べ替える方法を考えていないので、任意の線と比較することができます。

答えて

7

ポリゴンの境界ボックス(最小 - 最大x、y座標)をとり、ボックス内にグリッドを作成できます。次に、各セルについて、セルを横切るすべての線を覚えておいてください。

  • グリッドを線 "を描く" ために使用Grid traversal algorithm線が最初にヒットしたセル(O(1))
  • をご覧ください:

    は、このようなintesectionを検索します。空でないセルにヒットしたら、すべてのラインをチェックし、セル内に交点があるかどうかをチェックし、最も近い交点を選んでください。すべての交点がセルの外側にある場合は、続行します(これはO(グリッド長)です)。

また、グリッドを階層的にすることもできます(つまり、あなたが求めていたツリーです)。同じアルゴリズムを使用して歩くこともできます。 This is done in raytracing in 3Dであり、時間複雑度はO(sqrt(N))である。


それとも、私は私のレイトレーサでやったアプローチを使用:行を含むquadtreeを構築

  • を(建物四分木は、記事にdesribedされる) - それらに含まれる場合は、ノード(=領域)に分割

    コンプ:4サブノード(サブエリア)にあまりにも多くのオブジェクトが

  • は全てリーフノード光線によってヒットされる四分木のを収集しますルートのute ray-rectangle intersection(ハードではない)。ルートがレイによってヒットした場合、その子を再帰的に処理します。

これについてのクールなことは、ツリーノードがないヒットしたとき、あなたはサブツリー全体(潜在的に大きな矩形領域)を処理をスキップしたことです。

最後に、これはグリッドをトラバースすることに相当します。レイのパス上で最小のセルを収集し、それらの中のすべてのオブジェクトを交差点でテストします。あなたはそれらのすべてをテストし、最も近い交差点を選んで(光線の経路上のすべての線を探索する)必要があります。

これはO(sqrt(N))です。

グリッドトラバーサルでは、交差点を見つけたら検索を停止できます。これを行うには、4つの矩形の交点を距離でソートするか、4セルのグリッドを巧みに横切るかのどちらかを選択します(これは、トラバーサルに戻ります)。

これは、私が思うに実装するのが比較的難しく、うまく機能する別のアプローチです(実データ-O(sqrt(N))でテストしました)。繰り返しますが、もしあなたが少なくとも二つの線を持っていれば、このアプローチの恩恵を受けるでしょう。ポリゴンが10のエッジを持つときには、それらの全てがテストされているのと比べて利益はほとんどありません。

+1

いいえ、私が考えていたO(log n)は、私が信じるだけの水平線または垂直線分のものでした。 Bresenhamのアルゴリズムは交差点を見逃すかもしれないように見えますが、それはできませんか?それは、それが入力するすべてのセルを "満たす"わけではありません。それ以外の場合、これは良いアプローチのように見えます。 – mpen

+1

グリッドトラバーサルはここで述べるアルゴリズムで行うべきです。http://www.devmaster.net/articles/raytracing_series/part4.php、セクション「グリッドトラバーサル」を参照してください。記事に表示されているように、多角形に(〜100)辺が多数ある場合にのみ、おそらく恩恵を受けるでしょう。 –

+1

まあ、彼はおそらく彼は何百ものエッジはないだろうが、同じエッジが何千回も使われるかもしれない。これは、私が死んだ質問であると思ったことについての最善の答えのように見えるので、私はあなたにその点検をします;)ありがとう。 – mpen

1

どのようにそれらのいずれかを打つだろうか?彼らがラインであれば、それはありそうもありません。

実際にテストしようとしているポリゴン(平面)の場合、このようなことを行う通常の方法は最初に平面と交差してから、内側/外側の点(2d座標)外側ポリゴン。

多分私はあなたが実際にやっていることを誤解していました。

一般に、複雑な図形で加速する交差点は、空間分割(そして、検査が高価な場合はメールボックスのような技術)によって行われます。

[更新:元の意図を誤って読んでいます](2d)空間パー​​ティショニングを使用することはできますが、オーバーヘッドはそれに値するものではありません。個々のテストは安価です。ポリゴンが複雑でなければ、歩くほうが安いかもしれません。説明から言うのは難しい。

+0

少なくとも1つの線分に光線が当たることを保証できます。光線はポリゴンの頂点から内部に向けて投射されます。 (これは2Dです) – mpen

+1

光線が常にポリゴンの同じ点に向かって投射されることがわかっている場合は、エッジで角度を並べ替えることができます。あなたの光線にも角度がありますので、ログ(N)バイナリ検索が可能です。 –

1

スキャンライン/アクティブエッジテーブルベースの方法をお探しですか? Scanline RenderingのWikipediaエントリーを見たり、アルゴリズムのためにGraphics Gemsディレクトリを探したりすることができます(主にCですが、いくつかのC++コードも同様です)。

+0

一見、これは、ポリゴン/線分がyオーダーでソートされ、走査線が厳密に水平であるためにのみ動作するように見えます。私の光線はどんな方向にも投げることができます...これは大きな問題です。 – mpen

+0

@マーク:あなたがやろうとしていること(ポリゴンの塗りつぶしなど)を私たちに与えることができれば、いくつかの特殊なアルゴリズムを指摘することができます。 – dirkgently

1

並べ替えは最高でもO(n log n)操作です。それぞれを個別にチェックする方が良いかもしれません。

+0

それは私には問題ありません。私のアルゴリズム全体は最高でO(n^2 log n)になり、多くの光線を投射する必要があります。 – mpen

+0

ソートはO(N log N)操作ではありません。 バイエレメント推移比較のみを使用したソートは、一般的にはソートではありません。 – SPWorley

0

説明が間違っていますか?これは正しいですか?

  • ダイナミックな線分のセットLがあります。
  • 問合せ:与えられた任意の点(x、y)とし、この点から線のどの方向が、あなたはL(もしあれば)に最も近いラインを決定したいですか?

したがって、ポイント(x、y)は修正されていませんか? (任意の点、任意の方向にすることができます)

+0

それは正しい、ジェイコブ。方向は、それが関連しているならば、角度ではなく別の点によって与えられる。いくつかの光線が同じ線分のセットと比較されるので、もし私が助けてくれれば、線上でいくつかの前処理を実行する価値があるかもしれないと思います。 – mpen

+0

おそらく、私たちはおそらく、約20本の線分と、平均して5本の線を見ているだけであることを明記するべきですが、上向きの線はありません。これが効率的である必要がある理由は、かなりコストがかかる再帰的アルゴリズムの一部であるためです。 (私の実装のうちの1つは約13行を処理するのに約1分かかりましたが、それを超えて試してみることもありません)。 – mpen

+0

20行と5光線を使ったブルートフォース実装でも数ミリ秒かかりますか?あなたはどうしてそんなに長くかかりますか? – jacob

関連する問題