2017-02-16 25 views
1

Я не очень разбираюсь в матричной математике, поэтому любая помощь будет оценена. Поэтому у меня есть простой спрайт корабля, который вращается и перемещается. Для того, чтобы вычислить ограничивающий прямоугольник Я попытался с помощью матрицы вращения и код, который я получил от этих учебных пособий:Вращающаяся матрица, вызывающая изменение позиции спрайта

http://xbox.create.msdn.com/en-US/education/catalog/tutorial/collision_2d_perpixel

Но всякий раз, когда спрайт вращается это X и Y позиции изменения ограничивающего прямоугольника резко, по как 100s пикселей. Метод расчета нового ограничивающего прямоугольника выглядит следующим образом:

public static Rectangle CalculateBoundingRectangle(Rectangle rectangle, Matrix transform) 
    { 
     // Get all four corners in local space 
     Vector2 leftTop = new Vector2(rectangle.Left, rectangle.Top); 
     Vector2 rightTop = new Vector2(rectangle.Right, rectangle.Top); 
     Vector2 leftBottom = new Vector2(rectangle.Left, rectangle.Bottom); 
     Vector2 rightBottom = new Vector2(rectangle.Right, rectangle.Bottom); 

     // Transform all four corners into work space 
     Vector2.Transform(ref leftTop, ref transform, out leftTop); 
     Vector2.Transform(ref rightTop, ref transform, out rightTop); 
     Vector2.Transform(ref leftBottom, ref transform, out leftBottom); 
     Vector2.Transform(ref rightBottom, ref transform, out rightBottom); 

     // Find the minimum and maximum extents of the rectangle in world space 
     Vector2 min = Vector2.Min(Vector2.Min(leftTop, rightTop), 
            Vector2.Min(leftBottom, rightBottom)); 
     Vector2 max = Vector2.Max(Vector2.Max(leftTop, rightTop), 
            Vector2.Max(leftBottom, rightBottom)); 

     // Return as a rectangle 
     return new Rectangle((int)min.X, (int)min.Y, 
          (int)(max.X - min.X), (int)(max.Y - min.Y)); 
    } 

Я предполагаю, что это работает, так как речь идет с сайта Microsoft и все. Поэтому я думаю, что проблема связана с моими матрицами. Я думал, что если бы я использовал только матрицу вращения, она бы только закрутила вещь; не меняйте его X и Y координаты. прямо сейчас это то, что у меня есть:

// calculate transformation 
      Matrix transformation = Matrix.CreateRotationZ((float)rotation) * Matrix.CreateRotationZ((float)rotation);; 

      //update bounding rectangle 
      rectangle = new Rectangle((int)(position.X - origin.X), (int)(position.Y - origin.Y), texture.Width, texture.Height); 
      rectangle = BoundingAndCollision.CalculateBoundingRectangle(rectangle, transformation); 

Я попробовал множество других вещей, в том числе без матрицы происхождения и различных порядков них. Я также попробовал то, что учебник сказал, было общим, что будет работать на что-нибудь, но дали в основном те же результаты:

Matrix transformation = Matrix.CreateTranslation(new Vector3(origin, 0.0f)) * 
       Matrix.CreateRotationZ((float)rotation) * 
       Matrix.CreateScale(scale) * 
       Matrix.CreateTranslation(position.X, position.Y, 0); 

Если этого не достаточно ясно, что я могу опубликовать скриншоты, просто дайте мне know.Thank вы заранее за помощь!

ответ

1

Вращательная матрица вращается вокруг 0,0, а ваш прямоугольник уже помещен в мир.

Чтобы решить сначала вычесть центр прямоугольника из каждой вершины (перевести прямоугольник в центр на 0,0), а затем добавить его снова после поворота (место снова в исходном месте). В коде im предполагается, что Y идет сверху вниз:

public static Rectangle CalculateBoundingRectangle(Rectangle rectangle, Matrix transform) 
{ 

    Vector2 center = new Vector2(rectangle.Left + (rectangle.Width/2), rectangle.Top + (rectangle.Height/2); 

    // Get all four corners in local space 
    Vector2 leftTop = new Vector2(rectangle.Left, rectangle.Top) - center; 
    Vector2 rightTop = new Vector2(rectangle.Right, rectangle.Top) - center; 
    Vector2 leftBottom = new Vector2(rectangle.Left, rectangle.Bottom) - center; 
    Vector2 rightBottom = new Vector2(rectangle.Right, rectangle.Bottom) - center; 

    // Transform all four corners into work space 
    Vector2.Transform(ref leftTop, ref transform, out leftTop); 
    Vector2.Transform(ref rightTop, ref transform, out rightTop); 
    Vector2.Transform(ref leftBottom, ref transform, out leftBottom); 
    Vector2.Transform(ref rightBottom, ref transform, out rightBottom); 

    leftTop += center; 
    rightTop += center; 
    leftBottom += center; 
    rightBottom += center; 

    // Find the minimum and maximum extents of the rectangle in world space 
    Vector2 min = Vector2.Min(Vector2.Min(leftTop, rightTop), 
           Vector2.Min(leftBottom, rightBottom)); 
    Vector2 max = Vector2.Max(Vector2.Max(leftTop, rightTop), 
           Vector2.Max(leftBottom, rightBottom)); 

    // Return as a rectangle 
    return new Rectangle((int)min.X, (int)min.Y, 
         (int)(max.X - min.X), (int)(max.Y - min.Y)); 
} 
+0

Работал отлично! Спасибо огромное! –