围绕中心点的 javafx 位置元素

javafx position elements around a central point

抱歉,这是一个垃圾问题,但我对最佳方法一无所知。我相信一定有一些内在的或常见的做法,但我找不到它,而且 Google 没有发现任何有价值的东西。

我有一个 javafx 场景,其中有多个 Circles。

(以下命名以说明我要达到的效果)

Circle earth= new Circle(30, Color.web("blue", 0.5));

Circle moon = new Circle(30, Color.web("blue", 0.5));
Circle moon = new Circle(30, Color.web("blue", 0.5));
Circle moon = new Circle(30, Color.web("blue", 0.5));

全部定位:

setCenterX(300); 
setCenterY(300);

在 600 x 600 的场景中。

我需要将 moon 对象放置在 earth 对象周围。我不在乎在哪里,只要它们与月球有 x 距离并且不接触。

我最初遍历每个对象,检查碰撞并使用递归函数将圆在y坐标上移动+10。

这很有效,但似乎我做了很多工作来有效地在圆形路径上绘制一些对象。 (遍历每个对象然后一旦所有对象移动再次循环以检查对象的移动没有​​产生碰撞效果)

我看过很多教程 SO questions such as this related question 但是它们都向您展示了如何在圆形路径上绘制矩形。 Circle 对象似乎没有相同的方法。

如能就我的处理方式提供任何帮助,我们将不胜感激

只需将它们围绕中心以相等的角度放置即可。

Pane pane = new Pane();

double centerX = 300 ;
double centerY = 300 ;
double radius = 30 ;

Circle earth = new Circle(centerX, centerY, radius, Color.web("blue", 0.5));
pane.getChildren().add(earth);

int numMoons = 3 ;
double distance = 100 ;

for (int i = 0 ; i < numMoons; i++) {
    double angle = 2 * i * Math.PI / numMoons ;
    double xOffset = distance * Math.cos(angle);
    double yOffset = distance * Math.sin(angle);
    double x = centerX + xOffset ;
    double y = centerY + yOffset ;
    Circle moon = new Circle(x, y, radius, Color.web("blue", 0.5));
    pane.getChildren().add(moon);
}

或者,将它们全部放在 (centerX + distance, centerY),然后应用不同的旋转:

Pane pane = new Pane();

double centerX = 300 ;
double centerY = 300 ;
double radius = 30 ;

Circle earth = new Circle(centerX, centerY, radius, Color.web("blue", 0.5));
pane.getChildren().add(earth);

int numMoons = 3 ;
double distance = 100 ;

for (int i = 0 ; i < numMoons; i++) {
    double angle = 360.0 * i / numMoons ;

    Circle moon = new Circle(centerX + distance, centerY, radius, Color.web("blue", 0.5));
    Rotate rotate = new Rotate(angle, centerX, centerY);
    moon.getTransforms().add(rotate);
    pane.getChildren().add(moon);
}

或者,如果你想在它们之间定义一个固定的间隙,不难证明增加的角度(以弧度为单位)是

incrementAngle = 2 * Math.asin((2 * moonRadius + gap) / (2 * distance) );

所以你可以做这样的事情

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;

public class CirclesAroundCircle extends Application {

    @Override
    public void start(Stage primaryStage) {
        Pane pane = new Pane();

        double centerX = 300 ;
        double centerY = 300 ;
        double earthRadius = 30 ;
        double moonRadius = 30 ;

        Circle earth = new Circle(centerX, centerY, earthRadius, Color.web("blue", 0.5));
        pane.getChildren().add(earth);

        int numMoons = 3 ;
        double gap = 10 ;
        double distance = 100 ;
        double angleIncrement = 2 * Math.asin((2 * moonRadius + gap) / (2  * distance) );

        for (int i = 0 ; i < numMoons; i++) {

            double angle = Math.toDegrees(angleIncrement * i) ;

            Circle moon = new Circle(centerX + distance, centerY, moonRadius, Color.web("blue", 0.5));
            Rotate rotate = new Rotate(angle, centerX, centerY);
            moon.getTransforms().add(rotate);
            pane.getChildren().add(moon);
        }

        Circle orbit = new Circle(centerX, centerY, distance, Color.TRANSPARENT);
        orbit.setStroke(Color.BLACK);
        pane.getChildren().add(orbit);

        Scene scene = new Scene(pane, 600, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}