• 10
• 9
• 13
• 10
• 18

Error When Applying Rotation, Polygon Shrink Over Time?

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

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)

void Poly2D::rotateBy(const float angle){ const float sinA = sinf(angle), cosA = cosf(angle); for(ushort i = 0; i < vertLength; i++){ float &x = vertices[X], &y = vertices[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; } }

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 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.

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 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?

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[X] = vertices[X]; rotVertices[Y] = vertices[Y]; float &x = rotVertices[X], &y = rotVertices[Y]; x -= center -> x; y -= center -> y; x = (x * cosA) - (y * sinA); y = (x * sinA) + (y * cosA); x += center -> x; y += center -> y; } }

Share on other sites
//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 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...

#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[X] = list -> x; vertices[Y] = list -> y; rotVertices[X] = (float)list -> x; rotVertices[Y] = (float)list -> y; } setCenter(); } Poly2D::~Poly2D(){ } void Poly2D::setCenter(){ float cx = 0.0f, cy = 0.0f; for(ushort i = 0; i < vertLength; i++){ cx += rotVertices[X]; cy += rotVertices[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[X] += (float)amount -> x; vertices[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[X] = vertices[X]; rotVertices[Y] = vertices[Y]; float &x = rotVertices[X], &y = rotVertices[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); }

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 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 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

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: