In Flash, throw a movie clip on the stage and give it an instance name of "clip". Go to Modify -> Transform -> Flip Horizontal. Then do a trace(clip._xscale); 100 is traced, even though you might expect -100. What gives?
Short Answer:
Flipping horizontally is the same as flipping vertically and rotating 180 degrees. This means that _xscale and _yscale can either be positive or negative. Flash can't really tell which you've done, so it assumes positive.
Long Answer:
The position info of every graphic in Flash is stored as a 3x3 homogeneous matrix:
[[ a b tx ]
[ c d ty ]
[ 0 0 1 ]]
This is a combination of a scale, rotation, skew, and translation.
A scale transformation looks like:
[[ x 0 0 ]
[ 0 y 0 ]
[ 0 0 1 ]]
where x and y are the amount of scaling on the x and y axis. Note that _xscale = x*100
A rotation transform is:
[[ cos(t) sin(t) 0 ]
[ -sin(t) cos(t) 0 ]
[ 0 0 1 ]]
where t is the amount of rotation.
Combine these by matrix multiplication, and you get:
[[ x*cos(t) x*sin(t) 0 ]
[ -y*sin(t) y*cos(t) 0 ]
[ 0 0 1 ]]
Flash only knows the final values (a, b, c, d). We know a = x*cos(t) and b = x*sin(t). You can start to see the sign ambiguity appear already -- whenever you multiply two values, you lose some information about the signs of those values.
To calculate _xscale, Flash has to solve for x. Your first thought might be x = a/cos(t), but that requires you to find out t. A more elegant way to solve this is to realize that the ( x*cos(t), x*sin(t) ) in the first row is just a vector x units long, in the direction of t. So x is just the length of the vector:
x = sqrt( a^2 + b^2 )
This makes sense intuitively, too -- because a scale transformation just scales a basis vector, (1, 0), by x. Rotation changes this more, but it doesn't affect vector length! So getting the magnitude of this vector tells you the amount of scaling.
You can chug through the math to see that this identity holds:
sqrt( a^2 + b^2 ) = sqrt( (x * cos(t))^2 + (x * sin(t))^2 )
= sqrt( x^2 * cos^2(t) + x^2 * sin^2(t) )
= sqrt( x^2 * ( cos^2(t) + sin^2(t) ) )
= sqrt( x^2 * 1 );
= +/- x
Since _xscale and _yscale are the result of a square root, we get two solutions, either + or -.
When you do _xscale = -100 in ActionScript, why does Flash trace(_xscale) as -100 then? Because whenever you set _rotation, _xscale, _yscale, Flash actually caches the value you passed and returns that, instead of wastefully recalculating it!