Форум программистов, компьютерный форум CyberForum.ru

Поворот вокруг произвольной оси - C++

Восстановить пароль Регистрация
 
NEvOl
12 / 11 / 0
Регистрация: 13.08.2012
Сообщений: 616
20.11.2013, 22:35     Поворот вокруг произвольной оси #1
Здравствуйте, пытаюсь реализовать функции поворота базиса вокруг произвольной оси, но почему-то немного не корректно работает, я не понимаю почему, есть предположение из-за неточности вычислений, можете подсказать что не так ?
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
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
        XMFLOAT3 right = XMFLOAT3(1, 0, 0);
    XMFLOAT3 up = XMFLOAT3(0, 1, 0);
    XMFLOAT3 target = XMFLOAT3(0, 0, 1);
 
void Rotation()
{
    static float angleX(0);
    static float angleY(0);
 
    if(GetAsyncKeyState(39))
    {
        if(angleX < XM_PI)
            angleX += 0.0001;
        else
            angleX = 0;
        RotAxis(up, -angleX);
        return;
    }
 
    if(GetAsyncKeyState(37))
    {
        if(angleX < XM_PI)
            angleX += 0.0001;
        else
            angleX = 0;
        RotAxis(up, angleX);
        return;
    }
 
    if(GetAsyncKeyState(38))
    {
        if(angleY < XM_PI)
            angleY += 0.0001;
        else
            angleY = 0;
 
        RotAxis(right, angleY);
 
    }
 
    if(GetAsyncKeyState(40))
    {
        if(angleY < XM_PI)
            angleY += 0.0001;
        else
            angleY = 0;
 
        RotAxis(right, -angleY);
    }
}
 
void RotAxis(XMFLOAT3 Axis, float Angle)
{
    float AngleBetZAndAx = GetAngleBetweenVec(XMFLOAT3(0, Axis.y, Axis.z), XMFLOAT3(0, 1, 0));
    if(AngleBetZAndAx)
    {
        RotX(up, AngleBetZAndAx);
        RotX(right, AngleBetZAndAx);
        RotX(target, AngleBetZAndAx);
        RotX(Axis,  AngleBetZAndAx);
    }
    
    float AngleBetXAndAx = GetAngleBetweenVec(XMFLOAT3(Axis.x, Axis.y, 0) , XMFLOAT3(0, 1, 0));
        
    
    if(AngleBetXAndAx)
    {
        RotZ(up, AngleBetXAndAx);
        RotZ(right, AngleBetXAndAx);
        RotZ(target, AngleBetXAndAx);
    }
    
    RotY(up, Angle);
    RotY(right, Angle);
    RotY(target, Angle);
    
    if(AngleBetXAndAx)
    {
        RotZ(up, -AngleBetXAndAx);
        RotZ(right, -AngleBetXAndAx);
        RotZ(target, -AngleBetXAndAx);
    }
 
    if(AngleBetZAndAx)
    {
        RotX(up, -AngleBetZAndAx);
        RotX(right, -AngleBetZAndAx);
        RotX(target, -AngleBetZAndAx);
    }   
}
 
float GetAngleBetweenVec(XMFLOAT3 a, XMFLOAT3 b)
{
    float lenA = GetLenght(a);
    float lenB = GetLenght(b);
 
    if(!lenA)
        return 0;
 
    if(lenA != 1)
        a = Normalize(a);
    if(lenB != 1)
        b = Normalize(b);
 
    float x = a.x*b.x;
    float y = a.y*b.y;
    float z = a.z*b.z;
 
    float scal = x + y + z;
    if(scal)
        return acos(scal);
    else
        return XM_PIDIV2;
}
 
float Cam::GetLenght(XMFLOAT3 a)
{
    return sqrt((DOUBLE)(a.x*a.x + a.y*a.y + a.z*a.z));
}
 
