• Create Account

# Error When Applying Rotation, Polygon Shrink Over Time?

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

9 replies to this topic

### #1SHOKWAV  Members   -  Reputation: 111

Like
0Likes
Like

Posted 12 June 2012 - 10:38 PM

I'm making my own polygon class for a game I'm making. However, whenever I try to apply rotation to 'em, it shrinks the entire polygon. After around 1000 rotations the shrinking becomes apparent, and visually you can notice them shrinking rapidly. Is there any way to minimize this? I'm assuming it's some precision errors? Here's my code below, I'm hoping it's enough to see my problem.

(X and Y are macros btw)

void Poly2D::rotateBy(const float angle){

const float sinA = sinf(angle), cosA = cosf(angle);

for(ushort i = 0; i < vertLength; i++){

float &x = vertices[i][X], &y = vertices[i][Y];

//move to origin for rotating
x -= center -> x;
y -= center -> y;

x = (x * cosA) - (y * sinA);
y = (x * sinA) + (y * cosA);

//move back
x += center -> x;
y += center -> y;

std::cout << x << ", " << y << std::endl;

}
}

### #2jefferytitan  Members   -  Reputation: 1039

Like
2Likes
Like

Posted 12 June 2012 - 11:20 PM

This is common in graphics due to compounding rounding issues. I would suggest keeping the original polygon co-ordinates untouched, and do rendering based on a copy which is the original polygon rotated by the accumulated rotations. Also consider letting the GPU do the work, as it's pretty good at applying a transformation to a sequence of primitives.

### #3SHOKWAV  Members   -  Reputation: 111

Like
0Likes
Like

Posted 13 June 2012 - 10:39 AM

This is common in graphics due to compounding rounding issues. I would suggest keeping the original polygon co-ordinates untouched, and do rendering based on a copy which is the original polygon rotated by the accumulated rotations. Also consider letting the GPU do the work, as it's pretty good at applying a transformation to a sequence of primitives.

Thanks, I figured that was the issue, I'll resolve it quite easily now. Also I'm not very good at things like GLSL, lol.

### #4SHOKWAV  Members   -  Reputation: 111

Like
0Likes
Like

Posted 13 June 2012 - 11:18 PM

Strange... I took your advice, and I created another array to hold a copy of the vertex data to apply the rotations to... now it's wanting to rotate on like every axis?

void Poly2D::rotateBy(const float angle){

//accumulated rotation... what's the efficient way to clamp this?
rotation += angle;

const float sinA = sinf(rotation), cosA = cosf(rotation);

for(ushort i = 0; i < vertLength; i++){

//this is just a copy of the vertex data
rotVertices[i][X] = vertices[i][X];
rotVertices[i][Y] = vertices[i][Y];

float &x = rotVertices[i][X], &y = rotVertices[i][Y];

x -= center -> x;
y -= center -> y;

x = (x * cosA) - (y * sinA);
y = (x * sinA) + (y * cosA);

x += center -> x;
y += center -> y;

}
}

### #5Bacterius  Crossbones+   -  Reputation: 5585

Like
0Likes
Like

Posted 13 June 2012 - 11:29 PM

//accumulated rotation... what's the efficient way to clamp this?
rotation += angle;

You don't. Unless your polygon is rotating at an insane rate you will not run out of accuracy any time soon. Don't worry about it (if you really want to, and with small increments (i.e. less than a full rotation) you can simply decrement it by 2pi if it gets greater than 2pi, sparing the expensive general-purpose real remainder operation)

What do you mean by rotating on every axis? There's only one possible rotation axis in your code which is the virtual depth axis through the object's center. Do you mean the vertices start rotating with incorrect centers or something? Could you elaborate and possibly post all of the rotation-related code, my guess is you forgot to change vertices to rotVertices somewhere.

Edited by Bacterius, 13 June 2012 - 11:30 PM.

"The best comment is a deleted comment."

### #6SHOKWAV  Members   -  Reputation: 111

Like
0Likes
Like

Posted 14 June 2012 - 12:37 PM

It's... really hard to explain, it's rotating very strangely. It's supposed to rotate only on the Z axis, and was doing just that a while ago...

#ifndef POLY2D_H
#define POLY2D_H

#include "Global.h"
#include "Dim2D.h"

