math - 查找一个圆是否完全包含在多个三角形中?
问题描述
在游戏中,区域由永不重叠的三角形定义,角色由圆形定义。我如何知道整个角色的碰撞圈是否包含在这些三角形中?示例图片:
在这里,红色部分是外部三角形,因此圆圈不包含在其中。有没有一种算法可以检测到这一点?
我只提出了“不完美”的解决方案,比如在圆的边界采样点,然后测试每个点是否在三角形内。
解决方案
所以基本上,三角形形成一个具有多边形边界的域,您想检查由中心点和半径定义的磁盘是否包含在域内。因此,如果您从三角形开始,您必须找到一种方法来提取域的多边形边界并将其表示为形状为 n 行和两列的二维数组(矩阵),以便每一行都是顶点的两个坐标多边形边界线的点和点是有序的,以便它们在逆时针位置沿边界连续排列,即当您从索引点i
到下一个点i+1
的方向上行走时,域保持在您的左侧。例如,这是像您这样的域的多边形边界的表示:
a = 4/math.sqrt(3)
Pgon = np.array([[0,0],
[a,0],
[2*a,-1],
[2*a+4,0],
[2*a+4,4],
[2*a,4],
[2*a,2],
[a,1],
[a,4],
[0,0]])
观察第一个点和最后一个点是相同的。
在这种情况下,也许您可以尝试以下算法:
import numpy as np
import math
def angle_and_dist(p1, p2, o):
p12 = p2 - p1
op1 = p1 - o
op2 = p2 - o
norm_p12 = math.sqrt(p12[0]**2 + p12[1]**2)
norm_op1 = math.sqrt(op1[0]**2 + op1[1]**2)
norm_op2 = math.sqrt(op2[0]**2 + op2[1]**2)
p12_perp = np.array([ - p12[1], p12[0] ])
h = - op1.dot(p12_perp)
theta12 = op1.dot(op2) / (norm_op1*norm_op2)
theta12 = math.acos( theta12 )
if h < 0:
theta12 = - theta12
if op1.dot(p12) > 0:
return theta12, norm_op1
elif op2.dot(p12) < 0:
return theta12, norm_op2
else:
return theta12, h/norm_p12
def is_in_polygon(p, disk):
o, r = disk
n_p = len(p)-1
index_o = 0
h_min = 400
for i in range(n_p):
theta, h = angle_and_dist(p[i,:], p[i+1,:], o)
index_o = index_o + theta
if 0 <= h and h < h_min:
h_min = h
if theta <= math.pi/100:
return 'center of disc is not inside polygon'
elif theta > math.pi/100:
if h_min > r:
return 'disc is inside polygon'
else:
return 'center of disc is inside polygon but disc is not'
a = 4/math.sqrt(3)
Pgon = np.array([[0,0],
[a,0],
[2*a,-1],
[2*a+4,0],
[2*a+4,4],
[2*a,4],
[2*a,2],
[a,1],
[a,4],
[0,0]])
# A test example:
#disc = (np.array([3*a/4, 2]), a/4-0.001)
disc = (np.array([3*a/4, 2]), math.sqrt(3)*a/8 - 0.0001)
print(is_in_polygon(Pgon, disc))
推荐阅读
- python - 尝试使用 locale.atof() 更改数据帧内的小数周期以使用 pivot_tables 进行转换
- c# - 迭代具有不同结构的类
- ios - 在 Pod 中使用“GooglePlacesRow”时没有此类模块“Eureka”错误
- git - Git 预提交挂钩未按预期工作
- asp.net-mvc - IIS ASP.net 获取用户在没有登录的情况下访问该站点的 Windows 用户名
- svn - 更改 SVN 存储库(远程)保持工作副本更改
- r - 将数据帧的每个值乘以通过 id 搜索的另一个数据帧的行
- java - 我的recycleview 不起作用。你能帮助我吗?
- javascript - qtip 隐藏特定元素的工具提示
- java - 值始终为空