summaryrefslogtreecommitdiff
path: root/src/tesseract/objects/Ellipsoid.java
blob: d2a752f2b56ae4717fd2c6bcf8eea40a06f9ed11 (plain)
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
/*
 * Class Ellipsoid
 * TCSS 491 Computational Worlds
 * Steve Bradshaw
 */

package tesseract.objects;

import java.awt.Color;

import javax.media.j3d.Appearance;
import javax.media.j3d.ColoringAttributes;
import javax.media.j3d.Material;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Color3f;
import javax.vecmath.Matrix3f;
import javax.vecmath.Vector3f;

import com.sun.j3d.utils.geometry.Sphere;

/**
 * This class creates an ellipsoid using the formula 
 * (x/a)^2  +  (y/b)^2  +  (z/c)^2 = 1 using a matrix3f transformation
 * on a basic Sphere.  This class sets 'a' to a constant 1.0 and allows
 * 'b' and 'c'  to alter the ellipsoid's shape along with the radius field 
 * Sphere.  Since this is a sphere, the normals are already calculated.
 * 
 * @author Steve Bradshaw
 * @version 1 Feb 2011
 */
public class Ellipsoid extends PhysicalObject {
	
	/**
	 * Default mass.
	 */
	//private static final float DEFAULT_MASS = Float.POSITIVE_INFINITY;
	private static final float DEFAULT_MASS = 10;
	
	/**
	 * Default Object color.
	 */
	private static final Color3f DEFAULT_COLOR = new Color3f(.9f, .05f, .05f);
	
	/**
	 * User definable color.
	 */
	private final Color3f myColor; 
	
	/**
	 * Number of divisions in the sphere.
	 */
	private static final int DEFAULT_DIVISIONS = 50;
	
	
	/**
	 * Create a new Ellipsoid.
	 * 
	 * @param position Initial position.
	 * @param mass Initial mass.
	 * @param radius the radius of the base sphere.
	 * @param primflags an int for the base spere primflags.
	 * @param divisions an in for the shape divisions.
	 * @param appearance an Appearance object.
	 * @param b a float for the b portion of the ellipsoid formula.
	 * @param c a float for the c portion of the ellipsoid formula.
	 * @param theColor of the object.
	 */
	public Ellipsoid(final Vector3f position, final float mass,
			final float radius,	final int primflags, final int divisions,
			final Appearance appearance, final float b, final float c) {
		super(position, mass);
		myColor = new Color3f();
		appearance.getMaterial().getDiffuseColor(myColor);
		setShape(createShape(radius, primflags, appearance, divisions, b, c));
		
		final float rSq = radius * radius;
		final float a = 1.0f;
		
		if (inverseMass != 0) {
			inverseInertiaTensor.m00 = 1f / 5 / inverseMass * (b * rSq + c * rSq);
			inverseInertiaTensor.m11 = 1f / 5 / inverseMass * (a * rSq + c * rSq);
			inverseInertiaTensor.m22 = 1f / 5 / inverseMass * (a * rSq + b * rSq);
			inverseInertiaTensor.invert();
		}
		updateTransformGroup();
	}
	
	/**
	 * Create a new Ellipsoid.
	 * @author Phillip Cardon
	 * @param position Initial position.
	 * @param mass mass of ellipsoid
	 * @param radius a float for the size of the base sphere.
	 * @param theColor of the object.
	 */
	public Ellipsoid(final Vector3f position, final float mass,
			final float radius) {
		this(position, mass, radius, DEFAULT_COLOR.get());
	}
	
