forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   3D-программирование (http://forum.boolean.name/forumdisplay.php?f=12)
-   -   Кватернионы мать их :) вернее отца :) (http://forum.boolean.name/showthread.php?t=672)

Conan Fedr 12.02.2006 20:48

Може ктонить сможен написать функцию для перевода кватерниона в обычный вектор :) . После прочтения статей по ним у меня постепенно срывает крышу . Всетаки зря какойто тип их в 18 веке придумал :).

Прошу кто можут функцию под блитз написать для перевода кватерниона в вектор и функцию для обратной конвертации :) .

impersonalis 12.02.2006 21:15

Jimona спроси :)

jimon 12.02.2006 23:21

Jimon game engine 0.61
отключоные программные модули
файл math.cpp
Код:

void Quaternion_To_Euler(const dQuaternion quaternion,vector3df &euler){
        dReal w,x,y,z;
        w=quaternion[0];
        x=quaternion[1];
        y=quaternion[2];
        z=quaternion[3];
        double sqw = w*w; 
        double sqx = x*x; 
        double sqy = y*y; 
        double sqz = z*z;
        euler.Z = (float) (atan2(2.0 * (x*y + z*w),(sqx - sqy - sqz + sqw))*GRAD_PI);
        euler.X = (float) (atan2(2.0 * (y*z + x*w),(-sqx - sqy + sqz + sqw))*GRAD_PI);
        euler.Y = (float) (asin(-2.0 * (x*z - y*w))*GRAD_PI);
}

void Euler_To_Quaternion(const vector3df &euler, dQuaternion quaternion)
{
        double _heading=euler.Z*GRAD_PI2/2.0;
        double _attitude=euler.Y*GRAD_PI2/2.0;
        double _bank=euler.X*GRAD_PI2/2.0;
        double c1 = cos(_heading); 
        double s1 = sin(_heading); 
        double c2 = cos(_attitude); 
        double s2 = sin(_attitude); 
        double c3 = cos(_bank); 
        double s3 = sin(_bank);
        double c1c2 = c1*c2; 
        double s1s2 = s1*s2; 
        quaternion[0]=(dReal) (c1c2*c3 + s1s2*s3);
        quaternion[1]=(dReal) (c1c2*s3 - s1s2*c3);
        quaternion[2]=(dReal) (c1*s2*c3 + s1*c2*s3);       
        quaternion[3]=(dReal) (s1*c2*c3 - c1*s2*s3);
}

для блица пока немногу написать (занят сильно)

alex-mad 13.02.2006 00:31

эээ... объясните непосвящённому, что есть "кватерниона"?

Conan Fedr 13.02.2006 01:34

Кватерниона это ужасная хрень :) Точно немогу обьяснить :) Но это что-то типа четырех мерного вектора ( хз зачем :) ) .

alex-mad 13.02.2006 01:44

гы... во бред!
и нафига он нужен, живя в 3-х мерном пространстве

Conan Fedr 13.02.2006 01:45

Спасибо большое jimon мне под блитз пока и ненадо всеровно то что я под блитзем написал нифига непашет :) . Я доделаю хоть свой cam есдитор :) под сями . Еще раз спасибо .

Conan Fedr 13.02.2006 02:15

Чему равна константа GRAD_PI ? :)

jimon 13.02.2006 22:23

Код:

const f64 irr::core::GRAD_PI = 180.0 / 3.1415926535897932384626433832795
квартерионы форева ! :)

2 alex-mad :
сравни умножение вектора положение на полную матрицу поворота
и вектора положения на квартерион
увидиш разницу

и квартерион занимает 4 числа вместо того что матрица поворота по одной оси занимает 16 чисел

если всеравно непонятно - учи основы физики, и игровой геометрии

Conan Fedr 15.02.2006 18:09

jimon можеш чтонибудь конретное посоветовать почитать по этой системе координат в которой используется 4 оси . сорри если что нетак сказал :) . Вот я неврублюка это все перемнить ведь до пусим в OGL можно задавать вершину четырьмя координатами а я хз нафик четвертая нужна :) . Вот хочется разобарться. Ну и по ксатернионам чтонить для нубов :) , но помоему это все из одной тарелки :) . Заранее спасибо :)

pax 15.02.2006 18:28

в ОГЛ координаты задаются так:
если задано 4 переменных x,y,z,w то реальные координаты получаются такие:
x/w,y/w,z/w
по умолчанию w=1.0 при задании координат 2-мя и 3-мя числами

pax 15.02.2006 18:43

Вот тока что нашел справку по кватернионам
quat3rot.pdf

