# 3D Rotation of Objects with two Vectors

Hi Guys!
I have a dumb question, i know, they are a couple of solutions in this forum but i dont understand how it realy works…

lets say, i have

``````ofVec3f BoxUpVector (0,1,0);
ofVec3f BoxNormalVector(0,0,1);
``````

some Object for ex.

``````ofDrawBox(bla bla bla);
``````

and i have two others vectors

``````ofVec3f NewUpVector (-0.608556, 0.789434, 0.0803312);
ofVec3f NewNormalVector(0.20675, 0.060007, 0.976552);
``````

The BoxUpVector and BoxNormalVector are Vectors that describe a rotation of the Box. How can i rotate my Box, so my BoxUpVector is aligned with NewUpVector and BoxNormalVector with NewNormalVector?

ive tryed this, but it does not works every time.

``````ofPushMatrix();

// align Normal Vectors
ofVec3f CrossNewBoxNormals = NewNormalVector.getCrossed(BoxNormalVector);
float   AngleBetweenNewBox = NewNormalVector.angle(BoxNormalVector);
ofRotate(AngleBetweenNewBox, CrossNewBoxNormals.x, CrossNewBoxNormals.y, CrossNewBoxNormals.z);

// rotate BoxUpVector
ofVec3f RotatedBoxUpVector = BoxUpVector.getRotated(AngleBetweenNewBox, CrossNewBoxNormals);

// Align Up Vectors
ofVec3f CrossUpVectors      = RotatedBoxUpVector.getCrossed(NewUpVector);
int RotationDirection       = CrossUpVectors.angle(NewNormalVector) < 1? 1: -1;
float AngleBetweenUpVectors = RotatedBoxUpVector.angle(NewUpVector) * RotationDirection;

// Rotate
ofRotateZ(AngleBetweenUpVectors);

// Draw this sh...
ofDrawBox (0,0,0,100,200,300);

ofPopMatrix();
``````

any suggestions? This kind of complex transformations are easier if you use ofNode or of3dPrimitives instead of trying to figure it out with global transformations.

Something like:

``````//h
ofBoxPrimitive box;

//setup
box.set(size);

//update
ofQuaternion qNormal;
qNormal.makeRotate(boxNormal, newNormal);
ofQuaternion qUp;
qUp.makeRotate(boxUp, newUp);
box.setOrientation(qNormal * qUp);

//draw
box.draw();
``````

also take a look at ofNode methods since it’s very probable that you won’t even need to calculate the rotations manually and you can just use lookAt to the new normal and up each frame:

``````//update
box.lookAt(box.getPosition() + normalVector, upVector);
``````

But this box is only a simple example, that i made to explain what i mean…Between ofPushMatrix() and ofPopMatrix() I have a bunch of different types of Objects like ofTrueTypeFont, ofDrawSphere, ofLine… What would the complex way looks like?

My Example dont works in a little particular position, but it anyhow works… May be i have some logic error it overthere… If i do this:

``````ofMatrixPush();
// align Normal Vectors
ofVec3f CrossNewBoxNormals = NewNormalVector.getCrossed(BoxNormalVector);
float   AngleBetweenNewBox = NewNormalVector.angle(BoxNormalVector);
ofRotate(AngleBetweenNewBox, CrossNewBoxNormals.x, CrossNewBoxNormals.y, CrossNewBoxNormals.z);
ofMatrixPop();
``````

than my Objects inside ofMatrixPop and Push is almoust aligned. The rest is to align his Up vector. If i try to get the angle between the new Up vector and the calculated old one, the system dont know, in which direction it should rotate the object because the angle is only til 180 and we are not in two dimensions… Therefore i make a cross vector and check if his direction is aligned with direction of the new normal vector… so simple but again ^^ works not every time

Here is some example with the box rotation. Just copy in your Project and if you will move your mouse, you will see that threre are a couple of spots, where the Up Vector of the Box is not aligned to the new one…

``````ofVec3f center (250, 250, 0);
float angleX, angleY;

//--------------------------------------------------------------
void ofApp::draw() {

ofEnableDepthTest();

// VECTORs THAT DESCRIPE A NEW ROTATION OF THE BOX
ofVec3f newNormal   (0,0,1000);
ofVec3f newUp       (0,-1000,0);

// ROTATE NEW VECTORS WITH THE MOUSE
newNormal.rotate(angleX, ofVec3f(0,-1,0));
newNormal.rotate(angleY, ofVec3f(-1,0,0));

newUp.rotate(angleX, ofVec3f(0,-1,0));
newUp.rotate(angleY, ofVec3f(-1,0,0));

// REFERENCE VECTORS OF THE BOX
ofVec3f boxNormal(0,0,1);
ofVec3f boxUp    (0,-1,0);

// GET ANGLE AND ROTATION AXIS OF NEW AND BOX NORMALS
ofVec3f crossBoxNewNormal = boxNormal.getCrossed(newNormal);
float   angleBoxNewNormal = boxNormal.angle(newNormal);

// ROTATE UP VECTOR OF THE BOX, GET CROSSED WITH THE NEW UP VECTOR, GET ANGLE AND ROTATION DIRECTION
ofVec3f rotatedBoxUp      = boxUp.getRotated(angleBoxNewNormal, crossBoxNewNormal);
ofVec3f crossBoxNewUp     = rotatedBoxUp.getCrossed(newUp);
int     direction         = crossBoxNewUp.angle(newNormal) < 1? 1: -1;
float   angleBoxNewUp     = rotatedBoxUp.angle(newUp) * direction;

// DRAW NEW NORMAL
ofSetLineWidth(1);
ofSetColor(255, 0, 0);
ofLine(center, center + newNormal);

// DRAW NEW UP
ofSetColor(0, 255, 0);
ofLine(center, center + newUp);

// DRAW ROTATED UP BOX VECTOR
ofSetLineWidth(3);
ofSetColor(0, 255, 255);
ofLine(center, center + rotatedBoxUp.scale(170));

ofPushMatrix();

ofTranslate(center);

// ALIGN NORMALS
ofRotate (angleBoxNewNormal, crossBoxNewNormal.x, crossBoxNewNormal.y, crossBoxNewNormal.z);

// ALIGN UP VECTORS
ofRotateZ(angleBoxNewUp);

// DRAW DA BOX
ofSetColor(0, 0, 255);
ofDrawBox(0, 0, 0, 100, 150, 200);

// DRAW NORMAL OF THE BOX
ofSetLineWidth(10);
ofSetColor(255, 0, 0);
ofLine(ofVec3f(0), ofVec3f(0,0,150));

// DRAW UP VECTOR OF THE BOX
ofSetColor(0, 255, 0);
ofLine(ofVec3f(0), ofVec3f(0,-150,0));

ofPopMatrix();
}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y){

angleX = x / 500. * 300;
angleY = y / 500. * 300;
}``````