Totally confused with ofPushMatrix transformations

Hello,

I’m totally confused with is supposed to be the most basic thing.

So I have a polygon, that draw on the screen.

I have a variable scale and then I need to center it on the screen.

ofPushMatrix()
  ofTranslate(-polygonCenterX, -polygonCenterY);
    ofPushMatrix()
       ofScale(scaleValue);
       ofTranslate(blah,blah to center);
	   for (unsigned int i = 0; i < blobs.size(); i++) {
	   tess.tessellateToMesh(blobs[i], ofPolyWindingMode::OF_POLY_WINDING_ODD, theMesh, true);
	   theMesh.draw();
     ofPopMatrix();
ofPopMatrix();

I would expect ofTranslate to moves the origin of coordinate system.

Then scale is supposed … well scale and stay at zero.
However when I scale it moves away from zero proportionally to scale.
Need some crazy calculations to bring it back… that doesn’t seems right.

if I do

ofPushMatrix();
  ofTranslate(-polygonCenterX, -polygonCenterY);
  ofScale(scaleValue);

the effect is the same… when I scale my mesh moves away!

What am I doing wrong, I don’t understand. I’ve spent hours…

SOS!

for some reason THIS works… but I don’t understand it…

ofTranslate(-currentX * testScale, -currentY * testScale);
ofScale(testScale);
ofTranslate(WIDTH*0.5 / testScale, HEIGHT*0.5 / testScale);

@SFR75 one of the ways to make this much easier is to have your mesh / blob / shape use coordinates that is relative to 0,0. So that 0,0 would represent the center of the shape.

ie: For a square:

Then you can do:

ofPushMatrix(); 
    ofTranslate(drawPosX, drawPosY);
    ofScale(4,  4, 1);
    myMesh.draw(); 
ofPopMatrix();

If you have a polyline where the blob center isn’t 0,0 you could do:

ofPolyline tmpPoly = blob[i]; 
auto center = tmpPoly.getBoundingBox().getCenter();
for( int i = 0; i < tmpPoly.size(); i++){
  tmpPoly[i] -= center;
}
//now tmpPoly is relative to 0,0

Ok. So normalisation is the key here… )
got it - thanks!!

Hi

I was doing the same mistake. I think this is relative to the post-multiplication or pre-multiplication topic.
My solution is to reverse the order:

ofTranslate(blah,blah to center);
ofScale(scaleValue);
ofTranslate(-polygonCenterX, -polygonCenterY);

Generally, given a 2D object and some anchor point A on this object, whose coordinates are (ax, ay) in the object coordinates system, the code to scale and rotate it around A, then to draw it with A placed at some (x,y) point on the screen is:

ofTranslate( x, y );
ofRotate( rotation, 0, 0, 1 );
ofScale( scale );
ofTranslate( -ax, -ay );
obj.draw()

ofScale too multiplies the translation coordinates, so you have to take this in consideration when translating after scaling.
and I think the state is saved for the next frames, until you reset scale using ofScale(1.0, 1.0, 1.0);
is it possible to make your object scale independently of ofScale? I usually prefer to work this way so coordinate system is intact.