pax 15.02.2006 18:49

вот тут еще есть инфа:
http://allprogramming.jino-net.ru/ebooks/d.../book3/43.phtml

Conan Fedr 15.02.2006 19:05

Спасиба . Но вы видели сколько я в той мессаге опечаток сделал щя сам сижу и прусь :)

jimon 15.02.2006 22:36

читать все здесь
http://gamedev.ru/articles/?sect=3
думаю понятно будет :)

Conan Fedr 24.02.2006 09:16

Вот может кому нада либа с сайта Матвея Меркулов для перещета кватернионов и углов Эйлера и еще для чегото :)

Код:

; Quat.bb : v1.0 : 15/11/02

; A tutorial on how to use this file is at http://www.dscho.co.uk/blitz/tutorials/quaternions.shtml

; Types
Type Rotation
        Field pitch#, yaw#, roll#
End Type

Type Quat
        Field w#, x#, y#, z#
End Type

; Change these constants if you notice slips in accuracy
Const QuatToEulerAccuracy# = 0.001
Const QuatSlerpAccuracy#  = 0.0001

; convert a Rotation to a Quat
Function EulerToQuat(out.Quat, src.Rotation)
; NB roll is inverted due to change in handedness of coordinate systems
        Local cr# = Cos(-src\roll/2)
        Local cp# = Cos(src\pitch/2)
        Local cy# = Cos(src\yaw/2)

        Local sr# = Sin(-src\roll/2)
        Local sp# = Sin(src\pitch/2)
        Local sy# = Sin(src\yaw/2)

; These variables are only here to cut down on the number of multiplications
        Local cpcy# = cp * cy
        Local spsy# = sp * sy
        Local spcy# = sp * cy
        Local cpsy# = cp * sy

; Generate the output quat
        out\w = cr * cpcy + sr * spsy
        out\x = sr * cpcy - cr * spsy
        out\y = cr * spcy + sr * cpsy
        out\z = cr * cpsy - sr * spcy
End Function

; convert a Quat to a Rotation
Function QuatToEuler(out.Rotation, src.Quat)
        Local sint#, cost#, sinv#, cosv#, sinf#, cosf#
        Local cost_temp#

        sint = (2 * src\w * src\y) - (2 * src\x * src\z)
        cost_temp = 1.0 - (sint * sint)

        If Abs(cost_temp) > QuatToEulerAccuracy
 cost = Sqr(cost_temp)
        Else
 cost = 0
        EndIf

        If Abs(cost) > QuatToEulerAccuracy
 sinv = ((2 * src\y * src\z) + (2 * src\w * src\x)) / cost
 cosv = (1 - (2 * src\x * src\x) - (2 * src\y * src\y)) / cost
 sinf = ((2 * src\x * src\y) + (2 * src\w * src\z)) / cost
 cosf = (1 - (2 * src\y * src\y) - (2 * src\z * src\z)) / cost
        Else
 sinv = (2 * src\w * src\x) - (2 * src\y * src\z)
 cosv = 1 - (2 * src\x * src\x) - (2 * src\z * src\z)
 sinf = 0
 cosf = 1
        EndIf

; Generate the output rotation
        out\roll = -ATan2(sinv, cosv); inverted due to change in handedness of coordinate system
        out\pitch = ATan2(sint, cost)
        out\yaw = ATan2(sinf, cosf)
End Function

