Rotating lines around a given vector
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?
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:
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]<br>[0 0 1 ]</pre>Where <i>s</i> and <i>c</i> 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:<pre>// Remember, c++ functions take radians<br>float s = sinf(angle);<br>float c = cosf(angle);<br><br>Vector2 wp[3]; // World-space points for your ship<br>for (int i = 0; i < 3; ++i) {<br> wp<span style="font-weight:bold;">.x = c * p<span style="font-weight:bold;">.x - s * p<span style="font-weight:bold;">.y + position.x;<br> wp<span style="font-weight:bold;">.y = s * p<span style="font-weight:bold;">.x + c * p<span style="font-weight:bold;">.y + position.y;<br>}</pre>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.<br><br><!–EDIT–><span class=editedby><!–/EDIT–>[Edited by - jyk on October 7, 2005 6:15:17 PM]<!–EDIT–></span><!–/EDIT–>
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.
/\
Just use the basic 2D rotation matrix/formula. I actually use glRotate, so OpenGL does it for me.
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.
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.
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.
Any moment what so ever and any further rotation cause's all the points to go all over the place.
Quote:Original post by Halsafar
As for using openGL and its rotate function matt_j, I cannot... Java2D only, lines only.
You can use the matrix class java.awt.geom.AffineTransform
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.
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.setLocation(c * rotPoints.getX() - s * rotPoints.getY() + m_vPos.x, s * rotPoints.getX() + c * rotPoints.getY() + m_vPos.y); } m_linebuf[0].setLine(wp[0], wp[1]); m_linebuf[1].setLine(wp[0], wp[2]);
That formula seems weird. Wouldn't it just be this?
And if you want the sides of the ship to be longer than 1, something like this:
for (int i = 0; i < 3; ++i) { wp.setLocation(c * rotPoints.getX() + m_vPos.x, s * rotPoints.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.setLocation(c * rotPoints.getX() * line_segment_dist + m_vPos.x, s * rotPoints.getY() * line_segment_dist + m_vPos.y); }
Quote:Jyk ur method is nothing working unless I am perfectly centered at 0,0.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.
Any moment what so ever and any further rotation cause's all the points to go all over the place.
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 :)
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement