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% 正确的,但是,从粗略的一瞥来看它看起来是正确的(或足够接近),似乎可以大多数情况下都是我。
我有一个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% 正确的,但是,从粗略的一瞥来看它看起来是正确的(或足够接近),似乎可以大多数情况下都是我。