Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Кватернионы: извлечение вращения вдоль одной из осей (2 стр)

Кватернионы: извлечение вращения вдоль одной из осей (2 стр)

Поделиться

Страницы: 1 2

AlerrПостоялецwww7 окт. 201723:01#15
}:+()___ [Smile]
Как вы получили решения?
На сколько знаю, расстояние считается так:
dist = (x2-x1)^2 + (y2-y1)^2 + (z2-z1)^2 + (w2-w1)^2
Минимальное расстояние:
0 = (x2-x1)^2 + (y2-y1)^2 + (z2-z1)^2 + (w2-w1)^2

Подставил кватернион поворота воокруг OY:

(x-0)^2 + (y-Y)^2 + (z-0)^2 + (w-W)^2 = 0
(y-Y)^2 + (w-W)^2 = 0

FordPerfectПостоялецwww8 окт. 20170:59#16
Alerr
Ноль? С какого это хрена?
(x-0)^2 + (y-Y)^2 + (z-0)^2 + (w-W)^2 = min
x^2 + (y-Y)^2 + z^2 + (w-W)^2 = min
Выразим Y=sin(phi), W=cos(phi):
x^2 + (y-sin(phi))^2 + z^2 + (w-cos(phi))^2 = min
Возьмём производную:
-(y-sin(phi))*cos(phi) + (w-cos(phi))*sin(phi) = 0
-(y-sin(phi))*cos(phi) + (w-cos(phi))*sin(phi) = 0
-y*cos(phi) + w*sin(phi) = 0
phi=atan2(y,w)
Y=y/sqrt(y^2+w^2), W=w/sqrt(y^2+w^2)
}:+()___ [Smile]Постоялецwww8 окт. 20171:07#17
Alerr
> Как вы получили решения?
Там куча способов, начиная от влобного применения формул и кончая напальцевым.
Собственно, элементарные задачи отличаются тем, что их можно решать первым попавшимся методом и без проблем получить ответ.

> На сколько знаю, расстояние считается так:
Это почти правильно, только обычно это называется квадратом расстояния. Однако для целей оптимизации сойдет и квадрат.
В случае кватернионов поворота, вместо минимизации расстояния можно максимизировать скалярное произведение кватернионов.

> Минимальное расстояние:
Минимальное расстояние не обязательно равно нулю.
Методы нахождения минимумов функций, насколько я помню, проходят в матане на первом курсе.

> Подставил кватернион поворота воокруг OY:
Стоит подучить школьную алгебру, ибо первая и вторая строчка никак не связаны.

Но, так и быть, расскажу самый простой напальцевый способ (хотя у меня есть сомнения, что матподготовки хватит, чтобы понять хотя бы его).

Надо найти при каких значениях Y и W достигается
[cht]\[\min_{Y,W}[x^2+(y-Y)^2+z^2+(w-W)^2]=\min_{Y,W}[(y-Y)^2+(w-W)^2]+x^2+z^2.\][/cht]
Т. е. результат от x и z не зависит и надо найти точку на единичной окружности (Y, W), которая ближе всего к точке (y, w).
Эта шаблонная задача сводится к нормализации вектора.

Правка: 8 окт. 2017 1:09

AlerrПостоялецwww8 окт. 201710:02#18
FordPerfect
> Ноль? С какого это хрена?
Да, забыл за неиспользованием, что нужно приравнивать производную к 0.

> Выразим Y=sin(phi), W=cos(phi):
эта замена мне очень помогла, я бы не догадался, полез уже было в многомерную минимизацию...

И вот здесь сильно тупил пытаясь понять откуда оно все взялось так сразу:
> Y=y/sqrt(y^2+w^2), W=w/sqrt(y^2+w^2)

Ответ нашел отсюда же (для тех кто будет читать пост):
phi=atan(y/w)
phi = (противолож. катет) / (прилеж. катет)
противолож. катет - y
прилеж. катет - w

Тогда согласно замене:
Y=sin(phi) => Y = (противолож. катет) / (гипотенуза)
гипотенуза прямоугольного треугольника: sqrt(y^2+w^2)

