JavaFX中有什么方法可以获取我在画布上在屏幕上绘制的路径的x,y坐标吗?
我有一个应用程序,可以在画布上绘制一些圆圈,然后将圆圈与线条连接起来。
之后,我可以通过拖动节点来更改圆圈的位置,并且程序始终重新绘制画布上圆圈之间的线条
但现在我想在这些圆圈之间绘制一条四边形曲线。
public void drawQuadCurveOnCanvas(double startX, double startY, double endX, double endY, double controlX, double controlY) {
// Set line width
lineDraw.setLineWidth(Constants.LINE_THICKNESS);
// Set the Color
lineDraw.setStroke(Constants.DRAG_COLOR);
// Start the Path
lineDraw.beginPath();
lineDraw.moveTo(startX, startY);
lineDraw.quadraticCurveTo(controlX, controlY, endX, endY);
// Draw the Path
lineDraw.stroke();
}
Run Code Online (Sandbox Code Playgroud)
我绘制四边形曲线,其中一个圆作为控制点,另外两个圆作为起点和终点坐标。
所以我想沿着我刚刚绘制的四边形曲线获取x,y坐标,这样我就可以在这些坐标上创建一些圆,之后当我将这些圆与线连接时我得到相同的四边形曲线。
我不知道我是否解释得很好,有人知道如何实现我想要的吗?
对于二次 B\xc3\xa9zier 曲线,曲线上的任何点都可以写为
\nx = (1-t)*(1-t)*startX + 2*t*(1-t)*controlX + t*t*endX\ny = (1-t)*(1-t)*startY + 2*t*(1-t)*controlY + t*t*endY\nRun Code Online (Sandbox Code Playgroud)\n其中0\xe2\x89\xa4 t\xe2\x89\xa41。
要沿着二次 B\xc3\xa9zier 曲线绘制多个圆,只需选择 0 到 1 之间的一些值,然后创建一堆圆,其中心由上面公式中的坐标给出。如果控制点可能发生变化,您可以使用绑定。这是一个简单的示例,它创建沿着曲线绑定到坐标的圆,线段的端点依次绑定到圆。
\nimport javafx.application.Application;\nimport javafx.beans.binding.Bindings;\nimport javafx.scene.Scene;\nimport javafx.scene.control.Label;\nimport javafx.scene.control.Spinner;\nimport javafx.scene.layout.BorderPane;\nimport javafx.scene.layout.HBox;\nimport javafx.scene.layout.Pane;\nimport javafx.scene.paint.Color;\nimport javafx.scene.shape.Circle;\nimport javafx.scene.shape.Line;\nimport javafx.stage.Stage;\n\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class BezierCurve extends Application {\n\n private Circle start;\n private Circle end;\n private Circle control;\n private Pane drawingPane;\n private List<Circle> points;\n private List<Line> segments;\n\n private Circle createPoint(double t) {\n Circle c = new Circle(4);\n c.setFill(Color.BLACK);\n c.centerXProperty().bind(Bindings.createDoubleBinding(\n () -> (1-t)*(1-t)*start.getCenterX() \n + 2*t*(1-t)*control.getCenterX() \n + t*t*end.getCenterX(),\n start.centerXProperty(),\n end.centerXProperty(),\n control.centerXProperty())\n );\n c.centerYProperty().bind(Bindings.createDoubleBinding(\n () -> (1-t)*(1-t)*start.getCenterY() \n + 2*t*(1-t)*control.getCenterY() \n + t*t*end.getCenterY(),\n start.centerYProperty(),\n end.centerYProperty(),\n control.centerYProperty())\n );\n return c;\n }\n\n private Line createSegment(Circle start, Circle end) {\n Line segment = new Line();\n segment.startXProperty().bind(start.centerXProperty());\n segment.startYProperty().bind(start.centerYProperty());\n segment.endXProperty().bind(end.centerXProperty());\n segment.endYProperty().bind(end.centerYProperty());\n return segment ;\n }\n\n @Override\n public void start(Stage stage) throws IOException {\n drawingPane = new Pane();\n points = new ArrayList<>();\n segments = new ArrayList<>();\n\n start = new Circle(100,100, 10, Color.GREEN);\n end = new Circle(700, 100, 10, Color.GREEN);\n control = new Circle(400, 500, 10, Color.GREEN);\n\n for (Circle c : List.of(start, end, control)) setUpDragging(c);\n\n Spinner<Integer> numSegmentsSpinner = new Spinner(5, Integer.MAX_VALUE, 25, 5);\n numSegmentsSpinner.setEditable(true);\n numSegmentsSpinner.valueProperty().addListener(\n (obs, oldValue, newValue) -> populatePointsAndSegments(newValue)\n );\n HBox ctrls = new HBox(5, new Label("Number of segments:"), numSegmentsSpinner);\n\n populatePointsAndSegments(numSegmentsSpinner.getValue()); ;\n drawingPane.getChildren().addAll(start, end, control);\n\n BorderPane root = new BorderPane();\n root.setCenter(drawingPane);\n root.setTop(ctrls);\n Scene scene = new Scene(root, 800, 800);\n stage.setScene(scene);\n stage.show();\n }\n\n private void populatePointsAndSegments(int numSegments) {\n\n drawingPane.getChildren().removeAll(points);\n drawingPane.getChildren().removeAll(segments);\n points.clear();\n segments.clear();\n\n Circle previousCircle = start ;\n\n for (int i = 1 ; i < numSegments; i++) {\n double t = 1.0 * i / numSegments ;\n Circle c = createPoint(t);\n points.add(c);\n segments.add(createSegment(previousCircle, c));\n previousCircle = c ;\n }\n segments.add(createSegment(previousCircle, end));\n drawingPane.getChildren().addAll(points);\n drawingPane.getChildren().addAll(segments);\n }\n\n private void setUpDragging(Circle c) {\n c.setOnMouseDragged(e -> {\n c.setCenterX(e.getX());\n c.setCenterY(e.getY());\n });\n }\n\n public static void main(String[] args) {\n launch();\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
379 次 |
| 最近记录: |