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
|
/*
* Icosahedron.java
* TCSS 491 Computational Worlds
* Phillip Cardon
*/
package tesseract.objects;
import javax.media.j3d.Appearance;
import javax.media.j3d.IndexedQuadArray;
import javax.media.j3d.Material;
import javax.media.j3d.PointArray;
import javax.media.j3d.Shape3D;
import javax.media.j3d.Transform3D;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;
import com.sun.j3d.utils.geometry.GeometryInfo;
import com.sun.j3d.utils.geometry.NormalGenerator;
/**
* Represents a Toroid, or donut like shape.
* @author Phillip Cardon
* @version 0.9a
*/
public class Toroid extends PhysicalObject {
/**
* @param position starting position.
* @param mass of object.
* @param scale mesh scale.
* @param sliceRadius radius of slice "flesh."
* @param sliceDivisions resolution of slice "flesh" circles.
* @param arcRadius Radius of donut circle
* @param arcDivisions resolution of slices on donut.
*/
public Toroid(final Vector3f position, final float mass, final float scale,
final float sliceRadius, final int sliceDivisions,
final float arcRadius, final int arcDivisions) {
super(position, mass);
setShape(buildToroid(scale, sliceRadius, sliceDivisions,
arcRadius, arcDivisions));
}
/**
* Creates donut.
* @param sliceRadius radius of slice "flesh."
* @param sliceDivisions resolution of slice "flesh" circles.
* @param arcRadius Radius of donut circle
* @param arcDivisions resolution of slices on donut.
*/
public Shape3D buildToroid(final float scale, final float sliceRadius, final int sliceDivisions,
final float arcRadius, final int arcDivisions) {
Point3f[][] coordinates = new Point3f[arcDivisions][sliceDivisions];
final float arcAngle = (float) (Math.PI * 2.0);
final float sliceDivisionAngle = 2 * (float) Math.PI / sliceDivisions;
for (int i = 0; i < sliceDivisions; i++) {
coordinates[0][i] = new Point3f(sliceRadius
* (float) Math.cos(i * sliceDivisionAngle), 0f, sliceRadius
* (float) Math.sin(i * sliceDivisionAngle));
}
Transform3D trans3D = new Transform3D();
trans3D.setTranslation(new Vector3f(arcRadius, 0, 0));
Transform3D tmp = new Transform3D();
tmp.rotZ(-arcAngle / (arcDivisions - 1));
trans3D.mul(tmp);
tmp.setIdentity();
tmp.setTranslation(new Vector3f(-arcRadius, 0, 0));
trans3D.mul(tmp);
for (int j = 1; j < arcDivisions; j++) {
for (int i = 0; i < sliceDivisions; i++) {
coordinates[j][i] = new Point3f(coordinates[j - 1][i]);
trans3D.transform(coordinates[j][i]);
coordinates[j][i].scale(scale);
}
}
IndexedQuadArray geometry = new IndexedQuadArray(arcDivisions
* sliceDivisions, PointArray.COORDINATES, 4 * sliceDivisions
* (arcDivisions - 1));
for (int j = 0; j < arcDivisions; j++) {
geometry.setCoordinates(j * sliceDivisions, coordinates[j]);
}
int index = 0;
int last = 0;
for (int j = 0; j < arcDivisions - 2; j++) {
for (int i = 0; i < sliceDivisions; i++) {
geometry.setCoordinateIndex(index++, j * sliceDivisions + i);
geometry.setCoordinateIndex(index++, (j + 1) * sliceDivisions
+ i);
geometry.setCoordinateIndex(index++, (j + 1) * sliceDivisions
+ (i + 1) % sliceDivisions);
geometry.setCoordinateIndex(index++, j * sliceDivisions
+ (i + 1) % sliceDivisions);
}
last = j;
}
last++;
for (int i = 0; i < sliceDivisions; i++) {
geometry.setCoordinateIndex(index++, last * sliceDivisions + i);
geometry.setCoordinateIndex(index++, (0) * sliceDivisions + i);
geometry.setCoordinateIndex(index++, (0) * sliceDivisions + (i + 1)
% sliceDivisions);
geometry.setCoordinateIndex(index++, last * sliceDivisions
+ (i + 1) % sliceDivisions);
}
GeometryInfo gInfo = new GeometryInfo(geometry);
new NormalGenerator().generateNormals(gInfo);
gInfo.convertToIndexedTriangles();
Shape3D shape = new Shape3D(gInfo.getGeometryArray());
Appearance app = new Appearance();
Material mat = new Material();
mat.setDiffuseColor(1, 0, 0);
app.setMaterial(mat);
shape.setAppearance(app);
return shape;
}
}
|