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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
package my3d; import java.util.ArrayList; import javafx.scene.paint.Color; import my3d._math3d.*; public class _shape3d implements Cloneable { public static class _face { public int[] vertex_indices; private Color color; public Color get_color() { return color; } public void set_color(Color color) { this.color = color; } } public _vector[] vertices; public ArrayList<_face> faces = new ArrayList<>(); private Color color; public Color get_color() { return color; } public void set_color(Color color) { this.color = color; } public void add_face(int... indices) { _face face = new _face(); face.vertex_indices = indices; faces.add(face); } // 立方体 public static _shape3d create_box(double x, double y, double z) { _shape3d shape = new _shape3d(); _vector[] vertices = new _vector[8]; for (int i = 0; i < 8; i++) vertices[i] = new _vector( (i % 4 == 0 || i % 4 == 1) ? x : -x, (i < 4) ? y : -y, (i % 4 == 0 || i % 4 == 3) ? z : -z); shape.vertices = vertices; for (int i = 0; i < 4; i++) { int j = (i + 1) % 4; shape.add_face(i, i + 4, j + 4, j); } shape.add_face(0, 1, 2, 3); shape.add_face(7, 6, 5, 4); return shape; } // 球 public static _shape3d create_ball(double radius, int slice_n) { _shape3d shape = new _shape3d(); int round_n = 2 * slice_n; _vector[] vertices = new _vector[round_n * (slice_n - 1) + 2]; double r, y, t; int top, bottom; for (int i = 0; i < slice_n - 1; i++) { r = radius * Math.sin((i + 1) * Math.PI / slice_n); y = radius * Math.cos((i + 1) * Math.PI / slice_n); for (int j = 0; j < round_n; j++) { t = j * 2 * Math.PI / round_n; top = i * round_n; vertices[top + j] = new _vector(r * Math.sin(t), y, r * Math.cos(t)); } } int north = vertices.length - 2, south = vertices.length - 1; vertices[north] = new _vector(0, radius, 0); vertices[south] = new _vector(0, -radius, 0); shape.vertices = vertices; for (int i = 0; i < slice_n - 2; i++) { top = i * round_n; bottom = (i + 1) * round_n; for (int j = 0; j < round_n; j++) { int k = (j + 1) % round_n; shape.add_face(top + j, bottom + j, bottom + k, top + k); } } for (int j = 0; j < round_n; j++) { int k = (j + 1) % round_n; shape.add_face(north, j, k); } bottom = (slice_n - 2) * round_n; for (int j = 0; j < round_n; j++) { int k = (j + 1) % round_n; shape.add_face(south, bottom + k, bottom + j); } return shape; } // 円柱 public static _shape3d create_tube(double r, double h, int n) { _shape3d shape = new _shape3d(); _vector[] vertices = new _vector[2 * n]; double t; for (int i = 0; i < n; i++) { t = i * 2 * Math.PI / n; vertices[i] = new _vector(r * Math.sin(t), h, r * Math.cos(t)); vertices[i + n] = new _vector(r * Math.sin(t), -h, r * Math.cos(t)); } shape.vertices = vertices; for (int i = 0; i < n; i++) { int j = (i + 1) % n; shape.add_face(i, i + n, j + n, j); } int[] top = new int[n], bottom = new int[n]; for (int i = 0; i < n; i++) { top[i] = i; bottom[i] = (n - i) % n + n; } shape.add_face(top); shape.add_face(bottom); return shape; } // 円錐 public static _shape3d create_corn(double r, double h, int n) { _shape3d shape = new _shape3d(); _vector[] vertices = new _vector[n + 1]; double t; for (int i = 0; i < n; i++) { t = i * 2 * Math.PI / n; vertices[i] = new _vector(r * Math.sin(t), -h, r * Math.cos(t)); } vertices[n] = new _vector(0, h, 0); shape.vertices = vertices; for (int i = 0; i < n; i++) shape.add_face(n, i, (i + 1) % n); int[] indices = new int[n]; for (int i = 0; i < n; i++) indices[i] = (n - i) % n; shape.add_face(indices); return shape; } // --- chap7 --- public _vector center; // --- chap10 --- public void transform(_transform tf) { for (int i = 0; i < vertices.length; i++) _math3d.mul(tf, vertices[i], vertices[i]); if (center == null) center = new _vector(tf.position); else _math3d.mul(tf, center, center); } public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { throw new InternalError(); } } }