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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
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.stage.Stage;
import my3d._line_art3d;
import my3d._math3d;
import my3d._math3d._transform;
import my3d._scene3d;
import my3d._shape3d;
import java.util.ArrayDeque;
public class _dog 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 _line_art3d line_art;
private static final double
BX = 25, BY = 25, BZ = 50,
HX = 18, HY = 18, HZ = 16;
private double[][]
body = {{BX, BY, BZ}, {60, 0, 0}, {0, 0, 0}},
f_pow = {{BX * .2, BY * 1.4, BX * .2}, {-50, 0, -15}, {BX * .3, BY * -.8, BZ * .0}},
h_leg = {{BX * .2, BY * 1.1, BX * .4}, {-55, 0, -5}, {BX * .5, BY * -.1, BZ * .3}},
tail = {{BX * .3, BX * .3, BX * .3}, {-60, 0, 0}, {BX * .0, BY * .2, BZ * .6}},
head = {{HX, HY, HZ}, {-60, 0, 0}, {0, 0, BZ * -.7}},
eye = {{HX * .18, HX * .18, HX * .05}, {0, 0, 0}, {HX * .18, HY * -.05, HZ * -.5}},
ear = {{HX * .35, HX * .35, HZ * .1}, {-10, 30, 40}, {HX * .25, HY * .6, HZ * .2}},
maxi = {{HX * .3, HY * .15, HZ * .8}, {0, 0, 0}, {HX * .0, HY * -.25, HZ * -.5}},
muzz = {{HX * .1, HX * .1, HX * .1}, {45, 0, 0}, {HX * .0, HY * .08, HZ * -.4}},
chin = {{HX * .2, HY * .1, HZ * .6}, {-25, 0, 0}, {HX * .0, HY * -.35, HZ * -.5}},
tang = {{HX * .15, HY * .05, HZ * .1}, {-15, 0, 0}, {HX * .0, HY * .05, HZ * -.2}};
private ArrayDeque<_transform> tf_stack = new ArrayDeque<>();
private ArrayDeque<_shape3d> sh_stack = new ArrayDeque<>();
@Override
public void start(Stage stage) throws Exception {
BorderPane pane = new BorderPane();
Scene scene = new Scene(pane);
stage.setScene(scene);
Canvas view = new Canvas(VIEW_W, VIEW_H);
pane.setCenter(view);
gc = view.getGraphicsContext2D();
// 情景の設定
_scene3d scene3d = new _scene3d();
scene3d.angle(-15, 30); scene3d.position(5, -8, 120);
scene3d.add_angle_listener(stage.getScene(), () -> draw());
// ラインアート情報の作成
line_art = new _line_art3d(gc, VIEW_W, VIEW_H, scene3d.get_transform());
// ルートパートの作成
_transform tf_root = new _transform(0, 0, 0, 0, 0, 0);
_shape3d sh_empty = new _shape3d(null, null, null);
tf_stack.push(tf_root);
sh_stack.push(sh_empty);
// 犬の作成
push_part(body);
add_part(f_pow); add_part(h_leg); add_part(tail);
push_part(head);
add_part(eye); add_part(ear);
push_part(maxi); add_part(muzz);
pop_part();
push_part(chin); add_part(tang);
draw();
stage.show();
}
private void draw() {
line_art.draw();
}
private void push_part(double[][] part_data) {
_transform tf_parent = tf_stack.peek();
_shape3d sh_parent = sh_stack.peek();
_transform tf = get_part_transform(part_data, tf_parent);
_shape3d sh = get_part_shape(part_data, tf);
line_art.add_shape(sh);
line_art.add_shape(_shape3d.border(sh, sh_parent));
tf_stack.push(tf);
sh_stack.push(sh);
}
private void add_part(double[][] part_data) {
_transform tf_parent = tf_stack.peek();
_shape3d sh_parent = sh_stack.peek();
do {
_transform tf = get_part_transform(part_data, tf_parent);
_shape3d sh = get_part_shape(part_data, tf);
line_art.add_shape(sh);
line_art.add_shape(_shape3d.border(sh, sh_parent));
reverse_x(part_data);
} while (is_reverse_x(part_data));
}
private void pop_part() {
tf_stack.pop();
sh_stack.pop();
}
private _transform get_part_transform(
double[][] part_data, _transform tf_parent
) {
double[] rot = part_data[1], pos = part_data[2];
_transform tf = new _transform(
rot[0], rot[1], rot[2],
pos[0], pos[1], pos[2]);
return _math3d.mul(tf_parent, tf, tf);
}
private _shape3d get_part_shape(
double[][] part_data, _transform tf
) {
double[] sca = part_data[0];
return _shape3d.create_box(sca[0], sca[1], sca[2], tf);
}
private void reverse_x(double[][] part_data) {
double[] rot = part_data[1], pos = part_data[2];
rot[1] *= -1; rot[2] *= -1;
pos[0] *= -1;
}
private boolean is_reverse_x(double[][] part_data) {
double[] pos = part_data[2];
return pos[0] < 0;
}
}