views:

809

answers:

3

Im trying to get into some basic JavaFX game development and I'm getting confused with some circle maths.

I have a circle at (x:250, y:250) with a radius of 50.

My objective is to make a smaller circle to be placed on the circumference of the above circle based on the position of the mouse.

Where Im getting confused is with the coordinate space and the Trig behind it all.

My issues come from the fact that the X/Y space on the screen is not centered at 0,0. But the top left of the screen is 0,0 and the bottom right is 500,500.

My calculations are:

var xpos:Number = mouseEvent.getX();
var ypos:Number = mouseEvent.getY();

var center_pos_x:Number = 250;
var center_pos_y:Number = 250;

var length = ypos - center_pos_y;
var height = xpos - center_pos_x;

var angle_deg = Math.toDegrees(Math.atan(height / length));
var angle_rad = Math.toRadians(angle_deg);

var radius = 50;

moving_circ_xpos = (radius * Math.cos(angle_rad)) + center_pos_x;
moving_circ_ypos = (radius * Math.sin(angle_rad)) + center_pos_y;

I made the app print out the angle (angle_deg) that I have calculated when I move the mouse and my output is below:

When the mouse is (in degrees moving anti-clockwise):

  • directly above the circle and horizontally inline with the center, the angle is -0
  • to the left and vertically centered, the angle is -90
  • directly below the circle and horizontally inline with the center, the angle is 0
  • to the right and vertically centered, the angle is 90

So, what can I do to make it 0, 90, 180, 270??

I know it must be something small, but I just cant think of what it is...

Thanks for any help (and no, this is not an assignment)

+2  A: 

atan(height/length) is not enough to get the angle. You need to compensate for each quadrant, as well as the possibility of "division-by-zero". Most programming language libraries supply a method called atan2 which take two arguments; y and x. This method does this calculation for you.

More information on Wikipedia: atan2

MizardX
Ok, it does have atan2, I had an small idea that it might be that method! Anyway, I have done that and now it gives me a range between -180 and 180 degrees. But im not really sure how exaclty to work with that.
Mark
Actually, I got it, thanks! I really appreciate the help. I knew it would be something small
Mark
+1  A: 

You can get away without calculating the angle. Instead, use the center of your circle (250,250) and the position of the mouse (xpos,ypos) to define a line. The line intersects your circle when its length is equal to the radius of your circle:

// Calculate distance from center to mouse.
xlen = xpos - x_center_pos;
ylen = ypos - y_center_pos;

line_len = sqrt(xlen*xlen + ylen*ylen);  // Pythagoras: x^2 + y^2 = distance^2

// Find the intersection with the circle.
moving_circ_xpos = x_center_pos + (xlen * radius / line_len);
moving_circ_ypos = y_center_pos + (ylen * radius / line_len);

Just verify that the mouse isn't at the center of your circle, or the line_len will be zero and the mouse will be sucked into a black hole.

Adam Liss
Thanks, thats also a good idea, but for now atan2 seems to do the job for me :)
Mark
A: 

There's a great book called "Graphics Gems" that can help with this kind of problem. It is a cookbook of algorithms and source code (in C I think), and allows you to quickly solve a problem using tested functionality. I would totally recommend getting your hands on it - it saved me big time when I quickly needed to add code to do fairly complex operations with normals to surfaces, and collision detections.

Kieveli
Thanks I will take a look, but Im really only just getting into the gaming side of things as a hobby. However, if it gets more serious I probably get it...
Mark