Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Position of point when rotated

Credits go to Evert, Felipe Maia, and X-G for helping out!
This thread is locked; no one can reply to it. rss feed Print
 1   2 
Position of point when rotated
Vasco Freitas
Member #6,904
February 2006
avatar

Given the distance of a point from a rotation axis in coordinates (for example, point A is 10 x units and -20 y units from axis) when the rotation angle is 0, how do I calculate the position of the point for any rotation angle (in radians)?

I've tried "x_pos = axis_x + x_distance * cos(angle); y_pos = axis_y + y_distance * -sin(angle);" but this only seems to work in some cases :-/

Epsi
Member #5,731
April 2005
avatar

I do it this way: (probably not the best method, but it works)

I use the vector length of pivot.x,pivot.y -> blit_point.x,blit_point_y and the angle of the vector (8.0 and 4.0 dec degree in that case)

let's say "18".

head_pos_ is the coordinate of the pivot of the head bitmap.
head_angle is the angle of rotation.

eyes_x and y are the "blitting point's" coord

float eyes_x = head_pos_x + int(18.0 * cosinus(head_angle -90.0))
+ int(8.0 * cosinus(head_angle));
float eyes_y = head_pos_y + int(18.0 * sinus(head_angle -90.0))
+ int(4.0 * sinus(head_angle));

___________________________________

piccolo: "soon all new 2d alegro games will be better. after i finsh my MMRPG. my game will serve as a code reference. so you can understand and grab code from."
piccolo: "just wait until my invetion comes out its going to take the wii to the next leave of game play. it will run sony and microsoft out of busness if i dont let them use it aswell."

Archon
Member #4,195
January 2004
avatar

Assuming 0 degrees is 'right',
x = cos(rotation) * distance + offsetamount_x
y = sin(rotation) * distance + offsetamount_y

+Rotation would be counter-clockwise.

Ceagon Xylas
Member #5,495
February 2005
avatar

I had this code right for a long time, but didn't really understand how radians worked. Remember to increment in decimals and add in conditions such as

rotation+=0.0036;

if(rotation>M_PI*2) rotation=0;
if(rotation<0) rotation=M_PI*2;

Without limiters your line or whatever you're drawing/calculating goes CRAZY =P

And, Epsi, what's that -90.0 for? To get it into the 'right' plane? I mean, so that 0 isn't pointing right, but instead, point up?

Epsi
Member #5,731
April 2005
avatar

Quote:

And, Epsi, what's that -90.0 for? To get it into the 'right' plane? I mean, so that 0 isn't pointing right, but instead, point up?

yup, or at least if I remember correctly. What I did was a little dirty hack (the angle is not even the same on x/y axis), so I'll be happy if another solution shows up :)

___________________________________

piccolo: "soon all new 2d alegro games will be better. after i finsh my MMRPG. my game will serve as a code reference. so you can understand and grab code from."
piccolo: "just wait until my invetion comes out its going to take the wii to the next leave of game play. it will run sony and microsoft out of busness if i dont let them use it aswell."

Evert
Member #794
November 2000
avatar

For rotation of a point <math>(x, y)</math> around the origin over an angle <math>\vartheta</math>, use
<math>\begin{pmatrix} x'\\ y' \end{pmatrix} = \begin{pmatrix} \sin(\vartheta) & \cos(\vartheta) \\ -\cos(\vartheta) & \sin(\vartheta)\end{pmatrix} \begin{pmatrix} x\\ y \end{pmatrix}.</math>

To rotate around an arbitrary point, translate to that point first, then rotate, then translate back. It wasn't entirely clear to me what you wanted to do, hope this helps.

Quote:

if(rotation>M_PI*2) rotation=0;
if(rotation<0) rotation=M_PI*2;

That's quite wrong: there's nothing wrong with angles outside this range.

Archon
Member #4,195
January 2004
avatar

Mine should be correct:

For 0 degrees is 'up'
x = sin(rotation) * distance + offsetamount_x
y = cos(rotation) * distance + offsetamount_y

+Rotation would be clockwise --> or just make the 'distance' negative in the x calculation for counter-clockwise.

For 0 degrees is 'down'
x = sin(rotation) * distance + offsetamount_x
y = cos(rotation) * -distance + offsetamount_y

Default: clockwise

For 0 degrees is 'left'
x = cos(rotation) * -distance + offsetamount_x
y = sin(rotation) * distance + offsetamount_y

Default: clockwise

Vasco Freitas
Member #6,904
February 2006
avatar

Thank you for all your responses, I'll try them later today. But there is one problem with most of your solutions, that I have to calculate the distance, and for that I have to use sqrt() which is slow. Evert's solution doesn't use the distance but I've never done matrix multiplications :-/

