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; } }