Разделить прямоугольник на прямоугольники одинакового размера?
мне нужно разделить прямоугольник (a 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 ответов
основываясь на вашем последнем комментарии, я предполагаю, что вы хотите разделить свой прямоугольник на n subrectangles равного размера, и что они должны быть выровнены таким образом, что количество строк и количество столбцов равны (с последней строкой, возможно, не заполняется полностью). Если это так, вы можете использовать ceil(sqrt(n))
для вычисления числа колонки (так как это, как вы, по-видимому, догадались, наименьшее количество столбцов вам нужно, чтобы не иметь больше строк чем колонки). Затем количество строк, необходимое для размещения n элементы распределены по numColumns столбцы будут даны ceil(n / (double)numColumns)
.
Что касается кода, который вы показали: причина, по которой он не работает (как вы, вероятно, обнаружили сами), что floor(sqrt(n)) * ceil(sqrt(n))
вполне может быть менее n; например, это относится к n = 7. Расчет я предлагаю более безопасный способ (косвенно) определить количество строки должны быть ceil(sqrt(n))
или floor(sqrt(n))
.
взгляните на это. Я знаю, что это на 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;
}
вы хотите найти коэффициенты n, которые ближе всего к sqrt (n).
factorMax = floor(sqrt(n));
factorY = 1;
for (x = factorMax; x > 0; x--) {
if ( (n % x) == 0 ) {
factorY = x;
break;
}
factorX = floor(n/factorX)
Это должно дать вам равномерное распределение строк и столбцов. Он потерпит неудачу, если вы выберете простое число, так как самый высокий коэффициент
попробуйте это:
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));