【问题标题】:Finding if a circle is fully contained within multiple triangles?查找一个圆是否完全包含在多个三角形中?
【发布时间】:2021-03-03 10:02:56
【问题描述】:

在游戏中,区域由永不重叠的三角形定义,角色由圆形定义。 我如何知道整个角色的碰撞圈是否包含在这些三角形中? 示例图片:

这里,红色部分是三角形的外部,所以圆圈不包含在其中。有没有算法可以检测到这一点?

我只提出了“不完美”的解决方案,例如在圆的边界处采样点,然后测试每个点是否在三角形内。

【问题讨论】:

    标签: math collision-detection


    【解决方案1】:

    所以基本上,三角形形成了一个具有多边形边界的域,您想检查由中心点和半径定义的圆盘是否包含在域内。因此,如果您从三角形开始,您必须找到一种方法来提取域的多边形边界并将其表示为形状为 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))
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-21
      • 1970-01-01
      • 2014-05-20
      • 2021-10-27
      • 1970-01-01
      • 1970-01-01
      • 2011-05-11
      • 2012-10-20
      相关资源
      最近更新 更多