00:00
00:00
View Profile mike
hello!

Mike Welsh @mike

33, Male

stupids

Penn State

San Diego

Joined on 2/24/00

Level:
22
Exp Points:
4,904 / 5,380
Exp Rank:
6,412
Vote Power:
6.33 votes
Rank:
Police Captain
Global Rank:
4,082
Blams:
1,198
Saves:
936
B/P Bonus:
16%
Whistle:
Normal
Trophies:
8
Medals:
721
Supporter:
3y 9m 10d
Gear:
1

_xscale & _yscale

Posted by mike - July 12th, 2008


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!


1

Comments (43)

Whoa, that just melted my mind.

My mind blew up. x(

is this basically an easier process in flash then or. . . .?

...Has anyone ever told you that you should become a math teacher?

I have NO idea what you just said, but i'm gonna try and figure it out. Or, my brain'll shrivel up and die in the process. That was a useless comment, wasn't it?

thats pretty smart how flash does that, how did you find that out?

What do you think I am, a freakin' rocket surgeon?

wow... that actually made sense to me, though ive never dealt with the scenario. thanks for that, ill keep it in mind. (you might want to explain the matrices and trig a little more for the typical newgroundser)

*pop*

Yeah I understood that

...and that's why I only make drawings. x_X

I understand the mathematical lingo but you lost me in the ActionScript...

I think my brain broke

what

Flash is smart sometimes, but sometime not so helpful. You can see exactly how it stores the transform if you have the transform window open - type in -100% for width, then reselect the clip, you'll see it actually counts as a skew of 180 degrees

Try this one! Its a problem with AS3, I'm not sure if it used to do it in AS2. Bear in mind that height and width of a movieclip are always relative to its parent's x/y axis, not the clips own internal axis (unlike xScale and yScale)

Add a 100x100 square MovieClip to the timeline, call it mc and add this to the stage timeline:

mc.rotation = 90;
mc.width = 50;
trace(mc.width);
trace(mc.height);

You'll see that it completely scews up which way it scales! then try this:

mc.rotation = 90;
mc.width = 50;
mc.width = 50;
trace(mc.width);
trace(mc.height);

It seems like the first time it uses width (same goes for height) it hasn't updated the rotation on the clip, but the second time it has! Crazy Flash...

Tom-

I understood the main message, but I've never used a flash program. It'd be freaking awesome to have the skills of Adam Phillips, Michael Swain or Jeff Bandelin, but sadly I know not one thing about it and I'm afraid of these mathematical bullshit you seem to have to go through. I hate math. :|

Any advice?
xx Martin xx

i understand the maths
but i fell swamped out by actionscript

I have more problems with _height and _width acting as positive when I try making them negative than I have with _xscale and _yscale.

I think my brain just popped... Painfully...

I think the point of this is:

Flash uses a square root function to flip things horizontally or vertically
the square root of any number is allways positive
so flipping something will allways give you a positive _xscale

I could be wrong there. Well done for finding out though.

More Results