上述文章給了我們一個高效的思路:在正六邊形爲原點且中心軸與y軸重合時,如何高效判斷點是否在該正六邊形內。本文的工作是將這種情況推廣到正六邊形處於任意位置。
數學推導
本文的所有的符號意義可以參考圖。
初始條件
已知六個頂點座標,六個頂點呈逆時針順序,分別爲。現在要判斷在不在正六邊形內。
因爲知道了六個頂點,因此:
- 中心點可求,即爲
- 長軸的一半可求,即爲
- 以爲正方向的 單位向量 也可求,這個用於後文求投影用。
思路
- 求出p點在如圖的兩條對稱軸上的投影長度和;
- 如果或,則不在內;
- 如果,則不在內;
- 否則,在正六邊形內。
投影求法
先建立向量,即將o點與p點連起來。
則,x即爲。
而由勾股定理,y易求。
python 程序實現
def isInGrid(x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, x_p, y_p):
x_o = (x2 + x5) / 2
y_o = (y2 + y5) / 2
A = (
(x4 - x_o)**2 + (y4 - y_o)**2
) ** 0.5
A1 = 3 ** 0.5 / 2 * A
T_module = (
(x3 - x5)**2 + (y3 - y5)**2
) ** 0.5
# T 即爲單位向量 t_53
T = (
(x3 - x5) / self.T_module,
(y3 - y5) / self.T_module,
)
t_op = (x_p - x_o, y_p - y_o)
x = abs(t_op[0] * T[0] + t_op[1] * T[1])
y = abs(t_op[0] * T[1] - t_op[1] * T[0])
if y > A or x > A1:
return False
if A < 3 ** 0.5 / 3 * x + y:
return False
return True
我做了幾個點,測試了幾次,感官上是對的。
如果有錯誤,請指出,不勝感謝!