gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > Rotation Problem

#79611 - ProblemBaby - Fri Apr 14, 2006 2:49 pm

Hello

Iam trying to rotate an object around a point. It works, but its so unsmooth it jumps around the rotcenter.
Is it something thats wrong with the code?
or any ideas how I can make it more accurate.

sx, sy: rotation point relative to the center of the object
- 32 is because its a 32x32 object Iam drawing
my COS and SIN table have the format 1:3:12

Code:

f16 cos = COS(Angle) >> 4;
f16 sin = SIN(Angle) >> 4;

Object.x = x - 32 + (((cos * sx) - (sin * sy)) >> 8);
Object.y = y - 32 - (((sin * sx) + (cos * sy)) >> 8);
Object.pa = cos;
Object.pb = -sin;
Object.pc = sin;
Object.pd = cos;


Thanks

#79624 - Cearn - Fri Apr 14, 2006 5:30 pm

ProblemBaby wrote:
Hello

Iam trying to rotate an object around a point. It works, but its so unsmooth it jumps around the rotcenter.
Is it something thats wrong with the code?
or any ideas how I can make it more accurate.

sx, sy: rotation point relative to the center of the object
- 32 is because its a 32x32 object Iam drawing
my COS and SIN table have the format 1:3:12

Code:

f16 cos = COS(Angle) >> 4;
f16 sin = SIN(Angle) >> 4;

Object.x = x - 32 + (((cos * sx) - (sin * sy)) >> 8);
Object.y = y - 32 - (((sin * sx) + (cos * sy)) >> 8);
Object.pa = cos;
Object.pb = -sin;
Object.pc = sin;
Object.pd = cos;


Thanks

You've seen this thread, right? What you got here is very similar, but not exactly the same. First, try
Code:
Object.x = x-32 - ( ( cos*sx + sin*sy)>>8);
Object.y = y-32 - ( (-sin*sx + cos*sy)>>8);
If you resolve all the parentheses and signs, the cosines should have equal signs and the sines' signs should be each other's opposites.

The smoothness problem might also be caused by a fixed point mismatch. The way I see it,
x and Object.x should be .0,
cos is .8 as you mentioned, which means that
sx and sy should be .0 as well, not .8.
Or .8 with a >>16 instead of a >>8.

If that doesn't help, can we see the thing in action for ourselves?

#79717 - ProblemBaby - Sat Apr 15, 2006 4:47 pm

I tried those things, it didn't help. I can't upload it, cause my friends server is down, so Ive nowhere to upload it. I can send it to you (its actually an NDS project).

But what I want to do is to have a clock with (don't know the word in english), you know the things that shows what time it is.
And it works quite good, but in the center it jumps around a bit, can it be because of the actual picture, cause I can't find put how the code could be more accurate.

#79718 - Cearn - Sat Apr 15, 2006 4:54 pm

ProblemBaby wrote:
I tried those things, it didn't help. I can't upload it, cause my friends server is down, so I've nowhere to upload it. I can send it to you (its actually an NDS project).

Feel free to send it, but it'd have to be able to run on one of the DS emulators as I don't have the right hardware.

#79735 - wintermute - Sat Apr 15, 2006 5:45 pm

Funnily enough a watch demo has been added to the libnds example code recently. It can be found in RealTimeClock/Watch in the latest tarball.

http://www.devkitpro.org/?action=fullnews&id=103
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#79737 - ProblemBaby - Sat Apr 15, 2006 6:08 pm

Cearn wrote:

Feel free to send it, but it'd have to be able to run on one of the DS emulators as I don't have the right hardware.


Ive sent it to your mail. Hope you see something missing!

wintermute wrote:

Funnily enough a watch demo has been added to the libnds example code recently. It can be found in RealTimeClock/Watch in the latest tarball.


I checked it out, but it used the 3d hardware=/

#79766 - Cearn - Sat Apr 15, 2006 10:04 pm

ProblemBaby wrote:
Cearn wrote:
Feel free to send it, but it'd have to be able to run on one of the DS emulators as I don't have the right hardware.

I've sent it to your mail. Hope you see something missing!

Got it and ran it. Don't think you're going to like the answer though.

The code is fine, the wobble you're seeing is innate to the way sprites are rotated, and there's little you can do about that. As you know, the way affine sprites are rendered is by scanning the 'on-screen space' of the sprite line by line, and using the affine matrix as increments to find the actual color from the object 'texture' that should be used at a given screenpoint. The truncating of coordinates that goes with this means that sometimes it will skip or double a (source)pixel, so you can always expect an inaccuracy of about a pixel. If your sprite is small enough, this makes a big difference.
A secondary point is that for sprites, the scanning process starts at the centre of the sprite, always (what you're doing now is placing the sprite in such a way that it looks like it's rotating around another point. It doesn't). This will cause uneven conversions away from the center and make circles not so round if they're not directly at the center of the sprite, as you can see. It also makes it impossible to exactly align two affine sprites, as can be seen in this demo.

You can improve things a little bit by properly rounding your positions by adding o.5 (one half; 256/2=128) before rightshifting, just like you would for floats. This won't make the wobble disappear, but it might make the average position a little better. Another trick you might try is just placing a non-rotated sprite in front of the pivot point, as that's where the onversion errors are most noticeable. But you can never get rid of it completely, though.

#79791 - ProblemBaby - Sun Apr 16, 2006 12:30 am

Thanks for the answer!
Yeah I couldn't see anything wrong so I wasn't that suprised. But One interesting thing you said inspired me to a new approach that in fact gaved me really good results... I changed the sprite size to 32x64 and rotated it around its own center.

#114650 - Ant6n - Tue Jan 09, 2007 7:48 pm

sorry for reviving old thread, but i was thinking that it might be possible to get subpixel accuracy on sprites if one changes the sprite attributes during hblank. has anybody ever tried that?