3D 仮想世界でゲームを作成しています。t1、t2、t3、t4、t5、t6 の番号が付けられた 6 つの正三角形を使用して六角形を作成しました。
六角形内の x、y 座標が与えられた場合、その点がどの三角形にあるかを決定するためにどの式を使用できますか?
ポイントが六角形の内側にあり、三角形の向きがわかっている場合は、中心に対するポイントの角度を計算できます。
atan2((y-yc)/(x-xc)).
x == xc
角度が y に応じて +90 度または -90 度 (PI/2 または -PI/2 ラジアン) の場合。
(持っていない場合はatan2
、象限を手動で確認する必要があります: を参照してください
三角形の内側の点のテスト (A、B、および C は、(x,y) として表される三角形の頂点です):
// Compute vectors
v0 = C - A // Which means v0[x] = C[x] - A[x], v0[y] = C[y] - A[y]
v1 = B - A // etc.
v2 = P - A
// Compute dot products
dot00 = dot(v0, v0) // dot(a,b) is a[x]*b[x]+a[y]*b[y]
dot01 = dot(v0, v1)
dot02 = dot(v0, v2)
dot11 = dot(v1, v1)
dot12 = dot(v1, v2)
// Compute barycentric coordinates (faster using inverse, but clearer this way)
denom = (dot00 * dot11 - dot01 * dot01)
u = (dot11 * dot02 - dot01 * dot12) / Denom
v = (dot00 * dot12 - dot01 * dot02) / Denom
// Check if point is in triangle
return (u >= 0) && (v >= 0) && (u + v < 1)
from http://www.blackpawn.com/texts/pointinpoly/default.html
計算を保存することで、50 ~ 66% の時間を節約できることに注意してください。すべての三角形には共通の 2 つの頂点があります。もちろん、テストできるのはそのうちの5 つだけです:-)
(x,y) 座標を極座標に変換できます。
六角形には 6 つの正三角形があるため、各「三角形の境界」は Pi/3 ラジアンで区切られています。したがって、シータ角がわかれば、自分がどの三角形に属しているかを推測できます。
ポイントが1つの三角形を形成する線の同じ側にあるかどうかを確認することでそれを行うことができます. 引き続き 6 つの三角形をチェックし、適合するものを見つけます。
三角形を形成する線の方程式を見つけ、各方程式にチェック対象の点の座標を入れます (各方程式の「x」が同じ符号を持っていることを確認してください)。結果の値に 2 つの同じ符号と 1 つの異なる符号がある場合、その点は三角形の内側にあります。
実際には、あなたの場合、直線の方程式は 9 つあります。六角形の中心に原点を取ると、直線の方程式は非常に簡単になります。これらの 9 つの値を見つけて、前述の条件を満たす 3 つの値を検索するだけです。これら 3 つの値の親方程式が三角形を構成します。
直観的に、ポイントは頂点が平均してポイントに近い三角形の内側にあるはずです。
中央の頂点は、すべての三角形で共有されているため、無視できます。
ポイントまでの距離で並べ替えられた残りの頂点 (隣接する三角形によって共有されるため、合計 6 つ) がある場合、探している三角形は、昇順でトラバースするリストで最も遠い頂点が最初に見つかった三角形です。