目录
题目:**18.35(H 树分形)
代码示例
代码解释
输出结果
题目:**18.35(H 树分形)
一个H 树分形(本章开始部分介绍过,如图18-1)如下定义:
1)从字母H开始。H的三条线长度一样,如图 18-1a 所示。
2)字母H(以它的 sans-serif 字体形式,H)有四个端点。以这四个端点为中心位置绘制一个 1 阶 H 树,如图18-1b所示。这些H的大小是包括这四个端点的 H的一半。
3)重复步骤2来创建2阶,3阶,…,n阶的H树,如图18-1c-d所示。
编写程序,绘制如图18-1所示的H树
-
代码示例
编程练习题18_35HTreeFractal.java
package chapter_18;
import javafx.application.Application;
import javafx.collections.ObservableList;
import javafx.css.Size;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.ContentDisplay;
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.shape.Line;
import javafx.stage.Stage;
public class 编程练习题18_35HTreeFractal extends Application{
private double WIDTH = 500;
private double HEIGHT = 500;
private TextField tfOrder = new TextField();
private int orderOfFractal = 0;
Pane drawPane = new Pane();
ObservableList<Node> FRACTAL = drawPane.getChildren();
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
Label lbOrder = new Label("Enter an Order",tfOrder);
lbOrder.setContentDisplay(ContentDisplay.RIGHT);
HBox hBox2 = new HBox(lbOrder,tfOrder);
hBox2.setAlignment(Pos.CENTER);
drawPane.setCenterShape(true);
drawPane.setPrefHeight(HEIGHT-hBox2.getHeight());
drawPane.setPrefHeight(WIDTH);
BorderPane borderPane = new BorderPane();
borderPane.setCenter(drawPane);
borderPane.setBottom(hBox2);
Scene scene = new Scene(borderPane,500, 500);
primaryStage.setTitle(getClass().getName());
primaryStage.setScene(scene);
primaryStage.show();
tfOrder.setOnKeyPressed(e ->{
FRACTAL.clear();
if(!tfOrder.getText().isEmpty()) {
orderOfFractal = Integer.parseInt(tfOrder.getText());
double baseHSize = HEIGHT/2 - 50;
double centerX = drawPane.getWidth()/2-baseHSize/2;
double centerY = drawPane.getHeight()/2-baseHSize/2;
drawHTree(orderOfFractal,centerX,centerY,baseHSize);
}
});
}
private void drawH(double x,double y,double size) {
Line leftVert = new Line(x,y,x,y+size);
Line rightVert = new Line(x+size,y,x+size,y+size);
Line horizontal = new Line(x,y+size/2.0,x+size,y+size/2.0);
FRACTAL.addAll(leftVert,rightVert,horizontal);
}
private void drawHTree(int order,double x,double y,double size) {
drawH(x, y, size);
if(order > 0) {
drawHTree(order-1, x-size/4, y-size/4, size/2);
drawHTree(order-1, x+size-size/4, y-size/4, size/2);
drawHTree(order-1, x-size/4, y+size-size/4, size/2);
drawHTree(order-1, x+size-size/4, y+size-size/4, size/2);
}
}
}
-
代码解释
- 初始化界面和变量:
- 创建一个
Application
类的子类编程练习题18_35HTreeFractal
,用于JavaFX应用程序。 - 初始化窗口大小(
WIDTH
和HEIGHT
),并创建一个文本字段tfOrder
用于输入分形的阶数(即递归深度)。 - 创建一个
Pane
(drawPane
)作为画布,用于绘制H树分形。
- 创建一个
- 构建用户界面:
- 使用
BorderPane
布局,将drawPane
置于中心,用于显示分形图。 - 在底部添加一个包含标签和文本字段的
HBox
,允许用户输入分形的阶数。 - 设置文本字段的按键监听器,以便在输入变化时更新分形图。
- 使用
- 绘制H树分形:
- 定义
drawH
方法,该方法接收x、y坐标和大小作为参数,绘制一个"H"形状(由两条垂直线和一条水平线组成)。 - 定义
drawHTree
方法,这是一个递归方法,根据阶数(order
)、中心坐标(x
、y
)和大小(size
)绘制H树。如果阶数大于0,则在每个"H"的四个末端递归地绘制更小的"H"。
- 定义
- 响应文本字段的输入:
- 在文本字段的按键监听器中,检查用户是否输入了非空且有效的整数值。
- 如果是,则清除当前画布上的所有内容,并根据新的阶数重新绘制H树分形。
- 设置画布属性:
- 尝试设置
drawPane
的centerShape
属性(注意:Pane
类没有centerShape
方法,这可能是个错误或误解。正确的做法可能是通过布局管理来调整子节点的位置)。 - 设置
drawPane
的首选高度和宽度,但注意这里对setPrefHeight
的调用被重复了,并且第二次调用使用了错误的参数(应该是HEIGHT
而非WIDTH
)。
- 尝试设置
-
输出结果