ABとCDの2つのセグメント(赤)があります。これらの2つのセグメントは互いに向き合っています。それらは完全に平行ではありませんが、互いに垂直になることもありません。
それから、互いに反対のこれらのセグメントの2つの法線(青色)を見つける必要があります(つまり、2つの法線はABCDの外側にあります)。セグメントの法線を計算する方法は知っていますが、明らかに各セグメントには2つの法線があり、プログラムで必要な法線を選択する方法がわかりません。なにか提案を?
ABからCDを指す、2つのセグメントの中点間のベクトルvを計算します。ここで、ABのvへの目的の法線の投影は負である必要があり、CDのvへの目的の法線の投影は正である必要があります。したがって、法線を計算し、vと照合し、必要に応じて法線を否定して、条件を満たします。
これがPythonです:
# use complex numbers to define minimal 2d vector datatype
def vec2d(x,y): return complex(x,y)
def rot90(v): return 1j * v
def inner_prod(u, v): return (u * v.conjugate()).real
def outward_normals(a, b, c, d):
n1 = rot90(b - a)
n2 = rot90(d - c)
mid = (c + d - a - b) / 2
if inner_prod(n1, mid) > 0:
n1 = -n1
if inner_prod(n2, mid) < 0:
n2 = -n2
return n1, n2
エンドポイントが問題の条件を満たす線を定義すると仮定していることに注意してください。また、線が同じ中点を持っている場合、エッジケースをチェックしません。その場合、「外部」の概念は適用されません。
考慮すべき2つのケースがあると思います。
ケース1:線の間の交差は、いずれかのセグメントの端点の外側で発生します。
この場合、@ MichaelJ.Barberによって提案された中点法が確実に機能します。したがって、セグメントの中点間にベクトルを形成し、この中点ベクトルを使用して法線ベクトルの内積を計算し、符号を確認します。
の法線を計算している場合lineA
、法線とベクトルの内積midB -> midA
はである必要があります+ve
。
ケース2:線間の交差は、1つのセグメントの端点の内側で発生します。
この場合、交点を囲まないセグメントの端点のいずれかと交点自体の間にベクトルを形成します。
交点とこの新しいベクトルを囲むセグメントの内積は、である必要+ve
があります。
2つの法線間の内積が-ve
(垂直セグメントの場合にのみあいまいになる)であることを要求することにより、他のセグメントの外向きの法線を見つけることができます。
セグメントは同一直線上にないか、実際には交差していないと仮定しました。
お役に立てれば。
次のように、標識の4つの組み合わせを減らすことができます。
法線の内積を計算します。負の符号は、両方が外側または内側に表示されることを示します。
法線の単位は長さだと思いますが、内積の大きさが1であれば、平行度を検出できます。正の値は両方が同じ方向に表示されることを示し、負の値は両方が異なる方向に表示されることを示します。
x(t) = x0 + t * n
法線が平行ではない場合:法線と同様に線をパラメータ化し、両方が交差する線n
を計算します。t
負の値t
は、両方が外側に表示されることを示します。手順1で組み合わせを4から2に減らしたので、法線の1つに対してこれを行うだけで十分です。
両方の法線が平行である場合:法線がt
セグメント間の中間点に到達する時間を計算します。ステップ1で組み合わせを4から2に減らしたので、法線の1つに対してこれを行う場合は、2のように十分です。