Advanced Coordinate Rotation

If you are going to be rotating objects around a point, and you are starting with just their positions , Ive got a formula for you. The formula just needs the x, y position of the object in relation to the center point and the angle to rotate by. It returns the new x, y position of the object, relative to the center. Heres the basic formula:

 x1 = cos(angle) * x  sin(angle) * y; y1 = cos(angle) * y + sin(angle) * x; 

If that just seems like a bunch of letters and symbols that happen to have a somewhat pleasing symmetry in the way they are arranged, dont feel bad. Thats the way I felt about it when I first started. Actually, even though I use this formula quite often, I still feel pretty much that way about it. I have sat down a couple of times and figured out with diagrams exactly how the sines and cosines, xs and ys, pluses and minuses, and so forth work in terms of triangles and coordinates. And when I did that, it made complete sense to me. And 30 minutes later, it looked like a bunch of symbols with nice symmetry.

So, although I usually strive to give you a complete conceptual understanding of the techniques Im presenting, Id be a hypocrite if I did that here. Because, personally , Ive just memorized the formula so that I can type it in my sleep. The good news is that if you know more trigonometry than I do, youll probably be able to get a deeper understanding of this technique, but even if you arent a rocket scientist, you can memorize the formula and still get great results.

So, lets just look at what this formula is saying, which Ive illustrated in Figure 10-1. The x and the y are, of course, the coordinates of the thing you are rotating. More specifically , they are the coordinates of that object in relation to the center point it is rotating around. Thus, if your center point is at 200, 100, and your object is at 300, 150, x will be 300 ˆ 200, or 100, and y will be 150 ˆ 100, or 50.

image from book
Figure 10-1. Rotating coordinates

The angle is how much you are rotating the object this particular time. Its not the current angle, or the resulting angle, but the difference between the two. In other words, talking in degrees for just a moment, if the object is at a 45-degree angle from the center point, and the angle here is 5 degrees, you will be rotating it another 5 degrees to put it at 50. Remember though, in this technique, you probably dont know, and dont really care about, the initial and final angles. Youre just interested in how much rotation is occurring. Also, Im sure I dont have to mention it, but as usual, this angle will be in radians, not degrees.

OK, so lets see it in action.

Rotating a single object

To begin, just change the code on the first frame of the previous example to read like this ( ch10_03.fla ):

 var vr:Number = .05; var cosine:Number = Math.cos(vr); var sine:Number = Math.sin(vr); function onEnterFrame():Void {       var x:Number = ball._x - Stage.width / 2;       var y:Number = ball._y - Stage.height / 2;       var x1:Number = cosine * x - sine * y;       var y1:Number = cosine * y + sine * x;       ball._x = Stage.width / 2 + x1;       ball._y = Stage.height / 2 + y1; } 

Here, you are setting the vr to the same value of .05 you used before. Then youre calculating the sine and cosine of that angle. Since it isnt going to change in this simple example, you can do it once outside the enterFrame handler, rather than inside, where it would need to be recalculated every frame. The x and y positions are calculated in relation to the point they will rotate aroundthe center of the stage. Then you apply the coordinate rotation formula as just described. This gives you x1 and y1 , the new position of the ball. Again, this is in relation to the center point, so you need to add x1 and y1 to the center point to get the final position of the ball.

Try it out, and youll see it should work exactly the same as the earlier version. Now, Im sure youre thinking, if it works exactly the same, why bother going through this new formula, which actually looks more complex? Well, in a very simple situation like this, youd probably be right. But lets look at some situations where this setup actually simplifies things. First, consider rotating multiple objects.

Rotating multiple objects

Suppose there are many objects to rotate. The for loop would look something like this:

 for(var i:Number = 0;i<mcCount;i++) {       var mc:MovieClip = this["mc" + i];       var dx:Number = mc._x  centerX;       var dy:Number = mc._y  centerY;       var angle:Number = Math.atan2(dy, dx);       var dist:Number = Math.sqrt(dx * dx + dy * dy);       angle += vr;       mc._x = centerX + Math.cos(angle) * dist;       mc._y = centerY + Math.sin(angle) * dist; } 

Whereas, the advanced coordinate rotation method would look like this:

 var cosine:Number = Math.cos(vr); var sine:Number = Math.sin(vr); for(var i:Number = 0;i<mcCount;i++) {       var mc:MovieClip = this["mc" + i];       var x:Number = mc._x  centerX;       var y:Number = mc._y  centerY;       var x1:Number = cosine * x  sine * y;       var y1:Number = cosine * y + sine * x;       mc._x = centerX + x1;       mc._y = centerY + y1; } 

Notice that the first version includes four calls to Math functions within the loop, meaning that all four are executed once for each object being rotated . The second version has just two calls to Math functions, both outside the loop, meaning they are executed only once, regardless how many objects there are. So, for example, if you have 30 movie clips, youre looking at 120 Math calls on each frame with the first version, as compared to two with the second version. You decide which is going to be more efficient.

In the previous example, you were able to remove the sine and cosine calculations right outside the enterFrame handler. This is because you were sticking with a fixed angle, so you could set it and forget it. In many cases, however, these angles of rotation may be changing, and youll need to recalculate the sine and cosine each time it changes.

To demonstrate these latest couple of concepts, lets build a quick example where the mouse position is controlling the speed of rotation of multiple objects. If the mouse is in the center of the screen, no rotation happens. As it moves to the left, the objects move faster and faster in a counterclockwise direction. As it moves to the right, they rotate in a clockwise direction. This example will start out quite similar to the previous one, except youll need four movie clip instances on stage, named ball0 through ball3 . Heres the code for frame 1 ( ch10_04.fla ):

 function onEnterFrame():Void {       var angle:Number = (_xmouse - 270) * .001;       var cosine:Number = Math.cos(angle);       var sine:Number = Math.sin(angle);       for(var i:Number = 0;i<4;i++)       {             var ball:MovieClip = this["ball" + i];             var x:Number = ball._x - Stage.width / 2;             var y:Number = ball._y - Stage.height / 2;             var x1:Number = cosine * x - sine * y;             var y1:Number = cosine * y + sine * x;             ball._x = Stage.width / 2 + x1;             ball._y = Stage.height / 2 + y1;      } } 

You can see that the code here isnt all that complex. If youre up to it, try recoding it using the angle and radius method, and see if it looks better or worse and how it performs .

Youll revisit this formula when you get to the discussion of 3D in Chapter 15. In fact, youll be using it twice within the same method, to rotate things around two axes and three dimensions. But dont let me scare you off yet. You have a lot to do before you get there.



Foundation ActionScript. Animation. Making Things Move
Foundation Actionscript 3.0 Animation: Making Things Move!
ISBN: 1590597915
EAN: 2147483647
Year: 2005
Pages: 137
Authors: Keith Peters

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net