Sign in to follow this  
Followers 0
manderin87

Polygon rotation is too fast compared to objects rotation

36 posts in this topic

I am designing a game in android and I have a problem when updating a polygon that is used for collision detection. When the objects update method is called it rotates the object by .5 and then updates the polygon by rotating it by the same amount. The problem is on the screen the polygon is rotating faster than the object when drawn. The polygon is rotating so fast that it looks like a star, eventually it slows down and then speeds up again. It will not stay in step with the objects rotation.

This is the rotation code for the polygon.

[CODE]
public void rotate(float x0, float y0, double angle) {
for(int i = 0; i < mOrigins.size(); i++) {
Point point = mOrigins.get(i);

float x = (float) (x0 + (point.x - x0) * Math.cos(Utilities.toRadians(angle)) -
(point.y - y0) * Math.sin(Utilities.toRadians(angle)));
float y = (float) (y0 + (point.x - x0) * Math.sin(Utilities.toRadians(angle)) +
(point.y - y0) * Math.cos(Utilities.toRadians(angle)));

Point npoint = mPoints.get(i);
npoint.x = x;
npoint.y = y;

mPoints.set(i, npoint);
}

}
[/CODE]

This is the update method for the object

[CODE]
public void update(float deltaTime) {

mAccumulatedTime += deltaTime;

while(mAccumulatedTime > FIXED_FRAME_TIME) {
mAccumulatedTime -= FIXED_FRAME_TIME;

if(isActive()) {
rotate();
mBounding.rotate(mPosition.x, mPosition.y, mDegree);
drawBounding();
}
}
}
[/CODE]

Trying to limit the time has no effect on the polygon and it continues to speed up and slow down.

Can anyone please identify the error or lead me in the right direction to fix this?

thanks
0

Share this post


Link to post
Share on other sites
Where is mDegree set?
Are they invoking the same rotate()? (The parameters could have default values)
If not, what does the other one look like?
The rest looks good.
0

Share this post


Link to post
Share on other sites
If mPoints and mOrigins are linked (the same values),
It will exhibit animating behavior when run multiple times (with the same rotation value),
Otherwise it will behave as it is setting the angle.
If it does the former but you give it an angle rather than an angle increment, it will produce an alternating slow to fast rotation.

It seems you don't give it an increment; now are the two point lists bound together outside the rotate(...) function?
1

Share this post


Link to post
Share on other sites
The mOrigins is just the original points set when the polygon was created, I use mPoints to keep track of the curent points after the rotation is applied. The two lists only exsist inside the polygon class. The only variable that is supposed to change is the degree, to rotate the polygon around the x and y points. The method as it is now is making the alternating slow to fast rotation instead of just rotating the polygon by the degree.
0

Share this post


Link to post
Share on other sites
Well in that case I'm out.
There's probably a trig genius in here who can point the error to the rotation math, then.
0

Share this post


Link to post
Share on other sites
I think your code is increasing mDegree by 0.5 each frame, and mDegree is the amount that you're rotating your object each frame. So after 100 frames you're rotating by 50 degrees per frame. Eventually, you're rotating so fast that it's starting to slow down and reverse.

Edit : Never mind - just noticed that you had a separate store for the original positions (mOrigins). Any chance that float deltaTime is incorrect, and is actually the total time elapsed? Edited by C0lumbo
0

Share this post


Link to post
Share on other sites
[quote name='C0lumbo' timestamp='1354212344' post='5005381']
I think your code is increasing mDegree by 0.5 each frame, and mDegree is the amount that you're rotating your object each frame. So after 100 frames you're rotating by 50 degrees per frame. Eventually, you're rotating so fast that it's starting to slow down and reverse.
[/quote]
Yes, but how is this possible if mOrigins (or the elements contained within) does not attain state of mPoints?
0

Share this post


Link to post
Share on other sites
mDegree should be how much to rotate by this frame. It should not grow with time. What rotate() is doing is increase the rotation speed.

EDIT: Wait... I think I see what the others are seeing now. Is it possible that mOrigins and mPoints are actually the same thing?

FURTHER EDIT: What does this line do?
[quote][code] Point npoint = mPoints.get(i);[/code][/quote] Edited by Álvaro
0

Share this post


