旋转矩阵导致精灵位置改变

时间:2017-02-16 17:49:02

标签: c# matrix rotation xna monogame

我不熟悉矩阵数学,所以任何帮助都会受到赞赏。所以我有一个简单的船只精灵旋转和移动。为了计算边界矩形,我尝试使用旋转矩阵和我从这些教程中得到的代码:

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

但是每当精灵旋转时,边界矩形的X和Y位置会像100像素那样急剧变化。计算新边界矩形的方法如下:

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

如果不够清楚我可以发布截图,请告诉我。请提前感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

旋转矩阵围绕0旋转,您的矩形已经放置在世界中。

要求解先从每个顶点减去矩形的中心(将矩形转换为以0,0为中心),然后在旋转后再次添加(再次放置在原始位置)。在代码中我假设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));
}