座標系の変換
まず、セットアップをより簡単な座標の何かに変換することをお勧めします。
- あなたのポイントを取る
p = (x, y)
。
(-x0, -y0)
光線が中央から始まるように移動します。
-a
光線がx軸上にくるように回転させます。
これまでのところ、上記の操作では、ポイントごとに4つの加算と4つの乗算が必要です。
ca = cos(a) # computed only once
sa = sin(a) # likewise
x' = x - x0
y' = y - y0
x'' = x'*ca + y'*sa
y'' = y'*ca - x'*sa
交差点の確認
y''
これで、ポリラインのセグメントは、その値の符号が変更された場合にのみ光線と交差することがわかりますy1'' * y2'' < 0
。x''
このチェックが完了するまで、値の計算を延期することもできます。さらに、セグメントとx軸との交差がx > 0で発生する場合にのみ、セグメントは光線と交差します。これは、いずれかの値がゼロより大きい場合にのみ発生する可能性がありますx1'' > 0 or x2'' > 0
。両方x''
がゼロより大きい場合は、交差点があることがわかります。
次の段落は一種のオプションです。理解していなくても心配しないでください。後で説明する代替案があります。
一方x''
が正でもう一方が負の場合は、さらに確認する必要があります。y''
の符号が負から正に変わったと仮定しy1'' < 0 < y2''
ます。からの線は、三角形がによって形成され、原点が反時計回りに向けられている場合にのみ、x >0でx軸と交差しp1''
ます。行列式の符号を調べることにより、その三角形の方向を決定できますp2''
p1''
p2''
x1''*y2'' - x2''*y1''
、反時計回りの三角形の場合は正になります。符号の変更の方向が異なる場合は、方向も異なる必要があります。したがって、これをまとめるために、次のことを確認できます。
(x1'' * y2'' - x2'' * y1'') * y2'' > 0
その場合は、交差点があります。これまでのところ、費用のかかる部門は含まれていなかったことに注意してください。
交差点の計算
交差点が存在するかどうかを判断するだけでなく、実際に特定の交差点を見つけたいので、次にその交差点を計算する必要があります。それを呼びましょうp3
。それは方程式を満たさなければなりません
(x2'' - x3'')/(y2'' - y3'') = (x1'' - x3'')/(y1'' - y3'') and
y3'' = 0
その結果、
x3'' = (x1'' * y1'' - x2'' * y2'')/(y1'' - y2'')
前の段落の三角形の向きのチェックの代わりに、いつでもこのx3''
値を計算して、負であることが判明した結果を破棄することができます。コードは少なくなりますが、分割は多くなります。パフォーマンスに疑問がある場合はベンチマーク。
光線の原点に最も近いポイントを見つけるには、最小x3''
値で結果を取得し、それを元の位置に戻すことができます。
x3 = x3''*ca + x0
y3 = x3''*sa + y0
あります。
上記のすべては、すべての数値が正または負のいずれかであると想定していることに注意してください。ゼロがある場合は、実際に計算したいものの正確な解釈、これらの境界ケースをどのように処理したいかによって異なります。