Understanding the Atan2, Please help

I was expecting to get the degrees from the center of the sketch to the mouse from 0 to 360 or zero to 2PI.

Instead I am getting zero to 180 from horizontal to the belly of the sketch and then I get negative numbers on the top…
This makes it very hard to send angle coordinates to Arduino,
What am I doing wrong?
Thanks


void setup()
{size(640, 840, JAVA2D);
}

void draw() {
  background(204);
  translate(width/2, height/2);
  float a = atan2(mouseY-height/2, mouseX-width/2);
  println(degrees (a));

 
  rotate(a);
  rect(-30, -5, 60, 10);
}

The doc states

Calculates the angle (in radians) from a specified point to the coordinate origin as measured from the positive x-axis. Values are returned as a float in the range from PI to -PI

Did you check what degrees() returns for -PI/2 or -PI?

I simply don’t get that , The origin is top right corner right?

But the angle I get seems to from the center of the sketch to my mouse.
The center of the sketch is not the origin. Right? Don’t get it…

You translated to the center of the drawing area with translate(width/2, height/2);
So that’s your (0,0) position

OK, then why don’t I get a complete 360 deg reading from the center of the sketch to the mouse?
As I circle the mouse around the center…

Thanks

you need to swap from atan2(y1-y2,x1-x2) to atan2(y2-y1,x2-x1)

OK so I tried

a = atan2((height/2)-mouseY,(width/2) -mouseX);

Half the screen is still generating negative numbers…

Hi @laptophead ,

If you want an unsigned range in [0, TAU] or [0, 360], then use floor modulo (or a specialized version for degrees or radians, which would spare you a divide, /).

This applies for any angle, not just the range of values returned by atan2.

float floorMod(float a, float b) {
  return a - b * floor( a / b);
}

float floorModDeg(float a) {
  return a - 360.0 * floor(a * 0.0027777778);
}

It also applies to hue in HSB color. If the second operand, b, is 1, you can also simplify by just subtracting the floor of a from a.

Hope that helps. Best,
Jeremy

1 Like

Remember that 0° is not at top but at right side in processing

This works with 0° at right side :




void setup()
{
  size(640, 840);
}

void draw() {
  background(204);

  translate(width/2, height/2);
  //float a = atan2(height/2-mouseY, width/2-mouseX);
  float a = atan2(mouseY-height/2, mouseX-width/2);
  if (a<0)
    a=TWO_PI+a;
  println(degrees (a));


  rotate(a);
  rect(-30, -5, 60, 10);
}

This version has 0° at the top / north




void setup()
{
  size(640, 840);
}

void draw() {
  background(204);

  translate(width/2, height/2);
  //float a = atan2(height/2-mouseY, width/2-mouseX);
  float a = atan2(mouseY-height/2, mouseX-width/2);
  if (a<0)
    a=TWO_PI+a;

  a+=HALF_PI;  
  if (a>TWO_PI)
    a-=TWO_PI; 
  println(degrees (a));

  rotate(a);
  rect(-30, -5, 60, 10);
}

Regards,

Chrisir

1 Like

OK I got it
Thanks guys

1 Like

to make the rect point upwards for 0°


  rect(-5, -30, 10, 60);

Hello @behreajj,

I always appreciate your insights.

Not everyone may understand the example…

float num = 1.0/360;
println(num);           // This prints 0.0027777778

:)

As atan2 returns values from -180 to 180 or its radian equivalent you can always just add 180 degrees to get rid of the negative. This will give you values from 0 to 360 or its.

Also here is a sketch I made a while back to understand the atan2 and atan functions.

PVector a,c;

void setup(){
   size(200,200);
   a = new PVector(width/2,height/2);
   c = new PVector(width,height/2);
};



void draw(){
  PVector b = new PVector(mouseX,mouseY);
   background(0);
   stroke(255);
   line(a.x,a.y,b.x,b.y);
   line(a.x,a.y,c.x,c.y);
   
   //float t1 = map(atan2(b.y-a.y,b.x-a.x),-PI,PI,0,360);
   //float t1 = map(atan((b.x-a.x)/(b.y-a.y)),-PI/2,PI/2,0,180);
   float t1 = degrees(atan2(b.y-a.y,b.x-a.x));
   float t2 = degrees(atan2(b.y-a.y,b.x-a.x)+PI);
   
   float t3 = (atan2(b.y-a.y,b.x-a.x)-PI/2);
   float t4 = (atan2(b.y-a.y,b.x-a.x)+PI/2);
   stroke(255,0,0);
   line(a.x,a.y,a.x + 20*cos(t3),a.y + 20*sin(t3));
   stroke(255,0,255);
   line(a.x,a.y,a.x + 20*cos(t4),a.y + 20*sin(t4));
   
   fill(255);
   text(t1,10,10);
   text(t2,10,20);
   text(round(cos(t3)),10,30);
   text(round(sin(t3)),10,40);
};

Hi !
You can find it helpful https://www.instagram.com/p/CGKdsJVnyfH/