void RotX(XMFLOAT3 &a, float Angle)
{
    XMMATRIX rotX;
    rotX._11 = 1; rotX._12 = 0;       rotX._13 = 0;                 
    rotX._21 = 0; rotX._22 = cos(Angle);  rotX._23 = sin(Angle);
    rotX._31 = 0; rotX._32 = -sin(Angle); rotX._33 = cos(Angle);
 
    float x = a.x * rotX._11 + a.y * rotX._21 + a.z * rotX._31;
    float y = a.x * rotX._12 + a.y * rotX._22 + a.z * rotX._32;
    float z = a.x * rotX._13 + a.y * rotX._23 + a.z * rotX._33;
 
    a.x = x;
    a.y = y;
    a.z = z;
}
 
void RotY(XMFLOAT3 &a, float Angle)
{
    XMMATRIX rotY;
    rotY._11 = cos(Angle);  rotY._12 = 0; rotY._13 = -sin(Angle);
    rotY._21 = 0;                   rotY._22 = 1; rotY._23 = 0;                 
    rotY._31 = sin(Angle);  rotY._32 = 0; rotY._33 = cos(Angle); 
 
    float x = a.x * rotY._11 + a.y * rotY._21 + a.z * rotY._31;
    float y = a.x * rotY._12 + a.y * rotY._22 + a.z * rotY._32;
    float z = a.x * rotY._13 + a.y * rotY._23 + a.z * rotY._33;
    
    a.x = x;
    a.y = y;
    a.z = z;
}
 
void RotZ(XMFLOAT3 &a, float Angle)
{
    XMMATRIX rotZ;
    rotZ._11 = cos(Angle);  rotZ._12 = sin(Angle);  rotZ._13 = 0;
    rotZ._21 = -sin(Angle); rotZ._22 = cos(Angle);  rotZ._23 = 0;
    rotZ._31 = 0;       rotZ._32 = 0;       rotZ._33 = 1;
 
    float x = a.x * rotZ._11 + a.y * rotZ._21 + a.z * rotZ._31;
    float y = a.x * rotZ._12 + a.y * rotZ._22 + a.z * rotZ._32;
    float z = a.x * rotZ._13 + a.y * rotZ._23 + a.z * rotZ._33;
 
    a.x = x;
    a.y = y;
    a.z = z;
 
}
по началу все нормально работает но спустя несколько оборотов начинается какой-то скос и в конце концов вообще виляет непонятно как.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
programina
 Аватар для programina
1912 / 597 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
20.11.2013, 23:30     Поворот вокруг произвольной оси #2
NEvOl, чему равно XM_PI?
NEvOl
12 / 11 / 0
Регистрация: 13.08.2012
Сообщений: 616
21.11.2013, 07:41  [ТС]     Поворот вокруг произвольной оси #3
Это константа длинная там 1.57.....
programina
 Аватар для programina
1912 / 597 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
21.11.2013, 08:53     Поворот вокруг произвольной оси #4
Цитата Сообщение от NEvOl Посмотреть сообщение
Это константа длинная там 1.57.....
В общем, вы вращаете на 360 градусов, а это значит 2*Pi = 2*3,14159 = 6.283

Добавлено через 1 минуту
то есть получается, что повернув на 90 градусов вы сбрасываете значение угла до нуля.

Добавлено через 1 минуту
Цитата Сообщение от NEvOl Посмотреть сообщение
Это константа длинная там 1.57.....
а не 3,14159 ?
NEvOl
12 / 11 / 0
Регистрация: 13.08.2012
Сообщений: 616
21.11.2013, 15:24  [ТС]     Поворот вокруг произвольной оси #5
Цитата Сообщение от programina Посмотреть сообщение
В общем, вы вращаете на 360 градусов, а это значит 2*Pi = 2*3,14159 = 6.283

Добавлено через 1 минуту
то есть получается, что повернув на 90 градусов вы сбрасываете значение угла до нуля.

Добавлено через 1 минуту


а не 3,14159 ?
а да 3.14159 не туда глянул)
Yandex
Объявления
21.11.2013, 15:24     Поворот вокруг произвольной оси
Ответ Создать тему
Опции темы

Текущее время: 07:27. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru