Разделить прямоугольник на прямоугольники одинакового размера?

мне нужно разделить прямоугольник (a CGRect структура, которая составляет {{float x,float y},{float w,float h}}) в несколько меньших прямоугольников/структур, создавая своего рода сетку. Я пишу диспетчер макетов окон, и мне нужен параметр предварительного просмотра окна.

enter image description here

Я видел подобные вопросы, но нет алгоритмов, которые я видел (с участием 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));