Followers 0

# Converting yaw Euler angles in range [-90, 90] to [0, 360]

## 6 posts in this topic

Hi,

Is it possible to convert the yaw Euler angle got from the Bullet physis engine using

btTransform trans;
trans.getBasis().getEulerYPR(rx, ry, rz);

into the range [0 , 360]. Otherwise for a 360 deg rotation I get the Euler angle varying from 0->90->0-> -90 -> 0

but I want from 0->90->180->270->0

My graphics API only accepts rotation angles in the range of 0 to 360 Edited by altreality
0

##### Share on other sites
[code]
if ( ang < 0 )
ang += 360;
[/code]

Though, you only have half of the total angles there, which makes me suspect that you're looking at the pitch angle. That is, assuming bullet's getEulerYPR is FPS-based and tries to keep pitch between -90 and 90...
0

##### Share on other sites
Yeah you are right, it is the pitch. Though I am not sure why a Y-axis rotation appears in pitch and not yaw.

This is the code I use now for getting the angle :

[code]
trans.getBasis().getEulerYPR(yaw, pitch, roll);
pitch = (pitch >= 0) ? pitch : (PI2 + pitch);
[/code]

Here are some angle values :

[CODE]

Previous Angle(used to undo) | Modified Pitch | Bullet(Yaw, pitch, roll) | Angle applied to rotate body manually
0.00000 | 5.00000 | (0.00000, 5.00000, 0.00000) | 5.00000
-5.00000 | 10.00000 | (0.00000, 10.00000, 0.00000) | 10.00000
-10.00000 | 15.00000 | (0.00000, 15.00000, 0.00000) | 15.00000
-15.00000 | 20.00000 | (0.00000, 20.00000, 0.00000) | 20.00000
-20.00000 | 25.00000 | (0.00000, 25.00000, 0.00000) | 25.00000
-25.00000 | 30.00000 | (0.00000, 30.00000, 0.00000) | 30.00000
-30.00000 | 35.00000 | (0.00000, 35.00000, 0.00000) | 35.00000
-35.00000 | 40.00000 | (0.00000, 40.00000, 0.00000) | 40.00000
-40.00000 | 45.00000 | (0.00000, 45.00000, 0.00000) | 45.00000
-45.00000 | 50.00000 | (0.00000, 50.00000, 0.00000) | 50.00000
-50.00000 | 55.00000 | (0.00000, 55.00000, 0.00000) | 55.00000
-55.00000 | 59.99999 | (0.00000, 59.99999, 0.00000) | 59.99999
-59.99999 | 64.99999 | (0.00000, 64.99999, 0.00000) | 64.99999
-64.99999 | 70.00001 | (0.00000, 70.00001, 0.00000) | 69.99999
-70.00001 | 74.99999 | (0.00000, 74.99999, 0.00000) | 74.99999
-74.99999 | 80.00001 | (0.00000, 80.00001, 0.00000) | 79.99999
-80.00001 | 85.00002 | (0.00000, 85.00002, 0.00000) | 84.99999 <------------------ increasing
-85.00002 | 89.98022 | (0.00000, 89.98022, 0.00000) | 89.99999 <------------------ decreasing
-89.98022 | 85.00002 | (180.00001, 85.00002, 180.00001) | 94.99999 <------------------ decreasing
-85.00002 | 80.00001 | (180.00001, 80.00001, 180.00001) | 99.99999
-80.00001 | 75.00003 | (180.00001, 75.00003, 180.00001) | 104.99999
-75.00003 | 70.00001 | (180.00001, 70.00001, 180.00001) | 109.99998
-70.00001 | 65.00001 | (180.00001, 65.00001, 180.00001) | 114.99999
-65.00001 | 59.99999 | (180.00001, 59.99999, 180.00001) | 119.99999
-59.99999 | 55.00001 | (180.00001, 55.00001, 180.00001) | 124.99999
-55.00001 | 50.00001 | (180.00001, 50.00001, 180.00001) | 129.99999
-50.00001 | 45.00001 | (180.00001, 45.00001, 180.00001) | 134.99999
-45.00001 | 40.00002 | (180.00001, 40.00002, 180.00001) | 139.99999
-40.00002 | 35.00001 | (180.00001, 35.00001, 180.00001) | 144.99998
-35.00001 | 30.00002 | (180.00001, 30.00002, 180.00001) | 149.99998
-30.00002 | 25.00002 | (180.00001, 25.00002, 180.00001) | 154.99998
-25.00002 | 20.00002 | (180.00001, 20.00002, 180.00001) | 159.99998
-20.00002 | 15.00002 | (180.00001, 15.00002, 180.00001) | 164.99998
-15.00002 | 10.00002 | (180.00001, 10.00002, 180.00001) | 169.99998
-10.00002 | 5.00002 | (180.00001, 5.00002, 180.00001) | 174.99998
-5.00002 | 0.00002 | (180.00001, 0.00002, 180.00001) | 179.99998
-0.00002 | 355.00001 | (180.00001, -4.99998, 180.00001) | 184.99998
-355.00001 | 350.00001 | (180.00001, -9.99998, 180.00001) | 189.99998
-350.00001 | 345.00001 | (180.00001, -14.99997, 180.00001) | 194.99997
-345.00001 | 340.00001 | (180.00001, -19.99997, 180.00001) | 199.99997
-340.00001 | 335.00002 | (180.00001, -24.99997, 180.00001) | 204.99997
-335.00002 | 330.00002 | (180.00001, -29.99997, 180.00001) | 209.99997
-330.00002 | 325.00004 | (180.00001, -34.99997, 180.00001) | 214.99997
-325.00004 | 320.00002 | (180.00001, -39.99997, 180.00001) | 219.99997
-320.00002 | 315.00002 | (180.00001, -44.99997, 180.00001) | 224.99997
-315.00002 | 310.00002 | (180.00001, -49.99998, 180.00001) | 229.99998
-310.00002 | 305.00002 | (180.00001, -54.99998, 180.00001) | 234.99998
-305.00002 | 300.00002 | (180.00001, -59.99998, 180.00001) | 239.99998
-300.00002 | 295.00002 | (180.00001, -64.99998, 180.00001) | 244.99998
-295.00002 | 290.00002 | (180.00001, -69.99998, 180.00001) | 249.99998
-290.00002 | 285.00000 | (180.00001, -75.00000, 180.00001) | 254.99998
-285.00000 | 280.00000 | (180.00001, -80.00001, 180.00001) | 259.99998
-280.00000 | 275.00003 | (180.00001, -84.99998, 180.00001) | 264.99997
-275.00003 | 270.00000 | (0.00000, -90.00000, 0.00000) | 269.99997
-270.00000 | 274.99997 | (0.00000, -85.00002, 0.00000) | 274.99997
-274.99997 | 279.99997 | (0.00000, -80.00003, 0.00000) | 279.99997
-279.99997 | 284.99997 | (0.00000, -75.00003, 0.00000) | 284.99997
-284.99997 | 289.99997 | (0.00000, -70.00004, 0.00000) | 289.99997
-289.99997 | 294.99997 | (0.00000, -65.00003, 0.00000) | 294.99997
-294.99997 | 299.99997 | (0.00000, -60.00003, 0.00000) | 299.99997
-299.99997 | 304.99997 | (0.00000, -55.00003, 0.00000) | 304.99997
-304.99997 | 309.99997 | (0.00000, -50.00004, 0.00000) | 309.99997
-309.99997 | 314.99996 | (0.00000, -45.00004, 0.00000) | 314.99996
-314.99996 | 319.99996 | (0.00000, -40.00004, 0.00000) | 319.99996
-319.99996 | 324.99996 | (0.00000, -35.00004, 0.00000) | 324.99996
-324.99996 | 329.99996 | (0.00000, -30.00004, 0.00000) | 329.99996
-329.99996 | 334.99996 | (0.00000, -25.00004, 0.00000) | 334.99996
-334.99996 | 339.99996 | (0.00000, -20.00004, 0.00000) | 339.99996
-339.99996 | 344.99996 | (0.00000, -15.00004, 0.00000) | 344.99996
-344.99996 | 349.99996 | (0.00000, -10.00004, 0.00000) | 349.99996
-349.99996 | 354.99996 | (0.00000, -5.00004, 0.00000) | 354.99996
-354.99996 | 359.99996 | (0.00000, -0.00004, 0.00000) | 359.99996
-359.99996 | -0.00000 | (0.00000, -0.00000, 0.00000) | 0.00000
0.00000 | 5.00000 | (0.00000, 5.00000, 0.00000) | 5.00000
[/CODE]

