目录
题目:18.36 (思瑞平斯基三角形)
编写一个程序,让用户输入一个阶数,然后显示填充的思瑞平斯基三角形,如图18-18所示。
-
代码示例
对原来的代码注释掉第66行即可,在order为0时不填充(默认填充黑色)
编程练习题18_36SierpinskiTriangle.java
package chapter_18;
import javafx.application.Application;
import javafx.geometry.Point2D;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.Polygon;
import javafx.stage.Stage;
public class 编程练习题18_36SierpinskiTriangle extends Application{
@Override
public void start(Stage primaryStage) throws Exception {
SierpinskiTrianglePane trianglePane = new SierpinskiTrianglePane();
TextField tfOrder = new TextField();
tfOrder.setOnAction(e ->trianglePane.setOrder(Integer.parseInt(tfOrder.getText())));
tfOrder.setPrefColumnCount(4);
tfOrder.setAlignment(Pos.BOTTOM_RIGHT);
HBox hBox = new HBox(10);
hBox.getChildren().addAll(new Label("Enter an order: "),tfOrder);
hBox.setAlignment(Pos.CENTER);
BorderPane borderPane = new BorderPane();
borderPane.setCenter(trianglePane);
borderPane.setBottom(hBox);
Scene scene = new Scene(borderPane, 200, 210);
primaryStage.setTitle("程序清单18_9SierpinskiTriangle");
primaryStage.setScene(scene);
primaryStage.show();
}
static class SierpinskiTrianglePane extends Pane{
private int order = 0;
public void setOrder(int order) {
this.order = order;
paint();
}
SierpinskiTrianglePane(){
}
protected void paint() {
Point2D p1 = new Point2D(getWidth()/2, 10);
Point2D p2 = new Point2D(10, getHeight() - 10);
Point2D p3 = new Point2D(getWidth()-10, getHeight() -10);
this.getChildren().clear();
displayTriangles(order,p1,p2,p3);
}
private void displayTriangles(int order,Point2D p1,
Point2D p2,Point2D p3) {
if(order < 0) {
System.out.println("Order must be non-negative");
return;
}
if(order == 0){
Polygon triangle = new Polygon();
triangle.getPoints().addAll(p1.getX(),p1.getY()
,p2.getX(),p2.getY(),p3.getX(),p3.getY());
triangle.setStroke(Color.BLACK);
//triangle.setFill(Color.WHITE);//注释掉这一行即可
this.getChildren().add(triangle);
}else {
Point2D p12 = p1.midpoint(p2);
Point2D p23 = p2.midpoint(p3);
Point2D p31 = p3.midpoint(p1);
displayTriangles(order-1, p1, p12, p31);
displayTriangles(order-1, p12, p2, p23);
displayTriangles(order-1, p31, p23, p3);
}
}
}
public static void main(String[] args) {
Application.launch(args);
}
}
-
代码逻辑
1. 应用程序入口
编程练习题18_36SierpinskiTriangle
类继承自Application
,是JavaFX应用程序的入口。start(Stage primaryStage)
方法是JavaFX应用程序的启动方法,它负责设置和显示图形用户界面(GUI)。
2. GUI设置
- 创建一个
SierpinskiTrianglePane
实例(一个自定义的Pane
),用于绘制谢尔宾斯基三角形。 - 创建一个
TextField
,允许用户输入分形的迭代次数(order
)。 - 创建一个
Label
,用于指示用户输入的内容。 - 将
Label
和TextField
添加到HBox
中,并将HBox
设置为BorderPane
的底部区域。 - 将
SierpinskiTrianglePane
设置为BorderPane
的中心区域。 - 创建一个
Scene
,包含BorderPane
,并将其设置为Stage
的场景。 - 显示
Stage
,即显示整个窗口。
3. 事件处理
- 当用户在
TextField
中输入一个值并按下回车键(或触发其他动作)时,setOnAction
事件处理器被调用。 - 事件处理器从
TextField
中获取文本,尝试将其转换为整数,并调用SierpinskiTrianglePane
的setOrder
方法。
4. 绘制逻辑
SierpinskiTrianglePane
类中的setOrder
方法更新迭代次数(order
),并调用paint
方法重新绘制图形。paint
方法首先计算三个顶点的位置(基于Pane
的宽度和高度),然后清除现有的子节点,并调用displayTriangles
方法进行递归绘制。displayTriangles
方法是一个递归函数,它根据当前的order
值决定是绘制一个基本的等边三角形(当order
为0时),还是递归地在三个更小的三角形中绘制谢尔宾斯基三角形(当order
大于0时)。- 如果
order
为0,则创建一个Polygon
对象,将其顶点设置为计算出的三个点,并添加到Pane
的子节点中。 - 如果
order
大于0,则计算三个新顶点的中点(这些中点是原三角形各边中点),并递归地在这些中点形成的三个子三角形中调用displayTriangles
方法。
- 如果
5. 递归绘制
- 递归调用
displayTriangles
时,order
值每次减少1,直到order
为0,此时开始绘制基本三角形。 - 通过递归地移除每个三角形的中心部分,最终形成了谢尔宾斯基三角形的图案。
-
输出结果