用矩形填充直线多边形

时间:2011-05-03 21:52:51

标签: algorithm geometry

给定一个多边形,完全由矩形创建,并由一个点数组定义,其中边始终与轴对齐:

a polygon created entirely from intersecting rectangles

我正在尝试确定一种快速算法,以找到可以填充此形状的少量矩形。这是我手工绘制的,用于显示我描述的矩形集合:a polygon created entirely from intersecting rectangles filled with non-overlapping rectangles

修改 这里有一些简单的processing代码来创建这个形状(好吧,靠近它)。

float[] xpts = {0,    50,  50,  100, 100, 150, 150, 250, 250, 300, 300, 325, 325, 300, 300, 250, 250, 210, 210, 250, 250, 125, 125, 25, 25,   50,  50,  0 };
float[] ypts = {100, 100,  80,   80, 10,   10,  80, 80,  75,  75, 80,   80,  200, 200, 300, 300, 275, 275, 260, 260, 200, 200, 270, 270, 165, 165, 125, 125};


void setup( )
{
  size( 350, 350 );
}

void draw( )
{

stroke( 0 );
strokeWeight( 1.5 );

float px = xpts[0];
float py = ypts[0];
for (int i=1; i < xpts.length; i++)
{
  float nx = xpts[i];
  float ny = ypts[i];
  line( px, py, nx, ny );


  px = xpts[i];
  py = ypts[i];
}
float nx = xpts[0];
float ny = ypts[0];

line( px, py, nx, ny );
}

3 个答案:

答案 0 :(得分:6)

使用现有边作为分割器平面构建KD树,并在递归期间忽略完全位于多边形外部的区域。然后叶节点将构成矩形分解。

获得良好的分解只是在递归的每个步骤中选择哪个拆分器的问题。您可能希望使用一个简单的启发式方法,将每一步的剩余区域减半。如果你愿意,你也可以尝试一些不同的分割器!

这是一些伪代码:

function makeRects(Rect r, Polygon p)

  if p is empty
    if r is inside your original polygon
      add r to results

  else
    choose good splitter s

    makeRects(left part of r relative to s, left part of p relative to s)
    makeRects(right part of r relative to s, right part of p relative to s)

Splitters for the OPs sample decomposition

答案 1 :(得分:1)

对我来说听起来很像NP问题。这意味着,如果矩形的数量对你来说并不重要,但是如果坚持最小的数字上,那么肯定会有一些算法可以用矩形快速填充你的形状。 ,那么你最好忘记“ quick ”这个词。实际上你甚至应该忘记“最小”这个词,而是使用“ small ”,因为确定该集合是否最小可能已经成为算法的一个大问题。 / p>

答案 2 :(得分:1)