	/**
	 * Create a new Ellipsoid.
	 * @author Phillip Cardon
	 * @param position Initial position.
	 * @param mass mass of ellipsoid
	 * @param radius a float for the size of the base sphere.
	 * @param theColor of the object.
	 */
	public Ellipsoid(final Vector3f position, final float mass,
			final float radius, Color theColor) {
		super(position, mass);
		myColor = new Color3f(theColor);
		final float rSq = radius * radius;
		final float a = 1.0f;
		final float b = 1.0f;
		final float c = 1.5f;
		
		
		setShape(createDefaultEllipsoid(radius, a, b, c));
		
		if (inverseMass != 0) {
			inverseInertiaTensor.m00 = 1f / 5 / inverseMass * (b * rSq + c * rSq);
			inverseInertiaTensor.m11 = 1f / 5 / inverseMass * (a * rSq + c * rSq);
			inverseInertiaTensor.m22 = 1f / 5 / inverseMass * (a * rSq + b * rSq);
			inverseInertiaTensor.invert();
		}
		updateTransformGroup();
	}
	
	/**
	 * Create a new Ellipsoid.
	 * 
	 * @param position Initial position.
	 * @param radius a float for the size of the base sphere.
	 */
	public Ellipsoid(final Vector3f position, final float radius) {
		this(position, radius, DEFAULT_COLOR.get());
	}
	
	/**
	 * Create a new Ellipsoid.
	 * 
	 * @param position Initial position.
	 * @param radius a float for the size of the base sphere.
	 * @param theColor of object.
	 */
	public Ellipsoid(final Vector3f position, final float radius,
			final Color theColor) {
		super(position, DEFAULT_MASS);
		myColor = new Color3f(theColor);
		final float rSq = radius * radius;
		final float a = 1.0f;
		final float b = 1.0f;
		final float c = 1.5f;
		
		
		setShape(createDefaultEllipsoid(radius, a, b, c));
		
		if (inverseMass != 0) {
			inverseInertiaTensor.m00 = 1f / 5 / inverseMass * (b * rSq + c * rSq);
			inverseInertiaTensor.m11 = 1f / 5 / inverseMass * (a * rSq + c * rSq);
			inverseInertiaTensor.m22 = 1f / 5 / inverseMass * (a * rSq + b * rSq);
			inverseInertiaTensor.invert();
		}
		updateTransformGroup();
	}
	
	/**
	 * This creates a default Ellipsoid for the 2 argument constructor.
	 * @param radius the size of the ellipsoid
	 * @param a float in the ellipsoid formula.
	 * @param b float in the ellipsoid formula.
	 * @param c float in the ellipsoid formula.
	 * @return TransformGroup with the shape.
	 */
	private TransformGroup createDefaultEllipsoid(final float radius, final float a,
			final float b, final float c) {
		Appearance meshApp = new Appearance();
		Material surface = new Material();
		surface.setDiffuseColor(myColor);
		meshApp.setMaterial(surface);
		meshApp.setColoringAttributes(new ColoringAttributes(myColor,
				ColoringAttributes.NICEST));
		Sphere sphere = new Sphere(radius, new Sphere().getPrimitiveFlags() | Sphere.ENABLE_GEOMETRY_PICKING,
				DEFAULT_DIVISIONS, meshApp);
		Transform3D tmp = new Transform3D();
		tmp.set(new Matrix3f(a, 0.0f, 0.0f, 0.0f, b, 0.0f, 0.0f, 0.0f, c));
		TransformGroup tg = new TransformGroup(tmp);
		tg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
		tg.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
		tg.addChild(sphere);
		return tg;
	}
	
	/**
	 * This method creates multiple ellipsoidial shapes.
	 * 
	 * @param radius a float for the size of the base sphere
	 * @param primflags an int for the base sphere
	 * @param appearance an Appearance object
	 * @param divisions an int for the number of divisons
	 * @param b a float for the y axis transform
	 * @param c a float for the z axis transfrom
	 * @return TransformGroup with the shape.
	 */
	private TransformGroup createShape(final float radius, final int primflags,
			final Appearance appearance, final int divisions, final float b,
			final float c) {
		
		Sphere sphere = new Sphere(radius, primflags, divisions, appearance);
		Transform3D tmp = new Transform3D();
		tmp.set(new Matrix3f(1.0f, 0.0f, 0.0f, 0.0f, b, 0.0f, 0.0f, 0.0f, c));
		TransformGroup tg = new TransformGroup(tmp);
		tg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
		tg.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
		tg.addChild(sphere);
		
		return tg;
	}
}