# scaling function

• 10-23-2006
rozner
scaling function
Hello,

I am working on a school assignment and have one small problem. Here's the general description of the assignment:

Create an openGL program (2D) that can be used to be a street map of a given area. So some functions are making buildings and streets, being able to place them and rotate and scale them. Now I've got most of that done already, don't worry, I didn't come here looking for someone to do my homework for me ... I'm just stuck on one thing. The tricky part came with group things together. Everything is a rectangle. I have a WorldObject class which has subclasses for building and street, which is not so relevant anyway. WorldObject has a vector of rectangles in this object.

So to rotate an object, I need to rotate every rectangle, with respect to the center of the object. After much math on paper and some old trial and error I figured a good way to do this that works great. My problem comes with the scaling function. I've got a function that almost works, but is slightly off, if I have two rectangles right next to each other (touching) and I increment the scale, they'll be slowly moving towards each other instead of the edges staying just next to each other like they should. It's close to perfect, and I may just give up and leave it like this, but I'm really a perfectionist and want this to work properly. So here's where I would be ever so greatful for your help. This is the code I have for this function:

Code:

```void Rectangle::incrementCenter(Point2D * pointOfOrigin, GLfloat width, GLfloat height) {         if (this->center == *pointOfOrigin) return;         // normalize to origin         this->center -= *pointOfOrigin;         // determine z and add the new distance to it (will usually be 1)         double z = sqrt(pow(this->center.x,2) + pow(this->center.y,2));         double z1 = sqrt(pow(width,2) + pow(height,2));         if (width < 0 || height < 0 && !(width < 0 && height < 0)) z1 *= -1;         z += z1;         // determine angle between center of rectangle and center of the object         double rads = atan(this->center.y/this->center.x);         // see comments in rotateCenter for this one         if (this->center.x < 0 && this->center.y > 0 ||                 this->center.x < 0 && this->center.y < 0) {                 rads += PI;         }         Point2D scaledCenter = Point2D(z*cos(rads), z*sin(rads));         this->center = scaledCenter + *pointOfOrigin; } // the above gets called from WorldObject void WorldObject::scale(GLfloat width, GLfloat height) {         Point2D * center = calulateCenter();         // how many rectangles in this object         int size = (int) this->rectangles.size();         for (vector<Rectangle>::iterator it = this->rectangles.begin(); it != this->rectangles.end(); it++) {                 it->incrementScale(width,height);                 // the center should only move by the width increment/size since there may be multiple                 // rectangles enlarged                 // not sure now why I put the 2 there but removing it makes this bad                 it->incrementCenter(center,width/(2*size),height/(2*size));         } }```
Sorry if this is the wrong forum, but I figured graphics related would best fit the game programming forum, even if it's not quite a game.

Thanks for any help on this
• 10-23-2006
VirtualAce
If the four corners of the rectangle are all drawn using offsets on x and y from a central point, scaling them is a matter of a simple multiplication.

I'm not sure why you are needing the angle here at all in either of these operations. Rotation only requires a radian value to increment/decrement the rotation.

float fRotX=fOrgX*cos(fAngle)-fOrgY*sin(fAngle);
float fRotY=fOrgX*sin(fAngle)+fOrgY*cos(fAngle);

A translate is simple:

fTransX=fOrgX+fDirectionX*fDistance;
fTransY=fOrgY+fDirectionY*fDistance;

These can all be done using matrices.

I will show the matrices for LEFT HANDED only since that is what I'm used to:

Rotate Z
cos(ZAngle),-sin(ZAngle),0,0
sin(ZAngle),cos(ZAngle),0,0
0,0,1,0
0,0,0,1

Translate dx,dy,dz
1,0,0,dx
0,1,0,dy
0,0,1,dz
0,0,0,1

Scale sx,sy,sz
sx,0,0,0
0,sy,0,0
0,0,sz,0
0,0,0,1

Transform a vector by a 4x4 matrix - [M]*v
M00 M01 M02 M03
M10 M11 M12 M13
M20 M21 M22 M23
M30 M31 M32 M33

fNewX=fOrgX*mat[M00]+fOrgY*mat[M01]*fOrgZ*mat[M02]+mat[M03];
fNewY=fOrgX*mat[M10]+fOrgY*mat[M11]*fOrgZ*mat[M12]+mat[M13];
fNewZ=fOrgX*mat[M20]+fOrgY*mat[M21]*fOrgZ*mat[M22]+mat[M23];

Concatenate 4x4 matrices
Code:

```void MatMul(float mat1[4][4],float mat2[4][4],float result[4][4]) {    for (int i=0;i<4;i++)   {     for (int j=0;j<4;j++)     {       result[i][j]=0.0f;       for (int k=0;k<4;k++)       {           mat[i][j]+=mat1[i][k]*mat2[k][j];       }     }   } }```