Ok, here we go. As you know, the tangent of an angle, is it's sine divided by it's cosine. On the goniometric circle (with radius 1), we can see the tangent:
Because the triangles ABC and AED are congruent, the relation between CB and BA is the same as the one between ED and DA. CB is the sine of angle µ, and BA is it's cosine. (opposite side/hypotenuse with hypotenuse == 1, the same goes for the cosine). Our equasion becomes:
sin µ / cos µ = tan µ / 1. Which is correct. Tangent comes from the latin word tangere by the way, which means 'to touch'. That is exactly what the tangent does: it touches the side of the circle.
Math.atan() is used with y/x: Math.atan(ydistance/xdistance). This is because you need to provide the tangent to calculate the angle from, and the tangent is sin/cos, where sin is on the y (vertical) axis and cos is on the x (horizontal) axis.
But, there's a but. Two angles can have the same tangent:
When calculating the arc tangent ( == atan == tan^-1), Flash will return the angle to the right side of the triangle. But that means that if our point is at the left part of the circle, Flash will return the angle at the right side that has the same tangent.
Therefore, we need to check if our point is at the left or at the right of our circle. If it's at the left, we will have to add 180°, so Math.PI, because Flash uses radians.
Another thing to be aware of is that Flash doesn't go counterclockwise around the circle, but clockwise. And, that the _rotation property doesn't go from 0 to 360, but from -180 to 180. So we can't have a clip rotate to 225° using _rotation = 225. We have to substract 360 from that value to make it negative, and then rotate it to that negative number.
Here's a FLA for you that puts all this theory into practice. Enjoy
And I've added the code here ...
_global.d = 0;
_global.angle = 0;
pointer._rotation = 0;
Math.convertToDegrees = function(radians) {
return radians*(180/Math.PI);
};
MovieClip.prototype.rotateTo = function(to){
to > 180 ? to-=360 : null
this.onEnterFrame = function(){
this._rotation = to-(to-this._rotation)/1.2
this._rotation > to-1 && this._rotation < to+1 ? delete this.onEnterFrame : null
}
}
this.onMouseDown = function() {
mc = this.attachMovie("dot","dot"+d,d)
mc._x = this._xmouse
mc._y = this._ymouse
var diffX = this._xmouse-pointer._x;
var diffY = this._ymouse-pointer._y;
diffX>=0 ? _global.angle = Math.atan(diffY/diffX) : _global.angle = Math.PI+Math.atan(diffY/diffX);
pointer.rotateTo(Math.convertToDegrees(angle));
_global.d++;
};
- _global.d = 0;
- _global.angle = 0;
- pointer._rotation = 0;
- Math.convertToDegrees = function(radians) {
- return radians*(180/Math.PI);
- };
- MovieClip.prototype.rotateTo = function(to){
- to > 180 ? to-=360 : null
- this.onEnterFrame = function(){
- this._rotation = to-(to-this._rotation)/1.2
- this._rotation > to-1 && this._rotation < to+1 ? delete this.onEnterFrame : null
- }
- }
- this.onMouseDown = function() {
- mc = this.attachMovie("dot","dot"+d,d)
- mc._x = this._xmouse
- mc._y = this._ymouse
- var diffX = this._xmouse-pointer._x;
- var diffY = this._ymouse-pointer._y;
- diffX>=0 ? _global.angle = Math.atan(diffY/diffX) : _global.angle = Math.PI+Math.atan(diffY/diffX);
- pointer.rotateTo(Math.convertToDegrees(angle));
- _global.d++;
- };