ARToolkitPlus, get translation/rotation from matrix

I need to get x,y,z axis angles from the 4by4 rotation matrix used in the ARToolKitPlus examples, since other than superimposing something along with the mark recognized, I want to use the translation and rotation of the mark as a controller for something else. For example, when rotating a mark, it functions like a knob to change color or so…

Also, how can I know the mark’s position (x,y) on the screen?

Many thanks!

In ofxVectorMath theres a matrix44 class that can do matri, decomposition. You can feed the matrix you are getting from artoolkit into an ofxMatrix4x4 and get all the individual transformations from that.

Great! sounds like exactly what I need!
Many thanks! I will give a try !

Hey guys,

I’m trying to do the same thing.

I can get the rotationX value from the ofxQuaternion but need help on converting that float to degrees. Anyone know how to do this?

Thanks,

David

If you’re just getting the rotation from an ofQuaternion it should be:

  
  
float f;  
ofVec3f v;  
quat.getRotate(f, v);  
cout << v.x * f * (180 / PI);  
  

Thanks for the fast reply Joshua, i’ll try this later!

David.

Hi Joshua,

I’ve just added this code. The result im getting is->

If I turn the marker right 180 around the max value I get is 150. 90 degree’s is about 100.
If I start turning the marker left it starts counting negative but when it gets to -140 it switches back to a positive float.

I don’t really know why it’s not going from 0 - 360?

Thanks,

David.

update function:

  
  
ofxMatrix4x4 mat = m; // m is set in the draw  
      
    ofxVec3f translation;  
    ofxQuaternion rotation;  
    ofxVec3f scale;  
    ofxQuaternion so;  
      
    mat.decompose(translation, rotation, scale, so);  
  
    float f;    
    ofxVec3f v;    
    rotation.getRotate(f, v);    
    cout << v.x * f * (180 / PI) << endl;  
  

draw function:

  
  
glViewport(cameraCenterX, cameraCenterX, cameraWidth, cameraHeight );  
	glMatrixMode( GL_PROJECTION );  
	glLoadMatrixf(tracker->getProjectionMatrix());  
	  
	for(int i=0; i<numDetected; i++)  
        {  
		  
		ARToolKitPlus::ARMarkerInfo marker = tracker->getDetectedMarker(i);  
		  
		float m34[ 3 ][ 4 ];  
		float c[ 2 ] = { 0.0f, 0.0f };  
		float w = 40.0f;  
		  
		  
		tracker->rppGetTransMat( &marker, c, w, m34 );  
		  
		//float m[ 16 ]; //this is some crazy matrix transformative stuff. I think initially it came out of one of the arToolkit functions.... but i got it from here: [http://chihara.naist.jp/people/STAFF/imura/computer/OpenGL/artp/disp-content](http://chihara.naist.jp/people/STAFF/imura/computer/OpenGL/artp/disp-content)  
		for ( int i = 0; i < 3; i++ ) {  
			for ( int j = 0; j < 4; j++ ) {  
				m[ j * 4 + i ] = m34[ i ][ j ];  
			}  
		}  
		for ( int j = 0; j < 3; j++ ) {  
			m[ j * 4 + 3 ] = 0.0f;  
		}  
		m[ 3 * 4 + 3 ] = 1.0f;  
          
		glMatrixMode( GL_MODELVIEW );  
		glLoadMatrixf( m );  
  

My bad, I thought the quaternion was in rads, but after decomposition, it’s not. This works fine:

  
  
	ofMatrix4x4 mat;  
	mat.rotate(100, 1, 0, 0);  
	  
	ofVec3f translation;    
    ofQuaternion rotation;    
    ofVec3f scale;    
    ofQuaternion so;    
	  
    mat.decompose(translation, rotation, scale, so);    
	  
    float f;      
    ofVec3f v;      
    rotation.getRotate(f, v);      
    cout << v.x * f  << endl;    
  

I’m not sure if the decomposition is different in 0062 than in 007.

1 Like

I’m still using 0062 for this project.

It’s now printing out these values:

turn right 90: 2
turn right 180: 4
turn left 90: -1.7
turn left 180: 4

It seems weird that when it rotates left in negatives it switches to positive just before 90 degrees.

Going back to 0062, the ofxMatrix4x4 is supposed to be set in quaternion rads, not degrees, so that might explain why the results are unintuitive. This seems to work fine.

  
	ofxMatrix4x4 mat = ofxMatrix4x4::newRotationMatrix(PI + 0.1, 1, 0, 0);  
	  
    ofxVec3f translation;      
    ofxQuaternion rotate;      
    ofxVec3f scale;      
    ofxQuaternion so;      
	  
    mat.decompose(translation, rotate, scale, so);      
	  
    float f;        
    ofxVec3f v;        
    rotate.getRotate(f, v);  

Also, for each marker you might try calling getOrientationQuaternion() or getOrientationMatrix() to see if that helps you get the rotation a little more cleanly. In the processing implementation of this I remember there being a really easy way to get the rotation for each axis, but it doesn’t seem like that exists in the ARToolKit implemenation.

1 Like

Used this code to extract the pitch, roll and yaw from the Quaternion representing rotation

So After…

  
  
mat.decompose(translation, rotation, scale, so);  
  

Use your rotation matrix to obtain the values:

  
  
double pitch = atan2(2*(rotation.y()*rotation.z()+rotation.w()*rotation.x()),rotation.w()*rotation.w()-rotation.x()*rotation.x()-rotation.y()*rotation.y()+rotation.z()*rotation.z());  
double roll = atan2(2*(rotation.x()*rotation.y()+rotation.w()*rotation.z()),rotation.w()*rotation.w()+rotation.x()*rotation.x()-rotation.y()*rotation.y()-rotation.z()*rotation.z());  
double yaw = asin(-2*(rotation.x()*rotation.z()-rotation.w()*rotation.y()));  
  

1 Like