Вращаясь вокруг точки - PullRequest
       24

Вращаясь вокруг точки

0 голосов
/ 05 марта 2012

У меня есть текстура корабля, и чуть ниже крыла порта корабля есть текстура ракеты.Когда я поворачиваю корабль, мне нужно, чтобы ракета оставалась в том же положении относительно корабля (то есть под крылом порта).Я прочитал несколько статей и придумал это (извините, это немного грязно):

        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;
    }

Где leftMissile - это Vector2, описывающее середину ракеты, а center - центркорабля как Vector2.Это почти работает, спрайт вращается вокруг центра.Проблема в том, что он не остается в той же точке на крыле порта.

Это нормально: This is normal

Это 90 градусов, это дальше от крыла: 90 Degree Rotation

А при повороте на 180 градусов его больше нет даже на корабле: 180 Degree Rotation

Ответы [ 2 ]

2 голосов
/ 05 марта 2012

То, что вы должны рассмотреть, это поддерживать постоянную (readonly) смещение от вашего корабля для ракеты:

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

Это держит вещи в относительном пространстве корабля. Тогда вы можете просто преобразовать только смещение, а затем добавить это к позиции корабля:

//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;

Это доставит ракету в нужное место. Затем, предполагая, что вы используете SpriteBatch, просто поверните корабль и ракету, передав угол в обе стороны:

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();
0 голосов
/ 05 марта 2012

Если у вас есть вектор вперед и центр, его легко вычислить.

enter image description here

  1. Нормализация вперед.

    Forward.Normalize ();

  2. Получить нормальный вектор для пересылки.

    Normal.X = Вперед.Y; Normal.Y = -Forward.X;

  3. Получите позицию ракеты.

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

...