Как я могу лучше упаковать прямоугольники, касательные к сфере для 3D-галереи? - PullRequest
2 голосов
/ 17 марта 2011

Я создаю 3D-галерею сфер с помощью ActionScript 3 и API-интерфейсов Flash 10 3D (2.5D).Я нашел метод, который работает, но не идеален.Я хотел бы увидеть, если есть лучший метод.

Мой алгоритм выглядит следующим образом:

Let n = the number of images
    h = the height of each image
    w = the width of each image
  1. Приблизить радиус круга, предполагая (неправильно), что поверхностьПлощадь изображений равна площади поверхности сферы, которую мы хотим создать.
    Чтобы вычислить радиус, решите для r в nwh = 4πr<sup>2</sup>.Это та часть, которую нужно улучшить.
  2. Рассчитать угол между рядами.
    rowAngle = 2atan(h / 2 / r).
  3. Рассчитать количество строк.
    rows = floor(π / rowAngle).
  4. Поскольку первый шаг является приблизительным, количество строк не будет идеально соответствовать, поэтому дляпрезентация добавить отступы rowAngle.
    rowAngle += (π - rowAngle * rows) / rows.
  5. Для каждого i in rows:

    1. Рассчитать радиус круга широты длястрока.
      latitudeRadius = radius * cos(π / 2 - rowAngle * i.
    2. Расчет угла между столбцами.
      columnAngle = atan(w / 2 / latitudeRadius) * 2.
    3. Расчет количества столбцов.
      columns = floor(2 * π / columnAngle)
    4. Поскольку первый шаг является приблизительным, количество столбцов не будет соответствовать идеально, поэтому для презентации добавьте отступ для columnAngle.
      columnAngle += (2 * π - columnAngle * column) / column.
    5. Для каждого j в columns переведите-radius вдоль оси Z, поверните π / 2 + rowAngle * i вокруг оси X и поверните columnAngle * j вокруг оси Y.

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

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

Ответы [ 2 ]

3 голосов
/ 17 марта 2011

Я бы разделил эту проблему на две связанные задачи.

  1. Учитывая радиус, как вы упаковываете вещи в сферу?

  2. Учитывая ряд вещей, как вы находите правильный радиус?

Если у вас есть решение по первой проблеме, вторую легко решить.Здесь это в псевдокоде.

lowerRadius = somethingTooSmall

fittedItems = itemsForRadius(lowerRadius)

while fittedItems < wantedItems:
    lowerRadius *= 2
    fittedItems = itemsForRadius(lowerRadius)

upperRadius = 2 * lowerRadius

while threshold < upperRadius - lowerRadius:
    middleRadius = (upperRadius + lowerRadius)/2
    if itemsForRadius(middleRadius) < wantedItems:
        lowerRadius = middleRadius
    else:
        upperRadius = middleRadius

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

Теперь давайте обратимся к первой проблеме.У вас очень разумный подход.Хотя есть одна серьезная ошибка.Ошибка в том, что ваш columnAngle не должен рассчитываться для середины строки.Что вам нужно сделать, это выяснить широту, в которой ваши предметы находятся ближе всего к полюсу, и использовать это для расчета.Вот почему, когда вы пытаетесь уместить 10 предметов, вы обнаруживаете упаковку, в которой углы перекрываются.

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

Кстати, мне нравится идея.Это выглядит красиво.

2 голосов
/ 17 марта 2011

В случае квадратов, это, кажется, приблизительная формула для знания взаимосвязи между радиусом, стороной квадрата и количеством внедренных квадратов.

После это число квадратов:

Floor[4 Pi/Integrate[(x^2 + y^2 + r^2)^(-3/2), {x, -a/2, a/2}, {y, -a/2, a/2}]]

или

Floor[(Pi r)/ArcCot[(2 Sqrt[2] r Sqrt[a^2+2 r^2])/a^2]]  

, где

   r = Radius
   a = Square side

Если вы построите график для r = 1, как функцию от:

enter image description here

Где вы можете увидеть случай, когда a = 2 - это граница для n = 6, что означает куб:

enter image description here

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

Редактировать

Для прямоугольников соответствующая формула имеет вид:

 Floor[4 Pi/Integrate[(x^2 + y^2 + r^2)^(-3/2), {x, -a/2, a/2}, {y, -b/2, b/2}]]

, что дает:

Floor[(2 Pi r)/(Pi-2 ArcTan[(2 r Sqrt[a^2+b^2+4 r^2])/(a b)])]

где

   r   = Radius
   a,b = Rectangle sides

Предположим, нам нужны прямоугольники с одной боковой половинойдругой (b = a / 2) и сфера радиуса 1.

Таким образом, число прямоугольников как функция a дает:

enter image description here

Где вы можете видеть, что прямоугольник с «большой» стороной размера 2 допускает 10 прямоугольников в сфере, в то время как прямоугольник с «большой» стороной 4 допускает только 4 прямоугольника.

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