Як можна отримати орієнтацію з матриці перетворення?


10

У мене є матриця трансформації 4х4 М, і я хочу з’ясувати форму кулі при перетворенні М. (Сфера знаходиться в початку і має радіус 1.)

Я знаю, що можу знайти центр, просто помноживши M на (0,0,0,1).

Однак радіус стає проблемою, оскільки M може скосити і обертати сферу. Як я можу дізнатись новий радіус (-и) отриманого еліпсоїда? Чи є спосіб дізнатися орієнтацію?

Більш конкретно, мені потрібно знати розмір обмежувальної сфери, яка охоплювала б перетворену сферу. Іншими словами, що є максимумом | M * V - M * (0,0,0,1) |, де V - одиничний вектор (точка на вихідній сфері).


1
Ви не можете просто обчислити довжину перетворених осей векторів? (3 стовпчики частини обертання вашої матриці) Обмежувальна сфера мала б радіус, рівний довжині найдовшого вектора.
Барт

Ні, я не думаю, що це правильно. Найдовший напрямок може не бути вирівняним по осі. (Уявіть, якби ви розчавив його, обертав, знову розчавив, ще трохи обернув тощо)
КапітанКодеман

Хм, не впевнений, що має значення. Якщо мені вдасться переконати себе, я напишу відповідь пізніше сьогодні. ;)
Барт

Проблема полягає в тому, що якщо ви зробите трансформацію SCALE, базові вектори матриці M не повинні залишатися ОРТОГОНАЛЬНИМ один для одного.
GPUquant

Відповіді:


6

Математично кількість, про яку ви запитуєте, називається нормою оператора . На жаль, немає простої формули для цього. Якщо це повністю загальна афінна трансформація - наприклад, якщо вона може мати довільну комбінацію обертів та неоднорідних шкал у будь-якому порядку - тоді, боюся, немає нічого для цього, крім використання розкладання єдиного значення . Якщо застосувати SVD до своєї матриці, то найбільшим значенням сингулярності буде максимальний радіус отриманого еліпсоїда. Іншими значеннями сингулярності будуть також два інші його радіуси, і процедура SVD також може отримати орієнтацію осей для вас.

Реалізація SVD не для слабкого серця, оскільки передбачає пошук власних значень. Якщо все, що вам потрібно, - це самі особливі значення, вони є квадратними коренями власних значень M ^ T * M. Отже, якщо у вас є підручник власного значення 3x3 під рукою, або ви не заперечуєте його писати, ви можете використовувати це. Якщо ви хочете витягнути також орієнтації осей, тоді це більше залучається, оскільки вам доведеться знаходити і власні вектори. У цій статті у Вікіпедії є список посилань на бібліотеки для роботи з SVD, однією з яких ви можете користуватися у своєму проекті.

Якщо форма вашої матриці обмежена таким чином, що неоднорідна шкала відбувається не більше одного разу і застосовується перше перетворення, тобто є найправішим, коли ви використовуєте вектори стовпців, то ви можете спростити це, щоб просто переглянути довжини трансформовані осі векторів. Тільки в такому випадку - тобто єдина неоднорідна шкала з наступною послідовністю обертання, відбиття та рівномірної шкали - дивлячись лише на осі векторів, ви дасте правильну відповідь.


Дякую, я вдячний за детальну відповідь. Де розкладання, передбачене в іншій відповіді, не працює?
КапітанКодеман

2
@CaptainCodeman Інша відповідь - це просто перегляд перетворених векторів осі (тобто стовпців матриці), як те, що я описав у третьому абзаці. Він не вдається, якщо після обертання з'являється неоднорідна шкала, оскільки тоді масштабування не застосовується вздовж вихідних осей.
Натан Рід

2

Можливо, витягніть масштабні коефіцієнти з матриці, а потім використовуйте максимальне значення її компонентів. Використовуючи матрицю SRT (Scale-Rotation-Translation), ви можете це зробити так:

glm::mat4 m = ...;
// Extract col vectors of the matrix
glm::vec3 col1(m[0][0], m[0][1], m[0][2]);
glm::vec3 col2(m[1][0], m[1][1], m[1][2]);
glm::vec3 col3(m[2][0], m[2][1], m[2][2]);
//Extract the scaling factors
glm::vec3 scaling;
scaling.x = glm::length(col1);
scaling.y = glm::length(col2);
scaling.z = glm::length(col3);

float scaleFactor = MAX(scaling.x, MAX(scaling.y, scaling.z));

(на основі http://wklej.org/id/950061/ - ім'я розкладається TRS, а не розкладаєтьсяSRT, оскільки я використовую імена besed в порядку, матриці яких множать у OpenGL).

Тепер ви можете помножити оригінальний радіус сфери на scaleFactor і у вас є обмежувальна сфера.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.