Даны два вектора А и B, которые образуют линейный сегмент L = A-B. Кроме того, дана усеченная область обзора F, которая определяется его левой, правой, нижней, верхней, ближней и дальней плоскостями.
Как закрепить L против F?
То есть проверить наличие пересечения и, где на L это пересечение происходит? (Имейте в виду, что отрезок прямой может иметь более более одного пересечения с усеченной вершиной, если он пересекает две стороны в углу.)
Если возможно, предоставьте пример кода (желательно C++ или Python).
Я вижу, что у него есть передняя и задняя плоскости, но они неявны.
Почему мы должны делать домашнее задание этого ребенка?
Это домашнее задание уже отмечено тегами, если вам не нравится, проголосуйте за него. Я не вижу причин для того, что считаю непристойными тегами.





Я не хочу сейчас писать для этого код, но если я правильно понимаю "усеченную пирамиду", следующее должно работать.
Но, возможно, я совершенно неправильно понял. В таком случае, пожалуйста, уточните :)
Хм. На самом деле я хочу, чтобы линейный сегмент до нет находился за пределами пирамиды обзора. Так что, если у меня есть два пересечения, мне нужно переместить как A, так и B, чтобы они совпадали с пересекающимися границами. Увы, я понятия не имею, как это работает.
Добавьте к тому, что сказал капрал Тачки выше, вам понадобится знать, как пересечь отрезок прямой с плоскостью. В описании на этой странице u представляет параметр в параметрическом определении вашей линии. Сначала вычислите u, используя один из двух описанных методов. Если значение u находится в диапазоне от 0,0 до 1,0, тогда плоскость обрезает линию где-нибудь на вашем сегменте. Возвращение u в уравнение линии дает вам точку, где происходит это пересечение.
Другой подход - найти направленное расстояние каждой точки на плоскости. Если расстояние одной точки положительно, а другой отрицательно, то они лежат на противоположных сторонах плоскости. Затем вы узнаете, какая точка находится за пределами усеченной пирамиды (в зависимости от того, в какую сторону указывает нормаль плоскости). Используя этот подход, можно быстрее найти точку пересечения, выполнив линейную интерполяцию на основе отношения направленных расстояний. Например. если расстояние одной точки +12, а другой -12, вы знаете, что плоскость разрезает сегмент пополам, и ваш параметр u равен 0,5.
Надеюсь это поможет.
Первый извлеките плоскости из вашей матрицы просмотра.
Затем используйте свои точки для определения вектора и min / max как (0, 1), затем перебирайте плоскости и пересекайте их с сегментом, обновляя min / max, выходя из строя раньше, если min > max.
Вот пример чистой функции Python, без внешних зависимостей.
def clip_segment_v3_plane_n(p1, p2, planes):
"""
- p1, p2: pair of 3d vectors defining a line segment.
- planes: a sequence of (4 floats): `(x, y, z, d)`.
Returns 2 vector triplets (the clipped segment)
or (None, None) then segment is entirely outside.
"""
dp = sub_v3v3(p2, p1)
p1_fac = 0.0
p2_fac = 1.0
for p in planes:
div = dot_v3v3(p, dp)
if div != 0.0:
t = -plane_point_side_v3(p, p1)
if div > 0.0: # clip p1 lower bounds
if t >= div:
return None, None
if t > 0.0:
fac = (t / div)
if fac > p1_fac:
p1_fac = fac
if p1_fac > p2_fac:
return None, None
elif div < 0.0: # clip p2 upper bounds
if t > 0.0:
return None, None
if t > div:
fac = (t / div)
if fac < p2_fac:
p2_fac = fac
if p1_fac > p2_fac:
return None, None
p1_clip = add_v3v3(p1, mul_v3_fl(dp, p1_fac))
p2_clip = add_v3v3(p1, mul_v3_fl(dp, p2_fac))
return p1_clip, p2_clip
# inline math library
def add_v3v3(v0, v1):
return (
v0[0] + v1[0],
v0[1] + v1[1],
v0[2] + v1[2],
)
def sub_v3v3(v0, v1):
return (
v0[0] - v1[0],
v0[1] - v1[1],
v0[2] - v1[2],
)
def dot_v3v3(v0, v1):
return (
(v0[0] * v1[0]) +
(v0[1] * v1[1]) +
(v0[2] * v1[2])
)
def mul_v3_fl(v0, f):
return (
v0[0] * f,
v0[1] * f,
v0[2] * f,
)
def plane_point_side_v3(p, v):
return dot_v3v3(p, v) + p[3]
Я что-то упустил или вы могли бы просто пересечь L со всеми плоскостями? Что вообще за усеченная пирамида? :)