隣接する三角形を作成するためのアルゴリズム


14

一度クリックしてシーンにノードを配置できるシステムがあります。3つのノードを配置すると、三角形が形成されます。将来のノードを配置すると、そのノードを2つの最も近い既存のノードに結合することにより、新しい三角形が作成されます。

これはほとんどの場合正常に機能しますが、2つの最も近いノードの1つは多くの場合使用すべきものではないため、非常に鋭角な三角形の近くで使用すると欠陥があります。

たとえば、次の画像を参照してください。マゼンタの三角形が最初に配置されます。次に、Xとマークされた位置をクリックすると、青いオーバーレイがある新しい三角形が表示されます。私が欲しいのは、緑のオーバーレイがある新しい三角形です。(つまり、この例では、マゼンタの三角形と対称です。明確化:緑とマゼンタの三角形は重なりません-緑の三角形は青の三角形の下で左端のノードまで延びています)

実際の動作と望ましい動作の例

三角形がこのように重ならないように、新しい三角形を作成するときに使用する既存の2つの頂点を決定するにはどうすればよいですか?

編集:最も近いエッジを検索すると、より良い結果が得られますが、完璧な結果は得られません。この状況を考慮してください:

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

「最近傍」テストはあいまいで、ABまたはACを返すことができます(両方のXに最も近い点がAにあるため)。望ましい結果はACになり、エッジが重ならないACX三角形を形成します。この結果をどのように確認できますか?(可能な場合、浮動小数点の精度の問題を考えると、最も近いエッジテストでは必ずしも2つが正確に等距離にあるとは限らないので、タイブレーカーとして個々のエッジオーバーラップテストを実行する必要はありません。)


最後に配置された5つの頂点を見て、新しく配置された頂点に最も近い2つの頂点を選択するだけでは十分ではありませんか?三角形ストリップのアルゴリズム(codercorner.com/Strips.htm)を紹介しますが、それらはしばしば最後の2つまたは最後の3つをスキップして使用します。
ロイT.

1
緑の三角形はマゼンタの三角形と重なっていますか?これの目標は何ですか?ユーザーは、三角形を作成する場所と方法を制御する必要がありますか、またはポイントクラウドの三角形分割は許容されますか?
bummzack

これをグラフコンテキストに配置するには、エッジをオーバーラップせずにノードを接続しますか?(マゼンタ/グリーンの三角形がエッジを共有すると仮定)
MichaelHouse

ロイT:いいえ-例にあるように、最も近い2つを選ぶだけでは間違っています。不明な点はありますか?Bummzack-緑のものはマゼンタのものと重ならない。目標は、これらの三角形のメッシュまたはグラフを作成することです。ユーザーには制御が必要です、はい。Byte56-はい、エッジは交差しません。
キロタン

2
ユーザーには実際に個々の三角形が表示されますか?それとも、1つの連続した表面になりますか?
-bummzack

回答:


11

ノードまでの最小距離を見つけるのではなく、エッジ(つまり、ノードで定義された線分)までの最小距離を見つけます。

次に、最も近いポイントが頂点である場合(浮動小数点イプシロン**テストを使用する必要があります)、新しいポイントから頂点までの線と、その頂点に接続された各エッジ間の角度を比較します。絶対角度が最小のものを選択します。

MinAngle(newPoint, vertex, edge1, edge2)
{
   newEdgeUnit = norm(newPoint - vertex); // don't actually need to normalize this
   edge1Unit = norm(edge1 - vertex);      // you probably have these from your dist to line tests
   edge2Unit = norm(edge2 - vertex);

   edge1Dot = dot(edge1Unit, newEdgeUnit);
   edge2Dot = dot(edge2Unit, newEdgeUnit);

   // you can simply compare dot products to find the minimum absolute angle
   if (edge1Dot > edge2Dot) return edge1;     // set up this way so you can generalize to an array
   return edge2;
}

**イプシロンテストを混乱させる可能性のある縮退三角形の追加を避けるために、ポイントの追加が禁止されている各頂点の周囲に領域を配置することができます(上記で使用されたイプシロンの倍数内のポイントを禁止するようなもの)。


3
+1-これは私見であり、他のものよりもはるかに簡単な答えであり、正しい結果を提供する可能性が高くなります。スマートスキームを使用すると、セグメントまでの距離も簡単に計算できます。
スティーブンスタドニッキー

同意して、これはよりクリーンな方法です。おそらく私がそれについてもっと考えていたら、私がたどり着いたであろうこと:/
マイケルハウス

ああ、とても近い!しかし、Byte56の答えとJimmyの図のように、2つの等距離のエッジが存在することがあり、そのうちの1つが制約に違反しています。質問を更新しました。
キロタン

@Kylotanおそらくその場合、どちらが重複するかを確認し、他のオプションを選択するだけでいいでしょうか?選択したエッジを共有する三角形を探し、既存の三角形と同じ辺に新しい三角形があるかどうかを確認します。
ケビンリード

