二維平面座標系中,判斷某點是否在正六邊形內 | python 實現 + 數學推導(已知正六邊形六個頂點座標)

參考:高效判斷點是否在正六邊形蜂窩內的方法

上述文章給了我們一個高效的思路:在正六邊形爲原點且中心軸與y軸重合時,如何高效判斷點是否在該正六邊形內。本文的工作是將這種情況推廣到正六邊形處於任意位置。

數學推導

本文的所有的符號意義可以參考圖。

初始條件

已知六個頂點座標,六個頂點呈逆時針順序,分別爲(x1,y1),...,(x6,y6)(x_1,y_1), ..., (x_6,y_6)。現在要判斷(xp,yp)(x_p,y_p)在不在正六邊形內。

因爲知道了六個頂點,因此:

  • 中心點可求,即爲o=(xo,yo)=(x2+x52,y2+y52)\vec{o} = (x_o, y_o) = (\frac{x_2+x_5}{2}, \frac{y_2+y_5}{2})
  • 長軸的一半可求,即爲a=(x4xo)2+(y4yo)2a = \sqrt{(x_4 - x_o)^2 + (y_4 - y_o)^2}
  • (x3x5,y3y5)(x_3 - x_5, y_3 - y_5)爲正方向的 單位向量 t53\vec{t_{53}}也可求,這個用於後文求投影用。

思路

  • 求出p點在如圖的兩條對稱軸上的投影長度xxyy
  • 如果y>ay > ax>32ax > \frac{\sqrt{3}}{2}a,則不在內;
  • 如果ay<x/3a-y < x / \sqrt{3},則不在內;
  • 否則,在正六邊形內。

投影求法

先建立向量top\vec{t_{op}},即將o點與p點連起來。

top=(xpxo,ypyo)\vec{t_{op}} = (x_p - x_o, y_p - y_o)

則,x即爲topt53\vec{t_{op}} \cdot \vec{t_{53}}

而由勾股定理,y易求。

y=top2x2y = \sqrt{||\vec{t_{op}}||^2 - x^2}

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

我做了幾個點,測試了幾次,感官上是對的。

如果有錯誤,請指出,不勝感謝!

[email protected]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章