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

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

enter image description here

Я видел похожие вопросы, но none алгоритмов, которые я видел (те, которые связаны с ceil и floor), работали. Я также пробовал:

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

Может ли кто-нибудь привести пример моей структуры в C?

Ответ 1

Основываясь на вашем последнем комментарии, я предполагаю, что вы хотите разделить свой прямоугольник на n субэлементов равного размера и что они должны быть выровнены таким образом, чтобы количество строк и количество столбцов были равны (с последним строка, возможно, не полностью заполнена). Если это так, вы можете использовать ceil(sqrt(n)) для вычисления количества столбцов (так как это, как вы, наверное, догадались, наименьшее количество столбцов вам нужно, чтобы не было больше строк, чем столбцов). Затем количество строк, необходимое для размещения n элементов, распределенных по столбцам numColumns, будет указано ceil(n / (double)numColumns).

Что касается кода, который вы показали: причина, по которой он не работает, (как вы, вероятно, обнаружили), что floor(sqrt(n)) * ceil(sqrt(n)) может быть меньше n; например, это имеет место для n = 7. Расчет, который я предлагаю, является более безопасным способом (косвенно) выяснить, должно ли число строк быть ceil(sqrt(n)) или floor(sqrt(n)).

Ответ 2

Посмотрите на это. Я знаю это на С++, а не на 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;
}

Ответ 3

Вы хотите найти коэффициенты 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)

Это должно дать вам равное распределение строк и столбцов. Это не удастся, если вы выберете простое число, поскольку самый высокий коэффициент < sqrt (n) будет равно 1.

Ответ 4

Попробуйте следующее:

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));