image rotation

Started by
1 comment, last by Thr33d 17 years, 4 months ago
Hi, I have a little question. For my simple racing gmae, i created a new bitmap-class, which draws the car on the screen, in the different rotations. To draw the car in a certain direction, I use the matrix rotations on each point like this: x = x*cos(PI*m_iRotation/360.0)-y*sin(PI*m_iRotation/360.0); y = x*sin(PI*m_iRotation/360.0)+y*cos(PI*m_iRotation/360.0); This works pretty good, to turn the car, but it gives a not so nice car. It draws some strange points, like this: Is there a better way to draw the sprite into a direction?
Spippo is magic,is magic!!!!!Oh ho hoo!!!!Spippo is magic
Advertisement
The little 'holes' in the car is what bugs you I'd assume....

Your math is just fine.
The holes are caused by innacuracies due to floating point and whatnot rounding errors.

While in theory your approach works, in practice the rotation transform will not be a 1-to-1 function for all pixels. Some pixels will get rounded to be sent to the same location, leaving the holes you see.

You probably do something like this right now:

for rows  for columns    NewImage[transform(row)][transform(col)].color=BaseImage[row][col].color;  }}


To avoid holes in the New Image
do the process backwards:

for rows  for columns    NewImage[row][col].color=BaseImage[reversetransform(row)][reversetransform(col)].color;  }}



Where reversetransform is the same math, but reversed angle...

See the sublte difference between the two methods?
in the first one (your method I bet) you loop on the Baseimage coordinates and rely on the transform to 'fill in' the NewImage's coordinates
but like i said... rounding errors make it no guarnatee that every pixel gets hit

in the second method, you loop on the NewImage coordinates and 'retrive' pixels from the BaseImage. by looping on them instead you Guarantee that each pixel is touched by the algorithm... Rounding errors in the transform will still be present, but not visible since any miss will retrieve a nearest neighbor pixel from the BaseImage reference...


P.S.
make sure that you build each new rotated image from the Base Image. Never rotate from an already rotated image; its like a xerox copy, errors will accumulate with each generation...
I second haphazardlynamed's suggestion, and add that you may want to implement some filtering as well.

Right now, choosing the closest pixel is what's known as "Nearest Neighbor" or just "Nearest" filtering.
For an antialiased look, use bilinear filtering.
Basically, you take the resulting (x,y) position, and instead of grabbing the nearest pixel, take a linear blend of the 4 surrounding pixels. The next step up is bicubic filtering (but *shouldn't* be at all necessary for what you're doing)

-M

This topic is closed to new replies.

Advertisement