• Create Account

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

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

6 replies to this topic

### #1altreality  Members

108
Like
0Likes
Like

Posted 22 June 2012 - 05:48 PM

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, 22 June 2012 - 05:49 PM.

### #2fastcall22  Moderators

9738
Like
0Likes
Like

Posted 22 June 2012 - 06:09 PM

if ( ang < 0 )
ang += 360;


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...
zlib: eJzVVLsSAiEQ6/1qCwoK i7PxA/2S2zMOZljYB1TO ZG7OhUtiduH9egZQCJH9 KcJyo4Wq9t0/RXkKmjx+ cgU4FIMWHhKCU+o/Nx2R LEPgQWLtnfcErbiEl0u4 0UrMghhZewgYcptoEF42 YMj+Z1kg+bVvqxhyo17h nUf+h4b2W4bR4XO01TJ7 qFNzA7jjbxyL71Avh6Tv odnFk4hnxxAf4w6496Kd OgH7/RxC

### #3altreality  Members

108
Like
0Likes
Like

Posted 22 June 2012 - 08:04 PM

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 :

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


Here are some angle values :


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


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, 22 June 2012 - 08:41 PM.

### #4saejox  Members

714
Like
0Likes
Like

Posted 22 June 2012 - 08:54 PM

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

### #5altreality  Members

108
Like
0Likes
Like

Posted 22 June 2012 - 09:22 PM

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 : http://bulletphysics...rce.html#l00279

/**@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;
}
};


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 :

/**@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);
}


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 :

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

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

Oh wow...that does work ! Its like magic :

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

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, 22 June 2012 - 10:01 PM.

### #6altreality  Members

108
Like
0Likes
Like

Posted 22 June 2012 - 11:44 PM

ok, so finally this is what I am using :


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;


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, 23 June 2012 - 12:43 AM.

### #7l0calh05t  Members

1610
Like
0Likes
Like

Posted 28 June 2012 - 07:40 AM

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.

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

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.