kreek - 1 year ago 157
ActionScript Question

# Get angle from matrix

I know a matrix [x scale, y skew, x skew, y scale, trans x, trans y], and would like to get the angle in degrees.

thanks!

Consider the following matrix

``````| x_sc  y_sk  0  |
| x_sk  y_sc  0  |
| x_tr  y_tr  1  |
``````

with `sk` indicating skew, `sc` indicating scale and `tr` indicating translation.

This only represents a pure rotation if all three are true

``````y_sk == -x_sk
y_sc == x_sc
x_sc * y_sc - x_sk * y_sk == 1
``````

In this case, if `theta` is the angle of rotation, then

``````theta == arcos(x_sc)
``````

This will give you the answer in radians (most likely), so you'll need to convert to degrees.

Assuming you have an object called M, representing the matrix, the properties that match my definitions above, you could do:

``````function toPureRotation(var M) {
if( (M.y_sk != (-1 * M.x_sk)) ||
(M.y_sc != M.x_sc) ||
((M.x_sc * M.y_sc - M.x_sk * M.y_sk) != 1)
) {
return Number.NaN;
}
else {
return Math.acos(M.x_sc); // For radians
return Math.acos(M.x_sc) * 180 / Math.PI; // For degrees
}
}
``````

EDIT

For a pure rotation followed by (or preceded by) a scaling transform that maintains aspect ratio:

``````| sc   0  0 |
|  0  sc  0 |
|  0   0  1 |
``````

Then you can us the following identity:

``````x_sc * y_sc - x_sk * y_sk == sc^2
``````

This gives us

``````function toRotation(var M) {
if( (M.y_sk != (-1 * M.x_sk)) ||
(M.y_sc != M.x_sc)
)
) {
return Number.NaN;
}
else {
var scale_factor = Math.sqrt((M.x_sc * M.y_sc - M.x_sk * M.y_sk));
return Math.acos(M.x_sc/scale_factor); // For radians
return Math.acos(M.x_sc/scale_factor) * 180 / Math.PI; // For degrees
}
}
``````

If you want to factor in translations, you're entering a world of hurt.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download