Алгоритм обнаружения множественных ограничивающих рамок - PullRequest
0 голосов
/ 02 июня 2018

Кто-нибудь знает алгоритм обнаружения включения нескольких ограничивающих рамок (или ссылки на реализацию) со следующим описанием:

  1. Позволяет иметь коллекцию ограничивающих рамок с осями, некоторые из них могут пересекаться
  2. и простая трехмерная форма, например сфера (или это может быть другая AABB).
  3. Мне нужен алгоритм, который может определить, полностью ли содержится форма в AABB-ов.Другими словами, никакие части сферы не находятся за пределами AABB-ов.

Проблема заключается в следующем: легко проверить содержание в одной AABB, однако есть случай, когда форма может бытьразделение между несколькими AABB-ами и даже случай, когда он может пересекать несколько AABB-ов, но некоторые части сферы находятся снаружи.

Ответы [ 3 ]

0 голосов
/ 04 июня 2018

IMO, вы можете сделать это с помощью подхода развертки.

Сортировать все AABB по их верхним и нижним "аппликациям" (координата z).Теперь рассмотрим горизонтальную плоскость, которая перемещается от лица к лицу вниз, каждый раз обновляя активный список (то есть те поля, которые соответствуют плоскости).Коробка входит в список на своей верхней грани и оставляет ее на своей нижней грани.

Раздел сцены на плоскости будет состоять из набора прямоугольников и, возможно, круга.На каждом шаге круг должен целиком содержаться в объединении прямоугольников.

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

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

Следуя тому же принципу, вы можете обратиться к последнемутехника стреловидности, сортировка прямоугольников по ординатам их верхней / нижней сторон и перемещение активного списка.На каждом шаге сечение по линии iso-y определяет набор сегментов, по одному на прямоугольник и, возможно, один для круга, и включение легко проверяется путем сортировки границ по x.

enter image description here

Иными словами, в процессе трехмерной развертки вы разбиваете пространство на призматические плиты и строите пересечения со сферой.А в процессе 2D-развертки вы разбиваете плоскость на прямоугольные плиты и строите пересечения с дисками сечений.

0 голосов
/ 05 июня 2018

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

Сначала мы должнынайти все значения z-координаты, где полное покрытие в соответствующей плоскости может измениться при движении вдоль оси z.Это может произойти при

  • максимальной и минимальной z-координате сферы (то есть z_center +/- radius)
  • максимальной и минимальной z-координатах всех блоков
  • максимальные и минимальные z-координаты всех окружностей / дуг пересечения сферы со всеми гранями ящика

После того, как эти z-значения собраны, отсортированы и ограничены z-диапазономсфера у нас есть разбиение z-диапазона сферы на интервалы.Мы выбираем значение внутри в каждом интервале z (например, в центре), чтобы проверить покрытие в соответствующей плоскости.Каждый двухмерный вырез может быть решен аналогично трехмерной задаче, что сводит проверку покрытия к набору одномерных задач.В одномерном случае у нас есть интервал вместо сферы или круга, и у нас также есть интервалы вместо прямоугольников или прямоугольников.Таким образом, проблема покрытия сферы против блоков сводится к набору тривиальных задач покрытия одного интервала с набором интервалов.

Реализация основной функции может выглядеть следующим образом:

# if the n-dimensional sphere is not fully covered by the boxes
# find a point inside the sphere but outside the boxes
# by a recursive sweep-plane algorithm.
# center: n-dimensional point
# radius: real value
# boxes: list of n-dimensional boxes (each box is a list of n intervals)
def getUncoveredSphereWitness(center, radius, boxes):
    sphereLimitsN = [center[-1]-radius, center[-1]+radius]
    if len(center) == 1: 
        # 1D case
        witness = getUncoveredIntervalWitness(sphereLimitsN, [box[0] for box in boxes])
        return [witness] if witness is not None else None

    boxLimitsN = sum([b[-1] for b in boxes], [])
    cutLimitsN = getCutLimitsN_boxes(center, radius, boxes)
    limitsN = list(set(sphereLimitsN + boxLimitsN + cutLimitsN))
    limitsN.sort()

    # get centers of relevant intervals
    coordNValsToCheck = []
    for b in limitsN:
        if b > sphereLimitsN[1]: break
        if b > sphereLimitsN[0]:
            coordNValsToCheck.append((bPrev+b)/2.)
        bPrev = b

    for z in coordNValsToCheck:
        # reduce to a problem of with 1 dimension less
        centerN1, radiusN1 = cutSphereN(center, radius, z)
        boxesN1 = cutBoxesN(boxes, z)
        witness = getUncoveredSphereWitness(centerN1, radiusN1, boxesN1)
        if witness is not None:
            return witness+[z] # lift witness to full dimension by appending coordinate

    return None
0 голосов
/ 02 июня 2018

Алгебраически эта проблема может быть выражена как проблема ограниченного удовлетворения по реалам.Условие для точки (x,y,z), находящейся внутри круга с координатами центра (cx,cy,cz) и радиусом r, равно:

C :=  (x-cx)^2 + (y-cy)^2 + (z-cz)^2 - r^2 <= 0

Условие для точки, находящейся внутри AABB:

B :=  x0 <= x /\ x <= x1 /\ y0 <= x /\ y <= y1 /\ z0 <= z /\ z <= z1

где /\ означает 'и', а x0, x1, ..., z1 - действительные числа.

Теперь, учитывая круг и несколько ограничивающих рамок, вопрос заключается в том, является ли список ограничений

C /\ !(B1 \/ ... \/ Bn)

может быть удовлетворенЕсли да, то есть точка внутри сферы, но не внутри любой AABB.Поскольку существует только три переменные x,y,z и полиномы степени не более двух существующих алгоритмов / библиотек, можно эффективно решить эту проблему.(например, Z3 , см. intro ).

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