Transpose ofNode orientation to pan/tilt like orientation system

Hi all,

This question is a bit of math… !
After two days of unsuccessful internal head banging I come out with this post!

I’m currently working with servobeam lightning material ( ) and I’ve created an interface to animate this.
The idea is to create simply a scenegraph and consider every projector as an instance of ofNode - so I can manage this way orientation/lookAt functions.

So far working great.

Now It’s time to communicate with my projectors and as It is a servo pan/tilt motor I need to figure out how to transpose each ofNode orientation to … pan/tilt system ?

My math is getting stucked at some point, and my desk is full of weird drawings.

Any help would be super great !

Here is a snippet of code which I believe represents the enigma.

ofTranslate(ofGetWidth() * .5- 100, ofGetHeight() * .5 );  
    // this is our node, referencing the beamer  
    ofNode servo;  
    ofBox(0,0,0, 10);  
    ofDrawArrow(ofVec3f(0,0,0), ofVec3f(0,100,0), 10);  
    // here this should represent more realisticallyt with pan/tilt motor  
    //this is the two values I need to calculate from the servo orientation   
    float pan, tilt;  
    ofNode panNode, tiltNode;  
    panNode.setOrientation(ofVec3f(0, pan,0));  
    tiltNode.setOrientation(ofVec3f(0,0, tilt));  
    ofBox(0,0,0, 10);  
    ofDrawArrow(ofVec3f(0,0,0), ofVec3f(0,100,0), 10);  

did you ever work this out?

i have a pan tilt zoom camera and want to use the images to build a dome 360 view.
i set the PTZ camera via pan tilt zoom values but have to now figure out where on the dome to place the image.

why are you declaring different ofNode objects for pan and tilt?
the ofNode actually has methods for setting pan and tilt.

/// \brief Tilt up+down (around local x axis)
    void tilt(float degrees);                        
    /// \brief Rotate left+right (around local y axis)
    void pan(float degrees);

hope it helps

a super belated thanks for this tip.

I am trying to apply the pan tilt to a simple box.
but it seems to apply them not the way I would expect them.
I pan the box, then tilt and the tilt is on a strange angle. if I only pan or only tilt all is good.
I was hoping to apply them separately but I seems the angles get combined over time?

did you ever solve your light beam head problem?
I’m stuck at a similar problem of orientation when using pan + tilt.

Don’t get what you’re trying to show on the picture.
but, ofNode’s pan and tilt are relative to the node’s local axes. Maybe you are expecting to get these rotations relative to the world axes.
for example use rotateDeg(degrees, {0,1,0}); for panning using the world Y axis.
hope this helps.

thanks for your response.

here is a quick video of what I call strange rotation.

I am also trying the rotateDeg() function but get the same behaviour than pan+tilt.
In the video you see how after turning horizontal to the right, I then call boxBody.rotateDeg(dir, 1, 0, 0) which causes the box to rotate not up and down but sideways on an angle.

   void rotateHorizontal(float dir){
    void rotateVertical(float dir){
        boxBody.rotateDeg(dir, 1, 0, 0);

this seems to work. basically not using ofNode but ofMatrix4x4

        ofMatrix4x4 translationMatrix;
        ofMatrix4x4 rotation_pan;
        ofMatrix4x4 rotation_tilt;

        ofMatrix4x4 main_matrix;
        main_matrix = rotation_tilt * rotation_pan * translationMatrix;

        ofPoint pp1(0,0,0);
        ofPoint pp2(1000,0,0); 
        pp1 = pp1 * main_matrix;
        pp2 = pp2 * main_matrix;

great. so I can now move a ofNode around by feeding it pan tilt angles.
problem 1 is solved.

but what is I now use lookAt for the main ofNode, so that it changes it’s orientation to constantly follow/lookAt an other node. Like a bird watchers that stationary and keeps on moving his/her head around to follow a bird.

How do I now extract the pan tilt angle from that?
Getting eulerAngles can cause nimble lock, using getPitch() and getHeading seemed to also make numbers jump around at certain positions.
I feel it’s something todo with dot and cross ?

Do you need those angles for further calculations? if so, I’d recomend that you get the orientation as an ofQuaternion.
You’ll avoid gimball lock + quaternions are great.

Otherwise, you can still extract eulers

as for the following other node, take a look at the example at 3d/cameraParentingExample


I will need those angles so I can feed them to a DMX controlled Pan Tilt light.
I have done this for now.
Do you think it should be ok?
I am worried about using getOrientationEulerRad() due to the gimbal lock problem.

   ofVec3f v1 = lineEnd - lineStart;
        ofVec3f v2 = ofVec3f(v1.x,0,v1.z);
        ofVec3f v3 = ofVec3f(0,0,100);
        //vectors used to calculate pan and tilt angles
//        ofDrawLine(lineStart,lineStart+v2);
//        ofDrawLine(lineStart,lineStart+v3);
        //get tilt angle
        v1 = v1.normalize();
        v2 = v2.normalize();
        float dot_v12 =;
        angleY = acos(dot_v12);
        if(v1.y > 0) angleY = -angleY;
        //get pan angle
        v3 = v3.normalize();
        float dot_v23 =;
        angleX = acos(dot_v23);
        if(v1.x < 0) angleX = -angleX;

Hi, I see. I think it is safer to use ofNode’s functions. At least on OF v0.10 it uses glm to do all the vector math and I would think that it handles gimbal lock in a good way.
Also, I’m not sure but I think that the pan tilt light can not get gimbal locked.