如何使用java fx将线连接到圆(而不是中心)

时间:2016-06-25 10:49:34

标签: java javafx graph

我正在使用javafx 我不会将一条线连接到2圈,连接必须是圆的表面而不是中心

当圆圈移动时,线条连接到圆圈中的最佳点。 连接时,线和圆圈不得重叠

谢谢

修改

我正在寻找的解决方案需要

  1. 该线与圆相交,因此切线不是解
  2. 如果线几乎继续,它必须与圆的中心相交

1 个答案:

答案 0 :(得分:1)

假设仅使用centerXcenterY属性修改位置,可以通过简单地将侦听器添加到这些属性来完成。

线的末端可以通过使用圆的中心来确定,该圆的平移距离等于另一个中心方向的半径。

请注意,这不会考虑笔划宽度:

public static Point2D getDirection(Circle c1, Circle c2) {
    return new Point2D(c2.getCenterX() - c1.getCenterX(), c2.getCenterY() - c1.getCenterY()).normalize();
}

public static void connect(Circle c1, Circle c2, Line line) {
    InvalidationListener startInvalidated = observable -> {
        Point2D dir = getDirection(c1, c2);
        Point2D diff = dir.multiply(c1.getRadius());
        line.setStartX(c1.getCenterX() + diff.getX());
        line.setStartY(c1.getCenterY() + diff.getY());
    };
    InvalidationListener endInvalidated = observable -> {
        Point2D dir = getDirection(c2, c1);
        Point2D diff = dir.multiply(c2.getRadius());
        line.setEndX(c2.getCenterX() + diff.getX());
        line.setEndY(c2.getCenterY() + diff.getY());
    };
    c1.centerXProperty().addListener(startInvalidated);
    c1.centerYProperty().addListener(startInvalidated);
    c1.radiusProperty().addListener(startInvalidated);

    startInvalidated.invalidated(null);

    c2.centerXProperty().addListener(endInvalidated);
    c2.centerYProperty().addListener(endInvalidated);
    c2.radiusProperty().addListener(endInvalidated);

    endInvalidated.invalidated(null);
}

@Override
public void start(Stage primaryStage) {
    Circle c1 = new Circle(100, 100, 50, null);
    c1.setStroke(Color.BLUE);

    Circle c2 = new Circle(200, 200, 50, null);
    c2.setStroke(Color.RED);

    Line line = new Line();

    connect(c1, c2, line);

    Pane pane = new Pane(line, c1, c2);

    // demonstrate update during movement
    Timeline timeline = new Timeline(
            new KeyFrame(Duration.ZERO, new KeyValue(c1.centerXProperty(), 100)),
            new KeyFrame(Duration.ZERO, new KeyValue(c1.centerYProperty(), 100)),
            new KeyFrame(Duration.seconds(1), new KeyValue(c1.centerXProperty(), 300)),
            new KeyFrame(Duration.seconds(1), new KeyValue(c1.centerYProperty(), 50)),
            new KeyFrame(Duration.ZERO, new KeyValue(c2.centerXProperty(), 200)),
            new KeyFrame(Duration.ZERO, new KeyValue(c2.centerYProperty(), 200)),
            new KeyFrame(Duration.seconds(1), new KeyValue(c2.centerXProperty(), 100)),
            new KeyFrame(Duration.seconds(1), new KeyValue(c2.centerYProperty(), 100))
    );

    timeline.setCycleCount(Animation.INDEFINITE);
    timeline.setAutoReverse(true);

    timeline.play();

    Scene scene = new Scene(pane, 500, 500);

    primaryStage.setScene(scene);
    primaryStage.show();
}

如果使用更大的笔划宽度,则可能需要考虑它们......

请注意,如果使用完全不透明的颜料填充圆圈并且不修改混合效果,整个问题会变得容易得多,因为线条之后的圆圈将导致在线条顶部绘制圆圈在这种情况下,这意味着连接中心就足够了。