Ceagon Xylas
Member #5,495
February 2005
avatar

You mean use sqrt() for acquiring the magnitude?
sqrt(x+x*y+y)?

Johan Halmén
Member #1,550
September 2001

Evert's matrix is just 1337. It's ok to use following:

x' = x*cos(v) - y*sin(v)
y' = x*sin(v) + y*cos(v)

I usually reinvent this wheel by dividing the point (x, y) to two "vectors" (x, 0) and (0, y).
Then I rotate these separately.
First becomes (x*cos(v), x*sin(v)) and the second becomes (-y*sin(v), y*cos(v)).
Then I add them and I get the formulae above.
This all is for a coordinate system where y grows upwards and v grows anti-clockwise, zero being x-axis direction.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Years of thorough research have revealed that the red "x" that closes a window, really isn't red, but white on red background.

Years of thorough research have revealed that what people find beautiful about the Mandelbrot set is not the set itself, but all the rest.

X-G
Member #856
December 2000
avatar

Quote:

sqrt(x+x*y+y)?

You fail it. sqrt(x*x + y*y).

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Matt Smith
Member #783
November 2000

Epsi's code is the "right" way to multiply by Evert's matrix, but it mixes up sine & cosine by ignoring the fact that sin(a - 90.0 degrees) == cos(a) and cos(a - 90.0) == -sin(a) because the sine & cosine of an angle are 90 degrees out of phase.

Felipe Maia
Member #6,190
September 2005
avatar

Evert's method is the best. You should always use vectors and not angles. Ever wondered why phisics is mainly based in vectors? Because they work very well. You can also include the translations in Evert's matrix, making it a 3x3 matrix. I would write how, but I don't know how to use the mock up well...

X-G
Member #856
December 2000
avatar

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Felipe Maia
Member #6,190
September 2005
avatar

The w should be 1 :)

Vasco Freitas
Member #6,904
February 2006
avatar

Well I tried the matrix multiplication but it didn't work. Maybe it's because the coordinate and/or angle system is different? Mine is like this:
http://mega.ist.utl.pt/~vbfr/coord.png

Felipe Maia
Member #6,190
September 2005
avatar

Aye, you're inverting the y axis, due to screen mapping, just switch the y by -y.

Vasco Freitas
Member #6,904
February 2006
avatar

I tried that and it still didn't work :-/ x and y go to strange places...

EDIT: The actual code I have is like this:

x = sin(angle) * xPos + cos(angle) * -yPos + OFFSET_X;
y = -cos(angle) * xPos + sin(angle) * -yPos + OFFSET_Y;

Felipe Maia
Member #6,190
September 2005
avatar

You need this:
x = (sin(angle) * (xPos-offset_X)) + (cos(angle) * (-y-offset_Y)) + offset_x;
Where offset_x is centerOfRotation(x);

Vasco Freitas
Member #6,904
February 2006
avatar

Still doesn't work... I feel that there is something very wrong because the position of the point changes much more than it should (it goes all over the screen when it should be near the center).

Anyway, OFFSET_X should be the x distance of the point to the axis right? And what you said is to change xPos (the x position of the axis) to (xPos - OFFSET_X) and yPos to (yPos - OFFSET_Y) right?

Maybe the problem has to do with the way I'm doing things. What I'm trying to do is set the position of a gun on a ship. The center of the ship is the rotation axis, and when the screen is rendered, everything is rotated except the ship, that is always motionless. I can't just set the gun coordinates because it's rotated, so I have to compensate for that rotation so the gun is always at the same position on the ship.

Felipe Maia
Member #6,190
September 2005
avatar

The offsext_x I meant was the center of the ship, the rotation point.

X-G
Member #856
December 2000
avatar

Quote:

The w should be 1

That depends on whether you are transforming a point or a direction.

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Vasco Freitas
Member #6,904
February 2006
avatar

Felipe Maia said:

The offsext_x I meant was the center of the ship, the rotation point.

So in that case, what's xPos? The position of the point I want to rotate, or the distance of that point to the axis (in x)?

Felipe Maia
Member #6,190
September 2005
avatar

Let's say that you want to rotate the square attached using the blue point as the rotation center.
You have to:
for each point:
T(x,y) = (x',y');
x' = ((sin(angle) * (x-blueCenterX)) + (cos(angle) * (y-blueCenterY))) + blueCenterX;

[edited}

Archon
Member #4,195
January 2004
avatar

Quote:

So in that case, what's xPos?

I'm guessing it's the position of the other object...

 1   2 


Go to: