Jump to content

  • Log In with Google      Sign In   
  • Create Account

Interested in a FREE copy of HTML5 game maker Construct 2?

We'll be giving away three Personal Edition licences in next Tuesday's GDNet Direct email newsletter!

Sign up from the right-hand sidebar on our homepage and read Tuesday's newsletter for details!


We're also offering banner ads on our site from just $5! 1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


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.

  • You cannot reply to this topic
6 replies to this topic

#1 altreality   Members   -  Reputation: 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.


Sponsor:

#2 fastcall22   Crossbones+   -  Reputation: 4376

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...
c3RhdGljIGNoYXIgeW91cl9tb21bMVVMTCA8PCA2NF07CnNwcmludGYoeW91cl9tb20sICJpcyBmYXQiKTs=

#3 altreality   Members   -  Reputation: 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.


#4 saejox   Members   -  Reputation: 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

#5 altreality   Members   -  Reputation: 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 Posted Image :

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.


#6 altreality   Members   -  Reputation: 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 ?

http://www.youtube.com/watch?v=XCT9ERCwY1s

-----------

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.


#7 l0calh05t   Members   -  Reputation: 772

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.



PARTNERS