# ofMatrix4x4, scaling and rotating around a registration point

here is a bit of code that i know that works,
its a really simple box rotating around a “registration point” of its own center.

``````void ofApp::draw(){
int w = 200;
int h = 200;
float rotation = ofGetElapsedTimef() * 10;

ofMatrix4x4 mat;
mat.preMultRotate(ofQuaternion(rotation, ofVec3f(0, 0, 1)));

ofPushMatrix();
ofTranslate(200, 200);
ofMultMatrix(mat);
ofRect(-w * 0.5, -h * 0.5, w, h);
ofPopMatrix();
}
``````

now for the problem!
i need to work out how to rotate around the box center without the box being offset,
so ofRect now becomes,

``````ofRect(0, 0, w, h);
``````

and i need to be able to do this only using ofMatrix4x4.
so far ive tried a few things which are giving me incorrect results.
like the below,

``````void ofApp::draw(){
int w = 200;
int h = 200;
float rotation = ofGetElapsedTimef() * 10;

ofMatrix4x4 mat;
mat.preMultTranslate(ofVec3f(-w * 0.5, -h * 0.5, 0));
mat.preMultRotate(ofQuaternion(rotation, ofVec3f(0, 0, 1)));
mat.preMultTranslate(ofVec3f(w * 0.5, h * 0.5, 0));

ofPushMatrix();
ofTranslate(200, 200);
ofMultMatrix(mat);
ofRect(0, 0, w, h);
ofPopMatrix();
}
``````

can any math heads help me out with this one?

cheers,
L.

ok so the problem was me making stupid mistakes.
solution below.

this rotates the box around its center,

``````void ofApp::draw(){
float rotation = ofGetElapsedTimef() * 10;

ofPushMatrix();

ofTranslate(200, 200);
ofTranslate(100, 100);
ofRotate(rotation);
ofTranslate(-100, -100);

ofRect(0, 0, 200, 200);
ofPopMatrix();
}
``````

and can also be written like this,

``````void ofApp::draw(){
float rotation = ofGetElapsedTimef() * 10;

ofMatrix4x4 mat;
mat.preMultTranslate(ofVec3f(200, 200, 0));
mat.preMultTranslate(ofVec3f(100, 100, 0));
mat.preMultRotate(ofQuaternion(rotation, ofVec3f(0, 0, 1)));
mat.preMultTranslate(ofVec3f(-100, -100, 0));

ofPushMatrix();

ofMultMatrix(mat);

ofRect(0, 0, 200, 200);
ofPopMatrix();
}
``````
1 Like

you could also do ofSetRectMode(OF_RECTMODE_CENTER);

but anyway for future reference if you are in coordinate system A , but you want to do something relative to coordinate system B(say a rotation R) your matrix order should be A * B * R * inverse(B), so in your case. you did this.

``````mat.preMultTranslate(ofVec3f(200, 200, 0)); // takes you to coordinate system A
mat.preMultTranslate(ofVec3f(100, 100, 0)); // coordinate system B
mat.preMultRotate(ofQuaternion(rotation, ofVec3f(0, 0, 1))); // perform a rotation R relative to coordinate system B
mat.preMultTranslate(ofVec3f(-100, -100, 0)); // multiply by inverse(B) to take you back to coordinate system A

``````