将矩形拆分成相等大小的矩形?

时间:2011-05-31 15:37:05

标签: c cgrect

我需要将一个矩形(一个 CGRect 结构,即{{float x,float y},{float w,float h}})拆分成许多较小的矩形/结构,从而创建某种网格。我正在写一个窗口布局管理器,我想要一个窗口预览选项。

enter image description here

我看到了类似的问题,但我看到的算法 none (涉及ceilfloor的算法)都有效。我也试过了:

float widthOfNewRect = total.size.width / floor(sqrt(n));
float heightOfNewRect = total.size.height / ceil(sqrt(n));

有人可以在 C 中使用我的结构提供一个示例吗?

4 个答案:

答案 0 :(得分:10)

根据您的上一条评论,我假设您要将矩形拆分为大小相等的 n 子矩形,并且它们应该以行数和行数的方式对齐列相等(最后一行可能未完全填充)。如果是这样,您可以使用ceil(sqrt(n))来计算列的数量(因为正如您所猜测的那样,这是您需要的最小数量的列,以便没有比列)。然后,ceil(n / (double)numColumns)将提供为了容纳 numColumns 列中分布的 n 元素所需的行数。

至于您展示的代码:它不起作用的原因(正如您可能发现的那样)floor(sqrt(n)) * ceil(sqrt(n))可能小于 n ;例如, n = 7 就是这种情况。我建议的计算是一种更安全的方法(间接)发现行数应该是ceil(sqrt(n))还是floor(sqrt(n))

答案 1 :(得分:3)

看看这个。我知道它是用C ++而不是C语言,但算法对你来说应该是可以理解的。这段代码未经测试,但应该给你一般的想法。

std:vector<CGRect> arrange(CGRect &original, int numWindows)
{
  int columns = ceil(sqrt(numWindows));
  int fullRows = numWindows / columns;
  int orphans = numWindows % columns;   // how many 'odd-sized' ones on our bottom row.

  int width =  original.width/ columns;
  int height = original.height / (orphans == 0 ? fullRows : (fullRows+1)); // reduce height if there are orphans

  std:vector<CGRect> output;

  //Calculate rectangles
  for (int y = 0; y < fullRows; ++y)
    for (int x = 0; x < columns; ++x)
      output.push_back(CGRect(x * width, y * height, width, height));

  if (orphans > 0)
  {
    int orphanWidth = original.width / orphans);
    for (int x = 0; y < orphans; ++x)
      output.push_back(CGRect(x * orphanWidth , y * height, orphanWidth , height));
  }

  return output;
}

答案 2 :(得分:0)

您想要找到最接近sqrt(n)的n的因子。

factorMax = floor(sqrt(n));
factorY = 1;
for (x = factorMax; x > 0; x--) {
if ( (n % x) == 0 ) {
    factorY = x;
    break;
}

factorX = floor(n/factorX)

这应该为您提供相等的行和列分布。如果你选择一个素数,它将失败,因为最高因子&lt; sqrt(n)将为1。

答案 3 :(得分:0)

试试这个:

CGRect rect = myView.bounds;
    CGRect slice;
    CGRect remainder;
    /*enum CGRectEdge {
     CGRectMinXEdge,
     CGRectMinYEdge,
     CGRectMaxXEdge,
     CGRectMaxYEdge
     };*/

    //CGRectDivide(<#CGRect rect#>, <#CGRect *slice#>, <#CGRect *remainder#>, <#CGFloat amount#>, <#CGRectEdge edge#>)
    CGRectDivide(rect, &slice, &remainder, rect.size.width/2, CGRectMinXEdge);

    LOG_DBUG(@"%@", NSStringFromCGRect(rect));
    LOG_DBUG(@"%@", NSStringFromCGRect(slice));
    LOG_DBUG(@"%@", NSStringFromCGRect(remainder));