Форум программистов, компьютерный форум, киберфорум
Программирование мультимедиа
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
 Аватар для TierX
21 / 21 / 0
Регистрация: 28.02.2014
Сообщений: 138

Повороты в 3д как получить нормальную матрицу?

27.03.2014, 09:13. Показов 2047. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//  Использующиеся переменные
float Rx = 0.0f; float Ry = 0.0f; float Rz = 0.0f; float Lx = 0.0f;
XMVECTOR DefaultMeshForward = XMVectorSet(0.0f,0.0f,1.0f, 0.0f);
XMVECTOR DefaultMeshRight = XMVectorSet(1.0f,0.0f,0.0f, 0.0f);
 
// Функция создания матрицы поворота и направлений движения.
camRotationMatrix1 = XMMatrixRotationX(Rx)*XMMatrixRotationY(Ry)*XMMatrixRotationZ(Rz);
MeshMoveForwardDir = XMVector3Normalize(XMVector3TransformCoord(DefaultMeshForward, camRotationMatrix1 ));
MeshMoveRightDir = XMVector3Normalize(XMVector3TransformCoord(DefaultMeshRight, camRotationMatrix1 ));
    
sheepPos += MeshMoveForwardDir* Lx;
Lx = 0; 
 
// Функция обновления матриц
meshWorld =  XMMatrixIdentity();
Rotation    =  camRotationMatrix1;
Translation = XMMatrixTranslationFromVector( sheepPos );
meshWorld  = Rotation*Translation ;
 
// Функция рисования
WVP = meshWorld * camView * camProjection;
cbPerObj.WVP = XMMatrixTranspose(WVP);   // в шейдере как output.Pos = mul(inPos, WVP);
cbPerObj.World = XMMatrixTranspose(meshWorld); // в шейдере как output.normal = mul(normal, World);
DirectX 11.
Делаю космич симулятор - кораблик вращается и летит вперед согласно новому направлению после вращения.
Летает он правильно - всегда носом вперед как бы его не вращали.
Но поворачивается/вращается он правильно только вокруг 1 оси которая является первым множителем в данном случае XMMatrixRotationX(Rx) (т.е он всегда правильно вращается вверх/низ при нажатии соответствующей клавиши ) Остальные оси - нет(они какбы остаются не движимые). Если переставить на первое место вращение допустим вокруг Y то он всегда правильно вращается вокруг Y (т.е вправо/лево) но вверх уже нет.

Как исправить/переделать чтобы Кораблик всегда правильно поворачивался по всем осям а не только по одной ?(первой в формуле).
Я вообще еще новичок поэтому прошу помочь доступным языком если не трудно, заранее спасибо.

Добавлено через 15 часов 48 минут
Upd Добавил мировые и локальные оси.(кораблик нарисован чюток выше поэтому он не в центре)Вверх всегда верно. Другие оси только в определенных положениях.
SWAD камера / FGHT передвижение корабля / JLKIUO вращение.
http://www.fayloobmennik.net/3679151

Добавлено через 20 часов 26 минут
пичаль nobody =\

Добавлено через 14 часов 56 минут
Нашел не безызвестное приложение по сравнению вращений которое наглядно демонстрирует разницу результатов кватернион/эйлер (хотя я вроде как использую матрицы что поидее не сильнов влияет на мою проблему)
Вот оно https://disk.yandex.ua/public/... F6pC1r0%3D
Понажимайте wsadqe и увидите что белый самолетик всегда знает где у него верх а где право итд в отличии от моего случая.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
27.03.2014, 09:13
Ответы с готовыми решениями:

Как добавить в игру повороты змейки?
// ConsoleApplication1.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы. // #include...

Как сделать повороты фигур в Тетрисе!
Пишу Тетрис в консоли. У меня есть массив - map. Ширина не 20 потому что появление фигур происходит постепенно. Есть фигура...

