Jack
Jack

Reputation: 950

Rotating Around a Point

I have a ship texture, and just below the ship's port wing is a missile texture. When I rotate the ship, I need the missile to stay in the same position relative to the ship (i.e., under the port wing). I read some articles and came up with this (sorry, it's a bit messy):

        private void RotateWeapons()
    {
        float x, y;
        /*
        x = leftMissile.X + (radius * (float)Math.Cos(Rotation));
        y = leftMissile.Y + (radius * (float)Math.Sin(Rotation));
        */

        leftMissile = Vector2.Transform(leftMissile - center, Quaternion.CreateFromAxisAngle(Vector3.Backward, Rotation)) + center;

        //leftMissile.X = x;
        //leftMissile.Y = y;
    }

Where leftMissile is a Vector2 describing the middle of the missile, and center is the center of the ship as a Vector2. It almost works, the sprite rotates around the center. The problem is, it doesn't stay at the same point on the port wing.

This is normal: This is normal

This is 90 degrees, it's further off the wing: 90 Degree Rotation

And when rotated 180 degrees, it's not even on the ship anymore: 180 Degree Rotation

Upvotes: 0

Views: 859

Answers (2)

user155407
user155407

Reputation:

What you should consider doing is keeping a constant (readonly) offset from your ship for the missile:

//non-rotated, where is the missile relative to the ship?
readonly Vector2 missileOffset = new Vector2(5.0f, 2.0f);

This keeps things in the ship's relative space. Then you can simply transform only the offset, and then add this to the ship's position:

//rotation of ship as quaternion
Quaternion rotation = Quaternion.CreateFromAxisAngle(Vector3.Backward, angle);
//the final position for the missile
Vector2 leftMissile = Vector2.Transform(missileOffset, rotation) + shipPosition;

This will get the missile in the proper place. Then, assuming you're using SpriteBatch, just rotate both ship and missile by passing in the angle to both:

batch.Begin();
batch.Draw(shipTex, shipPosition, null, Color.White, angle, Vector2.Zero, 1.0f, SpriteEffects.None, 1.0f);
batch.Draw(missileTex, leftMissile, null, Color.White, angle, Vector2.Zero, 1.0f, SpriteEffects.None, 1.0f);
batch.End();

Upvotes: 2

Blau
Blau

Reputation: 5762

If you have a forward vector and the center, is easy to calc it.

enter image description here

  1. Normalize forward.

    Forward.Normalize();

  2. Get a normal vector to forward.

    Normal.X = Forward.Y; Normal.Y = -Forward.X;

  3. Get the pos of the missile.

    MissilePos = CenterShip - Forward * OffsetY (+ or -) Normal * OffsetX;

Upvotes: 0

Related Questions