Создайте оптимальную сетку, основанную на n-элементах, общей площади и соотношении H: W - PullRequest
11 голосов
/ 18 августа 2010

Я создаю приложение, которое берет несколько прямоугольников одинакового размера и размещает их в сетке на экране.У меня есть большая часть логики для изменения размера и центрирования прямоугольника внутри ячейки, но у меня возникли проблемы с фактической частью, которая определяет сетку, которой должны соответствовать прямоугольники.

В идеале, в конце я быесть функция, подобная этой (псевдокод):


function getGridDimensions (rect surface, int numItems, float hwRatio) {
    // do something to determine grid-height and grid-width
    return gridDimensions;
}

Мой первоначальный удар при этом включал что-то вроде этого:


gridHeight = surface.width / sqrt(numItems);
gridWidth = surface.height / sqrt(numItems);

Это бы хорошо работало, если бы все мои вещи были идеальными квадратами, но поскольку они прямоугольники, в каждой ячейке много неиспользуемого пробела.

Какие-нибудь мысли или термины в Google, которые могли бы указать мне правильное направление?

1 Ответ

15 голосов
/ 18 августа 2010

Мне немного неясно некоторые из ваших входных параметров, но я предполагаю, что у вас есть высота и ширина прямоугольника, количество прямоугольников и идеальное соотношение высоты и ширины (то есть предпочтительная высота сетки / ширина сетки).

Если это так, то, вероятно, я бы начал с "нормализации" ваших размеров, поэтому в целях следующих вычислений мы говорим, что единица ширины равна ширине прямоугольника, а также для единицырост.Если бы ваше отношение высоты / ширины в реальных единицах было k, тогда ваше отношение высоты / ширины в единицах Rectange было бы равно k * RectWidth / RectHeight.Я назову это K.

Так что теперь каждый прямоугольник по определению имеет площадь 1, поэтому наша общая площадь равна N, где N - количество элементов.Затем мы можем аппроксимировать нашу высоту добавления ширины, чтобы задать себе предпочтительное соотношение сторон сетки:N / K).

Если вы округлите одно из этих значений до подходящего целого числа (я не уверен, что, какое бы ни было ближайшее целое число, округленное даст вам лучший результат или если его округление дастНаименьшее процентное изменение в этом значении является наилучшим - вы всегда можете попробовать все четыре, если вам так важно).Когда у вас есть одно целочисленное значение, вы вычисляете другое, находя наименьшее целое число, которое может умножить другое и все же быть больше, чем N, чтобы убедиться, что вы вписываете все прямоугольники в сетке).

Тогда вы, конечно, можетеизмените ваши целочисленные значения обратно на действительные, умножив высоту на rectHeight и ширину на RectWidth.

Надеюсь, что все это имеет смысл.:)

Редактировать для обработанного примера:

Требуемое конечное соотношение сторон сетки = 1024/768 (k) (предполагается, что 768 - ширина, а 1024 - высота - я сохранилжелая выразить это как стандартное разрешение экрана :))

«Нормализованное» соотношение сторон = (1024/768) * (300/109) = 3.6697 (K)

Таким образом, высота сетки равна sqrt (KN) = sqrt (366.97) = 19.16

Ширина сетки равна sqrt (N / K) = 5.22

Глядя на это, мы интуитивно видим, что ширина 5 и высота20 будет нашим лучшим матчем.Другими вариантами могут быть 6 и 19. Но это будет тратить больше места (я думаю, возможно, на самом деле минимизация произведения ширины и высоты здесь - лучший расчет, но я не уверен).

ЭтоТеперь наш размер сетки в ячейках.Затем это масштабируется до размеров пикселя 1500 к 2180. Уменьшение до 768x1024 означает деление на 2.129 (большее из 1500/768 и 2180/1024).Таким образом, ваши изображения будут уменьшены в 2,129 раза до 141x51 (изобразительный), а общая используемая площадь будет на самом деле 705x1020, что должно давать минимальный пробел.

Надеюсь, теперь это имеет больше смысла.Признаюсь, я несколько раз ошибался, вставляя реальные ценности, поэтому я полностью понимаю, почему вы хотели получить удачный пример.; -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...