Как найти повороты вправо, влево в двумерном массиве?
class Program { static void Main(string args) { int map = new int{ ...

15
 Аватар для TierX
21 / 21 / 0
Регистрация: 28.02.2014
Сообщений: 138
28.03.2014, 14:16  [ТС]
упростим вопрос как реализовать повороты как в этом приложении с белым самолетом

https://disk.yandex.ua/public/... F6pC1r0%3D
0
2838 / 1647 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
28.03.2014, 17:33
Цитата Сообщение от TierX Посмотреть сообщение
как реализовать повороты как в этом приложении с белым самолетом
Если координаты умножить на матрицу поворота вокруг Y, потом на матрицу поворота вокруг X - это вроде и получится? Даже проще, чем с чёрным самолётом.
1
 Аватар для TierX
21 / 21 / 0
Регистрация: 28.02.2014
Сообщений: 138
28.03.2014, 18:03  [ТС]
Цитата Сообщение от Somebody
Если координаты умножить на матрицу поворота вокруг Y, потом на матрицу поворота вокруг X - это вроде и получится? Даже проще, чем с чёрным самолётом.
Нет получаеться вокруг оси Y будет вращаться верно всегда, а вокруг X верно только тогда когда локальный Y будет совпадать с мировым Y . Во всех остальных случаях вращение вокрг Х будет не верным(в том числе и Z). Потомучто на Y мы умножили первым а на Х вторым. И наоборот если бы мы умножили первым на Х то вращение былобы всегда верным только вокруг Х а Y/Z неверно.
В этом то и проблема.
0
2838 / 1647 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
28.03.2014, 18:49
Да, я тоже с этими координатами путаюсь время от времени... Тогда, думаю, можно состояние объекта представить текущей матрицей поворота и 3 векторами - локальными осями. Тогда при любом повороте обновляются матрица и 2 другие оси.
1
 Аватар для TierX
21 / 21 / 0
Регистрация: 28.02.2014
Сообщений: 138
28.03.2014, 20:51  [ТС]
Цитата Сообщение от Somebody
Да, я тоже с этими координатами путаюсь время от времени... Тогда, думаю, можно состояние объекта представить текущей матрицей поворота и 3 векторами - локальными осями. Тогда при любом повороте обновляются матрица и 2 другие оси.
Я не совсем понял...
Как это реализовать.
У меня состояние обьекта (если я правильно понял это выражение) итоговая матрица модели находиться как: MeshWorld=Scale*Rotation*Translate;
Где
MeshWorld изначально еденичная.
Rotation = XMMatrixRotationX(Rx)*XMMatrixRotationY( Ry)*XMMatrixRotationZ(Rz); (Rx Ry Rz углы с клавы/мышки)
После чего WVP = MeshWorld*Viev*Progection; отправляеться в шейдер.

Что нужно сделать/изменить чтобы воплотить вашу идею? (хотябы на псевдокоде)
0
2838 / 1647 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
28.03.2014, 21:29
Так нужны ли вообще Rx, Ry, Rz? Я предлагаю ориентацию кораблика в пространстве хранить как матрицу поворота. Тогда матрица всегда будет уже готовая, а в её строках (или столбцы - смотря как всё представляется) получатся оси локальной системы координат.
0
 Аватар для TierX
21 / 21 / 0
Регистрация: 28.02.2014
Сообщений: 138
29.03.2014, 03:27  [ТС]
Цитата Сообщение от Somebody
Так нужны ли вообще Rx, Ry, Rz? Я предлагаю ориентацию кораблика в пространстве хранить как матрицу поворота. Тогда матрица всегда будет уже готовая, а в её строках (или столбцы - смотря как всё представляется) получатся оси локальной системы координат.
Конечно нужны я же косм симулятор делаю. Жмем вверх корабль носом подымаеться вверх итд(все как в этом приложении с белым самолетиком там же точно такиеже Rx Ry Rz от кнопок SWADQE).
Просто задать нужную ориентацию один раз для этого явно не достаточно.

А локальные оси и изменяються в следствии умножения на матрицу поворота. Проблема как раз в том, что потом корабль не крутиться вокруг них правильно, кроме одной (первой в формуле матрицы поворота).
Происходит все как в шутерах где голову можно наклонять верх в низ а крутиться только вокруг Y. Для шутеров это вполне нормально.Но в управлении летательным апаратом в космосе это весело кончно но едвали правильно. Это всеравно что ехать на машине по дороге без наклонов со скоростью 200 км в час при этом влево и в право поворачиваем нормально. Но теперь если мы будем ехать по спуску т.е дорога наклониться то наше вправо будет как будто мы куборем покатились с дороги через правый бок.
А белый самолетик всегда знает где право и автомобиль тоже независимо от наклона дороги или горизонта.
Просто в космосе еще есть вращение вокруг Z оси направления. Автомобилю такое ненужно)

Добавлено через 5 часов 4 минуты
вот парень делает в мат лабе то что мне нужно
http://www.youtube.com/watch?v=UcYoC7uQzNA
я мало что понимаю из его обьяснений касательно мат лаба - поэтому нужен рабочий код на с++ этого всего дела, или такойже код на матлабе или где либо еще.
0
2838 / 1647 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
29.03.2014, 11:13
Лучший ответ Сообщение было отмечено TierX как решение

Решение

Вот то, что я предлагал без углов:
Полностью (код C++11, библиотека glm, проект Code::Blocks): Spaceship.zip
Основные моменты
C++
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
struct Spaceship
{
    vec3 pos;
    mat3 transf;
    void Rotate(float dax, float day, float daz);
};
 
void Spaceship::Rotate(float dax, float day, float daz)
{
    transf *= mat3(
        rotate(dax, vec3(1, 0, 0)) *
        rotate(day, vec3(0, 1, 0)) *
        rotate(daz, vec3(0, 0, 1)));
}
 
int main()
{
    Spaceship s;
    while (true)
    {
        float dax, day, daz;
        // dax = ...; day = ...; daz = ...;
        s.Rotate(dax, day, daz);
    }
}
Оси треугольника: X - вправо, Y - перпендикулярно плоскости, Z - вниз. WS/AD/FG - повороты вокруг локальных X, Z, Y.
Но, ак я понял, вариант с кватернионами лучше всех, только мне бы самому ещё с этим разобраться... Там по ссылке из описания видео есть статья ещё: http://www.gamedev.ru/articles/?id=30129
1
2838 / 1647 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
29.03.2014, 11:21
Вообще даже Spaceship::pos не нужна, надо просто сделать матрицу 4x4.
0
 Аватар для TierX
21 / 21 / 0
Регистрация: 28.02.2014
Сообщений: 138
29.03.2014, 20:58  [ТС]
Цитата Сообщение от Somebody
Оси треугольника: X - вправо, Y - перпендикулярно плоскости, Z - вниз. WS/AD/FG - повороты вокруг локальных X, Z, Y.
Но, ак я понял, вариант с кватернионами лучше всех, только мне бы самому ещё с этим разобраться... Там по ссылке из описания видео есть статья ещё: http://www.gamedev.ru/articles/?id=30129
Госпади я какбудто вернулся на спектрум в прошлое Но на первый взгляд все работает как нужно будем разберать. А нащет видио и статей. Я их все читал но толку мало там весь прикол в хранении каких добавочных угловых смещений которые добавляються к обычным поворотам.
И да спасибо огромное

Добавлено через 1 час 13 минут
transf *= mat3(
rotate(dax, vec3(1, 0, 0)) *
rotate(day, vec3(0, 1, 0)) *
rotate(daz, vec3(0, 0, 1)));
нужен аналог функции rotate для dx. Думал что XMMatrixRotationAxis но видимо нет с ним не получаеться. Хотел вскрыть библиотечные файлы глянуть на ее работу чото мозг закипел =\
0
2838 / 1647 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
29.03.2014, 21:07
Лучший ответ Сообщение было отмечено TierX как решение

Решение

В стиле DirectX при умножении вектор слева, а матрица справа, и матрицы надо в обратном порядке умножать:
Code
1
2
3
4
5
MeshRotationMatrix =
  XMMatrixRotationAxis(XMVectorSet(0,0,1,0),Rz) *
  XMMatrixRotationAxis(XMVectorSet(0,1,0,0),Ry) *
  XMMatrixRotationAxis(XMVectorSet(1,0,0,0),Rx) *
  MeshRotationMatrix;
Это 2 разных подхода к представлению преобразований: в OpenGL векторы считаются столбцами, в DirectX - строками. Соответственно, если для векторов-столбцов порядок операций P*V*M1*M2*x, то для строк то же самое будет x*M2*M1*V*P. (Хотя сами матрицы в OpenGL хранятся по столбцам, а в DirectX - по строкам, так что в памяти они абсолютно одинаковые, и их представление - это чисто философский вопрос.)
1
 Аватар для TierX
21 / 21 / 0
Регистрация: 28.02.2014
Сообщений: 138
29.03.2014, 21:44  [ТС]
РАБОТАЕТ !1111
:se nor:

Добавлено через 5 минут
Только тут порядок умножения не влияет а влияет то что нужно было использовать XMMatrixRotationAxis а не XMRotationX(X)
Насколько я понял. точнее порядок умножения первых трех множетелей с осями

Добавлено через 11 минут
даже неееееттттт нетак можно и MRotationX(X) только все дело в том что обязательно в
MeshRotationMatrix = (XMMatrixRotationY(Ry)*XMMatrixRotationX (Rx)*XMMatrixRotationZ(Rz))*MeshRotation Matrix;

*MeshRotationMatrix; должно быть в конце формулы.

Допустим так будет не верно
MeshRotationMatrix *= (XMMatrixRotationY(Ry)*XMMatrixRotationX (Rx)*XMMatrixRotationZ(Rz));
Точно так как и
MeshRotationMatrix =MeshRotationMatrix*(XMMatrixRotationY(R y)*XMMatrixRotationX(Rx)*XMMatrixRotatio nZ(Rz));

Добавлено через 7 минут
Почему тогда перемена мест множетелей осей невилияет на результат но расположение MeshRotationMatrix спереди формулы или сзади влияет?

P.S. Блин я с самого начала знал что тут или все просто достаточно гдето типо знако пменять. Или нереально сложно.
0
2838 / 1647 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
29.03.2014, 22:04
Цитата Сообщение от TierX Посмотреть сообщение
Почему тогда перемена мест множетелей осей невилияет на результат
Порядок вращений никуда не делся - при вращении по нескольким осям одновременно оно влияет, только при маленьких углах это незаметно. В реальности же при таком вращении сами эти оси непрерывно меняются, так что тут получатся интегрирование бесконечного числа бесконечно малых вращений или что-то типа того.
0
 Аватар для TierX
21 / 21 / 0
Регистрация: 28.02.2014
Сообщений: 138
30.03.2014, 03:36  [ТС]
Somebody,
Тоесть они пошагово поочереди меняються но настолько быстро что незаметно?
Я в принципе за время поиска рещений неплохо разобрался в матрицах поворота но всеже я немогу понять смысла перестановки MeshRotationMatrix в конец.

Посути мы "старую" матрицу поворота множим на "свежую" но очередность осей что там что там одинаковые. Почему тогда местоположение старой матрицы как множетеля влияет так сильно.
0
2838 / 1647 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
30.03.2014, 11:53
Цитата Сообщение от TierX Посмотреть сообщение
Тоесть они пошагово поочереди меняються но настолько быстро что незаметно?
Что по очереди меняется? Не очень понял... Тут та же проблема: если повернуть, например, вокруг X, потом вокруг Y, то это будет не то же самое, что вокруг Y, потом вокруг X. Но если поворачивать всего на несколько градусов, результаты будут очень близкие. Если, допустим, в этом примере нажать сразу 2 клавиши, то разницу между 2 соседними кадрами при различном порядке умножения не будет видно, но разница между текущим положением и положением через 10 секунд может уже быть вполне приличная.
Вот, например, что-то похожее. Физический движок моделирует равноускоренное движение с шагом по времени dt. За каждый кадр тело перемещается на https://www.cyberforum.ru/cgi-bin/latex.cgi?v \cdot dt + \frac{a \cdot dt^2}{2}. Но если для простоты считать, что оно перемещается всего на v*dt, то разница между соседними кадрами при малом dt незаметна, но за несколько секунд может набежать уже много. Только здесь идеальная формула простая и известная, да и ожидаемый результат более очевиден.
Цитата Сообщение от TierX Посмотреть сообщение
Я в принципе за время поиска рещений неплохо разобрался в матрицах поворота но всеже я немогу понять смысла перестановки MeshRotationMatrix в конец.
При использовании векторов-строк каждое следуещее преобоазование дописывается в цепочку умножений слева, как например, здесь:
C++
1
WVP = meshWorld * camView * camProjection;
В данном случае тоже.
Цитата Сообщение от TierX Посмотреть сообщение
Посути мы "старую" матрицу поворота множим на "свежую" но очередность осей что там что там одинаковые. Почему тогда местоположение старой матрицы как множетеля влияет так сильно.
При чём тут "очередность осей"? Тут просто разный порядок применения.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
30.03.2014, 11:53
Помогаю со студенческими работами здесь

Как получить 3D матрицу?
http://read.pudn.com/downloads154/sourcecode/graph/texture_mapping/684266/VBM3D.m__.htm Сказано что на вход подается 3D матрица. К...

Как получить матрицу
как получить матрицу из цикла for i=1:1:m for j=1:n l= hist(Mas(i,:),(1:5)) v=sum((l(:,j)^3)-l(:,j)) end; end

Как получить матрицу изображения
Здравствуйте. Передо мной стоит следующая задача - нужно выделить R, G, B составляющие изображения, а после провести дискретное косинусное...

Как из одного вектора получить матрицу?
Как из одного вектора получить матрицу в маткаде?

Получить матрицу из чисел, заполняющих матрицу по линиям, параллельным главной диагонали
Получить матрицу A=(aij), i,j=1..n, n<=100, элементами которой является ряд натуральных чисел, заполняющих матрицу по линиям параллельным...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru