_xscale & _yscale

2008-07-12 15:10:54 by mike

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!


You must be logged in to comment on this post.


2008-07-12 15:44:43

Whoa, that just melted my mind.


2008-07-12 16:13:40

My mind blew up. x(


2008-07-12 16:34:39

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


2008-07-12 17:16:17

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


2008-07-12 17:33:54

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?


2008-07-12 19:07:33

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


2008-07-12 19:13:25

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


2008-07-12 22:02:40

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)


2008-07-13 00:40:25



2008-07-13 00:48:34

Yeah I understood that


2008-07-13 01:19:18

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


2008-07-13 01:45:46

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


2008-07-13 03:25:27

I think my brain broke


2008-07-13 06:44:07



2008-07-13 07:34:48

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;

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

mc.rotation = 90;
mc.width = 50;
mc.width = 50;

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...



2008-07-13 09:28:05

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


2008-07-13 09:29:03

i understand the maths
but i fell swamped out by actionscript


2008-07-13 12:53:13

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


2008-07-13 14:04:43

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


2008-07-13 14:25:50

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.


2008-07-13 14:42:20

Hehe, you certainly learn new stuff from your posts. I always wondered what that third column was for... Thanks for that link :P


2008-07-13 15:02:04

All I know is that Flash applies trigonometry into it's programming. Except the plane is upside down and I think backwards.


2008-07-13 15:12:14

my girlfriend_flipped when I X_scaled into her mouth


2008-07-13 15:26:30

God I wish I understood action script. The only thing vaguely familiar to me is cos and sin. And it's been ages since i've done that.


2008-07-13 15:42:07

My brain was about to die out, but Mindchamber's comment fixed that problem :P


2008-07-13 16:13:56

Fascinating. Where did you learn this? Adobe forums?


2008-07-13 16:36:50

0.99999 (repeating) = 1 because

1/3 = 0.33333333333333333333333

1/3 X 3=1 or 1/3 X 3= 0.9999999999999999999999999999999


2008-07-13 16:51:04

Steven Hawking could explain better!

http://spamtheweb.com/ul/upload/13070 8/60172_bob2.mp3


2008-07-13 16:58:12

I never liked trig anyway... I can code just about anything without looking something up except when trig comes up... I really shoulda paid better attention during that unit :/ ... Also: why does flash not have an _xskew/_yskew option yet?


2008-07-13 17:23:55

Heh, interesting stuff! I didn't know Flash was actually using a complete 3x3 transformation matrix, but now that I do it all makes sense. ;)


2008-07-13 18:05:48



2008-07-13 20:22:10

..what the fu--?
*head explodes all over computer*


2008-07-14 00:10:17

Great, someone give him a Nobel!!!

¬¬ I accept it; Impressing for teenagers.


2008-07-14 00:52:31

I cannot comprehend what the fuck you just said back there...How did you get all this down in your head?


2008-07-14 03:24:29

That was my head when reading the second part.
I'll stick to the short version...


2008-07-14 04:34:30

When you flip the x axis in flash that way, the xscale is 100 since that is the new shape's scale. If you wanted to flip it in an .swf, flash records the old position, so that a scale of 100 would return the object to scale.

Flipping horizontally is different than changing the _xscale. Although it would do the same thing, these are two seperate functions. Its more common sense than having to look at the math of it, although I did understand that dreadfully, hated learning that stuff last year.


2008-07-14 14:15:27

Thats wierd... Are you using flash CS3 because i'm pretty sure that flash cs3 was supposed to be the ultimate calculating system. (and you would think it wouldn't do something like that.)


2008-07-14 20:56:41

If my mind was a Nuclear Power Plant,then you just set off another "Chernobyl"


2008-07-15 05:52:15

Ok , the mathematics are ok , but the actionscript are problematic :p


2008-07-15 21:42:05

Conclusion: I suck


2008-07-16 08:53:03

AAAAAAAAAGGGH!! MY BRAIN EXPLODED!!!! AGGHHGHHH (foams at the mouth) *gag *blurb


2008-08-17 17:05:48



2011-06-29 12:09:32

Thanks for the thorough post Mike. I'm trying to create a solution that automatically sets scaleX to -1 if the stage placed instance is horizontally flipped, so that going forward I can just assume all left facing mc's are properly represented by scaleX being negative (otherwise I've been making them all face right and then flipping them programmatically as needed, which I'd rather not have to do).

I get that -scaleY and 180 rotation is equivalent to -scaleX. However, Flash CS3 is setting both scaleY and scaleX to positive and rotation to 180. Perhaps that's because of the sign ambiguity, I didn't take the time to fully understand the math here. However, if all I do is set the transform.matrix back to itself, then scaleY all of a sudden goes negative, so that it now works as I would expect, and I can then convert 180 rotation negative scaleY to negative scaleX as needed. Since all I did was set the matrix to what it currently is (the a,b,c,d values it already knew), this seems like a Flash bug that scaleY is not getting set to negative initially.

Here's the solution I came up with:
obj.transform.matrix = obj.transform.matrix; //resets scaleY to expected value
if(obj.scaleX > 0 && obj.scaleY < 0 && Math.abs(obj.rotation) > 90){
obj.scaleX *= -1;
obj.scaleY *= -1;
obj.rotation -= 180;