aboutsummaryrefslogtreecommitdiffstats
path: root/src/GearTest/SpurGear.java
diff options
context:
space:
mode:
authorkcr <kcr@28c7f869-5b4e-e670-f602-82bfaf57f300>2004-06-09 03:28:13 +0000
committerkcr <kcr@28c7f869-5b4e-e670-f602-82bfaf57f300>2004-06-09 03:28:13 +0000
commit53ebfcc5ad5554b67d2287f8b02c22ec8405af0f (patch)
tree70c8fabf4cbef5a9d2a50735c4e502d56ce156da /src/GearTest/SpurGear.java
parent4dead457a59220406dd9fcd40997d7a7b27571b0 (diff)
Initial creation of j3d-examples sources in CVS repository
Diffstat (limited to 'src/GearTest/SpurGear.java')
-rw-r--r--src/GearTest/SpurGear.java556
1 files changed, 556 insertions, 0 deletions
diff --git a/src/GearTest/SpurGear.java b/src/GearTest/SpurGear.java
new file mode 100644
index 0000000..c294503
--- /dev/null
+++ b/src/GearTest/SpurGear.java
@@ -0,0 +1,556 @@
+/*
+ * $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 SpurGear extends Gear {
+
+ float toothTopAngleIncrement;
+ float toothDeclineAngleIncrement;
+
+ float rootRadius;
+ float outsideRadius;
+
+ //The angle subtended by the ascending or descending portion of a tooth
+ float circularToothEdgeAngle;
+ // The angle subtended by a flat (either a tooth top or a valley
+ // between teeth
+ float circularToothFlatAngle;
+
+ /**
+ * internal constructor for SpurGear, used by subclasses to establish
+ * SpurGear's required state
+ * @return a new spur gear that contains sufficient information to
+ * continue building
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param toothToValleyAngleRatio the ratio of the angle subtended by the
+ * tooth to the angle subtended by the valley (must be <= .25)
+ */
+ SpurGear(int toothCount, float pitchCircleRadius,
+ float addendum, float dedendum, float toothToValleyAngleRatio) {
+
+ super(toothCount);
+
+ // The angle about Z subtended by one tooth and its associated valley
+ circularPitchAngle = (float)(2.0 * Math.PI / (double)toothCount);
+
+ // The angle subtended by a flat (either a tooth top or a valley
+ // between teeth
+ circularToothFlatAngle = circularPitchAngle * toothToValleyAngleRatio;
+
+ //The angle subtended by the ascending or descending portion of a tooth
+ circularToothEdgeAngle = circularPitchAngle/2.0f -
+ circularToothFlatAngle;
+
+ // Increment angles
+ toothTopAngleIncrement = circularToothEdgeAngle;
+ toothDeclineAngleIncrement
+ = toothTopAngleIncrement + circularToothFlatAngle;
+ toothValleyAngleIncrement
+ = toothDeclineAngleIncrement + circularToothEdgeAngle;
+
+ // Differential angles for offsetting to the center of tooth's top
+ // and valley
+ toothTopCenterAngle
+ = toothTopAngleIncrement + circularToothFlatAngle/2.0f;
+ valleyCenterAngle
+ = toothValleyAngleIncrement + circularToothFlatAngle/2.0f;
+
+ // Gear start differential angle. All gears are constructed with the
+ // center of a tooth at Z-axis angle = 0.
+ gearStartAngle = -1.0 * toothTopCenterAngle;
+
+ // The radial distance to the root and top of the teeth, respectively
+ rootRadius = pitchCircleRadius - dedendum;
+ outsideRadius = pitchCircleRadius + addendum;
+
+ // Allow this object to spin. etc.
+ this.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+ }
+
+ /**
+ * Construct a SpurGear;
+ * @return a new spur gear that conforms to the input paramters
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param shaftRadius radius of hole at center
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ */
+ public SpurGear(int toothCount, float pitchCircleRadius, float shaftRadius,
+ float addendum, float dedendum, float gearThickness) {
+ this(toothCount, pitchCircleRadius, shaftRadius, addendum, dedendum,
+ gearThickness, gearThickness, 0.25f, null);
+ }
+
+ /**
+ * Construct a SpurGear;
+ * @return a new spur gear that conforms to the input paramters
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param shaftRadius radius of hole at center
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ * @param look the gear's appearance
+ */
+ public SpurGear(int toothCount, float pitchCircleRadius, float shaftRadius,
+ float addendum, float dedendum, float gearThickness,
+ Appearance look) {
+ this(toothCount, pitchCircleRadius, shaftRadius, addendum, dedendum,
+ gearThickness, gearThickness, 0.25f, look);
+ }
+
+ /**
+ * Construct a SpurGear;
+ * @return a new spur gear that conforms to the input paramters
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param shaftRadius radius of hole at center
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ * @param toothTipThickness thickness of the tip of the tooth
+ * @param look the gear's appearance
+ */
+ public SpurGear(int toothCount, float pitchCircleRadius, float shaftRadius,
+ float addendum, float dedendum, float gearThickness,
+ float toothTipThickness, Appearance look) {
+ this(toothCount, pitchCircleRadius, shaftRadius, addendum, dedendum,
+ gearThickness, toothTipThickness, 0.25f, look);
+ }
+
+ /**
+ * Construct a SpurGear;
+ * @return a new spur gear that conforms to the input paramters
+ * @param toothCount number of teeth
+ * @param pitchCircleRadius radius at center of teeth
+ * @param shaftRadius radius of hole at center
+ * @param addendum distance from pitch circle to top of teeth
+ * @param dedendum distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ * @param toothTipThickness thickness of the tip of the tooth
+ * @param toothToValleyAngleRatio the ratio of the angle subtended by the
+ * tooth to the angle subtended by the valley (must be <= .25)
+ * @param look the gear's appearance object
+ */
+ public SpurGear(int toothCount, float pitchCircleRadius, float shaftRadius,
+ float addendum, float dedendum, float gearThickness,
+ float toothTipThickness, float toothToValleyAngleRatio,
+ Appearance look) {
+
+ this(toothCount, pitchCircleRadius, addendum, dedendum,
+ toothToValleyAngleRatio);
+
+ // Generate the gear's body disks
+ addBodyDisks(shaftRadius, rootRadius, gearThickness, look);
+
+ // Generate the gear's interior shaft
+ addCylinderSkins(shaftRadius, gearThickness, InwardNormals, look);
+
+ // Generate the gear's teeth
+ addTeeth(pitchCircleRadius, rootRadius,
+ outsideRadius, gearThickness, toothTipThickness,
+ toothToValleyAngleRatio, look);
+ }
+
+ /**
+ * Construct a SpurGear's teeth by adding the teeth shape nodes
+ * @param pitchCircleRadius radius at center of teeth
+ * @param rootRadius distance from pitch circle to top of teeth
+ * @param outsideRadius distance from pitch circle to root of teeth
+ * @param gearThickness thickness of the gear
+ * @param toothTipThickness thickness of the tip of the tooth
+ * @param toothToValleyAngleRatio the ratio of the angle subtended by the
+ * tooth to the angle subtended by the valley (must be <= .25)
+ * @param look the gear's appearance object
+ */
+ void addTeeth(float pitchCircleRadius, float rootRadius,
+ float outsideRadius, float gearThickness,
+ float toothTipThickness, float toothToValleyAngleRatio,
+ Appearance look) {
+ int index;
+ Shape3D newShape;
+
+ // Temporaries that store start angle for each portion of tooth facet
+ double toothStartAngle, toothTopStartAngle,
+ toothDeclineStartAngle, toothValleyStartAngle,
+ nextToothStartAngle;
+
+ // 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;
+ float xOuter1, yOuter1;
+ float xOuter2, yOuter2;
+ float xRoot3, yRoot3;
+ float xRoot4, yRoot4;
+
+ // The z coordinates for the gear
+ final float frontZ = -0.5f * gearThickness;
+ final float rearZ = 0.5f * gearThickness;
+
+ // The z coordinates for the tooth tip of the gear
+ final float toothTipFrontZ = -0.5f * toothTipThickness;
+ final float toothTipRearZ = 0.5f * toothTipThickness;
+
+ int toothFacetVertexCount; // #(vertices) per tooth facet
+ int toothFacetCount; // #(facets) per tooth
+ int toothFaceTotalVertexCount; // #(vertices) in all teeth
+ int toothFaceStripCount[] = new int[toothCount];
+ // per tooth vertex count
+ int topVertexCount; // #(vertices) for teeth tops
+ int topStripCount[] = new int[1]; // #(vertices) in strip/strip
+
+ // Front and rear facing normals for the teeth faces
+ Vector3f frontToothNormal = new Vector3f(0.0f, 0.0f, -1.0f);
+ Vector3f rearToothNormal = new Vector3f(0.0f, 0.0f, 1.0f);
+
+ // Normals for teeth tops up incline, tooth top, and down incline
+ Vector3f leftNormal = new Vector3f(-1.0f, 0.0f, 0.0f);
+ Vector3f rightNormal = new Vector3f(1.0f, 0.0f, 0.0f);
+ Vector3f outNormal = new Vector3f(1.0f, 0.0f, 0.0f);
+ Vector3f inNormal = new Vector3f(-1.0f, 0.0f, 0.0f);
+
+ // Temporary variables for storing coordinates and vectors
+ Point3f coordinate = new Point3f(0.0f, 0.0f, 0.0f);
+ Point3f tempCoordinate1 = new Point3f(0.0f, 0.0f, 0.0f);
+ Point3f tempCoordinate2 = new Point3f(0.0f, 0.0f, 0.0f);
+ Point3f tempCoordinate3 = new Point3f(0.0f, 0.0f, 0.0f);
+ Vector3f tempVector1 = new Vector3f(0.0f, 0.0f, 0.0f);
+ Vector3f tempVector2 = new Vector3f(0.0f, 0.0f, 0.0f);
+
+ /* Construct the gear's front facing teeth facets
+ * 0______2
+ * / /\
+ * / / \
+ * / / \
+ * //___________\
+ * 1 3
+ */
+ toothFacetVertexCount = 4;
+ toothFaceTotalVertexCount = toothFacetVertexCount * toothCount;
+ for(int i = 0; i < toothCount; i++)
+ toothFaceStripCount[i] = toothFacetVertexCount;
+
+ TriangleStripArray frontGearTeeth
+ = new TriangleStripArray(toothFaceTotalVertexCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS,
+ toothFaceStripCount);
+
+ for(int count = 0; count < toothCount; count++) {
+ index = count * toothFacetVertexCount;
+
+ toothStartAngle
+ = gearStartAngle + circularPitchAngle * (double)count;
+ toothTopStartAngle = toothStartAngle + toothTopAngleIncrement;
+ toothDeclineStartAngle
+ = toothStartAngle + toothDeclineAngleIncrement;
+ toothValleyStartAngle
+ = toothStartAngle + toothValleyAngleIncrement;
+
+ xRoot0 = rootRadius * (float)Math.cos(toothStartAngle);
+ yRoot0 = rootRadius * (float)Math.sin(toothStartAngle);
+ xOuter1 = outsideRadius * (float)Math.cos(toothTopStartAngle);
+ yOuter1 = outsideRadius * (float)Math.sin(toothTopStartAngle);
+ xOuter2 = outsideRadius * (float)Math.cos(toothDeclineStartAngle);
+ yOuter2 = outsideRadius * (float)Math.sin(toothDeclineStartAngle);
+ xRoot3 = rootRadius * (float)Math.cos(toothValleyStartAngle);
+ yRoot3 = rootRadius * (float)Math.sin(toothValleyStartAngle);
+
+ tempCoordinate1.set(xRoot0, yRoot0, frontZ);
+ tempCoordinate2.set(xRoot3, yRoot3, frontZ);
+ tempVector1.sub(tempCoordinate2, tempCoordinate1);
+
+ tempCoordinate2.set(xOuter1, yOuter1, toothTipFrontZ);
+ tempVector2.sub(tempCoordinate2, tempCoordinate1);
+
+ frontToothNormal.cross(tempVector1, tempVector2);
+ frontToothNormal.normalize();
+
+ coordinate.set(xOuter1, yOuter1, toothTipFrontZ);
+ frontGearTeeth.setCoordinate(index, coordinate);
+ frontGearTeeth.setNormal(index, frontToothNormal);
+
+ coordinate.set(xRoot0, yRoot0, frontZ);
+ frontGearTeeth.setCoordinate(index + 1, coordinate);
+ frontGearTeeth.setNormal(index + 1, frontToothNormal);
+
+ coordinate.set(xOuter2, yOuter2, toothTipFrontZ);
+ frontGearTeeth.setCoordinate(index + 2, coordinate);
+ frontGearTeeth.setNormal(index + 2, frontToothNormal);
+
+ coordinate.set(xRoot3, yRoot3, frontZ);
+ frontGearTeeth.setCoordinate(index + 3, coordinate);
+ frontGearTeeth.setNormal(index + 3, frontToothNormal);
+ }
+ newShape = new Shape3D(frontGearTeeth, look);
+ this.addChild(newShape);
+
+ /* Construct the gear's rear facing teeth facets (Using Quads)
+ * 1______2
+ * / \
+ * / \
+ * / \
+ * /____________\
+ * 0 3
+ */
+ toothFacetVertexCount = 4;
+ toothFaceTotalVertexCount = toothFacetVertexCount * toothCount;
+
+ QuadArray rearGearTeeth
+ = new QuadArray(toothCount * toothFacetVertexCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS);
+
+ for(int count = 0; count < toothCount; count++) {
+
+ index = count * toothFacetVertexCount;
+ toothStartAngle =
+ gearStartAngle + circularPitchAngle * (double)count;
+ toothTopStartAngle = toothStartAngle + toothTopAngleIncrement;
+ toothDeclineStartAngle
+ = toothStartAngle + toothDeclineAngleIncrement;
+ toothValleyStartAngle = toothStartAngle + toothValleyAngleIncrement;
+
+ xRoot0 = rootRadius * (float)Math.cos(toothStartAngle);
+ yRoot0 = rootRadius * (float)Math.sin(toothStartAngle);
+ xOuter1 = outsideRadius * (float)Math.cos(toothTopStartAngle);
+ yOuter1 = outsideRadius * (float)Math.sin(toothTopStartAngle);
+ xOuter2 = outsideRadius * (float)Math.cos(toothDeclineStartAngle);
+ yOuter2 = outsideRadius * (float)Math.sin(toothDeclineStartAngle);
+ xRoot3 = rootRadius * (float)Math.cos(toothValleyStartAngle);
+ yRoot3 = rootRadius * (float)Math.sin(toothValleyStartAngle);
+
+ tempCoordinate1.set(xRoot0, yRoot0, rearZ);
+ tempCoordinate2.set(xRoot3, yRoot3, rearZ);
+ tempVector1.sub(tempCoordinate2, tempCoordinate1);
+ tempCoordinate2.set(xOuter1, yOuter1, toothTipRearZ);
+ tempVector2.sub(tempCoordinate2, tempCoordinate1);
+ rearToothNormal.cross(tempVector2, tempVector1);
+ rearToothNormal.normalize();
+
+ coordinate.set(xRoot0, yRoot0, rearZ);
+ rearGearTeeth.setCoordinate(index, coordinate);
+ rearGearTeeth.setNormal(index, rearToothNormal);
+
+ coordinate.set(xOuter1, yOuter1, toothTipRearZ);
+ rearGearTeeth.setCoordinate(index + 1, coordinate);
+ rearGearTeeth.setNormal(index + 1, rearToothNormal);
+
+ coordinate.set(xOuter2, yOuter2, toothTipRearZ);
+ rearGearTeeth.setCoordinate(index + 2, coordinate);
+ rearGearTeeth.setNormal(index + 2, rearToothNormal);
+
+ coordinate.set(xRoot3, yRoot3, rearZ);
+ rearGearTeeth.setCoordinate(index + 3, coordinate);
+ rearGearTeeth.setNormal(index + 3, rearToothNormal);
+
+ }
+ newShape = new Shape3D(rearGearTeeth, look);
+ this.addChild(newShape);
+
+ /*
+ * Construct the gear's top teeth faces (As seen from above)
+ * Root0 Outer1 Outer2 Root3 Root4 (RearZ)
+ * 0_______3 2_______5 4_______7 6_______9
+ * |0 3| |4 7| |8 11| |12 15|
+ * | | | | | | | |
+ * | | | | | | | |
+ * |1_____2| |5_____6| |9____10| |13___14|
+ * 1 2 3 4 5 6 7 8
+ * Root0 Outer1 Outer2 Root3 Root4 (FrontZ)
+ *
+ * Quad 0123 uses a left normal
+ * Quad 2345 uses an out normal
+ * Quad 4567 uses a right normal
+ * Quad 6789 uses an out normal
+ */
+ topVertexCount = 8 * toothCount + 2;
+ topStripCount[0] = topVertexCount;
+
+ toothFacetVertexCount = 4;
+ toothFacetCount = 4;
+
+ QuadArray topGearTeeth
+ = new QuadArray(toothCount * toothFacetVertexCount
+ * toothFacetCount,
+ GeometryArray.COORDINATES
+ | GeometryArray.NORMALS);
+
+ for(int count = 0; count < toothCount; count++) {
+ index = count * toothFacetCount * toothFacetVertexCount;
+ toothStartAngle = gearStartAngle +
+ circularPitchAngle * (double)count;
+ toothTopStartAngle = toothStartAngle + toothTopAngleIncrement;
+ toothDeclineStartAngle
+ = toothStartAngle + toothDeclineAngleIncrement;
+ toothValleyStartAngle
+ = toothStartAngle + toothValleyAngleIncrement;
+ nextToothStartAngle = toothStartAngle + circularPitchAngle;
+
+ xRoot0 = rootRadius * (float)Math.cos(toothStartAngle);
+ yRoot0 = rootRadius * (float)Math.sin(toothStartAngle);
+ xOuter1 = outsideRadius * (float)Math.cos(toothTopStartAngle);
+ yOuter1 = outsideRadius * (float)Math.sin(toothTopStartAngle);
+ xOuter2 = outsideRadius * (float)Math.cos(toothDeclineStartAngle);
+ yOuter2 = outsideRadius * (float)Math.sin(toothDeclineStartAngle);
+ xRoot3 = rootRadius * (float)Math.cos(toothValleyStartAngle);
+ yRoot3 = rootRadius * (float)Math.sin(toothValleyStartAngle);
+ xRoot4 = rootRadius * (float)Math.cos(nextToothStartAngle);
+ yRoot4 = rootRadius * (float)Math.sin(nextToothStartAngle);
+
+ // Compute normal for quad 1
+ tempCoordinate1.set(xRoot0, yRoot0, frontZ);
+ tempCoordinate2.set(xOuter1, yOuter1, toothTipFrontZ);
+ tempVector1.sub(tempCoordinate2, tempCoordinate1);
+ leftNormal.cross(frontNormal, tempVector1);
+ leftNormal.normalize();
+
+ // Coordinate labeled 0 in the quad
+ coordinate.set(xRoot0, yRoot0, rearZ);
+ topGearTeeth.setCoordinate(index, coordinate);
+ topGearTeeth.setNormal(index, leftNormal);
+
+ // Coordinate labeled 1 in the quad
+ coordinate.set(tempCoordinate1);
+ topGearTeeth.setCoordinate(index + 1, coordinate);
+ topGearTeeth.setNormal(index + 1, leftNormal);
+
+ // Coordinate labeled 2 in the quad
+ topGearTeeth.setCoordinate(index + 2, tempCoordinate2);
+ topGearTeeth.setNormal(index + 2, leftNormal);
+ topGearTeeth.setCoordinate(index + 5, tempCoordinate2);
+
+ // Coordinate labeled 3 in the quad
+ coordinate.set(xOuter1, yOuter1, toothTipRearZ);
+ topGearTeeth.setCoordinate(index + 3, coordinate);
+ topGearTeeth.setNormal(index + 3, leftNormal);
+ topGearTeeth.setCoordinate(index + 4, coordinate);
+
+ // Compute normal for quad 2
+ tempCoordinate1.set(xOuter1, yOuter1, toothTipFrontZ);
+ tempCoordinate2.set(xOuter2, yOuter2, toothTipFrontZ);
+ tempVector1.sub(tempCoordinate2, tempCoordinate1);
+ outNormal.cross(frontNormal, tempVector1);
+ outNormal.normalize();
+
+ topGearTeeth.setNormal(index + 4, outNormal);
+ topGearTeeth.setNormal(index + 5, outNormal);
+
+ // Coordinate labeled 4 in the quad
+ topGearTeeth.setCoordinate(index + 6, tempCoordinate2);
+ topGearTeeth.setNormal(index + 6, outNormal);
+ topGearTeeth.setCoordinate(index + 9, tempCoordinate2);
+
+ // Coordinate labeled 5 in the quad
+ coordinate.set(xOuter2, yOuter2, toothTipRearZ);
+ topGearTeeth.setCoordinate(index + 7, coordinate);
+ topGearTeeth.setNormal(index + 7, outNormal);
+ topGearTeeth.setCoordinate(index + 8, coordinate);
+
+ // Compute normal for quad 3
+ tempCoordinate1.set(xOuter2, yOuter2, toothTipFrontZ);
+ tempCoordinate2.set(xRoot3, yRoot3, frontZ);
+ tempVector1.sub(tempCoordinate2, tempCoordinate1);
+ rightNormal.cross(frontNormal, tempVector1);
+ rightNormal.normalize();
+
+ topGearTeeth.setNormal(index + 8, rightNormal);
+ topGearTeeth.setNormal(index + 9, rightNormal);
+
+ // Coordinate labeled 7 in the quad
+ topGearTeeth.setCoordinate(index + 10, tempCoordinate2);
+ topGearTeeth.setNormal(index + 10, rightNormal);
+ topGearTeeth.setCoordinate(index + 13, tempCoordinate2);
+
+ // Coordinate labeled 6 in the quad
+ coordinate.set(xRoot3, yRoot3, rearZ);
+ topGearTeeth.setCoordinate(index + 11, coordinate);
+ topGearTeeth.setNormal(index + 11, rightNormal);
+ topGearTeeth.setCoordinate(index + 12, coordinate);
+
+ // Compute normal for quad 4
+ tempCoordinate1.set(xRoot3, yRoot3, frontZ);
+ tempCoordinate2.set(xRoot4, yRoot4, frontZ);
+ tempVector1.sub(tempCoordinate2, tempCoordinate1);
+ outNormal.cross(frontNormal, tempVector1);
+ outNormal.normalize();
+
+ topGearTeeth.setNormal(index + 12, outNormal);
+ topGearTeeth.setNormal(index + 13, outNormal);
+
+ // Coordinate labeled 9 in the quad
+ topGearTeeth.setCoordinate(index + 14, tempCoordinate2);
+ topGearTeeth.setNormal(index + 14, outNormal);
+
+ // Coordinate labeled 8 in the quad
+ coordinate.set(xRoot4, yRoot4, rearZ);
+ topGearTeeth.setCoordinate(index + 15, coordinate);
+ topGearTeeth.setNormal(index + 15, outNormal);
+
+ // Prepare for the loop by computing the new normal
+ toothTopStartAngle
+ = nextToothStartAngle + toothTopAngleIncrement;
+ xOuter1 = outsideRadius * (float)Math.cos(toothTopStartAngle);
+ yOuter1 = outsideRadius * (float)Math.sin(toothTopStartAngle);
+
+ tempCoordinate1.set(xRoot4, yRoot4, toothTipFrontZ);
+ tempCoordinate2.set(xOuter1, yOuter1, toothTipFrontZ);
+ tempVector1.sub(tempCoordinate2, tempCoordinate1);
+ leftNormal.cross(frontNormal, tempVector1);
+ leftNormal.normalize();
+ }
+ newShape = new Shape3D(topGearTeeth, look);
+ this.addChild(newShape);
+ }
+
+}