If you want, you can make Math functions to make the conversion for you:
Code:
Math.toRadians = function(degrees){
return degrees*Math.PI/180;
}
Math.toDegrees = function(radians){
return radians*180/Math.PI;
}
Since, if you think about it, if 180 degrees is Math.PI radians, just
taking that as a fraction will convert either degrees or radians into
the other based on the order of that fraction. Make sense? If not dont
worry, its there and you can use it

:
trace(Math.toDegrees(Math.PI)); // traces 180
The original Vector.prototype.rotate used a sinD and cosD I initially
said are probably just sine and cosine in degrees. If so, heres how
they would look:
Code:
Math.sinD = function(angle){
return Math.sin(angle*Math.PI/180);
}
Math.cosD = function(angle){
return Math.cos(angle*Math.PI/180);
}
Doing basically the same thing as toRadians, but doing it within the
sine and cosine call itself (converting the passed degrees value into a
radians value to be used in the sin or cos function)
continuing, now that thats all cleared up...
So, what sine and cosine really do is give a proportion of the two
lines in respect to 1. This base value of 1 is part of the imaginary
'unit circle' which the functions sine and cosine are based around.
This unit circle assumes a vector with a force (or length or radius) of
1. The reason for this is because an angle value alone cant tell you
how long the vector is, just where its pointing. So sine and cosine
just assume 1 and return a value based on that. Ok, so what value? Well
looking at that chart, sine returns opposite/hypotenuse or y/radius and
cosine returns adjacent/hypotenuse or x/radius. So you're probably
thinking, "Hmm well thats just some bloody fraction, whats that going
to do for me?" Well if you remember what I just said about how sine and
cosine think interms of a radius of 1, you'll see that y/radius and
x/radius are just y/1 and x/1 which are just y and x! And what are y
and x? They're the base (adjacent) and height (opposite) of the
triangle which is effectively the x and y of the vector! ... at least a
vector with a force of 1. See this swf I made a while back to see what
I mean (and to see the graphs of sine and cosine).
http://www.umbc.edu/interactive/fla/trigsincos.swf
Now, what arc tangent2 can do for us is go the other way around, it can
take a y and x value and return an angle. An angle in radians of
course. Yippie, we'll leave it at that.
The Pythagorean theorem is probably one of the best known functions of
those used in trigonometric calculations. What it does (as my little
chart explained) is finds any right triangles side assuming 2 are
already known. Now the function itself doesnt look that way, but
solving for any a, b or c will do just that. Chances are if you are
using this function, you are finding the hypotenuse of a triangle. This
is because we all ready saw that sine and cosine can be used to find
the x and y sides of a triangle given its angle, so if we have the
angle (which we usually do) we find those 2 sides and then can find the
hypotenuse using the good olde Pythagorean theorem. Typically this is
translated into the 'distance function' which finds the distance
between any two points, since as you can see, the hypotenuse is the
distance between our two important points, the origin (0,0) and the
vector point(x,y). So solving for the hypotenuse we develop the
equation:
hypotenuse = √ (opposite² + adjacent²)
or in Flash terms
hypotenuse = Math.sqrt(opposite*opposite + adjacent*adjacent);
Wow! So using those 4 things, sine, cosine, arc tangent2 and the
Pythagorean theorem we can find every side and even the angle of any
given right triangle or in Vector terms, its angle, x, y and force! Now
that brings us to rotating... well not without one more diversion.
Changing the force of a vector...
Changing the force of a vector (if you havent already figured it out)
is only a matter of multiplying that vector my a scalar, which itself
is just a number representing a force. For example, you saw how the
very first vector, was twice as strong as the previous vector. Taking
note of the x and y of both of those vectors you can see that the first
vectors x and y are twice as large as the seconds. So to cut a vectors
force in half, youd multiply it by the scalar .5 (which is 1/2).
Multiplying a vector by a scalar is simply multiplying both its x and y
by that number. So the vector (6,5) when multiplied by the scalar .5
becomes (3,2.5) which is what the second vector is. A function for that
is:
Code:
Vector.prototype.multiply = function(scalar) {
this.x *= scalar;
this.y *= scalar;
};
So given a sine (y) or cosine (x) based value (remember, thats always
based on 1), if you multiply that value a vectors force, you get that
vectors actual y or x value.
So (FINALLY) to the function which started this question in the first place:
Code:
Vector.prototype.rotate = function(angle) {
var ca = Math.cosD(angle);
var sa = Math.sinD(angle);
with (this) {
var rx = x*ca-y*sa;
var ry = x*sa+y*ca;
x = rx;
y = ry;
}
};
This follows the formula
x' = x * cosine(theta) + y * sine(theta)
y' = x * sine(theta) - y * cosine(theta)
where theta is an angle of rotation and x' and y' are 'x prime' and 'y
prime' which are the 'new' x and y derived by the rotation. Since it
doesnt quite seem to relate directly to what Ive covered through all
the previous explanation, I think the best way to actually see this in
action is from a base on-axis example using or cartesian plane.
The reason for this is because with the our initial on-axis (on the x
axis) vector (x,y), our x is equal to the vector force and y is 0,
making it easy to work with. So right off, lets plug that in to that
rotation equation:
x' = force * cosine(theta) + 0 * sine(theta)
y' = force * sine(theta) - 0 * cosine(theta)
which resolves to
x' = force * cosine(theta)
y' = force * sine(theta)
which is exactly the definition of of sine and cosine! Now the example
end vector (x',y') in the diagram above is actually the first vector I
showed, (6,5). So lets work backwards from that and that initial
on-axis vector that this example is supposed to start from. First
though, we need to find the rotation of our vector though, and that is
done through what? Thats right, atan2
angle = Math.atan2(y,x)
angle = Math.atan2(5,6)
angle = 0.6947 radians
angle = about 40 degrees
...whats that? What does atan2 do? I was hoping you wouldnt ask

