目录
题目:**18.27 (科赫雪花分形)
本章给出了思瑞平斯基三角形分形。本练习要编写一个程序,显示另一个称为科赫雪花(Koch snowflake)的分形,这是根据一位著名的瑞典数学家的名字命名的。
- 科赫雪花按如下方式产生:
- 从一个等边三角形开始,将其作为0阶(或0级)科赫分形,如图18-14a所示。
- 三角形中的每条边分成三个相等的线段,以中间的线段作为底边向外画一个等边三角形,产生1阶科赫分形,如图18-14b所示。
- 重复步骤2产生2阶科赫分形,3阶科赫分形,···,如图18-14c-d所示
-
代码示例
编程练习题18_27KochSnowflakeFractal.java
package chapter_18;
import java.util.ArrayList;
import javafx.application.Application;
import javafx.geometry.Point2D;
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_27KochSnowflakeFractal extends Application{
private double WIDTH = 400;
private double HEIGHT = 400;
private TextField tfOrder;
private Pane trianglePane = new Pane();
@Override
public void start(Stage primaryStage) throws Exception {
tfOrder = new TextField();
Label lbOrder = new Label("Enter an order: ",tfOrder);
lbOrder.setContentDisplay(ContentDisplay.RIGHT);
HBox hBox = new HBox(lbOrder);
hBox.setAlignment(Pos.CENTER);
drawBaseTriangle(0);
tfOrder.setOnKeyPressed(e ->{
if(!tfOrder.getText().isEmpty()) {
trianglePane.getChildren().clear();
drawBaseTriangle(Integer.valueOf(tfOrder.getText()));
}
});
BorderPane borderPane = new BorderPane();
borderPane.setCenter(trianglePane);
borderPane.setBottom(hBox);
Scene scene = new Scene(borderPane,WIDTH,HEIGHT+20);
primaryStage.setTitle("编程练习题18_27KochSnowflakeFractal");
primaryStage.setScene(scene);
primaryStage.show();
}
private void drawBaseTriangle(int order) {
double length = HEIGHT - 100;
Line l1 = new Line(WIDTH / 2, 0, (WIDTH / 2) + length * Math.cos(1 * (Math.PI * 2 / 6)),
0 + length * Math.sin(1 * (Math.PI * 2 / 6)));
Line l2 = new Line(l1.getEndX(), l1.getEndY(), l1.getEndX() - length, l1.getEndY());
Line l3 = new Line(l2.getEndX(), l2.getEndY(), l1.getStartX(), l1.getStartY());
trianglePane.getChildren().addAll(l1, l2, l3);
if (order > 0) {
draw(order);
}
}
public void draw(int order) {
if(order == 0)
return;
ArrayList<Line> lines = new ArrayList<Line>();
for(Node node:trianglePane.getChildren()) {
if(node instanceof Line) {
lines.add((Line)node);
}
}
for(Line l:lines) {
drawFractalTriangle(l);
/*double x1 = l.getStartX();
double y1 = l.getStartY();
double x2 = l.getEndX();
double y2 = l.getEndY();
drawFractalTriangle(x1,y1,x2,y2, order);;*/
}
draw(order-1);
}
public void drawFractalTriangle(Line line) {
double DIST = getLength(line) / 3;
double dy = (line.getStartY() - line.getEndY());
double dx = (line.getEndX() - line.getStartX());
double th = Math.atan2(dy, dx);
double x1 = line.getStartX() + DIST * Math.cos(th);
double y1 = line.getStartY() - DIST * Math.sin(th);
double x2 = line.getEndX() + DIST * Math.cos(th + Math.toRadians(180));
double y2 = line.getEndY() - DIST * Math.sin(th + Math.toRadians(180));
double x3 = x2 + DIST * Math.cos(th + Math.toRadians(120));
double y3 = y2 - DIST * Math.sin(th + Math.toRadians(120));
Line l1 = new Line(line.getStartX(), line.getStartY(), x1, y1);
Line l2 = new Line(x2, y2, line.getEndX(), line.getEndY());
Line l3 = new Line(l1.getEndX(), l1.getEndY(), x3, y3);
Line l4 = new Line(l3.getEndX(), l3.getEndY(), x2, y2);
trianglePane.getChildren().remove(line);
trianglePane.getChildren().addAll(l1, l2, l3, l4);
}
private double getLength(Line line) {
return Math.sqrt(Math.pow(line.getEndX() - line.getStartX(), 2) + Math.pow(line.getEndY() - line.getStartY(),
2));
}
public static void main(String[] args) {
Application.launch(args);
}
}
-
输出结果