Математика для 2D обнаружения столкновений между OBB и окружностью - PullRequest
5 голосов
/ 15 марта 2010

Я создаю 2D-игру и хочу проверить столкновение между OBB (Oriented Bounding Box) и Кругом. Я не уверен в математике и коде, чтобы сделать это. Я создаю игру на C ++ и OpenGL.

Ответы [ 3 ]

8 голосов
/ 15 марта 2010

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

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

Ссылки и общий ответ взяты из этого вопроса .

1 голос
/ 15 марта 2010

Вот что я бы сделал в псевдокоде:

function does_line_go_through_circle (original_line, circle_centerpoint, radius):
    original_slope = get_slope_of_line (original_line)
    perpendicular_slope = 1/original_slope
    perpendicular_line = create_line_with_slope_through_point (perpendicular_slope, circle_centerpoint)
    intersect_point = intersection_of_infinite_lines (perpendicular_line, original_line)
    if point_is_on_line (intersect_point, original_line):
        finite_line_along_radius = create_finite_line_between_points (circle_centerpoint, intersect_point)
        if length_of_line (finite_line_along_radius) < length_of_line (radius):
            return true
        end
    end
    return false
end

function does_box_intersect_with_circle (bounding_box, circle):
    for each side in bounding_box:
        if does_line_go_through_circle (side, circle.center, circle.radius):
            return true
        end
    end
    return false
end

Имейте в виду, я немного заржавел в этом, я могу ошибаться.

В любом случае, это должно быть тривиально реализовать в C ++.

0 голосов
/ 02 июля 2012

Мы разделим прямоугольник на 4 конечные линии. Мы можем построить линейное уравнение ax + by + c = 0, соединяющее точки (x1, y1) и (x2, y2) следующим образом:

mx - y + c = 0

, где m = (y2-y1) / (x2-x1)

Наименьшее (перпендикулярное) расстояние от линии ax + by + c = 0 до точки (xc, yc) определяется выражением:

d = (a*xc + b*yc + c) / sqrt(a*a + b*b)

или d = (m*xc - yc + c) / sqrt(m*m + 1) в соответствии с приведенным выше уравнением

Для бесконечных линий вы можете проверить, меньше ли 'd' радиуса круга. Но для конечных линий вам также необходимо убедиться, что точка соприкосновения находится внутри линии.

Теперь m = tan (угол). Вы можете иметь

cos = 1 / sqrt(m*m + 1);  sin = m / sqrt(m*m + 1)

Тогда вы можете рассчитать точку контакта как

xp = xc + d*cos;   yp = yc + d*sin

А чтобы проверить, лежит ли (xp, yp) между точками, соединяющими линию, вы можете сделать простую проверку как

if(x1 < xp < x2 && y1 < yp < y2)
    return true

в зависимости от того, что больше среди x1 x2 и y1 y2.

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

Пожалуйста, поправьте меня, если я где-то ошибаюсь.

...