【问题标题】:AS3: Getting the scale of a Matrix objectAS3:获取 Matrix 对象的比例
【发布时间】:2011-03-14 20:22:13
【问题描述】:

最常见的问题是如何缩放 DisplayObject,答案通常是使用矩阵。

我的问题是,如何获取矩阵的比例(scaleX 和 scaleY)?

有一个 Matrix.scale 方法来设置 scaleX 和 scaleY,但它不返回值,并且没有其他属性可以读取它。

我问的原因是,我正在使用深埋在显示列表中的对象,并且每个对象都可以转换。所以我使用了子对象的 sprite.transform.concatenatedMatrix getter,但我一直坚持如何从中读取比例。

家里有数学高手吗?

【问题讨论】:

    标签: flash actionscript-3 math matrix scale


    【解决方案1】:

    通常,在矩阵中隔离缩放分量的可靠​​方法是使用相关矩阵沿轴变换单位向量,然后测量结果向量的长度。

    例如,给定来自 DisplayObject 的 transform,并使用 Matrix3D,将按如下方式获得 scaleX

    transform.matrix3D.deltaTransformVector(Vector3D.X_AXIS).length
    

    或者,如果您使用连接的二维矩阵,scaleY 将是:

    transform.concatenatedMatrix.deltaTransformPoint(new Point(0,1)).length
    

    请注意,deltaTransform* 函数会忽略矩阵的平移效果,这对缩放没有影响。

    【讨论】:

    • 有趣,我试了一下(作为 2D 矩阵),它确实给出了比例值,但与 DisplayObject 的 scaleX 和 scaleY 的实际值相比,它们通常会有所不同 - 但只是非常稍微(如小数点后 4 到 5 个位置)。尽管如此,还是很好的答案!谢谢
    • 值得注意的是:我尝试 deltaTransformPoint( new Point(1,1) ) 认为结果 x & y 将是比例值。但不幸的是,这并没有给出准确的值。每个轴都必须独立处理。我不是矩阵的天才,但无论如何!这对我有用:)
    • 值的差异可能是由长度的计算引入的,或者来自矩阵的串联,这意味着除了任何 scaleX 之外,所有祖先的缩放都应用于对象/Y 你可以直接添加到它。在 (1,1) 变换中:变换点的长度将产生 sqrt(2)*(沿 Y=X 轴的比例因子)。
    【解决方案2】:

    即使旋转矩阵,您也可以获得矩阵的 x 和 y 比例。

    代码如下:

    public static function getScaleX(m:Matrix):Number
    {
        return Math.sqrt(Math.pow(m.a + m.b, 2));
    }
    
    public static function getScaleY(m:Matrix):Number
    {
        return Math.sqrt(Math.pow(m.c + m.d, 2));
    }
    

    解释:

    我发现将A B C D 视为在转换后的坐标空间中定义x 和y 轴的点更容易。 A, B 是变换后的 x 轴的第一个点的位置(单位矩阵有这些 1, 0,不会变换),C, D 是变换后的 y 轴的第一个点的位置(身份0, 1) 的值。

    如果我们有一个将 x 轴缩放 2 的矩阵,那么 A, B 将是 2, 0。 x 轴上的其余点与最后一个点的距离相同(因此距离最后一个点 2 个点)。

    如果我们有一个顺时针旋转 90 度的矩阵,那么 A, B 将是 0, 1(将 x 轴指向 y 轴的正侧),C, D 将是 -1, 0(指向 y轴在 x 轴的负侧)。

    x 轴的刻度是到第一个点的距离。在我提到的场景中,规模很容易找到。在前面的示例中,A, B0, 1,因此比例为 1。如果没有以 90 度增量旋转,那么您可以使用勾股定理找到从 0, 0A, B 的线段长度: sqrt(a^2 + b^2) = c。这就是我的代码正在做的事情。

    希望这对某人有所帮助。

    【讨论】:

      【解决方案3】:

      你可以访问矩阵对象的ad公共属性,分别代表x轴和y轴的缩放:

      package
      {
      //Imports
      import flash.display.Sprite;
      import flash.geom.Matrix;
      import flash.display.Shape;
      
      //Class
      public class Test extends Sprite
          {
          //Constructor
          public function Test()
              {       
              var sh:Shape = new Shape();
              sh.graphics.beginFill(0xFF0000, 1.0);
              sh.graphics.drawRect(0, 0, 100, 100);
              sh.graphics.endFill();
      
              var scaleMatrix:Matrix = new Matrix();
              scaleMatrix.scale(4, 6);
      
              sh.transform.matrix = scaleMatrix;
      
              addChild(sh);
      
              trace("Matrix X Scale: " + scaleMatrix.a, "\nMatrix Y Scale: " + scaleMatrix.d);
              }
          }
      }
      
      // Matrix X Scale: 4 
      // Matrix Y Scale: 6
      

      【讨论】:

      • 忘了说 a 和 d 也代表旋转,所以我上面的代码只有在你只缩放时才有效。
      • 是的,在我的情况下,考虑到旋转很重要,有些物体会旋转 90 度,一般来说,最好有一个可以解决任何场景(任何比例)的一体化解决方案,旋转或倾斜)。不过谢谢!
      猜你喜欢
      • 2013-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-13
      • 1970-01-01
      • 2012-10-22
      • 1970-01-01
      • 2015-08-19
      相关资源
      最近更新 更多