Home > other >  Java Swing - Calculating what angle the mouse position is to the center of the screen
Java Swing - Calculating what angle the mouse position is to the center of the screen

Time:03-14

I'm making a 2D topdown view shooter game with Java Swing. I want to calculate what angle the mouse pointer is compared to the center of the screen so some of my Sprites can look toward the pointer and so that I can create projectiles described by an angle and a speed. Additionally If the pointer is straight above the middle of the screen, I want my angle to be 0°, if straight to its right, 90°, if straight below 180°, and straight left 270°.

I have made a function to calculate this:

public static float calculateMouseToPlayerAngle(float x, float y){
        float mouseX = (float) MouseInfo.getPointerInfo().getLocation().getX();
        float mouseY = (float)MouseInfo.getPointerInfo().getLocation().getY();
        float hypotenuse = (float) Point2D.distance(mouseX, mouseY, x, y);
        return (float)(Math.acos(Math.abs(mouseY-y)/hypotenuse)*(180/Math.PI));
    }

The idea behind it is that I calculate the length of the hypotenuse then the length of the side opposite of the angle in question. The fraction of the 2 should be a cos of my angle, so taking that result's arc cos then multiplying that by 180/Pi should give me the angle in degrees. This does work for above and to the right, but straight below returns 0 and straight left returns 90. That means that I currently have 2 problems where the domain of my output is only [0,90] instead of [0,360) and that it's mirrored through the y (height) axis. Where did I screw up?

CodePudding user response:

You can do it like this.

  • For a window size of 500x500, top left being at point 0,0 and bottom right being at 500,500.
  • The tangent is the change in Y over the change in X of two points. Also known as the slope it is the ratio of the sin to cos of a specific angle. To find that angle, the arctan (Math.atan or Math.atan2) can be used. The second method takes two arguments and is used below.
BiFunction<Point2D, Point2D, Double> angle = (c,
        m) -> (Math.toDegrees(Math.atan2(c.getY() - m.getY(),
                c.getX() - m.getX()))   270)60;
        
BiFunction<Point2D, Point2D, Double> distance = (c,
                m) -> Math.hypot(c.getY() - m.getY(),
                        c.getX() - m.getX());
                
int screenWidth = 500;
int screenHeight = 500;
int ctrY = screenHeight/2;
int ctrX = screenWidth/2;

Point2D center = new Point2D.Double(ctrX,ctrY );

Point2D mouse = new Point2D.Double(ctrX, ctrY-100);
double straightAbove = angle.apply(center, mouse);
System.out.println("StraightAbove: "   straightAbove);

mouse = new Point2D.Double(ctrX 100, ctrY);
double straightRight = angle.apply(center, mouse);
System.out.println("StraightRight: "   straightRight);

mouse = new Point2D.Double(ctrX, ctrY 100);
double straightBelow = angle.apply(center, mouse);
System.out.println("StraightBelow: "   straightBelow);

mouse = new Point2D.Double(ctrX-100, ctrY);
double straightLeft = angle.apply(center, mouse);
System.out.println("Straightleft: "   straightLeft);
      

prints

StraightAbove: 0.0
StraightRight: 90.0
StraightBelow: 180.0
Straightleft: 270.0

I converted the radian output from Math.atan2 to degrees. For your application it may be more convenient to leave them in radians.

Here is a similar Function to find the distance using Math.hypot

BiFunction<Point2D, Point2D, Double> distance = (c,m) ->
             Math.hypot(c.getY() - m.getY(),
                        c.getX() - m.getX());
  • Related