即使数学正确,矩形也不跟随鼠标

Rectangle not following mouse even though math is correct

我有一个基本的寻路程序,我希望矩形跟随我的鼠标。我正在使用这种特定的寻路方法,因为我想在未来扩展它。我有 2 种方法:一种获取 2 个矩形之间的角度,另一种以 x 角度移动矩形。出于某种原因,矩形只在我的鼠标在它前面时跟随我的鼠标,而不是在它后面时。

如果我去掉角度方法的 Math.abs,问题仍然存在。

以下是我的 2 个基本 classes.

PathfindingTest.java,这是主要的 class 并初始化所有内容:

package pathfindingtest;

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

/**
 *
 * @author Preston Tang
 */
public class PathfindingTest extends Application {

    private final long[] frameTimes = new long[100];
    private int frameTimeIndex = 0;
    private boolean arrayFilled = false;

    private double mouseX, mouseY;

    @Override
    public void start(Stage stage) {
        Pane base = new Pane();
        base.setStyle("-fx-background-color: rgb(" + 40 + "," + 40 + ", " + 40 + ");");

        Entity virus = new Entity(100, 100, 20, 5, Color.RED);
        Entity cell = new Entity(700, 450, 20, 5, Color.GREEN);

        base.getChildren().add(virus);
        base.getChildren().add(cell);

        base.setOnMouseMoved((MouseEvent event) -> {
            mouseX = event.getX();
            mouseY = event.getY();
        });

        Scene scene = new Scene(base, 800, 550);

        AnimationTimer timer = new AnimationTimer() {
            @Override
            public void handle(long now) {
                //To get frame data
                long oldFrameTime = frameTimes[frameTimeIndex];
                frameTimes[frameTimeIndex] = now;
                frameTimeIndex = (frameTimeIndex + 1) % frameTimes.length;
                if (frameTimeIndex == 0) {
                    arrayFilled = true;
                }
                if (arrayFilled) {
                    long elapsedNanos = now - oldFrameTime;
                    long elapsedNanosPerFrame = elapsedNanos / frameTimes.length;
                    double frameRate = 1_000_000_000.0 / elapsedNanosPerFrame;
//                    System.out.println(String.format("Current frame rate: %.3f", frameRate));
                }

                if (!(mouseX == 0) && !(mouseY == 0)) {
                    virus.move(virus.getAngle(virus.getX(), virus.getY(), mouseX, mouseY), 1);
                }

            }
        };

        timer.start();

        stage.setTitle("Pathfinding Test Application Started 9/9/2019");
        stage.setResizable(false);
        stage.setScene(scene);
        stage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}

Entity.java,它扩展了 Rectangle,并且是计算寻路数学的地方:

package pathfindingtest;

import javafx.geometry.Point2D;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;

/**
 *
 * @author Preston Tang
 */
public class Entity extends Rectangle {

    private double x, y, size, speed;
    private Color c;

    public Entity(double x, double y, double size, double speed, Color c) {
        this.setX(x);
        this.setY(y);
        this.setWidth(size);
        this.setHeight(size);
        this.speed = speed;

        this.setFill(c);
    }

    public double getDistance(Rectangle r1, Rectangle r2) {
        return Math.sqrt((r2.getY() - r1.getY()) * (r2.getY() - r1.getY()) + (r2.getX() - r1.getX() * (r2.getX() - r1.getX())));
    }

    public double getAngle(double x1, double y1, double x2, double y2) {
        double ang = Math.atan(Math.abs((y2 - y1) / (x2 - x1)));
        System.out.println("delta x: " + (x2 - x1) + " delta y: " + (y2 - y1) + " + Angle: " + Math.toDegrees(ang));
        return ang;
    }

    public void move(double angle, double distance) {
        this.setX(this.getX() + (distance * Math.cos(angle)));
        this.setY(this.getY() + (distance * Math.sin(angle)));
    }

    public double getSpeed() {
        return speed;
    }

    public void setSpeed(double speed) {
        this.speed = speed;
    }

    public double getSize() {
        return size;
    }

    public void setSize(double size) {
        this.size = size;
    }

    public Color getC() {
        return c;
    }

    public void setC(Color c) {
        this.c = c;
    }

}

感谢您的帮助!

您正在调用 Math.atan,其中 returns 的值介于 -pi/2(-90 度)到 pi/2(90 度)之间(https://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#atan(double) )

尝试切换到 Math.atan2,其中 returns -pi 到 pi ( https://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#atan2(double,%20double) )

的完整范围