Матрицы аффинных преобразований в пространстве аналогичны матрицам на плоскости с той лишь разницей, что добавляется ещё одна координата. Соответственно, матрицы становятся размером 4✕4 и их становится больше. По-прежнему, только четыре разновидности преобразований: поворот, перенос, масштаб и сдвиг.
В общем виде
Преобразование в пространстве точки (x, y, z) в точку (x′, y′, z′) осуществляется по формулам:
Или в матричном виде:
Для получения сложного преобразования необходимо последовательно перемножить матрицы всех преобразований, в него входящих. Результат зависит от порядка следования матриц.
Поворот
Поворот по оси X
Координаты меняются только в плоскости YZ. Координата X неизменна.
Угол α — угол от оси Y в сторону положительного направления Z.
Матрица | Формула |
---|---|
Поворот по оси Y
Координаты меняются только в плоскости XZ. Координата Y неизменна.
Угол α — угол от оси X в сторону положительного направления Z. Чтобы вращение было против часовой стрелки, берём угол со знаком «минус». Пояснения под таблицей.
Матрица | Формула |
---|---|
Если ничего не менять, вращение будет происходить по часовой стрелке. Чтобы исправить ситуацию, берём угол со знаком «минус». По формулам приведения видим, что cos(-α) = cos(α), sin(-α) = -sin(α). Поэтому знаки в формулах не перепутаны, все минусы и плюсы на своих местах.
Поворот по оси Z
Координаты меняются только в плоскости XY. Координата Z неизменна.
Угол α — угол от оси X в сторону положительного направления Y.
Матрица | Формула |
---|---|
Перенос
Dx, Dy, Dz — смещения по соответствующим осям.
Матрица | Формула |
---|---|
Масштаб
Sx, Sy, Sz — коэффициенты масштаба по соответствующим осям.
Матрица | Функции |
---|---|
Сдвиг
Сдвигом называется любое преобразование, главная диагональ матрицы которого единичная. По традиции возьмём тангенс угла отклонения от выбранной оси в плоскости трансформации. Например, для сдвига от оси X плоскостью трансформации является YZ, поэтому выбираем углы либо от Y, либо от Z.
Хотя это значение может иметь совершенно разный смысл. Приведённые ниже матрицы, это больше пример возможных сдвигов. Вариантов тут может быть множество, в зависимости от замысла и ситуации.
Сдвиг по оси X (в YZ)
Сдвиги происходят только в плоскости YZ. Координата X неизменна.
Угол α — угол от оси Y в сторону положительного направления Z.
Угол β — угол от оси Z в сторону положительного направления Y.
Матрица | Функции |
---|---|
Сдвиг по оси Y (в XZ)
Сдвиги происходят только в плоскости XZ. Координата Y неизменна.
Угол α — угол от оси X в сторону положительного направления Z.
Угол β — угол от оси Z в сторону положительного направления X.
Матрица | Функции |
---|---|
Сдвиг по оси Z (в XY)
Сдвиги происходят только в плоскости XY. Координата Z неизменна.
Угол α — угол от оси X в сторону положительного направления Y.
Угол β — угол от оси Y в сторону положительного направления X.
Матрица | Функции |
---|---|
Для копипаста
В Delphi существует модуль System.Math.Vectors, в котором есть всё необходимое для работы с матрицами 3D преобразований. Приведённый ниже код исключительно для копипаста с последующей модификацией под свои нужды там, где такой модуль отсутствует, либо это не Delphi.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
type _TMatrix3D = record m11, m12, m13, m14: Single; m21, m22, m23, m24: Single; m31, m32, m33, m34: Single; m41, m42, m43, m44: Single; end; const _Identity: _TMatrix3D = ( m11: 1; m12: 0; m13: 0; m14: 0; m21: 0; m22: 1; m23: 0; m24: 0; m31: 0; m32: 0; m33: 1; m34: 0; m41: 0; m42: 0; m43: 0; m44: 1;); function _CreateRotationX(const A: Single): _TMatrix3D; begin Result := _Identity; Result.m22 := Cos(A); Result.m23 := Sin(A); Result.m32 := - Result.m23; Result.m33 := Result.m22; end; function _CreateRotationY(const A: Single): _TMatrix3D; begin Result := _Identity; Result.m11 := Cos(A); Result.m13 := - Sin(A); Result.m31 := - Result.m13; Result.m33 := Result.m11; end; function _CreateRotationZ(const A: Single): _TMatrix3D; begin Result := _Identity; Result.m11 := Cos(A); Result.m12 := Sin(A); Result.m21 := - Result.m12; Result.m22 := Result.m11; end; function _CreateScaling(Sx, Sy, Sz: Single): _TMatrix3D; begin Result := _Identity; Result.m11 := Sx; Result.m22 := Sy; Result.m33 := Sz; end; function _CreateTranslation(Dx, Dy, Dz: Single): _TMatrix3D; begin Result := _Identity; Result.m41 := Dx; Result.m42 := Dy; Result.m43 := Dz; end; function _CreateSkewX(const AngleY, AngleZ: Single): _TMatrix3D; begin Result := _Identity; Result.m22 := 1; Result.m23 := Tan(AngleY); Result.m32 := Tan(AngleZ); Result.m33 := 1; end; function _CreateSkewY(const AngleX, AngleZ: Single): _TMatrix3D; begin Result := _Identity; Result.m11 := 1; Result.m13 := Tan(AngleX); Result.m31 := Tan(AngleZ); Result.m33 := 1; end; function _CreateSkewZ(const AngleX, AngleY: Single): _TMatrix3D; begin Result := _Identity; Result.m11 := 1; Result.m12 := Tan(AngleX); Result.m21 := Tan(AngleY); Result.m22 := 1; end; |
Скачать
Друзья, спасибо за внимание! Возможно, будет продолжение, посмотрим )))
Пример работы с матрицами 3D преобразования сделан с использованием родного Delphi модуля System.Math.Vectors и GDI+.
Левая кнопка мыши вращает сцену, правая кнопка приближает/отдаляет. Зажатая средняя перетаскивает сцену по полотну. Клик любой кнопкой по левому верхнему углу сцены, там где надпись «Rotation Order: …», вызовет появление контекстного меню с дополнительными настройками. Клик на подписи слева у элементов редактирования вызовет старт соответствующего преобразования. Ну и конечно можно просто ввести значение руками.
Исходник (zip) 81 Кб. Delphi XE 7
Исполняемый файл (zip) 965 Кб (Скомпилирован в XE 7)