AS3: Getting the scale of a Matrix object

前端 未结 3 1565
余生分开走
余生分开走 2021-01-16 08:49

Most often, questions are asked about how to scale a DisplayObject, and the answer is usually to use a Matrix.

My question is, how to you GET the scale of a Matrix (

相关标签:
3条回答
  • 2021-01-16 09:28

    you have access to the matrix object's a and d public properties, which represent the scaling of the x-axis and y-axis respectively:

    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
    
    0 讨论(0)
  • 2021-01-16 09:32

    Generally, a reliable way to isolate the scaling component in a matrix is to use the matrix in question to transform the unit vectors along the axes, and then measure the length of the resulting vectors.

    For instance, given the transform from a DisplayObject, and using the Matrix3D, the scaleX would be obtained as follows:

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

    Or, if you use the concatenated 2D Matrix, the scaleY would be:

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

    Note that the deltaTransform* functions ignore the translation effects of the matrices, which have no effect on the scaling.

    0 讨论(0)
  • 2021-01-16 09:46

    You can get the x and y scales of a matrix even when it's rotated.

    Here's the code:

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

    Explanation:

    I've found that it's easier to think of A B C D as points that define the x and y axes in the transformed coordinate space. A, B is the position of the first point of the transformed x axis (an identity matrix has these as 1, 0, which will not transform), and C, D is the position of the first point of the transformed y axis (identity values of 0, 1).

    If we have a matrix that will scale the x axis by 2 then A, B will be 2, 0. The rest of the points on x axis will be this same distance away from the last (so 2 points away from the last).

    If we have a matrix that will rotate 90 degrees clockwise then A, B will be 0, 1 (pointing the x axis along the positive side of the y axis) and C, D will be -1, 0 (pointing the y axis down the negative side of the x axis).

    The scale of the x axis is the distance to the first point. In the scenarios that I've mentioned the scale is easy to find. In the previous example A, B is 0, 1 so the scale is 1. If rotation is not on at a 90 degree increment then you can find the length of the line segment from 0, 0 to A, B by using the Pythagorean theorem: sqrt(a^2 + b^2) = c. This is what my code is doing.

    Hope this helps someone.

    0 讨论(0)
提交回复
热议问题