aboutsummaryrefslogtreecommitdiffstats
path: root/src/GearTest/Gear.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/GearTest/Gear.java')
-rw-r--r--src/GearTest/Gear.java397
1 files changed, 397 insertions, 0 deletions
diff --git a/src/GearTest/Gear.java b/src/GearTest/Gear.java
new file mode 100644
index 0000000..fbd0f03
--- /dev/null
+++ b/src/GearTest/Gear.java
@@ -0,0 +1,397 @@
+/*
+ * $RCSfile$
+ *
+ * Copyright (c) 2004 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any
+ * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
+ * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
+ * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
+ * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
+ * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
+ * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
+ * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+ * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
+ * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed, licensed or
+ * intended for use in the design, construction, operation or
+ * maintenance of any nuclear facility.
+ *
+ * $Revision$
+ * $Date$
+ * $State$
+ */
+
+import java.lang.Math.*;
+import javax.media.j3d.*;
+import javax.vecmath.*;
+
+public class Gear extends javax.media.j3d.TransformGroup {
+
+ // Specifiers determining whether to generate outward facing normals or
+ // inward facing normals.
+ static final int OutwardNormals = 1;
+ static final int InwardNormals = -1;
+
+ // The number of teeth in the gear
+ int toothCount;
+
+ // Gear start differential angle. All gears are constructed with the
+ // center of a tooth at Z-axis angle = 0.
+ double gearStartAngle;
+ // The Z-rotation angle to place the tooth center at theta = 0
+ float toothTopCenterAngle;
+ // The Z-rotation angle to place the valley center at theta = 0
+ float valleyCenterAngle;
+ // The angle about Z subtended by one tooth and its associated valley
+ float circularPitchAngle;
+
+ // Increment angles
+ float toothValleyAngleIncrement;
+
+ // Front and rear facing normals for the gear's body
+ final Vector3f frontNormal = new Vector3f(0.0f, 0.0f, -1.0f);
+ final Vector3f rearNormal = new Vector3f(0.0f, 0.0f, 1.0f);
+
+
+ Gear(int toothCount) {
+ this.toothCount = toothCount;
+ }
+
+ void addBodyDisks(float shaftRadius, float bodyOuterRadius,
+ float thickness, Appearance look) {
+ int gearBodySegmentVertexCount; // #(segments) per tooth-unit
+ int gearBodyTotalVertexCount; // #(vertices) in a gear face
+ int gearBodyStripCount[] = new int[1]; // per strip (1) vertex count
+
+ // A ray from the gear center, used in normal calculations
+ float xDirection, yDirection;
+
+ // The x and y coordinates at each point of a facet and at each
+ // point on the gear: at the shaft, the root of the teeth, and
+ // the outer point of the teeth
+ float xRoot0, yRoot0, xShaft0, yShaft0;
+ float xRoot3, yRoot3, xShaft3, yShaft3;
+ float xRoot4, yRoot4, xShaft4, yShaft4;
+
+ // Temporary variables for storing coordinates and vectors
+ Point3f coordinate = new Point3f(0.0f, 0.0f, 0.0f);
+
+ // Gear start differential angle. All gears are constructed with the
+ // center of a tooth at Z-axis angle = 0.
+ double gearStartAngle = -1.0 * toothTopCenterAngle;
+
+ // Temporaries that store start angle for each portion of tooth facet
+ double toothStartAngle, toothTopStartAngle,
+ toothDeclineStartAngle, toothValleyStartAngle,
+ nextToothStartAngle;
+
+ Shape3D newShape;
+ int index;
+
+ // The z coordinates for the body disks
+ final float frontZ = -0.5f * thickness;
+ final float rearZ = 0.5f * thickness;
+
+ /* Construct the gear's front body (front facing torus disk)
+ * __2__
+ * - | - 4
+ * - /| /-
+ * / / | /| \
+ * 0\ / | / / >
+ * \ / | / | >
+ * \ / | / / |
+ * \ / ____|/ | >
+ * \-- --__/ |
+ * 1 3 5
+ *
+ */
+ gearBodySegmentVertexCount = 4;
+ gearBodyTotalVertexCount = 2 + gearBodySegmentVertexCount * toothCount;
+ gearBodyStripCount[0] = gearBodyTotalVertexCount;
+
+ TriangleStripArray frontGearBody
+ = new TriangleStripArray(gearBodyTotalVertexCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS,
+ gearBodyStripCount);
+
+ xDirection = (float)Math.cos(gearStartAngle);
+ yDirection = (float)Math.sin(gearStartAngle);
+ xShaft0 = shaftRadius * xDirection;
+ yShaft0 = shaftRadius * yDirection;
+ xRoot0 = bodyOuterRadius * xDirection;
+ yRoot0 = bodyOuterRadius * yDirection;
+
+ coordinate.set(xRoot0, yRoot0, frontZ);
+ frontGearBody.setCoordinate(0, coordinate);
+ frontGearBody.setNormal(0, frontNormal);
+
+ coordinate.set(xShaft0, yShaft0, frontZ);
+ frontGearBody.setCoordinate(1, coordinate);
+ frontGearBody.setNormal(1, frontNormal);
+
+ for(int count = 0; count < toothCount; count++) {
+ index = 2 + count * 4;
+ toothStartAngle
+ = gearStartAngle + circularPitchAngle * (double)count;
+ toothValleyStartAngle
+ = toothStartAngle + toothValleyAngleIncrement;
+ nextToothStartAngle = toothStartAngle + circularPitchAngle;
+
+ xDirection = (float)Math.cos(toothValleyStartAngle);
+ yDirection = (float)Math.sin(toothValleyStartAngle);
+ xShaft3 = shaftRadius * xDirection;
+ yShaft3 = shaftRadius * yDirection;
+ xRoot3 = bodyOuterRadius * xDirection;
+ yRoot3 = bodyOuterRadius * yDirection;
+
+ xDirection = (float)Math.cos(nextToothStartAngle);
+ yDirection = (float)Math.sin(nextToothStartAngle);
+ xShaft4 = shaftRadius * xDirection;
+ yShaft4 = shaftRadius * yDirection;
+ xRoot4 = bodyOuterRadius * xDirection;
+ yRoot4 = bodyOuterRadius * yDirection;
+
+ coordinate.set(xRoot3, yRoot3, frontZ);
+ frontGearBody.setCoordinate(index, coordinate);
+ frontGearBody.setNormal(index, frontNormal);
+
+ coordinate.set(xShaft3, yShaft3, frontZ);
+ frontGearBody.setCoordinate(index + 1, coordinate);
+ frontGearBody.setNormal(index + 1, frontNormal);
+
+ coordinate.set(xRoot4, yRoot4, frontZ);
+ frontGearBody.setCoordinate(index + 2, coordinate);
+ frontGearBody.setNormal(index + 2, frontNormal);
+
+ coordinate.set(xShaft4, yShaft4, frontZ);
+ frontGearBody.setCoordinate(index + 3, coordinate);
+ frontGearBody.setNormal(index + 3, frontNormal);
+ }
+ newShape = new Shape3D(frontGearBody, look);
+ this.addChild(newShape);
+
+ // Construct the gear's rear body (rear facing torus disc)
+ TriangleStripArray rearGearBody
+ = new TriangleStripArray(gearBodyTotalVertexCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS,
+ gearBodyStripCount);
+ xDirection = (float)Math.cos(gearStartAngle);
+ yDirection = (float)Math.sin(gearStartAngle);
+ xShaft0 = shaftRadius * xDirection;
+ yShaft0 = shaftRadius * yDirection;
+ xRoot0 = bodyOuterRadius * xDirection;
+ yRoot0 = bodyOuterRadius * yDirection;
+
+ coordinate.set(xShaft0, yShaft0, rearZ);
+ rearGearBody.setCoordinate(0, coordinate);
+ rearGearBody.setNormal(0, rearNormal);
+
+ coordinate.set(xRoot0, yRoot0, rearZ);
+ rearGearBody.setCoordinate(1, coordinate);
+ rearGearBody.setNormal(1, rearNormal);
+
+ for(int count = 0; count < toothCount; count++) {
+ index = 2 + count * 4;
+ toothStartAngle
+ = gearStartAngle + circularPitchAngle * (double)count;
+ toothValleyStartAngle
+ = toothStartAngle + toothValleyAngleIncrement;
+ nextToothStartAngle = toothStartAngle + circularPitchAngle;
+
+ xDirection = (float)Math.cos(toothValleyStartAngle);
+ yDirection = (float)Math.sin(toothValleyStartAngle);
+ xShaft3 = shaftRadius * xDirection;
+ yShaft3 = shaftRadius * yDirection;
+ xRoot3 = bodyOuterRadius * xDirection;
+ yRoot3 = bodyOuterRadius * yDirection;
+
+ xDirection = (float)Math.cos(nextToothStartAngle);
+ yDirection = (float)Math.sin(nextToothStartAngle);
+ xShaft4 = shaftRadius * xDirection;
+ yShaft4 = shaftRadius * yDirection;
+ xRoot4 = bodyOuterRadius * xDirection;
+ yRoot4 = bodyOuterRadius * yDirection;
+
+ coordinate.set(xShaft3, yShaft3, rearZ);
+ rearGearBody.setCoordinate(index, coordinate);
+ rearGearBody.setNormal(index, rearNormal);
+
+ coordinate.set(xRoot3, yRoot3, rearZ);
+ rearGearBody.setCoordinate(index + 1, coordinate);
+ rearGearBody.setNormal(index + 1, rearNormal);
+
+ coordinate.set(xShaft4, yShaft4, rearZ);
+ rearGearBody.setCoordinate(index + 2, coordinate);
+ rearGearBody.setNormal(index + 2, rearNormal);
+
+ coordinate.set(xRoot4, yRoot4, rearZ);
+ rearGearBody.setCoordinate(index + 3, coordinate);
+ rearGearBody.setNormal(index + 3, rearNormal);
+
+ }
+ newShape = new Shape3D(rearGearBody, look);
+ this.addChild(newShape);
+ }
+
+ void addCylinderSkins(float shaftRadius, float length,
+ int normalDirection, Appearance look) {
+ int insideShaftVertexCount; // #(vertices) for shaft
+ int insideShaftStripCount[] = new int[1]; // #(vertices) in strip/strip
+ double toothStartAngle, nextToothStartAngle, toothValleyStartAngle;
+
+ // A ray from the gear center, used in normal calculations
+ float xDirection, yDirection;
+
+ // The z coordinates for the body disks
+ final float frontZ = -0.5f * length;
+ final float rearZ = 0.5f * length;
+
+ // Temporary variables for storing coordinates, points, and vectors
+ float xShaft3, yShaft3, xShaft4, yShaft4;
+ Point3f coordinate = new Point3f(0.0f, 0.0f, 0.0f);
+ Vector3f surfaceNormal = new Vector3f();
+
+ Shape3D newShape;
+ int index;
+ int firstIndex;
+ int secondIndex;
+
+
+ /*
+ * Construct gear's inside shaft cylinder
+ * First the tooth's up, flat outer, and down distances
+ * Second the tooth's flat inner distance
+ *
+ * Outward facing vertex order:
+ * 0_______2____4
+ * | /| /|
+ * | / | / |
+ * | / | / |
+ * |/______|/___|
+ * 1 3 5
+ *
+ * Inward facing vertex order:
+ * 1_______3____5
+ * |\ |\ |
+ * | \ | \ |
+ * | \ | \ |
+ * |______\|___\|
+ * 0 2 4
+ */
+ insideShaftVertexCount = 4 * toothCount + 2;
+ insideShaftStripCount[0] = insideShaftVertexCount;
+
+ TriangleStripArray insideShaft
+ = new TriangleStripArray(insideShaftVertexCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS,
+ insideShaftStripCount);
+ xShaft3 = shaftRadius * (float)Math.cos(gearStartAngle);
+ yShaft3 = shaftRadius * (float)Math.sin(gearStartAngle);
+
+ if (normalDirection == OutwardNormals) {
+ surfaceNormal.set(1.0f, 0.0f, 0.0f);
+ firstIndex = 1;
+ secondIndex = 0;
+ } else {
+ surfaceNormal.set(-1.0f, 0.0f, 0.0f);
+ firstIndex = 0;
+ secondIndex = 1;
+ }
+
+ // Coordinate labeled 0 in the strip
+ coordinate.set(shaftRadius, 0.0f, frontZ);
+ insideShaft.setCoordinate(firstIndex, coordinate);
+ insideShaft.setNormal(firstIndex, surfaceNormal);
+
+ // Coordinate labeled 1 in the strip
+ coordinate.set(shaftRadius, 0.0f, rearZ);
+ insideShaft.setCoordinate(secondIndex, coordinate);
+ insideShaft.setNormal(secondIndex, surfaceNormal);
+
+ for(int count = 0; count < toothCount; count++) {
+ index = 2 + count * 4;
+
+ toothStartAngle = circularPitchAngle * (double)count;
+ toothValleyStartAngle
+ = toothStartAngle + toothValleyAngleIncrement;
+ nextToothStartAngle = toothStartAngle + circularPitchAngle;
+
+ xDirection = (float)Math.cos(toothValleyStartAngle);
+ yDirection = (float)Math.sin(toothValleyStartAngle);
+ xShaft3 = shaftRadius * xDirection;
+ yShaft3 = shaftRadius * yDirection;
+ if (normalDirection == OutwardNormals)
+ surfaceNormal.set(xDirection, yDirection, 0.0f);
+ else
+ surfaceNormal.set(-xDirection, -yDirection, 0.0f);
+
+ // Coordinate labeled 2 in the strip
+ coordinate.set(xShaft3, yShaft3, frontZ);
+ insideShaft.setCoordinate(index + firstIndex, coordinate);
+ insideShaft.setNormal(index + firstIndex, surfaceNormal);
+
+ // Coordinate labeled 3 in the strip
+ coordinate.set(xShaft3, yShaft3, rearZ);
+ insideShaft.setCoordinate(index + secondIndex, coordinate);
+ insideShaft.setNormal(index + secondIndex, surfaceNormal);
+
+ xDirection = (float)Math.cos(nextToothStartAngle);
+ yDirection = (float)Math.sin(nextToothStartAngle);
+ xShaft4 = shaftRadius * xDirection;
+ yShaft4 = shaftRadius * yDirection;
+ if (normalDirection == OutwardNormals)
+ surfaceNormal.set(xDirection, yDirection, 0.0f);
+ else
+ surfaceNormal.set(-xDirection, -yDirection, 0.0f);
+
+ // Coordinate labeled 4 in the strip
+ coordinate.set(xShaft4, yShaft4, frontZ);
+ insideShaft.setCoordinate(index + 2 + firstIndex, coordinate);
+ insideShaft.setNormal(index + 2 + firstIndex, surfaceNormal);
+
+ // Coordinate labeled 5 in the strip
+ coordinate.set(xShaft4, yShaft4, rearZ);
+ insideShaft.setCoordinate(index + 2 + secondIndex, coordinate);
+ insideShaft.setNormal(index + 2 + secondIndex, surfaceNormal);
+
+ }
+ newShape = new Shape3D(insideShaft, look);
+ this.addChild(newShape);
+ }
+
+ public float getToothTopCenterAngle() {
+ return toothTopCenterAngle;
+ }
+
+ public float getValleyCenterAngle() {
+ return valleyCenterAngle;
+ }
+
+ public float getCircularPitchAngle() {
+ return circularPitchAngle;
+ }
+}