【问题标题】:Given a Grid, find which Blocks are occupied by a circular object of radius R给定一个网格,找出哪些块被半径为 R 的圆形物体占据
【发布时间】:2021-12-17 16:38:17
【问题描述】:

正如你从标题中猜到的那样,我正在尝试解决以下问题。

给定一个大小为 NxN 的网格和一个以 (x_c, y_c) 为中心的半径为 R 的圆形物体 O,找出 O 占据了哪些 Blocks。

一个例子如下图所示:

在该示例中,我希望输出为 [1,2,5,6]。

如果有人有建议或资源,我将非常感激。

【问题讨论】:

    标签: geometry grid language-agnostic robotics


    【解决方案1】:

    查找受影响的行范围:

    miny = floor(y_c-r);
    maxy = ceil(y_c+r)-1;
    

    对于每一行,通过将圆与通过它的具有最大交点的水平线相交来找到列的范围。有3种情况:

    for (y=miny; y<=maxy; ++y) {
        if (y+1 < y_c)
            ytest = y+1;
        else if (y > y_c)
            ytest = y;
        else
            ytest = y_c;
    
        // solve (x-x_c)^2 + (ytest-y_c)^2 = r^2
        ydist2 = (ytest-y_c)*(ytest-y_c);
        xdiff = sqrt(r*r - ydist2);
        minx = floor(x_c - xdiff);
        maxx = ceil(x_c + xdiff)-1;
    
        for (x=minx; x<=maxx; ++x)
            output(x,y);
    }
        
    

    【讨论】:

      【解决方案2】:

      我使用过 Python3 和 OpenCv,但它可以用任何语言完成。

      来源:

      import cv2
      import numpy as np
      import math
      
      def drawgrid(im,xv,yv,cx,cy,r):
          #params: image,grid_width,grid_height,circle_x,circle_y,circle_radius
          cellcoords = set() #i use set for unique values 
          h,w,d = im.shape
      
          #cell width,height
          cew = int(w/xv)
          ceh = int(h/yv)
      
          #center of circle falls in this cells's coords 
          nx = int(cx / cew )
          ny = int(cy / ceh )
          cellcoords.add((nx,ny))
      
      
          for deg in range(0,360,1):
              cirx = cx+math.cos(deg)*r
              ciry = cy+math.sin(deg)*r
      
              #find cell coords of the circumference point 
              nx = int(cirx / cew )
              ny = int(ciry / ceh )
              cellcoords.add((nx,ny))
      
      
      
      
          #grid,circle colors
          red = (0,0,255)
          green = (0,255,0)
      
          #drawing red lines
          for ix in range(xv):
              lp1 = (cew * ix , 0)
              lp2 = (cew * ix , h)
              cv2.line(im,lp1,lp2,red,1)
      
          for iy in range(yv):
              lp1 = (0 , ceh * iy)
              lp2 = (w , ceh * iy)
              cv2.line(im,lp1,lp2,red,1)
      
          #drawing green circle
          cpoint = (int(cx),int(cy))
          cv2.circle(im,cpoint,r,green)
      
          print("cells coords:",cellcoords)
      
      
      imw=500
      imh=500
      
      im  = np.ndarray((imh,imw,3),dtype="uint8")
      drawgrid(im,9,5, 187,156 ,50)
      
      
      cv2.imshow("grid",im)
      cv2.waitKey(0)
      

      输出:单元格坐标:{(3, 2), (3, 1), (2, 1), (2, 2), (4, 1)}

      cells coords are zero based x,y. 
      So ...
      
      1° cell top left is at (0,0) 
      2° cell  is at (1,0) 
      3° cell  is at (2,0) 
      
      1° cell of 2° row is at (0,1) 
      2° cell of 2° row is at (1,1) 
      3° cell of 2° row is at (2,1) 
      and so on ...
      
      Getting cell number from cell coordinates might be fun for you
      

      【讨论】:

      • 不适用于非常大的圆圈,不会返回光盘内部的大多数单元格。也很慢。
      • 显然,如果您需要它们,只需在找到的单元格之间添加单元格。为了加快这个过程,您可以在 for 循环语句中使用更大的角度步骤。或者更确切地说,所有与圆心距离小于圆半径的单元格。
      • 没有一个真正可靠的角度步长。您总是会错过插入点之间的正方形的一角。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-14
      • 1970-01-01
      相关资源
      最近更新 更多