13

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

在此处输入图像描述

我看到了类似的问题,但看到的算法(涉及ceil和的算法floor)都不起作用。我也试过:

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

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

4

4 回答 4

12

根据您的最后评论,我假设您要将矩形拆分为n 个大小相等的子矩形,并且它们应该以行数和列数相等的方式对齐(最后一行可能不是被完全填满)。如果是这样,您可以使用它ceil(sqrt(n))来计算数(因为正如您显然已经猜到的那样,这是您需要的最少列数,以便行数不超过列数)。然后,为了容纳分布在numColumns列中的n 个元素,您需要的行数将由 给出。ceil(n / (double)numColumns)

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

于 2011-05-31T15:47:38.367 回答
4

看看这个。我知道它是 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;
}
于 2011-05-31T16:21:12.690 回答
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)

这应该给你行和列的平等分布。如果您选择质数,它将失败,因为最高因子 < sqrt(n) 将为 1。

于 2011-05-31T15:59:15.733 回答
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));
于 2013-08-16T13:37:44.227 回答