我需要将一个矩形(一个 CGRect 结构,即{{float x,float y},{float w,float h}}
)拆分成许多较小的矩形/结构,从而创建某种网格。我正在写一个窗口布局管理器,我想要一个窗口预览选项。
我看到了类似的问题,但我看到的算法 none (涉及ceil
和floor
的算法)都有效。我也试过了:
float widthOfNewRect = total.size.width / floor(sqrt(n));
float heightOfNewRect = total.size.height / ceil(sqrt(n));
有人可以在 C 中使用我的结构提供一个示例吗?
答案 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));