1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package sample;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class _tree3d extends Application {
public static void main(String... args) {
Application.launch(args);
}
private static final int VIEW_W = 400, VIEW_H = 300;
private GraphicsContext gc;
private _transform tf;
@Override
public void start(Stage stage) throws Exception {
BorderPane pane = new BorderPane();
stage.setScene(new Scene(pane));
Canvas view = new Canvas(VIEW_W, VIEW_H);
gc = view.getGraphicsContext2D();
tf = new _transform();
tf.angle(-10, 15);
tf.position(0, -80, 0);
tf.add_angle_listener(stage.getScene(), () -> { draw(); });
pane.setCenter(view);
draw();
stage.show();
}
private double[][] rot_x(double t) {
t *= Math.PI / 180;
double ct = Math.cos(t), st = Math.sin(t);
return new double[][] { {1, 0, 0}, {0, ct, st}, {0, -st, ct} };
}
private double[][] rot_y(double t) {
t *= Math.PI / 180;
double ct = Math.cos(t), st = Math.sin(t);
return new double[][] { {ct, 0, -st}, {0, 1, 0}, {st, 0, ct} };
}
private double[] mul(double[][] m, double[] v) {
double[] ret_v = new double[3];
for (int i = 0; i < 3; i++)
ret_v[i] = m[0][i] * v[0] + m[1][i] * v[1] + m[2][i] * v[2];
return ret_v;
}
private double[][] mul(double[][] m, double[][] n) {
double[][] ret_m = new double[3][];
for (int i = 0; i < 3; i++)
ret_m[i] = mul(m, n[i]);
return ret_m;
}
private static final int N = 6, A = 22, BRANCH_N = 3;
private double[][] points = new double[N + 1][];
private void add_vector_and_draw(double[] v, int n) {
double[] curr = project(tf.mul(v[0], v[1], v[2]));
points[n] = curr;
if (n == N) return;
double[] prev = points[n + 1];
gc.beginPath();
gc.moveTo(prev[0], prev[1]);
gc.lineTo(curr[0], curr[1]);
gc.stroke();
}
private double[][] curr_m = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
private void draw() {
gc.setTransform(1, 0, 0, 1, 0, 0);
gc.clearRect(0, 0, VIEW_W, VIEW_H);
gc.setTransform(1, 0, 0, -1, VIEW_W / 2, VIEW_H / 2);
double[] p = {0, 0, 0};
add_vector_and_draw(p, N);
tree(p, 45, N);
}
private double[][] enter_x = rot_x(A), exit_x = rot_x(-A);
private double[][] turn_y = rot_y(360.0 / BRANCH_N);
private void tree(double[] p, double len, int n) {
n--;
double[] q = new double[3], y = curr_m[1];
gc.setStroke(Color.BLACK);
for (int i = 0; i < 3; i++)
q[i] = p[i] + y[i] * len;
add_vector_and_draw(q, n);
if (n == 0) return;
for (int i = 0; i < BRANCH_N; i++) {
curr_m = mul(curr_m, enter_x);
tree(q, len * 0.8, n);
curr_m = mul(curr_m, exit_x);
curr_m = mul(curr_m, turn_y);
}
}
private double[] project(double[] v) {
double z = v[2] / 200 + 1;
v[0] *= 1.5 / z; v[1] *= 1.5 / z;
return v;
}
}