В алгоритме трассировки для построения изображения необходимо вычислять точки пересечения лучей с примитивами сцены. Луч задается параметрическим уравнением прямой. Любая точка луча удовлетворяет уравнению
R = A + Vt,
где R – радиус вектор произвольной точки, принадлежащей лучу, A – радиус- вектор начальной точки луча, V – направляющий вектор луча, t – параметр.Если направляющий вектор V нормализовать, то параметр t будет численно равен расстоянию от начальной точки луча A до точки R.
Можно записать это уравнение в координатном виде:
x = x1 + at,
y = y1 + bt,
z = z1 + ct.
Здесь x1, y1, z1 – координаты начальной точки луча в прямоугольной декартовой мировой системе координат, a,b,c – координаты направляющего вектора луча.
Вычисление точки пересечения луча с поверхностью второго порядка.
Для нахождения точки пересечения луча, заданного уравнениями (2) с поверхностью второго порядка, заданной уравнениями (2.2.2.3) или (2.2.2.4):
(x–x0)2/A2 + (y–y0)2/B2 + (z–z0)2 /C2 = 1 (эллипсоид)
(x–x0)2/A2 + (y–y0)2/B2 – (z–z0)2 /C2 = 1 (параболоид),
нужно подставить в уравнение поверхности второго порядка вместо x, y и z соответствующие уравнения луча. В результате этого после раскрытия всех скобок и приведения подобных мы получим квадратное уравнение относительно параметра t. Если дискриминант квадратного уравнения меньше нуля, то луч и поверхность второго порядка общих точек пересечения не имеют. В противном случае можно будет вычислить два значения параметра t. Дискриминант может быть равен нулю – это соответствует предельному случаю касания луча поверхности, и мы получим два совпадающих значения параметра t.
Для нахождения координат точек пересечения луча и поверхности достаточно подставить найденные значения параметра t в уравнения луча (2).
В программе при нахождении двух пересечений для визуализации выбирается ближнее из них. Ближнее пересечение определяется путем сравнения найденных параметров t. Ближе к точке наблюдения находится то пересечение, которому соответствует меньший параметр t. Тут надо заметить, что в результате решения квадратного уравнения одно или оба значения параметра t могут получиться отрицательными. Это означает, что точка пересечения лежит «сзади» относительно точки начала луча, на половине прямой, находящейся «по нашу сторону» относительно картинной плоскости. Такие точки при поиске пересечения отбрасываются.
Кроме того, в программе для каждой фигуры введены верхняя и нижняя секущие плоскости. Отображается только часть фигуры, лежащая между ними.
Для этого после нахождения точки пересечения анализируется ее z-координата.
Вычисление точки пересечения луча с полигоном (Треугольником).
Для вычисления точки пересечения луча, заданного уравнениями (2) необходимо сначала определить точку пересечения этого луча с плоскостью, содержащей этот треугольник.
Уравнение плоскости выглядит следующим образом:
Q(x, y, z) = Ax + By + Cz +D = 0.
Здесь коэффициенты A, B, C совпадают с координатами нормали к этой плоскости. Координаты нормали плоскости совпадают с координатами нормали треугольника, которые мы посчитали на этапе загрузки сцены.
Для нахождения свободного члена D необходимо подставить координаты любой точки треугольника, например, одной из вершин.
D = –Ax –By – Cz.
По ходу выполнения программы значение D меняться не будет, поэтому его целесообразно посчитать при инициализации сцены и хранить, как и координаты нормали. Пересчитывать его необходимо только при изменении положения треугольника.
Теперь для нахождения точки пересечения подставим уравнения луча (2) в уравнение плоскости.
A (x1 + at) + B (y1 + bt) + C (z1 + ct) + D = 0
t = – (Ax1 + By1 + Cz1 + D) / (Aa + Bb + Cc)
Если знаменатель этой дроби равен нулю, значит луч параллелен плоскости, в которой лежит треугольник. Точки пересечения нет.
Для нахождения координат точки пересечения надо подставить найденное значение параметра t в уравнения луча (2). Назовем точку пересечения D. Мы получим координаты xD, yD, zD.
Теперь необходимо определить, попала ли точка D внутрь треугольника. Найдем координаты векторов AB, BC, CA (A, B, C – вершины треугольника) и координаты векторов AD, BD, CD. Затем найдем три векторных произведения:
nA = AB x AD,
nB = BC x BD,
nC = CA x CD.
Эти вектора будут коллинеарны. Если все три вектора сонаправлены, то точка D лежит внутри треугольника. Сонаправленность определяется равенству знаков соответствующих координат всех трех векторов.
Операцию проверки принадлежности точки D треугольнику ABC можно ускорить. Если ортогонально спроецировать треугольник ABC и точку D на одну из плоскостей xOy, yOz или xOz, то попадание проекции точки в проекцию треугольника будет означить попадание самой точки в треугольник (конечно же, если уже известно, что точка D лежит в плоскости, содержащей треугольник ABC). При этом число операций заметно сокращается. Так для поиска координат всех векторов нужно искать по две координаты на каждый вектор, а при поиске векторных произведений нужно искать только одну координату (остальные равны нулю).
Для проверки сонаправленности векторов, полученных при вычислении векторного произведения нужно проверить знаки этой единственной координаты для всех трех векторов. Если все знаки больше нуля, или меньше нуля, то вектора сонаправлены. Равенство нулю одного из векторных произведений соответствует случаю, когда точка D попадает на прямую, содержащую одну из сторон треугольника.
Кроме того, перед вычислениями векторов и векторных произведений можно провести простой габаритный тест. Если проекция точки D лежит правее, левее, выше или ниже каждой из проекций вершин треугольника, то она не может лежать внутри.
Остается добавить, что для проецирования лучше выбирать ту из плоскостей, площадь проекции треугольника на которую больше. При таком условии исключается случай проецирования треугольника в отрезок (при условии, что проверяемый треугольник не вырожден в отрезок). Кроме того, при увеличении площади проекции уменьшается вероятность ошибки. Для определения такой плоскости проецирования достаточно проверить три координаты нормали треугольника. Если z-координата нормали больше (по абсолютному значению) x и y, то проецировать надо на плоскость xOy. Если y больше чем x и z, то проецируем на xOz. В оставшемся случае – на yOz.
Дата: 2019-07-24, просмотров: 262.