Sign in to follow this  

Error When Applying Rotation, Polygon Shrink Over Time?

This topic is 2009 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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)

[CODE]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;

}
}[/CODE]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
[quote name='jefferytitan' timestamp='1339564827' post='4948721']
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.
[/quote]

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.

Share this post


Link to post
Share on other sites
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?

[CODE]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;

}
}[/CODE]

Share this post


Link to post
Share on other sites
[quote]//accumulated rotation... what's the efficient way to clamp this?
rotation += angle;[/quote]
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

Share this post


Link to post
Share on other sites
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...

header:

[CODE]#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[/CODE]

definition file:

[CODE]#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);

glLoadIdentity();
glPushMatrix();

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

glPopMatrix();

glDisableClientState(GL_VERTEX_ARRAY);

}[/CODE]

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
It's a typical mistake, sorry to say that.

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

These equations work on the [i]original[/i] coordinates. But in the first equation, you overwrite the [i]x[/i], and you use the overwritten [i]x[/i] 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

Share this post


Link to post
Share on other sites
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:

http://www.youtube.com/watch?v=yDVF08jILE4&feature=youtu.be

Share this post


Link to post
Share on other sites
I'm glad.
Now you can express your love by rating up my post [img]http://public.gamedev.net//public/style_emoticons/default/wink.png[/img] Edited by szecs

Share this post


Link to post
Share on other sites

This topic is 2009 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this