class Poly2D{

Dim2D<float>* center;
float rotation;

short (*vertices)[2];
float (*rotVertices)[2]; //rotated vertices

const ushort vertLength;

void setCenter();

public:

Poly2D(Dim2D<short>* list[], const ushort len);
~Poly2D();

void translate(Dim2D<short>*& amount);
void rotateBy(const float angle);

void draw();

};

#endif

definition file:

#include "Poly2D.h"

Poly2D::Poly2D(Dim2D<short>* list[], const ushort len):center(new Dim2D<float>()), vertices(new short[len][2]),
rotVertices(new float[len][2]), vertLength(len), rotation(0.0f){

for(ushort i = 0; i < len; i++){

vertices[i][X] = list[i] -> x;
vertices[i][Y] = list[i] -> y;
rotVertices[i][X] = (float)list[i] -> x;
rotVertices[i][Y] = (float)list[i] -> y;

}

setCenter();

}

Poly2D::~Poly2D(){

}

void Poly2D::setCenter(){

float cx = 0.0f, cy = 0.0f;

for(ushort i = 0; i < vertLength; i++){
cx += rotVertices[i][X];
cy += rotVertices[i][Y];
}

cx = cx / (float)vertLength;
cy = cy / (float)vertLength;

center -> x = cx;
center -> y = cy;

}

void Poly2D::translate(Dim2D<short>*& amount){
//todo: update this
for(ushort i = 0; i < vertLength; i++){
vertices[i][X] += (float)amount -> x;
vertices[i][Y] += (float)amount -> y;
}

setCenter();

}

void Poly2D::rotateBy(const float angle){

rotation += angle;

const float sinA = sinf(rotation), cosA = cosf(rotation);

for(ushort i = 0; i < vertLength; i++){

//reset vertices
rotVertices[i][X] = vertices[i][X];
rotVertices[i][Y] = vertices[i][Y];

float &x = rotVertices[i][X], &y = rotVertices[i][Y];

x -= center -> x;
y -= center -> y;

x = (x * cosA) - (y * sinA);
y = (x * sinA) + (y * cosA);

x += center -> x;
y += center -> y;

}
}

void Poly2D::draw(){

glEnableClientState(GL_VERTEX_ARRAY);

glPushMatrix();

glVertexPointer(2, GL_FLOAT, 0, rotVertices);
glDrawArrays(GL_POLYGON, 0, vertLength);

glPopMatrix();

glDisableClientState(GL_VERTEX_ARRAY);

}

### #7SHOKWAV  Members   -  Reputation: 111

Like
0Likes
Like

Posted 15 June 2012 - 12:42 AM

Guys, please help... I'm really desperate to get this done... please, can anyone explain this unfixable, sudden problem? It ONLY does this when I reset the rotated polygon and try to rotate it from there...

### #8szecs  Members   -  Reputation: 1859

Like
2Likes
Like

Posted 15 June 2012 - 01:36 AM

It's a typical mistake, sorry to say that.

x = (x * cosA) - (y * sinA);
y = (x * sinA) + (y * cosA);

These equations work on the original coordinates. But in the first equation, you overwrite the x, and you use the overwritten x in the second equation. you have to use temporary variables.

This was the mistake all along, but the angle was small first, so the mistake only resulted in shrinking.

Something like:

x -= center -> x;
y -= center -> y;

float x_temp = (x * cosA) - (y * sinA);
float y_temp = (x * sinA) + (y * cosA);

//move back
x = x_temp + center -> x;
y = y_temp + center -> y;

There are precision errors, but these shouldn't be apparent under so few rotations. I use this kind of accumulated rotation in a few places, and I never needed to use correction on the vertices.

Edited by szecs, 15 June 2012 - 02:01 AM.

### #9SHOKWAV  Members   -  Reputation: 111

Like
0Likes
Like

Posted 15 June 2012 - 09:37 AM

I love you.

That fixed everything, and I can finally more forward with the program.

THANK.YOU.

In case anyone was wondering, this is what I was trying to describe:

### #10szecs  Members   -  Reputation: 1859

Like
0Likes
Like

Posted 15 June 2012 - 09:40 AM

Now you can express your love by rating up my post

Edited by szecs, 15 June 2012 - 09:41 AM.

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

PARTNERS