Basically, all atan2 is, is atan (arc tangent - look back at my beautiful chart

)
but using not using a tangent derived value to get the angle, instead
using just the y and x. Tangent itself is after all just y/x; what
atan2 does is prevents you from having to take your y divide it by x to
before throwing it in (which you would do for atan). This is good not
only in that it saves you time (possibly heh), but it also
automatically saves you from instances where x might be 0. And why is
that bad? Because you CANT DIVIDE BY ZERO!!! (My highschool math
teacher would be proud!) Back to our equation though...
x' = x * cosine(theta) + y * sine(theta)
y' = x * sine(theta) - y * cosine(theta)
x' = 6 * cosine(0.6947) + 5 * sine(0.6947) // remember we're using radians
y' = 6 * sine(0.6947) - 5 * cosine(0.6947)
x' = 4.6093 + 3.2009
y' = 3.8411 - 3.8411
x' = 7.8102
y' = 0
which would give us the axis vector of (7.8,0). Right away you can tell
the 0 is right since there should be no y value if the vector is on the
x axis. But what about x? How would we know if thats right? Why the
Pythagorean theorem, of course! Since the vector is on the x axis, x is
actually representative of the force of the vector as well. So using
the Pythagorean theorem on the original vector (6,5) solving for
hypotenuse (force) will give us... 7.8 - we hope... lets see:
hypotenuse = √ (opposite² + adjacent²)
hypotenuse = √ (5² + 6²)
hypotenuse = √ (25 + 36)
hypotenuse = √ 61
hypotenuse = 7.8102
And there you have it!
So basically what the
x' = x * cosine(theta) + y * sine(theta)
y' = x * sine(theta) - y * cosine(theta)
formula more or less does (or at least a way you can think about it) is
supposes the vector to be rotated to be as if it were on an axis. Then
as seen above, calculates the new vector treating that 'on axis' vector
as a base vector from which a new vector is just added on to.
Chances are this doesnt make sense right away if you are only now
getting into it. But within time and some research on your own, it
should come together more and more bit by bit until you have it down.
-------------------------------------
wheeeew I completely didnt mean to spend this much time on the explanation
OK WHOA... I forgot something. Remember how I mentioned that the y axis
in Flash is flipped (since a y of 0 starts at the top and increases
going down)? Ok good, I knew you would. However, DONT FEAR! This will
actually cause NO problems for you whatso ever. The reason? Because
rotation in flash is also backwards! Look at the unit circle rotation
values in the swf link. The angle starts at 0 on the right and
increases moving counter-clockwise. Rotation in flash increases moving
clockwise. That being the case, it basically cancels out any
complications that would have been had from the flipping of the y axis.
Ok, just had to clear that up
