Как закрепить отрезок линии на усеченной вершине?

Даны два вектора А и B, которые образуют линейный сегмент L = A-B. Кроме того, дана усеченная область обзора F, которая определяется его левой, правой, нижней, верхней, ближней и дальней плоскостями.

Как закрепить L против F?

То есть проверить наличие пересечения и, где на L это пересечение происходит? (Имейте в виду, что отрезок прямой может иметь более более одного пересечения с усеченной вершиной, если он пересекает две стороны в углу.)

Если возможно, предоставьте пример кода (желательно C++ или Python).

Я что-то упустил или вы могли бы просто пересечь L со всеми плоскостями? Что вообще за усеченная пирамида? :)

Sarien 17.09.2008 02:17

Я вижу, что у него есть передняя и задняя плоскости, но они неявны.

Sarien 17.09.2008 02:18

Почему мы должны делать домашнее задание этого ребенка?

Danimal 17.09.2008 02:27

Это домашнее задание уже отмечено тегами, если вам не нравится, проголосуйте за него. Я не вижу причин для того, что считаю непристойными тегами.

zxcv 17.09.2008 02:30
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
4
3 638
3

Ответы 3

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

  1. Пересечь линию со всеми заданными плоскостями
  2. Если у вас есть два перекрестка, все готово.
  3. Если у вас есть только одно пересечение, вычислите переднюю плоскость и пересеките.
  4. Если у вас осталось только одно пересечение, вычислите заднюю плоскость и пересеките.

Но, возможно, я совершенно неправильно понял. В таком случае, пожалуйста, уточните :)

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

MHOOO 17.09.2008 02:37

Добавьте к тому, что сказал капрал Тачки выше, вам понадобится знать, как пересечь отрезок прямой с плоскостью. В описании на этой странице 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]

Другие вопросы по теме