8

好的,这应该是一个简单的矩阵问题,但是我对矩阵的理解有些有限。这是场景:我有一个 1px x 1px 的精灵,我想按一定量 x 和 y 缩放(每边不同的量),然后我想将该精灵旋转某个角度,然后我希望能够精确定位整个事物(从左上角或中心,对我来说没有区别)。

到目前为止,我的代码模糊地接近,但根据我传入的角度,它往往会偏离一些随机量。

我认为这样做可以:

        Point center = new Point( 50, 50 );
        float width = 60;
        float height = 100;
        float angle = 0.5;
        Vector3 axis = new Vector3( center.X, center.Y, 0 );
        axis.Normalize();
        Matrix m = Matrix.Scaling( width, height, 0 ) *
            Matrix.RotationAxis( axis, angle ) *
            Matrix.Translation( center.X, center.Y, 0 );

但它往往会缩小旋转线的比例,即使我认为它的定位是正确的。

我也试过这个:

  Matrix m = Matrix.Transformation2D( new Vector2( center.X, center.Y ), 0f,
      new Vector2( width, height ), new Vector2( center.X, center.Y ),
      angle, Vector2.Zero );

这条线看起来完全正确,大小和形状都完全正确,但我根本无法正确定位它。如果我在上述调用结束时使用平移向量,或者如果我使用 Sprite.Draw 设置位置,则两者都无法正常工作。

这一切都在 SlimDX 中。我究竟做错了什么?

4

4 回答 4

12

我刚刚经历了学习矩阵变换的痛苦,但是使用了 XNA。

我发现这些 文章 理解 发生的事情非常有帮助。XNA 中的方法调用非常相似,其背后的理论都应该适用于您,即使使用 SlimDX。

看一眼你的代码,我认为你应该在开始时翻译到原点,然后在最后再翻译到最终位置,尽管我在这方面还是有点新手。

我这样做的顺序是:

  • 翻译为原点
  • 规模
  • 旋转
  • 翻译到所需位置

首先翻译到原点的原因是旋转是基于原点的。因此,要围绕某个点旋转某些东西,请在旋转之前将该点放在原点上。

于 2009-03-11T20:04:07.820 回答
3

好的,这正在工作。这是我的工作代码,以防其他人需要它:

    Point sourceLoc = new Point ( 50, 50 );
    float length = 60;
    float thickness = 2;
    float angle = 0.5;
    Matrix m = Matrix.Scaling( length, thickness, 0 ) *
            Matrix.RotationZ( angle ) *
            Matrix.Translation( sourceLoc.X, sourceLoc.Y, 0 );
    sprite.Transform = m;

    sprite.Draw( this.tx, Vector3.Zero, Vector3.Zero, Color.Red );

这将绘制一条您选择的长度的斜线,其厚度等于您选择的厚度(假设您的纹理是 1x1 像素的白色图像)。源位置是发射线的位置,无论您指定什么角度(以弧度为单位)。因此,如果您从零开始并以 0.1 之类的增量递增直到达到 2PI,然后重置为 0,您将拥有一条围绕中心旋转的线,如时钟指针或雷达扫描。这就是我一直在寻找的——感谢所有做出贡献的人!

于 2009-03-12T02:32:52.627 回答
1

您需要做的是一次一步地进行每个转换。做缩放先画它。是不是你期望的地方。然后加入旋转,然后平移。这将有助于发现不正确的假设。

您还可以绘制临时线以帮助确定坐标的位置。例如,如果您进行拉伸和旋转,并期望您的终点位于 0,0。在 0,0 处绘制一个端点为另一条线将用作仔细检查,看看是否真的如此。

对于您的具体问题,问题可能与旋转有关。缩放和旋转后,线现在偏离中心,导致您在翻译时出现问题。

一般的解决方案是将线移回原点,执行任何涉及更改其形状或方向的操作。之后,因为您在一个已知的好位置,您可以翻译到您的最终目的地。

回应评论

如果平移是一个问题并且您正在转换坐标系,那么您将需要编写一个转换函数来在旧系统和新系统之间进行转换。

例如,如果您旋转 45 度。在旋转之前,您可以平移 0,1 以向上移动 1 英寸。旋转后,您必须大致平移 -.70707、.070707 才能相对于原始坐标系向上移动 1 英寸。

于 2009-03-11T20:18:28.533 回答
1

您是否围绕正确的轴旋转?我是矩阵材料的新手,但在我看来,由于精灵存在于 x、y 空间中,旋转轴应该是 Z 轴 - 即 (0,0,1)。

于 2009-03-11T20:30:02.127 回答