MX: Trig question, atan & atan2

I thought that Math.atan2(y, x) computes the arc tan of y/x in radians, and that Math.atan(x) computes the arctan of x in radians. How come then are these two following lines different?

[AS]Math.atan((y1-y2) / (x1-x2));[/AS] and…
[AS]Math.atan2((y1-y2) , (x1-x2));[/AS]
They look to me like they should be the same, but they give very different results.

[fixed typo]


Oh yeah, and I also have another issue with my code. I’m making this little archer project (you aim and shoot with mouse and move with keys,) and I can’t figure out how to weight the front of the arrow so that the arrow doesn’t look stiff as gravity brings it down. (See attached swf file.) The attached SWF doesn’t have gravity coded into the arrows’ movement right now, but if it did, what would the trigonometry involved be in making the front end of the arrow weighted?



You made a typo…[AS]Math.atan((y1-y2) / (x1-x2));[/AS] and…
[AS]Math.atan2((y1-y2) , (x1-x2));[/AS]And they do return the same thing, except for a few values (which I can’t remember). But it is commonly said that atan2 ‘works’ better than atan.

pom :slight_smile:

When you have a doubt, ask Senocular…

Math.atan is still arc tangent, but instead of two x and y values, it takes a slope value which is the normal input for arc tangenet. Slope is simply a value derived from y divided by x. It gives you an indication of how steep a line is based on x and y values that for its triangle. Now, it is true you could just as well say Math.atan(y/x) in Flash instead of Math.atan2(y,x). However, built into atan2 is a check to return a proper value if x is 0. As we all know (or should know) you CANNOT divide by 0 and using an x of 0 in y/x … well it’s just not good. Math.atan2 lends a helping hand to prevent difficulties you’d otherwise encounter with that.
Excerpt from the trigonometry tutorial :slight_smile:

Ok, thanks for the reply - there must have been some division by 0 thing going on with atan.

Do you have any ideas about how I’d go about making the arrow’s front weighted?

Oh yeah, for some reason, the SWF I attached doesn’t view for me when I click it, but it does when I save it to my desktop.


To make the what??? :h:

I’ve attached a different archer.swf to this post that might make things a little more clear. Notice how in the SWF, the arrows are pulled down to the ground by gravity, but do not rotate at all when they are falling? I’d like them to rotate in such a fashon that would give the illusion of them being weighted in the front, but I don’t know how.

I’m sure it would involve trigonometry of some type, but I’m not quite sure how to implement it.


OK, let’s suppose that the ‘clip’ clip is your arrow, and that it’s pointing right, with its registration point at the right end of the arrow (the spike). We choose this because that’s angle 0 for Flash. If you put this in the first frame, you should get what you want:

clip.onEnterFrame = function () {
	this.vx = 5*Math.sin(b+=.01);
	this.vy = 10*Math.cos(a+=.05);
	var ang = Math.atan2(this.vy, this.vx)*180/Math.PI;
	this._rotation = ang;
	this._x += this.vx;
	this._y += this.vy;

pom :slight_smile:

Thanks for the code - it kind of worked.

When you click the mouse, the arrow is shot, but it does not fly on the trajectory that it’s supposed to fly on. Instead, it kind of “swims” back and forth on the screen.

I already had code in my arrow onEnterFrame function:

[AS]this.ychange+= _root.gravity;
this._x += this.xchange;
this._y += this.ychange;[/AS]I deleted that, but it still didn’t seem to work right. I also tried renaming the vx and vy variables, but that didn’t have much of an effect.

How was I supposed to add that piece of code?

  1. as for atan and atan2 not matching up, chances are you’ve used values in atan that are ‘out of range’ of atan2 which is restricted to -Pi and Pi. atan will go beyond that, though, in terms of angle of rotation in radians will still equal that given by atan2. atan2 just has the protection from 0 division which I believe Pom mentioned (which is actually from me isnt it :crazy: ).

  2. poms posted code is an example which works on its own. For you, you would just need to incorporate that which is missing from yours into… yours ;). Since you don’t quite understand that yet (so it seems) I’ll tell you what you need.

You already have your x/y vector going. All you need is to convert that into a rotation. In poms example, its vx and vy. You seem to be using xchange and ychange. Same thing. To make that an angle, atan2 is used. Obviously, right? This I think has been whats been the problem from the start, atan2, right? One thing to be careful of is that the value returned by atan2 is in fact a rotation, but one in radians, not degrees, which movieclip rotation is based. Thats why Pom used *180/Math.PI - to convert those radians into degrees. With yours, you’d probably simply need.

this._rotation = Math.atan2(this.ychange, this.xchange)*180/Math.PI;

Thanks senocular and Ilyas, that worked great!