Геометрический смысл перекрестного произведения в графике — оценка того, находится ли точка внутри треугольника.

1 Что такое перекрестный продукт

Позвольте мне кратко представить 叉乘(cross product):
вставьте сюда описание изображения

a → × b → \overrightarrow{a} \times \overrightarrow{b}а ×б , и результат по-прежнему является вектором.
Его направление соответствует правилу правой спирали (палец правой руки поворачивается от a к b, смотрите, куда указывает большой палец); его модуль
равен ∣ a → ∣ ∣ b → ∣ sin θ |\overrightarrow{a }||\overrightarrow{b }|sin\тетаа ∣∣б s в θ (фактически площадь параллелограмма, образованного a и b)

a → × b → = ∣ i → j → k → axayazbxbybz ∣ = (aybz − azby) i → + (azbx − zxbz) j → + (axby − aybx) k → \
overrightarrow{a} \times \overrightarrow{b} = \left | \begin{matrix} \overrightarrow{i} & \overrightarrow{j} & \overrightarrow{k}\\ a_x & a_y & a_z\\ b_x & b_y & b_z \end{matrix} \right | = (a_ybz - a_zb_y)\overrightarrow{i} + (a_zb_x - z_xb_z)\overrightarrow{j} + (a_xb_y - a_yb_x)\overrightarrow{k}а ×б "=" я ахбхДж аубук агбг "="( ауб загбу)я +( агбхгхбг)Дж +( ахбуаубх)к
其中,i → , j → , k → \overrightarrow{i}, \overrightarrow{j}, \overrightarrow{k}я ,Дж ,к Он имеет 3 оси 单位向量.
Его важные свойства:
a → × a → = 0 → \overrightarrow{a} \times \overrightarrow{a} = \overrightarrow{0}а ×а "="0
a → × b → = - b → × a → \overrightarrow{a} \times \overrightarrow{b} = - \overrightarrow{b} \times \overrightarrow{a}а ×б "="б ×а
a → × ( b → + c → ) = a → × b → + a → × c → \overrightarrow{a} \times (\overrightarrow{b} + \overrightarrow{c}) = \overrightarrow{a} \times \overrightarrow{b} + \overrightarrow{a} \times \overrightarrow{c}а ×(б +с )"="а ×б +а ×с

2 Геометрический смысл

В графике векторное произведение векторов в основном используется для вычисления вектора нормали к плоскости, в которой расположены два вектора, и для вычисления оси вращения между ориентацией камеры и ориентацией объекта.Конкретные приложения включают:

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

  2. Вычисляет ось вращения между ориентацией камеры и ориентацией объекта: используется в таких операциях, как отслеживание камеры и вращение камеры.

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

  4. Вычислить угол между векторами: Угол между векторами можно рассчитать с помощью длины модуля векторного перекрестного произведения и результата скалярного произведения, которое можно использовать для вычисления угла между источником света и объектом и вычисления тень.

  5. Определить, находится ли точка внутри треугольника

Следующее предназначено для 5, в частности, как его использовать.

3 Пример использования — определить, находится ли точка внутри треугольника

3.1 Использовать фон

Какой смысл судить, находится ли точка внутри треугольника? Классическое использование заключается в том, что на этапе растеризации графический процессор будет обрабатывать каждый пиксель один за другим, какие данные должны отображаться, или, другими словами, какие данные грани треугольника должны отображаться.
Опишем этот процесс самым простым образом:
False color Наша 3D картинка очень простая, на экран отображается всего 4 вершины, то есть 2 треугольника, как показано на рисунке ниже
вставьте сюда описание изображения

Теперь просканируйте каждый пиксель, чтобы определить, что отображать. Метод заключается в том, чтобы определить, находится ли он внутри двух треугольников. Если нет, будет отображаться цвет по умолчанию. Если да, будет выбрано соответствующее значение цвета текстуры треугольника.
Таким образом, текущую проблему можно резюмировать как функцию:
isInTringle(Trangle tr)