@Kylotan三角形が常に同じ巻きになっていることを確認していますか?はいの場合、法線が新しい頂点から離れる方向を向いたエッジを除外できます(ドット積を使用)。
bummzack

6

最初の三角形を配置した後、新しい頂点を配置すると、常に2つの新しいエッジが生成されます。新しい三角形の3番目のエッジは、常に前の三角形との共有エッジになります。共有エッジを決定する方法を見つけることができた場合、どの頂点に接続するかがわかりますが、それは難しい部分です。新しい頂点から、生成された最後の3つのエッジ(またはおそらく3つの最も近いエッジ)のそれぞれの中心に線を引くことで、これを実現できる1つの方法だと思います。

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

頂点からエッジの中心までの線が他の2つのエッジのいずれとも交差しない場合、共有エッジがあります。共有エッジは、新しい頂点を接続する2つの頂点を示します。

ジミーは、新しい三角形が次のようにどこに行くかに関して曖昧な点について、ケースを提起しました。

あいまいな三角形

これにより、2つの有効な三角形から選択する機会が与えられます。おそらくタイブレークは、どの中心点が最も近いかです。

更新を考慮すると、より複雑ですが、私のソリューションでは、有効な三角形が2つある場合にのみ同点になります。この方法を使用すると、2番目のサンプル画像で目的の結果が得られます。

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


2本の線がエッジと交差しない状況が発生する可能性があります(Xがエッジよりも頂点に近い場合)
ジミー

@ジミーはそのような状況のイメージを描くことができますか?
マイケルハウス


ああ、そうだとしたら、三角形をどこに置くかという2つの選択肢があります!どちらの側でも機能します。おそらく、ブレークポイントを中心までの距離が最も短いものと結ぶことができます。
マイケルハウス

@Kylotanはこのソリューションが機能しないのですか?ジェフへのコメントで、ジミーの画像には2つのケースがあり、1つは制約に違反していると述べましたが、それは正しくありません。Jimmyの画像では、2つのケースはどちらも私の方法を使用して有効な三角形を生成します。
マイケルハウス

1

マゼンタの三角形ABCを使用して、新しい頂点Xを組み込みます。三角形ABCの​​エッジのいずれとも交差しないDから始まる2本の線があることは明らかだと思います。

これらの2行は、AXとBX、BXとCX、またはAXとCXです。次に、問題を「2本の線が交差する」という古典的な問題として扱うことができますか?次に、このペアの線のどれが、たとえばこの質問のメソッドのいずれかに続くABC三角形のエッジのいずれとも交差しないことを確認できます。したがって、新しい三角形の2つの新しいエッジがあります。


これは良いように見えますが、あなたが述べた方法は、1つの三角形のみが存在すると仮定しているようです。多くの人にどのように一般化されますか?
キロタン

ええと...あなたのXと三角形のABCが固定されている場合、私は1つだけだと思いますか?
ダン

システムは、2番目以降のすべてのノードに対して新しい三角形を作成します。
キロタン

申し訳ありませんが、私はあなたの質問を誤解しました。これを多くの三角形に拡張する方法を見てみましょう。
ダン

さて、Xに接続したときにエッジと交差しない、Xに最も近い2つの頂点を検索できると思いますか?
bummzack

1

明確な領域(以下の1、2、3)のいずれかにいるかどうかを判断するのは非常に簡単です。三角形の各エッジを2D平面として扱い、新しい点が平面のどちら側にあるかをテストします。あなたがそれらのうちの2つの中にいるが1つの外側にいる場合、その1つは新しい三角形に2つの頂点を提供する三角形のエッジに対応します。

三角形のボロノイ領域

1の内側と2の外側にいる場合、新しいポイントに最も近い三角形の部分がコーナーであるというあいまいなケースにいます。その場合、反対側のエッジ(内側にあるエッジ)と最も近い頂点(外側にある2つのプレーンで共有される頂点)の中点から2Dプレーンを形成できます。新しい平面がこの平面のどちら側にあるかに応じて、エッジを選択できます。

2Dでの平面テストは3Dと同じように機能することに注意してください。平面上のどこからでも、平面の法線(2Dではこれが線の垂直線)をポイントにベクトルをドットします。

(ちなみに、この画像のマゼンタで区切られた領域はボロノイ領域と呼ばれます。三角形の特定のフィーチャ(エッジまたは頂点)に最も近いポイントを含む空間の領域です。編集:ここでの私の用語は実際にはありません非常に正しい、これらは正確にはボロノイ領域ではありません。)


これがシーン内の複数の三角形にどのように一般化されるのか、特に最も近いフィーチャが複数の三角形で共有される可能性のある頂点である場合、すぐにはわかりません。
キロタン

@Kylotanすべての三角形に対してアルゴリズムを実行し、全体の最も近い特徴を選択します。何であれ、いくつかのタイブレークロジックが必要です。あなたが共有頂点さ最寄りの機能で終わる場合は、必要があるので、多分あなたはそれを選ぶことができ、唯一の1つの三角形のためのエッジ領域(#1、#2、#3)であること?
ジョンカルスビーク
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.