; use this to interpolate between quaternions
Function QuatSlerp(res.Quat, start.Quat, fin.Quat, t#)
        Local scaler_w#, scaler_x#, scaler_y#, scaler_z#
        Local omega#, cosom#, sinom#, scale0#, scale1#

        cosom = start\x * fin\x + start\y * fin\y + start\z * fin\z + start\w * fin\w

        If cosom <= 0.0
 cosom = -cosom
 scaler_w = -fin\w
 scaler_x = -fin\x
 scaler_y = -fin\y
 scaler_z = -fin\z
        Else
 scaler_w = fin\w
 scaler_x = fin\x
 scaler_y = fin\y
 scaler_z = fin\z
        EndIf

        If (1 - cosom) > QuatSlerpAccuracy
 omega = ACos(cosom)
 sinom = Sin(omega)
 scale0 = Sin((1 - t) * omega) / sinom
 scale1 = Sin(t * omega) / sinom
        Else
        ; Angle too small: use linear interpolation instead
 scale0 = 1 - t
 scale1 = t
        EndIf

        res\x = scale0 * start\x + scale1 * scaler_x
        res\y = scale0 * start\y + scale1 * scaler_y
        res\z = scale0 * start\z + scale1 * scaler_z
        res\w = scale0 * start\w + scale1 * scaler_w
End Function

; result will be the same rotation as doing q1 then q2 (order matters!)
Function MultiplyQuat(result.Quat, q1.Quat, q2.Quat)
        Local a#, b#, c#, d#, e#, f#, g#, h#

        a = (q1\w + q1\x) * (q2\w + q2\x)
        b = (q1\z - q1\y) * (q2\y - q2\z)
        c = (q1\w - q1\x) * (q2\y + q2\z)
        d = (q1\y + q1\z) * (q2\w - q2\x)
        e = (q1\x + q1\z) * (q2\x + q2\y)
        f = (q1\x - q1\z) * (q2\x - q2\y)
        g = (q1\w + q1\y) * (q2\w - q2\z)
        h = (q1\w - q1\y) * (q2\w + q2\z)

        result\w = b + (-e - f + g + h) / 2
        result\x = a - ( e + f + g + h) / 2
        result\y = c + ( e - f + g - h) / 2
        result\z = d + ( e - f - g + h) / 2
End Function

; convenience function to fill in a rotation structure
Function FillRotation(r.Rotation, pitch#, yaw#, roll#)
        r\pitch = pitch
        r\yaw = yaw
        r\roll = roll
End Function


Maxus 24.02.2006 12:45

Цитата:

Originally posted by Conan Fedr@24.2.2006, 9:16
Вот может кому нада либа с сайта Матвея Меркулов для перещета кватернионов и углов Эйлера и еще для чегото :)

А вот это уже интереснее...

WISHMASTER35 16.06.2011 16:28

Ответ: Кватернионы мать их :) вернее отца :)
 
скажите, можно как-то задать кватерниону 3д вектор направление и угол?
т.е. что-то типа задания матрице dir и up, но вместо up угол.
п.с. ни в одной статье не видел, чтобы описывалось что такое кватернион т.е. как влияют его числа на ориентацию и как его можно представить в 3д пространстве. с матрицей это действительно просто. 3 вектора задающие направление и размер осей модели и вектора - позиция.

Mr_F_ 16.06.2011 16:50

Ответ: Кватернионы мать их :) вернее отца :)
 
q = [ V*sin(alpha/2), cos(alpha/2) ]
http://www.gamedev.ru/articles/?id=30129

WISHMASTER35 16.06.2011 18:18

Ответ: Кватернионы мать их :) вернее отца :)
 
Mr_F_, чот не получается. вообще эта формула задает угол поворота вокруг вектора.
Мне надо сделать след от выстрела. для этого надо, чтобы Z-вектор матрицы спрайта смотрел в сторону нормали.
матрицами я это так делаю:
Vector3f dir = new Vector3f(nx, ny, nz); //нормаль
Vector3f up = null;
if(Math.abs(dir.y) < 0.5f ) {
up = new Vector3f(0, 1, 0);
} else { // если нормаль смотрит вверх или вниз
up = new Vector3f(1, 0, 0);
}
matrix.lookAt(dir, up); //задаем dir, up, вычисляем side и выравниваем up.
Все просто. но интересно как это кватернионом сделать. видь с ним не надо находить вектор up.

dsd 17.06.2011 13:36

Ответ: Кватернионы мать их :) вернее отца :)
 
Правильно ли я понимаю?

Сначала я поварачиваю вокруг любой оси совпадающей с осью икс, игрек или зед. Потом вычисляю пару углов направляющих мою ось от той вокруг которой я крутил и путем домножения всех координат на соответствующие синусы-косинусы имею точки повернутые на желаемый угол вокруг произвольной оси.

Т.е. под этим термином понимается сведение этих операций в одну формулу?

dsd 17.06.2011 13:36

Ответ: Кватернионы мать их :) вернее отца :)
 
Правильно ли я понимаю?

Сначала я поварачиваю вокруг любой оси совпадающей с осью икс, игрек или зед. Потом вычисляю пару углов направляющих мою ось от той вокруг которой я крутил и путем домножения всех координат на соответствующие синусы-косинусы имею точки повернутые на желаемый угол вокруг произвольной оси.

Т.е. под этим термином понимается сведение этих операций в одну формулу?

Mr_F_ 17.06.2011 23:56

Ответ: Кватернионы мать их :) вернее отца :)
 
реквестируются мегаматематики в тред, т.к. я кватернионолох и ничего лучше с ними делать, чем копипастить из разных мест, пока они не заработают, делать не умею)


Часовой пояс GMT +4, время: 03:36.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot