二维平面坐标系中,判断某点是否在正六边形内 | python 实现 + 数学推导(已知正六边形六个顶点坐标)

参考:高效判断点是否在正六边形蜂窝内的方法

上述文章给了我们一个高效的思路:在正六边形为原点且中心轴与y轴重合时,如何高效判断点是否在该正六边形内。本文的工作是将这种情况推广到正六边形处于任意位置。

数学推导

本文的所有的符号意义可以参考图。
二维平面坐标系中,判断某点是否在正六边形内 | python 实现 + 数学推导(已知正六边形六个顶点坐标)_第1张图片

初始条件

已知六个顶点坐标,六个顶点呈逆时针顺序,分别为 ( x 1 , y 1 ) , . . . , ( x 6 , y 6 ) (x_1,y_1), ..., (x_6,y_6) (x1,y1),...,(x6,y6)。现在要判断 ( x p , y p ) (x_p,y_p) (xp,yp)在不在正六边形内。

因为知道了六个顶点,因此:

  • 中心点可求,即为 o ⃗ = ( x o , y o ) = ( x 2 + x 5 2 , y 2 + y 5 2 ) \vec{o} = (x_o, y_o) = (\frac{x_2+x_5}{2}, \frac{y_2+y_5}{2}) o =(xo,yo)=(2x2+x5,2y2+y5)
  • 长轴的一半可求,即为 a = ( x 4 − x o ) 2 + ( y 4 − y o ) 2 a = \sqrt{(x_4 - x_o)^2 + (y_4 - y_o)^2} a=(x4xo)2+(y4yo)2
  • ( x 3 − x 5 , y 3 − y 5 ) (x_3 - x_5, y_3 - y_5) (x3x5,y3y5)为正方向的 单位向量 t 53 ⃗ \vec{t_{53}} t53 也可求,这个用于后文求投影用。

思路

  • 求出p点在如图的两条对称轴上的投影长度 x x x y y y
  • 如果 y > a y > a y>a x > 3 2 a x > \frac{\sqrt{3}}{2}a x>23 a,则不在内;
  • 如果 a − y < x / 3 a-y < x / \sqrt{3} ay<x/3 ,则不在内;
  • 否则,在正六边形内。

投影求法

先建立向量 t o p ⃗ \vec{t_{op}} top ,即将o点与p点连起来。

t o p ⃗ = ( x p − x o , y p − y o ) \vec{t_{op}} = (x_p - x_o, y_p - y_o) top =(xpxo,ypyo)

则,x即为 t o p ⃗ ⋅ t 53 ⃗ \vec{t_{op}} \cdot \vec{t_{53}} top t53

而由勾股定理,y易求。

y = ∣ ∣ t o p ⃗ ∣ ∣ 2 − x 2 y = \sqrt{||\vec{t_{op}}||^2 - x^2} y=top 2x2

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]

你可能感兴趣的:(数学建模与算法,python,算法,数据结构,数学,GPS,GIS)