需要在整个区域均匀布置节点

Need to arrange node evenly all over the area

我有以下代码遍历我的模型列表然后创建 该地区的节点

        final AtomicDouble x = new AtomicDouble(0.0);
        final AtomicDouble y = new AtomicDouble(0.0);
        bottomAnchorPane.getChildren().clear();
        modelSet.getModels().stream().forEach(model -> {
            final DraggableNode node = new DraggableNode();
            node.setType(DragIconType.MODEL);
            node.setTitle(model.getName());
            bottomAnchorPane.getChildren().add(node);
            node.relocateToPoint(new Point2D(x.get(), y.get()));
            x.addAndGet(10 + Math.random() * (50 - 10));
            y.addAndGet(20 + Math.random() * (300 - 50));
        });

public class DraggableNode extends AnchorPane {

   public void relocateToPoint(final Point2D p) {
        final Point2D localCoords = getParent().sceneToLocal(p);
        relocate((int) (localCoords.getX() - dragOffset.getX()),
                (int) (localCoords.getY() - dragOffset.getY()));
    }
}

现在好像关注了。我想将它均匀地分布在整个区域。

node.relocateToPoint(new Point2D(x.get(), y.get())); 

是此处采用节点位置 x,y 的关键,但不知何故我的随机化效果不佳。有没有更好的办法。

这里是一个如何在随机位置重新定位节点的示例:

import javafx.application.Application;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class RandomRelocateTest extends Application {

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

    @Override
    public void start(Stage primaryStage) throws Exception {

        BorderPane box = new BorderPane();

        AnchorPane mainPane = new AnchorPane();

        addPanes(mainPane);

        Button button = new Button("Randomize Location");
        button.setOnAction(e -> {
            randomizeLoc(mainPane);
        });

        box.setCenter(mainPane);
        box.setBottom(button);

        Scene scene = new Scene(box, 550, 450);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    // Add 15 rectangle to a specific location
    private void addPanes(AnchorPane mainPane) {
        for (int i = 0; i < 15; i++) {
            Rectangle rec = new Rectangle();
            rec.setStyle("-fx-border-color: black");
            rec.setWidth(20);
            rec.setHeight(20);

            rec.relocate(50 + 20 * i + 5 * i, 10);

            mainPane.getChildren().add(rec);
        }
    }

    private void randomizeLoc(AnchorPane mainPane) {

        double myMargins = 30;
        double rectangleSize = 20;

        double paneWidth = mainPane.getWidth() - myMargins - rectangleSize;
        double paneHeight = mainPane.getHeight() - myMargins - rectangleSize;

        // Get all the Nodes inside the AnchorPane
        ObservableList<Node> childrens = mainPane.getChildren();
        for (Node n : childrens) {

            double x = myMargins + Math.random() * (paneWidth);
            double y = myMargins + Math.random() * (paneHeight);

            n.relocate(x, y);
        }
    }
}

看看 randomizeLoc(),我将添加一些图片来解释我的计算逻辑。

编辑:上面有一个 AnchorPane 的例子。实际尺寸是实心矩形,我们要绘制对象的区域是虚线矩形。现在 Math.random 会给你一个介于 0.0 和 1.0 之间的数字。首先,我们要确保我们在虚线区域内,所以左上角位于 (20,20)(如果我们设置 marginValue = 20),右下角位于 (width-20,height- 20).所以如果我们想正好在虚线区域内,我们需要像这样设置 X 和 y:

x = 20 + Math.random() * (width-20);
y = 20 + Math.random() * (height-20);

不幸的是,如果我们从 Math.random() 中得到 1.0(或接近 1.0),这意味着矩形的起点将位于 x,y = (width-20,height-20 ) 并且矩形的大小为 20x20,因此矩形(或其一部分,取决于 random() 的值)将在虚线区域之外。所以我们需要从宽度和高度中减去实际的矩形大小。因此我们需要:

x = 20 + Math.random() * (width -20 - 20); // if we say the rect is 20x20
y = 20 + Math.random() * (height -20 - 20);

所以我们的区域现在是虚线减去的虚线区域。