2

In order to better understand how trigonometry works in game development, I've been creating little javascript snippets on CodePen.

I managed to create an example that uses Math.atan2() to point a pixel-art shotgun at the mouse cursor.

Now, I am trying to accomplish the same exact thing using the Math.atan() function but it isn't functioning properly.

Here is the logic code I am using:

canvas.onmousemove = function(event) {
  Mouse = {
    x: event.pageX,
    y: event.pageY
  }

  // These length variables use the distance formula
  var opposite_length = Math.sqrt((Mouse.x - Mouse.x) * (Mouse.x - Mouse.x) + (Mouse.y - y) * (Mouse.y - y));

  var adj_length = Math.sqrt((Mouse.x - x) * (Mouse.x - x) + (y - y) * (y - y));


  var angle_in_radians = Math.atan(opposite_length / adj_length);

  //var angle_in_radians = Math.atan2(Mouse.y - y, Mouse.x - x);

  angle = angle_in_radians * (180 / Math.PI);
}

The in my draw() function, I rotate the gun to the angle var using:

cxt.rotate(angle*(Math.PI/180));

If you uncomment the line that starts as // var angle_in_radians, everything will suddenly work.

So, atan2 is working, but atan is producing the result I want.

I know that opposite_length and adj_length are accurate, because when i console.log() them, they are the correct values.

You can check out the code being used on CodePen for a live example.

There's a lot of initialization stuff but you only really need to focus on the canvas.onmousemove = function(event) section, starting on line 50. You can also check out my draw function on line 68.

Doug Beney
  • 310
  • 2
  • 13
  • Your calculation for the opposite_length variable looks incorrect. `(Mouse.x - Mouse.x) * (Mouse.x - Mouse.x)` is always going to equal zero. Either you don't need that portion of the calculation or some of those `Mouse.x` values should probably be `x` instead. – RickyTomatoes Jun 24 '16 at 18:24
  • The opposite side of a triangle is going to be on the same x value. I didn't need to include the Mouse.x-Mouse.x point, because like you said it equals zero, but I kept it in just for the sake of the distance formula. After `console.log`ing the value of the side length, I saw they were correct. – Doug Beney Jun 24 '16 at 18:30

1 Answers1

2

Note that your atan computation is equivalent to

atan2( abs(mouse.y-y), abs(mouse.x-x) )

The screen coordinates have the opposite orientation to the cartesian coordinates. To get a cartesian angle from screen coordinates, use

atan2( y-mouse.y, mouse.x-x )
Lutz Lehmann
  • 25,219
  • 2
  • 22
  • 51
  • The atan2 I'm using works perfectly. It's the plain atan I'm trying to get working. Is it possible to use the regular Math.atan function instead, even though it will involve a couple more lines of code? – Doug Beney Jun 24 '16 at 19:36
  • Why do you want to use atan? atan(y/x) = atan2(y,x) for all (x,y) in the 1. and 4. quadrant, in the 2. and 3. quadrant atan has the wrong sign. In most situations you are better served using atan2. – Lutz Lehmann Jun 24 '16 at 19:41
  • For educational purposes. You're right though! `var angle_in_radians = Math.atan((Mouse.y - y) / (Mouse.x - x));` solved it :) Not too sure why that is though. I figured I could find the angle of the mouse position and the gun position by using arctangent with the opposite side divided by the adjacent side. That wouldn't work? – Doug Beney Jun 24 '16 at 19:55