3.2 Как судить

Пожалуйста, посмотрите на следующую группу изображений, точка Q находится внутри треугольника, вы можете видеть, что такое правила:
вставьте сюда описание изображения
векторы P1P2 и P1Q, правая спиральная линейка, направленная наружу;
векторы P2P3 и P2Q, правая спиральная линейка, направленная наружу наружу,
векторы P3P1 и P3Q , правило правой спирали, обращенные наружу;

Посмотрите на другую группу рисунков, точка Q находится вне треугольника:
вставьте сюда описание изображения
векторы P1P2 и P1Q, правая спиральная линейка, 朝内;
векторы P2P3 и P2Q, правая спиральная линейка, направленная наружу;
векторы P3P1 и P3Q, правая спиральная линейка , лицом наружу;

В крайних случаях, если Q находится только на краю треугольника, например, на краю P1P2, то векторы P1P2 и P1Q имеют одинаковое направление, спиральное правило Барби Q, и направление оси z не может быть найдено, то есть значение z равно 0.

в заключение:只要计算三次叉乘,如果z值有一个为0,则在三角形边上; 如果z值正负一致,则在里面;如果z值正负不一致,则在外面

3.3 Реализация кода

Как видно из первого раздела, вычисление векторного произведения zzПроще говоря, значение z
равно ( axby − aybx ) (a_xb_y - a_yb_x)( ахбуаубх)
Итак, из программы это можно реализовать очень просто, напишем питон:

#!/usr/bin/python

#这是一个判断一个点是否在三角形内的例子


print("Hello, World! Let's do some test");

def check_signs(a, b, c):
    """
    判断三个浮点数的符号
    :param a: 第一个浮点数
    :param b: 第二个浮点数
    :param c: 第三个浮点数
    :return: True 如果三个数都为正数或都为负数,True 否则False
    """
    if a > 0 and b > 0 and c > 0:
        return True
    if a < 0 and b < 0 and c < 0:
        return True
    return False

def cal_z_value(v1, v2):
    """
    计算2个三维向量,叉乘的z值
    """
    return v1[0] * v2[1] - v1[1]* v2[0]

def subtract_vectors(vector1, vector2):
    """
    计算两个三维向量的差向量
    :param vector1: 第一个向量,格式为 [x, y, z]
    :param vector2: 第二个向量,格式为 [x, y, z]
    :return: 差向量,格式为 [x, y, z]
    """
    x = vector1[0] - vector2[0]
    y = vector1[1] - vector2[1]
    z = vector1[2] - vector2[2]
    return [x, y, z]

def is_point_in_triangle(p1, p2, p3, q):
    """
    判断一个点是否在某个三角形内
    """
    p1_q = subtract_vectors(q, p1)
    p1_p2 = subtract_vectors(p2, p1)
    z1 = cal_z_value(p1_p2, p1_q)

    p2_q = subtract_vectors(q, p2)
    p2_p3 = subtract_vectors(p3, p2)
    z2 = cal_z_value(p2_p3, p2_q)

    p3_q = subtract_vectors(q, p3)
    p3_p1 = subtract_vectors(p1, p3)
    z3 = cal_z_value(p3_p1, p3_q)

    print("z1 ",z1)
    print("z2 ",z2)
    print("z3 ",z3)
    return check_signs(z1, z2, z3)

"""
p1=[0, 0, 0]
p2=[0.5, 0.5, 0]
p3=[0.5, 1, 0]
q=[0.25, 0.5, 0]
"""

#测试代码
p1=[0, 0, 0]
p2=[1, 0, 0]
p3=[0.5, 1, 0]
q=[0.25, 0.35, 0]

result = is_point_in_triangle(p1, p2, p3, q)
print("result ",result)

Supongo que te gusta

Origin blog.csdn.net/newchenxf/article/details/130645922
Recomendado
Clasificación