Отсюда и ответы.

}:+()___ [Smile]
> Т. е. результат от x и z не зависит и надо найти точку на единичной окружности (Y, W), которая ближе всего к точке (y, w).
> Эта шаблонная задача сводится к нормализации вектора.
Честно признаюсь, имею с математикой дела "постольку поскольку", потому туповат для матанализовой логики.

Подставил решения, проверил, доворот работает но не всегда. Если обьект по оси OY перевернуть так, чтобы OY смотрела вниз (инвертировать так сказать), то куб выверчивается как неожидалось и располагается так, что его OY смотрит вверх, применяю найденное вращение так:

whiteCube.rotation = Quaternion.Slerp (whiteCube.rotation, foundRot, Time.fixedDeltaTime);
Пока сам попытаюсь разобраться что происходит.

Правка: 8 окт. 2017 10:03

SuslikМодераторwww8 окт. 201711:31#19
Alerr
> Подставил решения, проверил, доворот работает но не всегда. Если обьект по оси
> OY перевернуть так, чтобы OY смотрела вниз (инвертировать так сказать), то куб
> выверчивается как неожидалось и располагается так, что его OY смотрит вверх,
> применяю найденное вращение так:
так ты его отражаешь что ли? вообще-то зеркальное отражение нельзя представить вращением, никаким.

Правка: 8 окт. 2017 11:31

AlerrПостоялецwww8 окт. 201716:19#20
Suslik
> так ты его отражаешь что ли?
не понял что это значит.
если ось OY белого куба направлена вверх, то все работает, найденное вращение работает, а если нет, то не работает.

Не знаю облегчит ли это поиски вращения или нет, поможет ли это мне как-то, дополню описание задачи:
красный куб - это куб, углы которого всегда кратны 90. Еще что, вращение красного куба подбирается таким (методом перебора), что оно наиболее близкое к вращению белого куба.
То есть если сделать: 

whiteCube.rotation = Quaternion.Slerp (whiteCube.rotation, redCube.rotation, time);
то белый куб довернется так, что все его углы станут кратны 90.

Боюсь показаться нулем, но все же спрошу, возможно ли получить +/-angle в градусах, такой, что:

whiteCube.rotation = Quaternion.Slerp (whiteCube.rotation, whiteCube.rotation * Quaternion.AngleAxis (angle, OY), time);
где whiteCube.rotation * Quaternion.AngleAxis (angle, OY) равно вращению, которое пока не удалось найти.
В итоге куб все равно должен довернуться до вращения красного куба по выбранной оси.

Правка: 8 окт. 2017 16:20

}:+()___ [Smile]Постоялецwww8 окт. 201718:23#21
Alerr
> Пока сам попытаюсь разобраться что происходит.
Очевидно, что "ближайшее" совсем не означает "близкое".
Если твое вращение абсолютно непохоже на вращение по оси Y, то как ни крути вокруг Y, ничего похожего не получишь.
Так что либо смирись, либо переформулируй задачу по другому.
Megabyte-CeercopПостоялецwww8 окт. 201721:29#22
выбираем одну из вершин куба как точку отсчета и аботаем только с ней. Вычитаем из ее координат координаты центра куба. Убираем одну из трех координат этой вершины в зависимости от выбранной плоскости. Оставшиеся две координаты будут вектором - проекцией вершины на выбранную плоскость. Что и есть вектор поворота в выбранной плоскости. Угол можно высчитать через atan2.
AlerrПостоялецwww9 окт. 201716:02#23
Megabyte-Ceercop
Выкручиваюсь с помощью вашей идеи.
Есть ситуация, когда вектор проецируется в точку, тогда atan2 принимает atan2(y, 0) или  atan2(0, 0).
В MSDN написано, что если y=0 или y=0 и x=0, то atan2 вернет 0.
В C# не могу найти, есть ли проверка на нули. Не подскажете, atan2 в C# проверяет аргументы на корректность?
Megabyte-CeercopПостоялецwww9 окт. 201716:53#24
На счет шарпа не знаю, в случае ошибки присваивай предыдущее валидное значение. Обчно такого хватает для игр.

Страницы: 1 2

/ Форум / Программирование игр / Физика

2001—2017 © GameDev.ru — Разработка игр