ポイントから三角形(3d)までの最短距離を計算します。ポイントを三角形の平面に投影し、ポイントの投影の重心座標を取得しました。しかし、座標を常に三角形の内側に固定する方法が見つかりませんでした。
検索すると、0 <= [u,v,w] と u+v+w = 1 しか見つかりませんでしたが、これはどのように解決されますか?
これは古い質問だと思いますが、実際にはまだ答えられておらず、現在、「重心座標をクランプする」という Google での最初のヒットです。
以下でp0
、p1
、p2
は三角形の頂点、 、 はu
点v
のw
重心座標ですp = p0*u + p1*v + p2*w
。私はそれを仮定していu+v+w = 1
ます。
MSN が指摘しているように、三角形の最も近い点は三角形に依存するため、u
, v
,だけの操作は機能しw
ません。
u
、v
、がすべてw
正の場合、その点は三角形の中にあり、何もする必要はありません。
それらのいずれかが負の場合、その点は対応するエッジの反対側にあります。ポイントをそのエッジに移動する必要があります。三角形の端にある点は、対応する重心座標がゼロです。残りの 2 つは、端から端までのポイントの距離です。
if ( u < 0)
{
float t = Dot(p-p1,p2-p1)/Dot(p2-p1,p2-p1);
t = Clamp01( t );
return Vector3( 0.0f, 1.0f-t, t );
}
else if ( v < 0 )
{
float t = Dot(p-p2,p0-p2)/Dot(p0-p2,p0-p2);
t = Clamp01( t );
return Vector3( t, 0.0f, 1.0f-t );
}
else if ( w < 0 )
{
float t = Dot(p-p0,p1-p0)/Dot(p1-p0,p1-p0);
t = Clamp01( t );
return Vector3( 1.0f-t, t, 0.0f );
}
else
{
return Vector3( u, v, w );
}
Clamp01()
t
と の間0
に1
ある0
場合、負の場合、または1
より大きい場合は を返します1
。は 2 つのベクトルとDot( a, b )
の内積です。a
b
ポイントから三角形までの最短距離を見つけたい場合、そのようにポイントを三角形に固定することはできません。距離はデカルト空間にありますが、重心座標はそうではありません。
三角形の外側にある三角形までのポイントの距離を決定するには、そのポイントが三角形のどのフィーチャ (線分またはコーナー) に最も近いかを決定し、そのフィーチャまでの距離を決定する必要があります。デカルト空間への変換を考慮しない方法で重心座標をクランプしても、まったく機能しません。
クランプu
しv
てから、正規化制約を維持するように0..1
設定してみてください。w = 1 - u - v
u
、v
およびw
の間にクランプする必要があります0..1
。それでおしまい。
だから例えば
[u,v,w] = [-0.17, 0.64, 1.85]
三角形の上に
[u,v,w] = [0, 0.64, 1]
誰かが知りたい場合に備えて、最初にクランプu
して、v
そしてw = 1 - u - v
クランプu
して、w
そしてv = 1 - u - w
クランプv
して、そしてそしてw
そしてu = 1 - v - w
他の2つの提案された解決策では、奇妙な出力が得られ、正しくクランプされていないようです。
おそらくより良い/より高速な方法がありますが、今のところこの作業です。