내가 테스트로 오일러각을 쿼터니온으로 변환하고, 아무것도 안한다음 다시 오일러각으로 변환해봤음.

내가 생각하기로는 첫 오일러 각이랑 최종 오일러 각은 값이 동일해야하는데, 동일하지 않음.

원래 이런거임???


오일러 to 쿼터니온, 쿼터니온 to 오일러 코드는 위키피디아에 있는 코드임.


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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include "pch.h"
#include <iostream>
 
#define _USE_MATH_DEFINES
#include <cmath>
 
struct Quaternion {
    double w, x, y, z;
};
 
Quaternion ToQuaternion(double yaw, double pitch, double roll) // yaw (Z), pitch (Y), roll (X)
{
    // Abbreviations for the various angular functions
    double cy = cos(yaw * 0.5);
    double sy = sin(yaw * 0.5);
    double cp = cos(pitch * 0.5);
    double sp = sin(pitch * 0.5);
    double cr = cos(roll * 0.5);
    double sr = sin(roll * 0.5);
 
    Quaternion q;
    q.w = cr * cp * cy + sr * sp * sy;
    q.x = sr * cp * cy - cr * sp * sy;
    q.y = cr * sp * cy + sr * cp * sy;
    q.z = cr * cp * sy - sr * sp * cy;
 
    return q;
}
 
 
struct EulerAngles {
    double roll, pitch, yaw;
};
 
EulerAngles ToEulerAngles(Quaternion q) {
    EulerAngles angles;
 
    // roll (x-axis rotation)
    double sinr_cosp = 2 * (q.w * q.x + q.y * q.z);
    double cosr_cosp = 1 - 2 * (q.x * q.x + q.y * q.y);
    angles.roll = std::atan2(sinr_cosp, cosr_cosp);
 
    // pitch (y-axis rotation)
    double sinp = 2 * (q.w * q.y - q.z * q.x);
    if (std::abs(sinp) >= 1)
        angles.pitch = std::copysign(math::PI / 2, sinp); // use 90 degrees if out of range
    else
        angles.pitch = std::asin(sinp);
 
    // yaw (z-axis rotation)
    double siny_cosp = 2 * (q.w * q.z + q.x * q.y);
    double cosy_cosp = 1 - 2 * (q.y * q.y + q.z * q.z);
    angles.yaw = std::atan2(siny_cosp, cosy_cosp);
 
    return angles;
}
 
int main() {
    EulerAngles Rotation = { math::PI / 2, math::PI / 2, math::PI / 2 };
    std::printf("Roll, Pitch, Yaw: %f %f %f\n", Rotation.roll, Rotation.pitch, Rotation.yaw);
 
    Quaternion quat = ToQuaternion(Rotation.yaw, Rotation.pitch, Rotation.roll);
    std::printf("QUAT(w, x, y ,z): %f %f %f %f\n", quat.w, quat.x, quat.y, quat.z);
 
    Rotation = ToEulerAngles(quat);
    std::printf("Roll, Pitch, Yaw: %f %f %f\n", Rotation.roll, Rotation.pitch, Rotation.yaw);
}
cs

Output:
Roll, Pitch, Yaw: 1.570796 1.570796 1.570796
QUAT(w, x, y ,z): 0.707107 -0.000000 0.707107 -0.000000
Roll, Pitch, Yaw: -1.570796 1.570796 -1.570796


단순히 변환만 했을 뿐인데 값이 다르네... 내가 잘못 이해하고있는건가?