Link to post
Share on other sites
[quote name='manderin87' timestamp='1354203176' post='5005329']
Trying to limit the time has no effect on the polygon and it continues to speed up and slow down.
[/quote]
Your framerate is messing with the rotation, which would explain the speed-up and slow-down. I think this is your problem:
[quote]
mAccumulatedTime += deltaTime;
while(mAccumulatedTime > FIXED_FRAME_TIME) {
mAccumulatedTime -= FIXED_FRAME_TIME;
[/quote]
You add the delta time (elapsed since last frame I'm assuming) and then loop during the frame redrawing and rotating until you get something roughly equivalent to the framerate you wanted? That's a lot of unnecessary work.

Decide on a rotation rate (deg/rad per sec) and multiply that by deltaTime in seconds to get the amount that it should be rotated this frame. Or in milliseconds, or minutes, I'm not trying to make that a particular sticking point, just make sure your units match.
0

Share this post


Link to post
Share on other sites
The issue pops up even if i dont use deltaTime at all, that was my attempt to limit the amount of updates, but even without it, the polygon still rotates slow and fast.

[quote name='C0lumbo' timestamp='1354212344' post='5005381']
I think your code is increasing mDegree by 0.5 each frame, and mDegree is the amount that you're rotating your object each frame. So after 100 frames you're rotating by 50 degrees per frame. Eventually, you're rotating so fast that it's starting to slow down and reverse.
[/quote]

This is what the polygon is doing, but I dont know how to fix it. The degree is the current degree, should it just be the incremented amount instead?

mDegree is the current degree of the object and is increased by .5 every frame.
0

Share this post


Link to post
Share on other sites
[quote name='Álvaro' timestamp='1354213068' post='5005386']
mDegree should be how much to rotate by this frame. It should not grow with time. What rotate() is doing is increase the rotation speed.

EDIT: Wait... I think I see what the others are seeing now. Is it possible that mOrigins and mPoints are actually the same thing?

FURTHER EDIT: What does this line do?
[quote][code] Point npoint = mPoints.get(i);[/code][/quote]
[/quote]

There are two lists of points inside the polygon class. The original points mOrigin and the current points mPoints. mPoints changes and mOrigin does not with the rotation.

That code takes the point i from mPoints and updates it.

The rotate method just applies the .5f to increase the degree... The speed never increases, its always .5f and mDegree is increased by that amount each update. Edited by manderin87
0

Share this post


Link to post
Share on other sites
[quote name='manderin87' timestamp='1354213770' post='5005390']
That code takes the point i from mPoints and updates it.
[/quote]
But since you are going to set x and y, why do you bother reading the old value?
0

Share this post


Link to post
Share on other sites
[quote name='manderin87' timestamp='1354213506' post='5005389']
mDegree is the current degree of the object and is increased by .5 every frame.
[/quote]
In case my previous post got skipped, you DON'T WANT to establish a "per frame" rate, as you can't necessarily control the varying length of time it takes to process each frame. Ex: your player is facing a wall that takes up 95% of their view and isn't moving. That frame only takes 2ms to process. Then they turn around, facing 2000 props, 12 animated enemies, and dozens of particle streams. That frame takes 17ms to process. Your triangle would be spinning like crazy at the 2ms/frame, and then slow down considerably at the 17ms/frame.

Rotate at a fixed time rate, not frame rate. That's why you want to use deltaTime, correctly, and why when you weren't bothering to use deltaTime it sped up and slowed down.
0

Share this post


Link to post
Share on other sites
I don't think it's an issue with the frame rate. The only suspicious part in how the code in the first post handles the frames is that there is a call to drawBounding() inside of the loop that updates the state, which seems wrong. Either the update happens independently of the drawing or --if update() is responsible for drawing-- the drawing should only happen once, at the end of the function.
0

Share this post


Link to post
Share on other sites
[quote name='BCullis' timestamp='1354214546' post='5005393']
In case my previous post got skipped, you DON'T WANT to establish a "per frame" rate, as you can't necessarily control the varying length of time it takes to process each frame. Ex: your player is facing a wall that takes up 95% of their view and isn't moving. That frame only takes 2ms to process. Then they turn around, facing 2000 props, 12 animated enemies, and dozens of particle streams. That frame takes 17ms to process. Your triangle would be spinning like crazy at the 2ms/frame, and then slow down considerably at the 17ms/frame.

Rotate at a fixed time rate, not frame rate. That's why you want to use deltaTime, correctly, and why when you weren't bothering to use deltaTime it sped up and slowed down.
[/quote]

That certainly sounds like what is going on, should i just multply the rotation speed by the deltatime? The behaivor happened even when deltaTime wasnt there.

[quote name='Álvaro' timestamp='1354215341' post='5005398']
I don't think it's an issue with the frame rate. The only suspicious part in how the code in the first post handles the frames is that there is a call to drawBounding() inside of the loop that updates the state, which seems wrong. Either the update happens independently of the drawing or --if update() is responsible for drawing-- the drawing should only happen once, at the end of the function.
[/quote]

The drawBounding() was relocated from the rendering loop so i could see if it had any effect. Its been moved back since, but the behaivor never changed. Edited by manderin87
0

Share this post


Link to post
Share on other sites
I added to the rotate method

[source lang="java"]mDegree += mRotationSpeed * deltaTime[/source]

This fixed the polygon rotation a little, it doesnt rotate as fast as it did, but it still rotates much faster than the object.
0

Share this post


Link to post
Share on other sites
[quote name='manderin87' timestamp='1354203176' post='5005329']
[code]
if(isActive()) {
rotate();
mBounding.rotate(mPosition.x, mPosition.y, mDegree);
drawBounding();
}
[/code]
[/quote]
The mRotation should reflect the rotated polygos exactly,
As they're both assigned in the same scope, mutually dependent on the framerate.

Maybe showing some more code will help us in finding the issue?
0

Share this post


Link to post
Share on other sites
[quote name='manderin87' timestamp='1354217411' post='5005413']
This fixed the polygon rotation a little, it doesnt rotate as fast as it did, but it still rotates much faster than the object.
[/quote]
What does the code in mBounding.rotate(params) look like? Or wait, no, it looks like that's what you showed us above. What does rotate() look like?

Ideally you want the image and the object rotating at the same rate (I'll smack myself for stating the obvious), meaning you would pass them both the same rotation amount. I'd think it would be easier to calculate the rotation degree value (degrees += rotationRate * timeDelta; degrees %= 360; ) once for the frame, then pass that rotation value to both items needing a rotation calculation.
0

Share this post


Link to post
Share on other sites
While trying to check, i made the rotation manual.... the polygon is still rotating faster. Its not the framerate, its the way the polygon is rotating using the polygon rotation method above or the method used to rotate the sprite.
0

Share this post


Link to post
Share on other sites
There is something wrong with the polygon rotation method... I watched the degrees subtract and the polygon was still rotating the other way.. as the degree increased it went left as the degree decreased it still went left, instead of right. Edited by manderin87
0

Share this post


Link to post
Share on other sites
Please post both rotation methods and their calling context.

Additionally, what is responsible for calculating deltaTime? Is it the elapsed time since last frame?
0

Share this post


Link to post
Share on other sites
The polygon rotation method is

[CODE]
public void rotate(float x0, float y0, double angle) {
Log.i("Polygon", "Degree: " + angle);

for(int i = 0; i < mPoints.size(); i++) {
Point point = mPoints.get(i);

float x = (float) (x0 + (point.x - x0) * Math.cos(Utilities.toRadians(angle)) -
(point.y - y0) * Math.sin(Utilities.toRadians(angle)));
float y = (float) (y0 + (point.x - x0) * Math.sin(Utilities.toRadians(angle)) +
(point.y - y0) * Math.cos(Utilities.toRadians(angle)));

point.x = x;
point.y = y;
}
}
[/CODE]

The sprite rotation is done through a libgdx spritebatch and I am certain its correct.

[CODE]
public void draw(SpriteBatch batch, float x, float y, float degree) {
batch.draw(mImage, x - width() / 2, y - height() / 2,
pivotX(), pivotY(),
width(), height(),
mScale, mScale,
degree,
0, 0,
(int) width(), (int) height(),
false, false);
}
[/CODE]

The delta time comes from libgdx and is the time since last frame.

[CODE]
float deltaTime = Gdx.graphics.getDeltaTime();
[/CODE]

I am almost certain its something in the polygon rotation code... I was testing it... it would rotate until a certain point and then go the other way. Edited by manderin87
0

Share this post


Link to post
Share on other sites
Your update method:
[quote]
public void update(float deltaTime) {
mAccumulatedTime += deltaTime;

while(mAccumulatedTime > FIXED_FRAME_TIME) {
mAccumulatedTime -= FIXED_FRAME_TIME;

if(isActive()) {
[b]rotate();[/b]
mBounding.rotate(mPosition.x, mPosition.y, mDegree);
drawBounding();
}
}
}
[/quote]

What does rotate() do? Because by your explanation, mBounding.rotate handles the collision object rotation, and the sprite for the object is rotated by the spritebatch call.

If the sprite is being rotated by a spritebatch call, you should be giving it the same degree value that mBounding.rotate receives. Is that the case? Edited by BCullis
0

Share this post


Link to post
Share on other sites

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