The Bullet values are in the fat middle column. The problem lies in the sudden decrease in the angle values as we cross 90 degrees. This causes my mesh to rotate backwards after 1/4th turn. Edited by altreality
0

##### Share on other sites
atan2(rotMatrix[0][2], rotMatrix[0][0]) * (180 / PI)
gives Y rotation between -180 and 180
if(angle < 0) angle+=360;
for the range you want
does your engine give you orientation as Matrix33
0

##### Share on other sites
Thanks, I will try it out now. Well Bullet does give me orientation as a btmatrix3x3, so I will use the rotation matrix (its apparently called a 'basis') with your method above.

The matrices are in openGL form, so the 3 columns contain the 3 axes x, y,z.

Here is how getEulerYPR() was implemented by Bullet autthor : [url="http://bulletphysics.com/Bullet/BulletFull/btMatrix3x3_8h_source.html#l00279"]http://bulletphysics...rce.html#l00279[/url]

[code]
/**@brief Get the matrix represented as euler angles around YXZ, roundtrip with setEulerYPR
* @param yaw Yaw around Y axis
* @param pitch Pitch around X axis
* @param roll around Z axis */
void getEulerYPR(btScalar& yaw, btScalar& pitch, btScalar& roll) const
{

// first use the normal calculus
yaw = btScalar(btAtan2(m_el[1].x(), m_el[0].x()));
pitch = btScalar(btAsin(-m_el[2].x()));
roll = btScalar(btAtan2(m_el[2].y(), m_el[2].z()));

// on pitch = +/-HalfPI
if (btFabs(pitch)==SIMD_HALF_PI)
{
if (yaw>0)
yaw-=SIMD_PI;
else
yaw+=SIMD_PI;

if (roll>0)
roll-=SIMD_PI;
else
roll+=SIMD_PI;
}
};
[/code]

Do you think the matrix format is same as the one in your code. You may be using a transposed version of what is used in the above code.

Here is how bullet forms the standard openGL submatrix, which may help decide :

[code]
/**@brief Fill the rotational part of an OpenGL matrix and clear the shear/perspective
* @param m The array to be filled */
void getOpenGLSubMatrix(btScalar *m) const
{
m[0] = btScalar(m_el[0].x());
m[1] = btScalar(m_el[1].x());
m[2] = btScalar(m_el[2].x());
m[3] = btScalar(0.0);
m[4] = btScalar(m_el[0].y());
m[5] = btScalar(m_el[1].y());
m[6] = btScalar(m_el[2].y());
m[7] = btScalar(0.0);
m[8] = btScalar(m_el[0].z());
m[9] = btScalar(m_el[1].z());
m[10] = btScalar(m_el[2].z());
m[11] = btScalar(0.0);
}
[/code]

I think its as :

X Y Z Origin (not included in btMatrix3x3)
0 4 8 12
1 5 9 13
2 6 10 14
3 7 11 15

So your calculation for Y rotation is equivalent to :

[CODE]yaw = btAtan2( m_el[0].z(), m_el[0].x() );[/CODE]

---------------

Oh wow...that does work ! Its like magic [img]http://public.gamedev.net//public/style_emoticons/default/tongue.png[/img] :

[CODE]btMatrix3x3 m_el = trans.getBasis();
ry = btAtan2( m_el[0].z(), m_el[0].x() );
if(ry < 0)
ry += SIMD_PI;[/CODE]

so are the other 2 angles - about the z axis and the x axis, also calculated differently from the default code in getEulerYPR() ? Is there a chance of a gimbal lock ? Edited by altreality
0

##### Share on other sites
ok, so finally this is what I am using :

[CODE]

btMatrix3x3 m_el = trans.getBasis();
ry = btAtan2( m_el[0].z(), m_el[0].x() );
if(ry < 0)
ry += SIMD_PI;

float yaw, pitch, roll;
trans.getBasis().getEulerYPR(yaw, pitch, roll);

rz = yaw;
if(rz < 0)
rz += SIMD_PI;

rx = roll;
if(rx < 0)
rx += SIMD_PI;
[/CODE]

So I apply the rotations in the order Z-Y-X
I am getting good rotations for half a turn an there is a wierd turn. I think I may have the order of the rotations wrong. Is this the correct order of rotation ?

-----------

Well I tried all 6 combinations, only ZYX and YXZ seems to give somewhat reasonable results for 1 half turn. The mesh then suddenly seems to flip over for the rest of the turn. Edited by altreality
0

##### Share on other sites
[quote name='altreality' timestamp='1340430280' post='4951929']
Well I tried all 6 combinations, only ZYX and YXZ seems to give somewhat reasonable results for 1 half turn. The mesh then suddenly seems to flip over for the rest of the turn.
[/quote]

Those are not proper euler angles. Euler angles repeat one axis, for example: ZXZ
0

## Create an account

Register a new account