I've got two bitmaps. A and B.
I've got a rotation-capable drawing function. This function also takes optional x and y parameters which are *offsets* for the default rotation point (which is the exact middle of the bitmap).
So... how do I calculate these x/y offsets so that two arbitrary bitmaps appear to rotate about the same point?
I've come up with a solution, but for some reason it's just not working correctly. It looks *almost* right. But I'm off somewhere... or possibly it's a floating point rounding issue. I'd be curious if anyone else can come up with the same answer.
Xa = bitmap A's upper left corner x position
Ya = bitmap A's upper left corner y position
Xb, Yb = bitmap B's position
Wa = width of A
Wb = width of B
Ha = height of A
Hb = height of B
I guess another way of phrasing this problem is: How do I translate a relative rotation coordinate into an absolute rotation coord? I'm sure this would be easy if I'd ever studied 3D graphics. :|
I don't understand, can you provide a simple drawing so I can see what you are talking about. From reading your problem, it doesn't sound difficult, rotation in 2d are not that complex... but I am not sure what it is you are trying to do.
So... you want to change the bitmaps anchor point (which is usually the center of the bitmap) and rotate around the new anchor point?
in this case, this is what I am doing:
float cs = cosf(-Rotation);
float ss = sinf(-Rotation);
V2 center = (Pos+Pos)/2.0f+CenterOffset;
for (int t=0; t<4; t++)
float x = GSprite2D[t].Pos.x-center.x;
float y = GSprite2D[t].Pos.y-center.y;
GSprite2D[t].Pos.x = x*cs-y*ss+center.x;
GSprite2D[t].Pos.y = x*ss+y*cs+center.y;
To rotate a point (or bitmap or whatever) around an arbitrary point, tou compose a translation, a rotation, and an inverse translation.
You first take the point to rotate and apply a translation negating the rotation center (ie x1 = x - cx). Then you rotate as if it were around (0, 0) using the standard rotation equations. Then you compensate for the translation (ie x3 = x2 + cx). This is exactly what jcottier's code does, if you look closely.
Right... but what you're doing there is taking a point x, y and finding x',y' -- which is the new location of that point after rotation. That doesn't help me... my drawing method doesn't take x',y'... it takes x, y, an angle, and a rotation offset. When I draw a bitmap with rotation, the upper left corner of that bitmap (x,y) is not going to actually get drawn in that location... unless of course that happens to also be the point of rotation.
Image this situation: You are drawing a snowman on the screen, but he is actually composed of three different bitmaps... a bottom, a torso, and a head. When you rotate the snowman, you want all his parts to still be aligned the same way... you want the rotation to loook the same as if it was a single bitmap.
The math is really obviously simple. It's just translation of the rotation point. Unfortunately, it just doesn't look right on the screen. It's close enough I think it's just floating point issues...
If the drawing method looks like this:
bitmap.draw(screen x, screen y, angle, rotation pt offset x, rotation pt offset y)
Then what I get is this:
A.draw(Xa, Ya, angle, 0, 0); // 0, 0 means rotation is center of bitmap A
B.offsetX = -Wb/2 - (Xb - Xa) + Wa/2
B.offsetY = -Hb/2 - (Yb - Ya) + Ha/2
B.draw(Xb, Yb, angle, B.offsetX, B.offsetY);
Unless I'm misunderstanding the API, it all seems pretty straightforward. Using PTK, by the way.
Now B.offsetX, B.offsetY should give me the same point of rotation as bitmap A.
Last edited by Pyabo; 12-20-2007 at 11:33 AM.
If I didn't misunderstood something, your offset calculation should look like this:
B.offsetX = Xa - Xb
B.offsetY = Ya - Yb
I'm assuming that (Xa, Ya) and (Xb, Yb) are the centers of the bitmaps A and B and that you're specifying the offset relative to the center of a bitmap.
If you're specifying it relativ to the top - left corner it has to look different of course.
If you can notice a strange rotation behaviour by just looking at it, I would't assume that this is due to floating point errors.
No, (Xa,Ya) is the upper left corner of Bitmap A...
So center would be Xa + Wa/2, Ya + Ha/2
ok, I understand what you are talking about. Basically, your rotatation position is the center of picture A: Rot(xa+wa/2, ya+ha)
Then you want to know what is Rot coordinate in a new metrix. This new metrix is based around the center of picture B. CenterB(xb+wb/2, yb+hb).
This is simply Rot-CenterB:
NewRotCoord = (xa+wa/2 - xb -wb/2, ya+ha - yb -hb)
This is the same result as your. So your math are correct. So, if you have glitch artefact, could it be because of the drawing function? Do you activate mipmap filtering? It is hard to help you if you don't provide screenshot and more helpfull data.
argh... I mean ha/2 and hb/2 you corrected it yourself ;-)