AS3: Getting the scale of a Matrix object

十年热恋 提交于 2019-12-30 11:33:10

问题


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 (scaleX and scaleY)?

There's a Matrix.scale method to set the scaleX and scaleY, but it doesn't return a value, and no other properties exist to read it back.

The reason I ask, I'm using object burried deep down into a Display list, and each may be transformed. So I use the child object's sprite.transform.concatenatedMatrix getter, but am stuck at this point on how to read the scale from it.

Any Math Wiz in the house?


回答1:


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.




回答2:


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.




回答3:


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


来源:https://stackoverflow.com/questions/5304022/as3-getting-the-scale-of-a-matrix-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!