JavaFX - 如何计算路径对象的中心?

JavaFX - How to calculate the center of a path object?

我有一个Path object composed of PathElements

所有5个对象都以相同的样式绘制。 - (移动到、LineTo、ArcTo、LineTo、ArcTo)

我需要一种可以计算整个 Path 对象中心的方法。

而且他们可以计算所有五个对象。

思路是计算两个圆弧的圆心(arcTo),创建一个连接这些圆心的Line,这个Line的圆心就是圆心整个 Path 对象。

但是,我不知道如何简单地计算它。卡在圆心的计算上了

我需要独立于对象创建来计算它,但我可以访问对象 - 我可以获得关于它们的所有信息。

会有更好的方法来做到这一点(通过适当地应用正确的数学方程式)。但是,您可以利用路径转换系统来获得所需的答案,就像在以下答案中所做的那样:

  • How to write text along a Bezier Curve?

绿点是圆弧的中点。 红点是路径中心的中点。

根据定义(我理解的):

根据描述,他试图定位两个路径元素(arcTo 元素)的中心。我假设路径元素中心点是沿弧的等距点。然后,他将计算这两个路径元素中心点之间的假想线的中点。这条线的中点就是 Yoda 定义为路径的中心(这是他最终试图计算的)。

import javafx.animation.Interpolator;
import javafx.animation.PathTransition;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;
import javafx.util.Duration;

public class ArcCenter extends Application {
    @Override
    public void start(Stage stage) {
        Path arcPath1 = new Path(
                new MoveTo(50, 25),
                new ArcTo(30, 15, 0, 100, 50, false, true)
        );
        arcPath1.setStrokeWidth(2);
        arcPath1.setStroke(Color.ORANGE);

        Path arcPath2 = new Path(
                new MoveTo(30, 40),
                new ArcTo(10, 5, 0, 60, 60, false, true)
        );
        arcPath2.setStrokeWidth(2);
        arcPath2.setStroke(Color.HOTPINK);

        Circle arcMidpoint1 = calcMidpoint(arcPath1, Color.FORESTGREEN);
        Circle arcMidpoint2 = calcMidpoint(arcPath2, Color.FORESTGREEN);

        Group group = new Group(
                arcPath1,
                arcPath2,
                arcMidpoint1,
                arcMidpoint2
        );

        arcMidpoint2.translateYProperty().addListener((observable, oldValue, newValue) -> {
            Path line = new Path(
                    new MoveTo(arcMidpoint1.getTranslateX(), arcMidpoint1.getTranslateY()),
                    new LineTo(arcMidpoint2.getTranslateX(), arcMidpoint2.getTranslateY())
            );
            line.setStroke(Color.LIGHTBLUE);
            line.setStrokeWidth(2);
            group.getChildren().add(line);
            line.toBack();

            Circle lineMidpoint = calcMidpoint(line, Color.RED.darker());
            lineMidpoint.translateYProperty().addListener((o, old, newV) -> {
                System.out.println(
                    "Path center point: ( " +
                    lineMidpoint.getTranslateX() + ", " +
                    lineMidpoint.getTranslateY() + " )"
                );
            });
            group.getChildren().add(lineMidpoint);
        });

        group.setScaleX(2);
        group.setScaleY(2);

        stage.setScene(
                new Scene(
                        new StackPane(new Group(group)),
                        300, 200,
                        Color.rgb(35, 39, 50)
                )
        );
        stage.show();
    }

    private Circle calcMidpoint(Path path, Color midpointColor) {
        Circle midpoint = new Circle(3, midpointColor);

        PathTransition pathTransition = new PathTransition(Duration.minutes(10), path, midpoint);
        pathTransition.setOrientation(PathTransition.OrientationType.NONE);
        pathTransition.setInterpolator(Interpolator.LINEAR);
        pathTransition.jumpTo(pathTransition.getDuration().divide(2));
        pathTransition.play();

        midpoint.translateYProperty().addListener((observable, oldValue, newValue) -> {
            pathTransition.stop();
        });

        return midpoint;
    }

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

我完全没有声称上面提出的解决方案在它计算的值中实际上是 100% 正确的,但是,从粗略的一瞥来看它看起来是正确的(或足够接近),似乎可以大多数情况下都是我。