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 > help please with background positioning and rotation

#21834 - immortalninjak - Mon Jun 07, 2004 10:51 am

Hey all,
My problem is I cant get a background to rotate about a point.
Here is what I am tring to do. In mode 1 i have backgound 2 as a 256x256 rotational background. It is a picture of a rolled up scroll to the right of the screen. What I am tring to do is get it to rotate around the centre of the scroll, so it looks like its spinning.
I am using the RotateBackground from Pern/junkie:

void RotateBackground(Bg* bg, s32 angle,s32 center_x, s32 center_y, FIXED zoom)
{

center_y = (center_y * zoom)>>8;
center_x = (center_x * zoom)>>8;

bg->DX = ((bg->x_scroll<<8)-center_y*(s32)SIN[angle]-center_x*(s32)COS[angle]);
bg->DY = ((bg->y_scroll<<8)-center_y*(s32)COS[angle]+center_x*(s32)SIN[angle]);

bg->PA = ((s32)COS[angle]*zoom)>>8; //cos&sin are LUTs that are .8 fixed numbers
bg->PB = ((s32)SIN[angle]*zoom)>>8; //zoom is also fixed
bg->PC = (-(s32)SIN[angle]*zoom)>>8;
bg->PD = ((s32)COS[angle]*zoom)>>8;
}

The tutorials didnt really explain how this works and I dont really understand it.
The problem I'm having is that when I use this method it shifts the background, ie when I use RotateBackground(&bg2scroll, 0, 10, 10, zoom); it shifts the background 10 to the left and 10 down.
The point I want to rotate about is (188,72)
Any help on this matter would be greatly appreciated thank you.

#21835 - f(DarkAngel) - Mon Jun 07, 2004 12:48 pm

Cearn's tutorials explain them correctly.

http://user.chem.tue.nl/jakvijn/tonc/affine.htm
http://user.chem.tue.nl/jakvijn/tonc/affbg.htm
_________________
death scream...

#21862 - immortalninjak - Tue Jun 08, 2004 9:54 am

thanks for the links,
Had a brief look and not easy to follow (for me at least) so it might be a while before I get it to work (sigh)
Or I can just give up on the flashy looks for now...
thanks anyways

#21966 - Cearn - Thu Jun 10, 2004 8:43 am

The thing about rotation is that it always rotates around the origin. To rotate around an arbitrary point r, you have to translate the map to the origin, do the rotation and translate back. As the GBA relies on one displacement vector dx and one affine transformation matrix P, you have to correct for the rotated coordinate system yourself.

Off the top of my head, try
Code:

// Note: rx and ry are .8 fixeds now
void RotateBackground(Bg* bg, s32 alpha, FIXED rx, FIXED ry, FIXED zoom)
{
    // construct P
    bg->PA = (COS[angle]*zoom)>>8;
    bg->PB = (SIN[angle]*zoom)>>8;
    bg->PC = -bg->PB;
    bg->PD = bg->PA;

    // construct displacement (= r - P? r)
    bg->DX= rx - ( (bg->PA*rx + bg->PC*ry)>>8 );
    bg->DY= ry - ( (bg->PC*rx + bg->PD*ry)>>8 );
}

This is basically eq 4, with p0 = q0 = r. I may have messed up with the signs of r, but this should work.