C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
трехмерная графика, матрица косинусов
GoodWin
Отправлено: 28.07.2006, 14:30


Дежурный стрелочник

Группа: Участник
Сообщений: 50



Здраствуйте.
У меня есть проблема сведения одного базиса к другому.
Есть базис X, Y , Z и базис X` , Y`, Z` , где XYZ -единичные вектора системы левосторонней системы координат.
Необходима такая матрица поворотов(3x3), которая может свести первый базис ко второму. Я пользовался положением, что матрица поворотов- это по сути матрица направляющих косинусов.
Таким образом находил все элементы матрицы как косинусы между векторами базиса. Почему это не работает. Может кто помочь?
Grigoriy
Отправлено: 29.07.2006, 07:39


Мастер участка

Группа: Участник
Сообщений: 381



QUOTE (GoodWin @ 28/07/2006, 14:30)
Здраствуйте.
У меня есть проблема сведения одного базиса к другому.
Есть базис X, Y , Z и базис X` , Y`, Z` , где XYZ -единичные вектора системы левосторонней системы координат.
Необходима такая матрица поворотов(3x3), которая может свести первый базис ко второму.

А базисы ортонормированные ?
То есть сами орты взаимно перпендикулярны друг другу ?
Тогда задача ваша имеет очень простое решение !

Кстати, матрица поворотов — это матрица перехода от одного базиса к другому.
Ну да ладно, у каждого своя терминология.

Теперь представим себе базис (X, Y, Z) в виде прямоугольной матрицы M1

____|X1 Y1 Z1|
M1= |X2 Y2 Z2|
____|X3 Y3 Z3|

а базис (X', Y', Z')


____|X'1 Y'1 Z'1|
M2= |X'2 Y'2 Z'2|
____|X'3 Y'3 Z'3|

Необходимо M1 разделить на M2. Для этого нужно взять от M2 Обратную матрицу — назовем её N2 и M1 умножить на N2. Вычисление N2 значительно упрощается, если векторы X', Y', Z' взаимно перпендикулярны.
Обратная матрица в таком случае — это транспонированная матрица от исходной — все ряды заменяем на столбцы

И таким образом матрица перехода


____________|X1 Y1 Z1|__|X'1 X'2 X'3|
MP = M1*N2 = |X2 Y2 Z2| * |Y'1 Y'2 Y'3|
____________|X3 Y3 Z3|__|Z'1 Z'2 Z'3|

MPX1 = X1*X'1+Y1*Y'1+Z1*Z'1;
MPX2 = X2*X'1+Y2*Y'1+Z2*Z'1;
MPX3 = X3*X'1+Y3*Y'1+Z3*Z'1;

MPY1 = X1*X'2+Y1*Y'2+Z1*Z'2;
MPY2 = X2*X'2+Y2*Y'2+Z2*Z'2;
MPY3 = X3*X'2+Y3*Y'2+Z3*Z'2;

MPZ1 = X1*X'3+Y1*Y'3+Z1*Z'3;
MPZ2 = X2*X'3+Y2*Y'3+Z2*Z'3;
MPZ3 = X3*X'3+Y3*Y'3+Z3*Z'3;

Отредактировано Grigoriy — 29/07/2006, 09:08
GoodWin
Отправлено: 29.07.2006, 10:57


Дежурный стрелочник

Группа: Участник
Сообщений: 50



)) Это и есть матрица косинусов ))
посмотрим
X1*X'1+Y1*Y'1+Z1*Z'1 = cos( 1^1` ), т.к вектора нормализованы
где 1 , 1` — это вектора X( X1, Y1, Z1) X( X`1, Y`1, Z`1)
и отстальные аналогично являются косинусами между различными векторами базисов.
Матрицу косинусов я и используя, но она почему то не работает.
Я ее транспонировал, все равно одно и то же.
ошибка в других местах исключена т.к. я тут же проверяю правильность матрицы переводя базис, и все время он не такой, какой ожидается

Может где и в кодах ошибка.

//единичная матрица
D3DUtil_SetIdentityMatrix( res );
//cosUgol_VV — косинус между векторами, т.к. нормализованы , то
//векторное произведение
//fO — базис 1, pO — базис 2
res._11 = cosUgol_VV( &fOX , &pOX ); res._12 = cosUgol_VV( &fOX , &pOY ); res._13 = cosUgol_VV( &fOX , &pOZ );
res._21 = cosUgol_VV( &fOY , &pOX ); res._22 = cosUgol_VV( &fOY , &pOY ); res._23 = cosUgol_VV( &fOY , &pOZ );
res._31 = cosUgol_VV( &fOZ , &pOX ); res._32 = cosUgol_VV( &fOZ , &pOY ); res._33 = cosUgol_VV( &fOZ , &pOZ );









Grigoriy
Отправлено: 29.07.2006, 16:22


Мастер участка

Группа: Участник
Сообщений: 381



QUOTE (GoodWin @ 29/07/2006, 10:57)
Матрицу косинусов я и используя, но она почему то не работает.
Я ее транспонировал, все равно одно и то же.
ошибка в других местах исключена т.к. я тут же проверяю правильность матрицы переводя базис, и все время он не такой, какой ожидается

Да, действительно у матрицы перехода в ячейках находятся значения косинусов, потому что скалярное произведение получается, а оно равно произведению длин векторов на косинус между ними, но длины равны 1, и следовательно остается одно значение косинуса.

А не работает она потому, что вероятно неправильно используете её. Матрицу перехода нужно умножать на вектор. Я ещё запишу это произведение


____|MPX1 MPY1 MPZ1|__|Vx|
V' = |MPX2 MPY2 MPZ2| * |Vy|
____|MPX3 MPY3 MPZ3|__|Vz|

V'x = MPX1*Vx + MPY1*Vy + MPZ1*Vz
V'y = MPX2*Vx + MPY2*Vy + MPZ2*Vz
V'z = MPX3*Vx + MPY3*Vy + MPZ3*Vz

Так пробовали ?

А вообще — я в принципе об этом думаю уже давно. Хочу попробовать сам написать на ассемблере графический 3D-двигатель. А использовать буду инструкции SSE2 расширения АЛУ. Только нужно подумать как там находить наиболее быстро массив точек пересечения лучей камеры с текстурами. Исходные данные будут — это базис камеры (базис локальной системы координат камеры) и базис текстуры.

Вернуться в Вопросы программирования в C++Builder