从原点坐标中找到表示行进方向的角度
Find an angle representing the direction of travel from origin coordinates
我正在制作一个动画,其中有许多三角形对象在屏幕上移动。为了确保每个都朝向它行进的方向,我需要将图像旋转适当的角度。
我的问题是我的代码 returns 的角度不准确。返回值的变化不会超过几度。
/**
* Accepts two grid positions are arguments. The current position
* of the object and the next grid position. Returns an angle representing
* the direction of travel from the current position towards the next position. By converting the Cartesian coordinates into polar coordinates.
*
*/
public void setAngle(Vector2d currentPos, Vector2d nextPos ) {
Double delta_x = current.xPos - next.xPos;
Double delta_y = current.yPos - next.yPos;
Double theta = Math.atan2(delta_y, delta_x);
this.angle = theta;
}
Example:
|| current: 1031.1438073417544 , 268.3133503758045 || next: 1033.101761841174 , 269.0819944286846 || Angle: 0.0
|| current: 1033.1901579769194 , 242.19363555578593 || next: 1035.1281222295695 , 243.08778242413436 || Angle: 0.0
|| current: 1022.1577455080815 , 255.24422527831163 || next: 1024.0301966330894 , 256.19078788718997 || Angle: 0.0
// calc the deltas as next minus current
double delta_x = next.xPos - current.xPos;
double delta_y = next.yPos - current.yPos;
// Calc the angle IN RADIANS using the atan2
double theta = Math.atan2(delta_y, delta_x);
// this.angle is now in degrees
// or leave off *180/Math.PI if you want radians
this.angle = theta*180/Math.PI;
以下是创建完整示例的方法。
在其上移动节点(三角形)的路径(椭圆路径Uluk)。在每次移动期间,都会计算和调整节点的旋转。
public class Main extends Application {
double prevX = 0;
double prevY = 0;
double radiusX = 200;
double radiusY = 100;
double centerX = 600;
double centerY = 200;
@Override
public void start(Stage primaryStage) {
try {
// race track
Path path = new Path();
MoveTo moveTo = new MoveTo(centerX - radiusX, centerY - radiusY);
ArcTo arcTo = new ArcTo();
arcTo.setX(centerX - radiusX + 1); // to simulate a full 360 degree celsius circle.
arcTo.setY(centerY - radiusY);
arcTo.setSweepFlag(false);
arcTo.setLargeArcFlag(true);
arcTo.setRadiusX(radiusX);
arcTo.setRadiusY(radiusY);
path.getElements().add(moveTo);
path.getElements().add(arcTo);
path.getElements().add(new ClosePath());
path.setFill(Color.TRANSPARENT);
path.setStroke(Color.LIGHTGRAY);
path.setStrokeWidth(40);
Pane root = new Pane();
// car: arrow pointing right
Polygon arrow = new Polygon(0, 0, 20, 10, 0, 20);
root.getChildren().addAll( path, arrow);
// lawn
Scene scene = new Scene(root, 800, 400, Color.GREEN);
primaryStage.setScene(scene);
primaryStage.show();
// movement: car path on race track
PathTransition pathTransition = new PathTransition();
pathTransition.setDuration(Duration.millis(4000));
pathTransition.setPath(path);
pathTransition.setNode(arrow);
pathTransition.setCycleCount(Timeline.INDEFINITE);
pathTransition.setAutoReverse(true);
// rotate car during movement
pathTransition.currentTimeProperty().addListener(e -> {
double rad = angle(new Point2D(prevX, prevY), new Point2D(arrow.getTranslateX(), arrow.getTranslateY()));
double deg = Math.toDegrees(rad);
arrow.setRotate(deg);
prevX = arrow.getTranslateX();
prevY = arrow.getTranslateY();
});
pathTransition.play();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
/**
* Calculate angle between source and target point in radians.
* @param source
* @param target
* @return
*/
public static double angle(Point2D source, Point2D target) {
double dx = target.getX() - source.getX();
double dy = target.getY() - source.getY();
double angle = Math.atan2(dy, dx);
return angle;
}
}
我正在制作一个动画,其中有许多三角形对象在屏幕上移动。为了确保每个都朝向它行进的方向,我需要将图像旋转适当的角度。
我的问题是我的代码 returns 的角度不准确。返回值的变化不会超过几度。
/**
* Accepts two grid positions are arguments. The current position
* of the object and the next grid position. Returns an angle representing
* the direction of travel from the current position towards the next position. By converting the Cartesian coordinates into polar coordinates.
*
*/
public void setAngle(Vector2d currentPos, Vector2d nextPos ) {
Double delta_x = current.xPos - next.xPos;
Double delta_y = current.yPos - next.yPos;
Double theta = Math.atan2(delta_y, delta_x);
this.angle = theta;
}
Example:
|| current: 1031.1438073417544 , 268.3133503758045 || next: 1033.101761841174 , 269.0819944286846 || Angle: 0.0
|| current: 1033.1901579769194 , 242.19363555578593 || next: 1035.1281222295695 , 243.08778242413436 || Angle: 0.0
|| current: 1022.1577455080815 , 255.24422527831163 || next: 1024.0301966330894 , 256.19078788718997 || Angle: 0.0
// calc the deltas as next minus current
double delta_x = next.xPos - current.xPos;
double delta_y = next.yPos - current.yPos;
// Calc the angle IN RADIANS using the atan2
double theta = Math.atan2(delta_y, delta_x);
// this.angle is now in degrees
// or leave off *180/Math.PI if you want radians
this.angle = theta*180/Math.PI;
以下是创建完整示例的方法。
在其上移动节点(三角形)的路径(椭圆路径Uluk)。在每次移动期间,都会计算和调整节点的旋转。
public class Main extends Application {
double prevX = 0;
double prevY = 0;
double radiusX = 200;
double radiusY = 100;
double centerX = 600;
double centerY = 200;
@Override
public void start(Stage primaryStage) {
try {
// race track
Path path = new Path();
MoveTo moveTo = new MoveTo(centerX - radiusX, centerY - radiusY);
ArcTo arcTo = new ArcTo();
arcTo.setX(centerX - radiusX + 1); // to simulate a full 360 degree celsius circle.
arcTo.setY(centerY - radiusY);
arcTo.setSweepFlag(false);
arcTo.setLargeArcFlag(true);
arcTo.setRadiusX(radiusX);
arcTo.setRadiusY(radiusY);
path.getElements().add(moveTo);
path.getElements().add(arcTo);
path.getElements().add(new ClosePath());
path.setFill(Color.TRANSPARENT);
path.setStroke(Color.LIGHTGRAY);
path.setStrokeWidth(40);
Pane root = new Pane();
// car: arrow pointing right
Polygon arrow = new Polygon(0, 0, 20, 10, 0, 20);
root.getChildren().addAll( path, arrow);
// lawn
Scene scene = new Scene(root, 800, 400, Color.GREEN);
primaryStage.setScene(scene);
primaryStage.show();
// movement: car path on race track
PathTransition pathTransition = new PathTransition();
pathTransition.setDuration(Duration.millis(4000));
pathTransition.setPath(path);
pathTransition.setNode(arrow);
pathTransition.setCycleCount(Timeline.INDEFINITE);
pathTransition.setAutoReverse(true);
// rotate car during movement
pathTransition.currentTimeProperty().addListener(e -> {
double rad = angle(new Point2D(prevX, prevY), new Point2D(arrow.getTranslateX(), arrow.getTranslateY()));
double deg = Math.toDegrees(rad);
arrow.setRotate(deg);
prevX = arrow.getTranslateX();
prevY = arrow.getTranslateY();
});
pathTransition.play();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
/**
* Calculate angle between source and target point in radians.
* @param source
* @param target
* @return
*/
public static double angle(Point2D source, Point2D target) {
double dx = target.getX() - source.getX();
double dy = target.getY() - source.getY();
double angle = Math.atan2(dy, dx);
return angle;
}
}