How to find out translated coordinate in the middle of draw()?

HI, I would like to know if it is possible to find out the currently translated x,y coordinate in the middle of the draw() function.

For example, let’s say I called ofTranslate() several times with random x,y values and I want to know where the object should be located at the end of the draw() loop, I can of course store all previous x,y information and add them all…

ofTranslate(100, 200);
ofDrawRectangle(0,0,10,10) // this rectangle should be placed at (150, 250)

But would there be any possible way to get the current translated x,y coordinates without having to calculate all the previous values?


First retrieve the current modelview matrix:

float mv[16];

Then do the following to transform your vertex:

float xp = mv[0] * x + mv[4] * y + mv[8] * z + mv[12];
float yp = mv[1] * x + mv[5] * y + mv[9] * z + mv[13];
float zp = mv[2] * x + mv[6] * y + mv[10] * z + mv[14];
float wp = mv[3] * x + mv[7] * y + mv[11] * z + mv[15];

xp /= wp;
yp /= wp;
zp /= wp;


Which in OF becomes (not tested)

ofTranslate(100, 200);
ofMatrix4x4 currentMatrix = ofGetCurrentMatrix(ofMatrixMode::OF_MATRIX_MODELVIEW);
ofVec3f origin(0,0,0);
origin *= currentMatrix;
ofLog() << "Translated origin" << origin; // should give you the new origin [100,200]
1 Like

Hi, Hennio. Thank you for your solution.
Sorry for the late reply, I couldn’t try this for a long time.
I just tried your code but I couldn’t get the expected result.

First of all, origin = currentMatrix; produces an error, "No viable overloaded '=’"
So if I change it to origin *= currentMatrix.getTranslation(); it compiles but I get 0,0,0 as new origin. not [100,200]
Shouldn’t the result always be (0,0,0) as anything that is multiplied to origin(0,0,0) becomes (0,0,0)?

Could you try origin = currentMatrix * origin; ?

1 Like

the correct order would be:

origin = origin * currentMatrix; 

since ofVec* and ofMatrix* have different multiplication order than glsl. the original, origin *= currentMatrix should work too but i think you were using = instead of *=.

1 Like

I just tried the code in empty project but I got this result instead of [100,200]

oh yes you need to also get the projection like:

auto currentMatrix = ofGetCurrentMatrix(ofMatrixMode::OF_MATRIX_PROJECTION) * ofGetCurrentMatrix(ofMatrixMode::OF_MATRIX_MODELVIEW);

i’m not a 100% sure right now but you might also need the orientation matrix which OF uses to flip the y axis. if the above doesn’t give you the expected result try:

auto currentMatrix = ofGetCurrentOrientationMatrix() * ofGetCurrentMatrix(ofMatrixMode::OF_MATRIX_PROJECTION) * ofGetCurrentMatrix(ofMatrixMode::OF_MATRIX_MODELVIEW);

actually that’s not correct. multiplying by the model view only as you were doing first would give you is the coordinates of the point as if the camera was the 0,0 of the world. multiplying by the projection and the modelview would give you the 2d projection of the coordinates.

what you want is to multiply the point by the model matrix alone which is not directly available in OF but you can get by multiplying the model view by the inverse of the view like:

auto modelMatrix = ofGetCurrentMatrix(OF_MATRIX_MODELVIEW) * ofGetCurrentViewMatrix().getInverse();
origin = origin * modelMatrix;

will return the point + any transformations in world coordinates

1 Like

Wow I just tested the code and it works decently even with ofRotate and ofScale.
Thank you so much @arturo :slight_smile:

Just for an update using glm and oF 0.10.0+.

    glm::vec4 origin(0, 0, 0, 1); // x = 0, y = 0, z = 0 (1 for homogenous coord)
    glm::mat4 modelMatrix = glm::inverse(ofGetCurrentViewMatrix()) * ofGetCurrentMatrix(OF_MATRIX_MODELVIEW) ;
    origin = modelMatrix * origin;

The main difference is the multiplication order in GLM.


I should hack this into a glm version!