Sign in to follow this  
Halsafar

Rotating lines around a given vector

Recommended Posts

Halsafar    205
Picture the classic Asteroid ship in ur mind /\ The tip being the start point. I am having HUGE difficulties rotating the bloodly end points around the start point. All lines. Any help?

Share this post


Link to post
Share on other sites
jyk    2094
Here's one way you could do it. This is basically a matrix transformation method, but for 2d you can easily do it all in place - you don't need a matrix class.

Say your ship has a position and an angle. Also say that you've set up three points that represent your ship in local space, that is, centered at the origin and pointing down the +x axis. Something like:
Vector2 p[3];
p[0].Set(10,0);
p[1].Set(-10,6);
p[2].Set(-10,-6);
Conceptually, what you want to do is set up a simple affine transformation matrix, like this:
[c -s tx]
[s c ty]
[0 0 1 ]
Where s and c are the sine and cosine of your rotation angle, and (tx,ty) is the ship position vector. In practice you can just do it in place, like this:
// Remember, c++ functions take radians
float s = sinf(angle);
float c = cosf(angle);

Vector2 wp[3]; // World-space points for your ship
for (int i = 0; i < 3; ++i) {
wp[i].x = c * p[i].x - s * p[i].y + position.x;
wp[i].y = s * p[i].x + c * p[i].y + position.y;
}
Now you can draw your ship using the wp points. You can also use them for collision detection, or any other purpose where you need the ship geometry in world space.

[Edited by - jyk on October 7, 2005 6:15:17 PM]

Share this post


Link to post
Share on other sites
matt_j    106
In my asteroids game, the centre of the ship is the centre of the overall


/\


Just use the basic 2D rotation matrix/formula. I actually use glRotate, so OpenGL does it for me.

Share this post


Link to post
Share on other sites
Halsafar    205
Thanks Jyk, that was perfect. Rating++
I may even try and work out the matrix method.

As for using openGL and its rotate function matt_j, I cannot... Java2D only, lines only.

Share this post


Link to post
Share on other sites
Halsafar    205
Jyk ur method is nothing working unless I am perfectly centered at 0,0.

Any moment what so ever and any further rotation cause's all the points to go all over the place.

Share this post


Link to post
Share on other sites
Halsafar    205
Hmmm.
That would really bottle neck the rendering routines.

See as of now I am using affinetransform to set up a user space and center 0,0... So I would need to set that for each object and rotate it before rendering.

But since no matter how hard I try my line end points keep shooting out to the middle of no where.... I'm about ready for an easier solution.


Here is the snippet which does the rotating:
-- m_vPos is a vector representing the tip where the 2 lines meet so they share that as a start point.


Point2D rotPoints[] = new Point2D[3];
rotPoints[0] = new Point2D.Double(m_vPos.x, m_vPos.y);
rotPoints[1] = new Point2D.Double(m_linebuf[0].getX2(), m_linebuf[0].getY2());
rotPoints[2] = new Point2D.Double(m_linebuf[1].getX2(), m_linebuf[1].getY2());

// Remember, c++ functions take radians
double s = Math.sin(deg * cGameMath.TORAD); //cCircleTable.vTable[deg].y;
double c = Math.cos(deg * cGameMath.TORAD);//cCircleTable.vTable[deg].x;

Point2D wp[] = new Point2D[3];
wp[0] = new Point2D.Double();
wp[1] = new Point2D.Double();
wp[2] = new Point2D.Double();

for (int i = 0; i < 3; ++i) {
wp[i].setLocation(c * rotPoints[i].getX() - s * rotPoints[i].getY() + m_vPos.x,
s * rotPoints[i].getX() + c * rotPoints[i].getY() + m_vPos.y);
}

m_linebuf[0].setLine(wp[0], wp[1]);
m_linebuf[1].setLine(wp[0], wp[2]);


Share this post


Link to post
Share on other sites
pinacolada    834
That formula seems weird. Wouldn't it just be this?


for (int i = 0; i < 3; ++i) {
wp[i].setLocation(c * rotPoints[i].getX() + m_vPos.x,
s * rotPoints[i].getY() + m_vPos.y);
}


And if you want the sides of the ship to be longer than 1, something like this:


float line_segment_dist = 5f;
for (int i = 0; i < 3; ++i) {
wp[i].setLocation(c * rotPoints[i].getX() * line_segment_dist + m_vPos.x,
s * rotPoints[i].getY() * line_segment_dist + m_vPos.y);
}

Share this post


Link to post
Share on other sites
jyk    2094
Quote:
Jyk ur method is nothing working unless I am perfectly centered at 0,0.

Any moment what so ever and any further rotation cause's all the points to go all over the place.
I just tested the code and it works fine. I did make a mistake with the indices for p, which I've now fixed. However, it looks like you already caught that.

However, you're setting up the initial points incorrectly. I now see that this isn't entirely clear from my example, but the array p[3] is set once at the beginning of the program and never changes (unless you want to change the shape of your ship). The whole point of the affine transform is to take the ship geometry in local space, which never changes, and transform it into world space based on its position and rotation angle. So try replacing the lines:
rotPoints[0] = new Point2D.Double(m_vPos.x, m_vPos.y);
rotPoints[1] = new Point2D.Double(m_linebuf[0].getX2(), m_linebuf[0].getY2());
rotPoints[2] = new Point2D.Double(m_linebuf[1].getX2(), m_linebuf[1].getY2());
With something like:
rotPoints[0] = new Point2D.Double(10, 0);
rotPoints[1] = new Point2D.Double(-10, 6);
rotPoints[2] = new Point2D.Double(-10, -6);
With those specific values adjusted for scale and the desired shape of the ship. Note also that in your code you're setting the nose of the ship to the ship position itself, which, even if we were doing 'world space' rotations, would cause the ship to rotate about its nose - probably not what you want.

I hope that clears up the example a bit. I can practically guarantee that the method works as advertised, so I'd just stick with it until you get the bugs ironed out.
Quote:
That formula seems weird.
Nevertheless, it is correct :)

Share this post


Link to post
Share on other sites
Halsafar    205
It is very correct.

Yes I totally didn't catch that object space part. The clarity in your reply was perfect. I know have it all setup and she rotates fine.

Thank you.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this