3. Необходимо совершить поворот вокруг оси OX по часовой стрелке на угол β.
.Матрица поворота, таким образом, будет равна:
Умножив M3 на M2, а результат на M1 получим искомую матрицу перехода:
Во многих функциях и процедурах в программе в качестве входных и выходных параметров выступают матрицы. Поэтому в программе введен специальный тип:
TMatrix=Array [0. .11] of real
Это массив из 12 элементов типа real. Он представляет собой последовательно записанные три верхние строчки матрицы. Я не включил последнюю строчку, так как она одинаковая у всех матриц преобразования и равна (0, 0, 0,1).
Для операций над матрицами в программе предусмотрены следующие процедуры:
1. Procedure MatrixAB (var Res: TMatrix; const M1,M2: TMatrix)
Процедура умножает матрицу M1 на матрицу M2 и помещает результат в Res.
2. Procedure ShiftMatrix (var M: TMatrix; Z: real)
Создает матрицу перехода из текущей системы координат в систему координат, сдвинутую по оси OZ на z.
Процедура перемещает систему координат, задаваемую матрицей M, по оси OZ на z.
3. Procedure SetMatrix (var M: TMatrix; dx,dy,dz,x,y,z: real) overload
Создает матрицу перехода из текущей системы координат в систему координат, находящуюся в точке (x,y,z), ось OZ которой направлена по вектору (dx,dy,dz).
4. Procedure SetMatrix (var M: TMatrix; dx,dy,dz: real) overload
Создает матрицу перехода из текущей системы координат в систему координат, ось OZ которой направлена по вектору (dx,dy,dz).
Преобразование координат
Для преобразования координат точки из одной системы координат в другую необходимо умножить матрицу преобразования на столбец координат точки.
Для преобразования точки из одной системы координат в другую в программе существует процедура Trans (const M: TMatrix; var F: TPoint; const V: TPoint).
В V содержатся координаты точки, координаты которой надо преобразовать.
В F содержатся результат.
M - матрица преобразования.
В процедуру Ray передается только матрица перехода из глобальной системы координат в систему, связанную с лучом (Mi).
Процедура находит координаты вторичного луча в новой системе координат.
Составляет матрицу перехода из текущей системы в систему, связанную с лучом (Li+1).
Умножает матрицы Mi+1=Li+1Mi
Вызывает рекурсивно Ray с параметром Mi+1
Преобразуем все вершины треугольника в локальную систему координат, связанную с лучом. Луч в этой системе координат имеет координаты (0, 0,1). После этого задача сводится плоской. Необходимо определить, лежит ли точка (0, 0) внутри треугольника в проекции на плоскость OXY.
Преобразуем координату x вершин треугольника в локальную систему координат.
Проверяем, лежат ли точки треугольника все справа от нуля или все слева. Если да, то пересечения с треугольником нет. Если нет, то:
Преобразуем координату у вершин треугольника в локальную систему координат.
Проверяем, лежат ли точки треугольника все сверху от нуля или все снизу. Если да, то пересечения с треугольником нет. Если нет, то:
Необходимо, чтобы при обходе треугольника по часовой стрелке точка (0,0) лежала справа от каждой стороны (либо наоборот). Это можно установить, проверив одного ли знака три векторных произведения:
, , .Если не одного знака, то пересечения нет, Если одного, то:
Преобразуем координату z вершин треугольника в локальную систему координат.
Определяем нормаль к треугольнику, для этого умножим векторно два вектора
иВ случае если, NZ равно нулю, луч параллелен оси OZ и соответственно лучу. Значит, пересечения нет. В другом случае пересечение есть.
Находим координаты пересечения.
Составим уравнение плоскости, в которой находится треугольник:
,подставим x=0 и y=0,
Обозначим отраженный луч через R, вектор, направленный против падающего луча - S, вектор нормали - N. Рассмотрим единичные векторы этих векторов R1, S1, N1. Так как все три вектора находятся в одной плоскости, то можно записать R1+S1=N’. Длина вектора N’ равна 2cosθ. Так как векторы N’ и N1 сонаправленные, то можно записать:
N’=N12cosθ.
Таким образом
.Поставим условие, что падающий и отраженный лучи имеют одинаковую длину.
Так как падающий луч в локальной системе координат имеет координаты (0, 0,1). То вектор S будет иметь координаты (0, 0, - 1). Подставим его координаты в выражение для отраженного луча. Получим
Обозначим преломленный луч, имеющий единичную длину, через T1. Единичный вектор нормали - через N1. А вектор, направленный противоположно падающему лучу - через S1. Разложим вектор S1 на A и Ns, а вектор T1 на B и NT. Вектор равен
.Найдем вектор NT. Этот вектор противоположен по направлению вектору нормали, а длина его равна
.Таким образом
.Для того, что бы определить cosα2, запишем закон преломления
.Воспользуемся тождеством
Получим
Значение для cosα1 можно выразить через скалярное произведение единичных векторов S1 и N1
. С учетом этого можно записать выражение для вектораNT:
Найдем вектор B. Он располагается на одной прямой с вектором A, причем
.Найдем отношение длин векторов A и B:
. Отсюда .Если подкоренное выражение отрицательно, то это соответствует полному внутреннему отражению. В этом случае преломленный луч создаваться не будет. Учтем то, что вектор S равен (0, 0,1).
В алгоритме трассировки лучей от 70 до 90 процентов временных затрат занимает процедура определения пересечений луча с объектами сцены. Если перебирать все объекты сцены, то время будет пропорционально Cn, где С - количество пикселей, а n - число объектов на сцене. Улучшить алгоритм можно, если каким-нибудь образом попробовать сократить число перебираемых объектов. Очень простой, но эффективной является идея иерархических оболочек. Предположим, что нам надо изобразить содержимое полки с посудой. Проведем мысленно большую сферу вокруг полки, так чтобы она включала и полку, и посуду на ней. Затем сферу вокруг каждого предмета посуды. Теперь представим себе процесс рендеринга. Проверяем, пересекается ли луч с самой большой сферой. Если нет, то это значит, что луч не пересекает внутренние оболочки, переходим к другому лучу. Если пересекает, то смотрим пересечение луча с подсферами данной сферы. Как видно из такого примера, многие лучи могут совершить всего одну проверку и отсеяться.