001: /*
002: * $RCSfile: SpurGear.java,v $
003: *
004: * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * - Redistribution of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * - Redistribution in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * Neither the name of Sun Microsystems, Inc. or the names of
019: * contributors may be used to endorse or promote products derived
020: * from this software without specific prior written permission.
021: *
022: * This software is provided "AS IS," without a warranty of any
023: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
024: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
025: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
026: * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
027: * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
028: * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
029: * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
030: * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
031: * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
032: * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
033: * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
034: * POSSIBILITY OF SUCH DAMAGES.
035: *
036: * You acknowledge that this software is not designed, licensed or
037: * intended for use in the design, construction, operation or
038: * maintenance of any nuclear facility.
039: *
040: * $Revision: 1.2 $
041: * $Date: 2007/02/09 17:21:39 $
042: * $State: Exp $
043: */
044:
045: package org.jdesktop.j3d.examples.gears;
046:
047: import java.lang.Math.*;
048: import javax.media.j3d.*;
049: import javax.vecmath.*;
050:
051: public class SpurGear extends Gear {
052:
053: float toothTopAngleIncrement;
054: float toothDeclineAngleIncrement;
055:
056: float rootRadius;
057: float outsideRadius;
058:
059: //The angle subtended by the ascending or descending portion of a tooth
060: float circularToothEdgeAngle;
061: // The angle subtended by a flat (either a tooth top or a valley
062: // between teeth
063: float circularToothFlatAngle;
064:
065: /**
066: * internal constructor for SpurGear, used by subclasses to establish
067: * SpurGear's required state
068: * @return a new spur gear that contains sufficient information to
069: * continue building
070: * @param toothCount number of teeth
071: * @param pitchCircleRadius radius at center of teeth
072: * @param addendum distance from pitch circle to top of teeth
073: * @param dedendum distance from pitch circle to root of teeth
074: * @param toothToValleyAngleRatio the ratio of the angle subtended by the
075: * tooth to the angle subtended by the valley (must be <= .25)
076: */
077: SpurGear(int toothCount, float pitchCircleRadius, float addendum,
078: float dedendum, float toothToValleyAngleRatio) {
079:
080: super (toothCount);
081:
082: // The angle about Z subtended by one tooth and its associated valley
083: circularPitchAngle = (float) (2.0 * Math.PI / (double) toothCount);
084:
085: // The angle subtended by a flat (either a tooth top or a valley
086: // between teeth
087: circularToothFlatAngle = circularPitchAngle
088: * toothToValleyAngleRatio;
089:
090: //The angle subtended by the ascending or descending portion of a tooth
091: circularToothEdgeAngle = circularPitchAngle / 2.0f
092: - circularToothFlatAngle;
093:
094: // Increment angles
095: toothTopAngleIncrement = circularToothEdgeAngle;
096: toothDeclineAngleIncrement = toothTopAngleIncrement
097: + circularToothFlatAngle;
098: toothValleyAngleIncrement = toothDeclineAngleIncrement
099: + circularToothEdgeAngle;
100:
101: // Differential angles for offsetting to the center of tooth's top
102: // and valley
103: toothTopCenterAngle = toothTopAngleIncrement
104: + circularToothFlatAngle / 2.0f;
105: valleyCenterAngle = toothValleyAngleIncrement
106: + circularToothFlatAngle / 2.0f;
107:
108: // Gear start differential angle. All gears are constructed with the
109: // center of a tooth at Z-axis angle = 0.
110: gearStartAngle = -1.0 * toothTopCenterAngle;
111:
112: // The radial distance to the root and top of the teeth, respectively
113: rootRadius = pitchCircleRadius - dedendum;
114: outsideRadius = pitchCircleRadius + addendum;
115:
116: // Allow this object to spin. etc.
117: this .setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
118: }
119:
120: /**
121: * Construct a SpurGear;
122: * @return a new spur gear that conforms to the input paramters
123: * @param toothCount number of teeth
124: * @param pitchCircleRadius radius at center of teeth
125: * @param shaftRadius radius of hole at center
126: * @param addendum distance from pitch circle to top of teeth
127: * @param dedendum distance from pitch circle to root of teeth
128: * @param gearThickness thickness of the gear
129: */
130: public SpurGear(int toothCount, float pitchCircleRadius,
131: float shaftRadius, float addendum, float dedendum,
132: float gearThickness) {
133: this (toothCount, pitchCircleRadius, shaftRadius, addendum,
134: dedendum, gearThickness, gearThickness, 0.25f, null);
135: }
136:
137: /**
138: * Construct a SpurGear;
139: * @return a new spur gear that conforms to the input paramters
140: * @param toothCount number of teeth
141: * @param pitchCircleRadius radius at center of teeth
142: * @param shaftRadius radius of hole at center
143: * @param addendum distance from pitch circle to top of teeth
144: * @param dedendum distance from pitch circle to root of teeth
145: * @param gearThickness thickness of the gear
146: * @param look the gear's appearance
147: */
148: public SpurGear(int toothCount, float pitchCircleRadius,
149: float shaftRadius, float addendum, float dedendum,
150: float gearThickness, Appearance look) {
151: this (toothCount, pitchCircleRadius, shaftRadius, addendum,
152: dedendum, gearThickness, gearThickness, 0.25f, look);
153: }
154:
155: /**
156: * Construct a SpurGear;
157: * @return a new spur gear that conforms to the input paramters
158: * @param toothCount number of teeth
159: * @param pitchCircleRadius radius at center of teeth
160: * @param shaftRadius radius of hole at center
161: * @param addendum distance from pitch circle to top of teeth
162: * @param dedendum distance from pitch circle to root of teeth
163: * @param gearThickness thickness of the gear
164: * @param toothTipThickness thickness of the tip of the tooth
165: * @param look the gear's appearance
166: */
167: public SpurGear(int toothCount, float pitchCircleRadius,
168: float shaftRadius, float addendum, float dedendum,
169: float gearThickness, float toothTipThickness,
170: Appearance look) {
171: this (toothCount, pitchCircleRadius, shaftRadius, addendum,
172: dedendum, gearThickness, toothTipThickness, 0.25f, look);
173: }
174:
175: /**
176: * Construct a SpurGear;
177: * @return a new spur gear that conforms to the input paramters
178: * @param toothCount number of teeth
179: * @param pitchCircleRadius radius at center of teeth
180: * @param shaftRadius radius of hole at center
181: * @param addendum distance from pitch circle to top of teeth
182: * @param dedendum distance from pitch circle to root of teeth
183: * @param gearThickness thickness of the gear
184: * @param toothTipThickness thickness of the tip of the tooth
185: * @param toothToValleyAngleRatio the ratio of the angle subtended by the
186: * tooth to the angle subtended by the valley (must be <= .25)
187: * @param look the gear's appearance object
188: */
189: public SpurGear(int toothCount, float pitchCircleRadius,
190: float shaftRadius, float addendum, float dedendum,
191: float gearThickness, float toothTipThickness,
192: float toothToValleyAngleRatio, Appearance look) {
193:
194: this (toothCount, pitchCircleRadius, addendum, dedendum,
195: toothToValleyAngleRatio);
196:
197: // Generate the gear's body disks
198: addBodyDisks(shaftRadius, rootRadius, gearThickness, look);
199:
200: // Generate the gear's interior shaft
201: addCylinderSkins(shaftRadius, gearThickness, InwardNormals,
202: look);
203:
204: // Generate the gear's teeth
205: addTeeth(pitchCircleRadius, rootRadius, outsideRadius,
206: gearThickness, toothTipThickness,
207: toothToValleyAngleRatio, look);
208: }
209:
210: /**
211: * Construct a SpurGear's teeth by adding the teeth shape nodes
212: * @param pitchCircleRadius radius at center of teeth
213: * @param rootRadius distance from pitch circle to top of teeth
214: * @param outsideRadius distance from pitch circle to root of teeth
215: * @param gearThickness thickness of the gear
216: * @param toothTipThickness thickness of the tip of the tooth
217: * @param toothToValleyAngleRatio the ratio of the angle subtended by the
218: * tooth to the angle subtended by the valley (must be <= .25)
219: * @param look the gear's appearance object
220: */
221: void addTeeth(float pitchCircleRadius, float rootRadius,
222: float outsideRadius, float gearThickness,
223: float toothTipThickness, float toothToValleyAngleRatio,
224: Appearance look) {
225: int index;
226: Shape3D newShape;
227:
228: // Temporaries that store start angle for each portion of tooth facet
229: double toothStartAngle, toothTopStartAngle, toothDeclineStartAngle, toothValleyStartAngle, nextToothStartAngle;
230:
231: // The x and y coordinates at each point of a facet and at each
232: // point on the gear: at the shaft, the root of the teeth, and
233: // the outer point of the teeth
234: float xRoot0, yRoot0;
235: float xOuter1, yOuter1;
236: float xOuter2, yOuter2;
237: float xRoot3, yRoot3;
238: float xRoot4, yRoot4;
239:
240: // The z coordinates for the gear
241: final float frontZ = -0.5f * gearThickness;
242: final float rearZ = 0.5f * gearThickness;
243:
244: // The z coordinates for the tooth tip of the gear
245: final float toothTipFrontZ = -0.5f * toothTipThickness;
246: final float toothTipRearZ = 0.5f * toothTipThickness;
247:
248: int toothFacetVertexCount; // #(vertices) per tooth facet
249: int toothFacetCount; // #(facets) per tooth
250: int toothFaceTotalVertexCount; // #(vertices) in all teeth
251: int toothFaceStripCount[] = new int[toothCount];
252: // per tooth vertex count
253: int topVertexCount; // #(vertices) for teeth tops
254: int topStripCount[] = new int[1]; // #(vertices) in strip/strip
255:
256: // Front and rear facing normals for the teeth faces
257: Vector3f frontToothNormal = new Vector3f(0.0f, 0.0f, -1.0f);
258: Vector3f rearToothNormal = new Vector3f(0.0f, 0.0f, 1.0f);
259:
260: // Normals for teeth tops up incline, tooth top, and down incline
261: Vector3f leftNormal = new Vector3f(-1.0f, 0.0f, 0.0f);
262: Vector3f rightNormal = new Vector3f(1.0f, 0.0f, 0.0f);
263: Vector3f outNormal = new Vector3f(1.0f, 0.0f, 0.0f);
264: Vector3f inNormal = new Vector3f(-1.0f, 0.0f, 0.0f);
265:
266: // Temporary variables for storing coordinates and vectors
267: Point3f coordinate = new Point3f(0.0f, 0.0f, 0.0f);
268: Point3f tempCoordinate1 = new Point3f(0.0f, 0.0f, 0.0f);
269: Point3f tempCoordinate2 = new Point3f(0.0f, 0.0f, 0.0f);
270: Point3f tempCoordinate3 = new Point3f(0.0f, 0.0f, 0.0f);
271: Vector3f tempVector1 = new Vector3f(0.0f, 0.0f, 0.0f);
272: Vector3f tempVector2 = new Vector3f(0.0f, 0.0f, 0.0f);
273:
274: /* Construct the gear's front facing teeth facets
275: * 0______2
276: * / /\
277: * / / \
278: * / / \
279: * //___________\
280: * 1 3
281: */
282: toothFacetVertexCount = 4;
283: toothFaceTotalVertexCount = toothFacetVertexCount * toothCount;
284: for (int i = 0; i < toothCount; i++)
285: toothFaceStripCount[i] = toothFacetVertexCount;
286:
287: TriangleStripArray frontGearTeeth = new TriangleStripArray(
288: toothFaceTotalVertexCount, GeometryArray.COORDINATES
289: | GeometryArray.NORMALS, toothFaceStripCount);
290:
291: for (int count = 0; count < toothCount; count++) {
292: index = count * toothFacetVertexCount;
293:
294: toothStartAngle = gearStartAngle + circularPitchAngle
295: * (double) count;
296: toothTopStartAngle = toothStartAngle
297: + toothTopAngleIncrement;
298: toothDeclineStartAngle = toothStartAngle
299: + toothDeclineAngleIncrement;
300: toothValleyStartAngle = toothStartAngle
301: + toothValleyAngleIncrement;
302:
303: xRoot0 = rootRadius * (float) Math.cos(toothStartAngle);
304: yRoot0 = rootRadius * (float) Math.sin(toothStartAngle);
305: xOuter1 = outsideRadius
306: * (float) Math.cos(toothTopStartAngle);
307: yOuter1 = outsideRadius
308: * (float) Math.sin(toothTopStartAngle);
309: xOuter2 = outsideRadius
310: * (float) Math.cos(toothDeclineStartAngle);
311: yOuter2 = outsideRadius
312: * (float) Math.sin(toothDeclineStartAngle);
313: xRoot3 = rootRadius
314: * (float) Math.cos(toothValleyStartAngle);
315: yRoot3 = rootRadius
316: * (float) Math.sin(toothValleyStartAngle);
317:
318: tempCoordinate1.set(xRoot0, yRoot0, frontZ);
319: tempCoordinate2.set(xRoot3, yRoot3, frontZ);
320: tempVector1.sub(tempCoordinate2, tempCoordinate1);
321:
322: tempCoordinate2.set(xOuter1, yOuter1, toothTipFrontZ);
323: tempVector2.sub(tempCoordinate2, tempCoordinate1);
324:
325: frontToothNormal.cross(tempVector1, tempVector2);
326: frontToothNormal.normalize();
327:
328: coordinate.set(xOuter1, yOuter1, toothTipFrontZ);
329: frontGearTeeth.setCoordinate(index, coordinate);
330: frontGearTeeth.setNormal(index, frontToothNormal);
331:
332: coordinate.set(xRoot0, yRoot0, frontZ);
333: frontGearTeeth.setCoordinate(index + 1, coordinate);
334: frontGearTeeth.setNormal(index + 1, frontToothNormal);
335:
336: coordinate.set(xOuter2, yOuter2, toothTipFrontZ);
337: frontGearTeeth.setCoordinate(index + 2, coordinate);
338: frontGearTeeth.setNormal(index + 2, frontToothNormal);
339:
340: coordinate.set(xRoot3, yRoot3, frontZ);
341: frontGearTeeth.setCoordinate(index + 3, coordinate);
342: frontGearTeeth.setNormal(index + 3, frontToothNormal);
343: }
344: newShape = new Shape3D(frontGearTeeth, look);
345: this .addChild(newShape);
346:
347: /* Construct the gear's rear facing teeth facets (Using Quads)
348: * 1______2
349: * / \
350: * / \
351: * / \
352: * /____________\
353: * 0 3
354: */
355: toothFacetVertexCount = 4;
356: toothFaceTotalVertexCount = toothFacetVertexCount * toothCount;
357:
358: QuadArray rearGearTeeth = new QuadArray(toothCount
359: * toothFacetVertexCount, GeometryArray.COORDINATES
360: | GeometryArray.NORMALS);
361:
362: for (int count = 0; count < toothCount; count++) {
363:
364: index = count * toothFacetVertexCount;
365: toothStartAngle = gearStartAngle + circularPitchAngle
366: * (double) count;
367: toothTopStartAngle = toothStartAngle
368: + toothTopAngleIncrement;
369: toothDeclineStartAngle = toothStartAngle
370: + toothDeclineAngleIncrement;
371: toothValleyStartAngle = toothStartAngle
372: + toothValleyAngleIncrement;
373:
374: xRoot0 = rootRadius * (float) Math.cos(toothStartAngle);
375: yRoot0 = rootRadius * (float) Math.sin(toothStartAngle);
376: xOuter1 = outsideRadius
377: * (float) Math.cos(toothTopStartAngle);
378: yOuter1 = outsideRadius
379: * (float) Math.sin(toothTopStartAngle);
380: xOuter2 = outsideRadius
381: * (float) Math.cos(toothDeclineStartAngle);
382: yOuter2 = outsideRadius
383: * (float) Math.sin(toothDeclineStartAngle);
384: xRoot3 = rootRadius
385: * (float) Math.cos(toothValleyStartAngle);
386: yRoot3 = rootRadius
387: * (float) Math.sin(toothValleyStartAngle);
388:
389: tempCoordinate1.set(xRoot0, yRoot0, rearZ);
390: tempCoordinate2.set(xRoot3, yRoot3, rearZ);
391: tempVector1.sub(tempCoordinate2, tempCoordinate1);
392: tempCoordinate2.set(xOuter1, yOuter1, toothTipRearZ);
393: tempVector2.sub(tempCoordinate2, tempCoordinate1);
394: rearToothNormal.cross(tempVector2, tempVector1);
395: rearToothNormal.normalize();
396:
397: coordinate.set(xRoot0, yRoot0, rearZ);
398: rearGearTeeth.setCoordinate(index, coordinate);
399: rearGearTeeth.setNormal(index, rearToothNormal);
400:
401: coordinate.set(xOuter1, yOuter1, toothTipRearZ);
402: rearGearTeeth.setCoordinate(index + 1, coordinate);
403: rearGearTeeth.setNormal(index + 1, rearToothNormal);
404:
405: coordinate.set(xOuter2, yOuter2, toothTipRearZ);
406: rearGearTeeth.setCoordinate(index + 2, coordinate);
407: rearGearTeeth.setNormal(index + 2, rearToothNormal);
408:
409: coordinate.set(xRoot3, yRoot3, rearZ);
410: rearGearTeeth.setCoordinate(index + 3, coordinate);
411: rearGearTeeth.setNormal(index + 3, rearToothNormal);
412:
413: }
414: newShape = new Shape3D(rearGearTeeth, look);
415: this .addChild(newShape);
416:
417: /*
418: * Construct the gear's top teeth faces (As seen from above)
419: * Root0 Outer1 Outer2 Root3 Root4 (RearZ)
420: * 0_______3 2_______5 4_______7 6_______9
421: * |0 3| |4 7| |8 11| |12 15|
422: * | | | | | | | |
423: * | | | | | | | |
424: * |1_____2| |5_____6| |9____10| |13___14|
425: * 1 2 3 4 5 6 7 8
426: * Root0 Outer1 Outer2 Root3 Root4 (FrontZ)
427: *
428: * Quad 0123 uses a left normal
429: * Quad 2345 uses an out normal
430: * Quad 4567 uses a right normal
431: * Quad 6789 uses an out normal
432: */
433: topVertexCount = 8 * toothCount + 2;
434: topStripCount[0] = topVertexCount;
435:
436: toothFacetVertexCount = 4;
437: toothFacetCount = 4;
438:
439: QuadArray topGearTeeth = new QuadArray(toothCount
440: * toothFacetVertexCount * toothFacetCount,
441: GeometryArray.COORDINATES | GeometryArray.NORMALS);
442:
443: for (int count = 0; count < toothCount; count++) {
444: index = count * toothFacetCount * toothFacetVertexCount;
445: toothStartAngle = gearStartAngle + circularPitchAngle
446: * (double) count;
447: toothTopStartAngle = toothStartAngle
448: + toothTopAngleIncrement;
449: toothDeclineStartAngle = toothStartAngle
450: + toothDeclineAngleIncrement;
451: toothValleyStartAngle = toothStartAngle
452: + toothValleyAngleIncrement;
453: nextToothStartAngle = toothStartAngle + circularPitchAngle;
454:
455: xRoot0 = rootRadius * (float) Math.cos(toothStartAngle);
456: yRoot0 = rootRadius * (float) Math.sin(toothStartAngle);
457: xOuter1 = outsideRadius
458: * (float) Math.cos(toothTopStartAngle);
459: yOuter1 = outsideRadius
460: * (float) Math.sin(toothTopStartAngle);
461: xOuter2 = outsideRadius
462: * (float) Math.cos(toothDeclineStartAngle);
463: yOuter2 = outsideRadius
464: * (float) Math.sin(toothDeclineStartAngle);
465: xRoot3 = rootRadius
466: * (float) Math.cos(toothValleyStartAngle);
467: yRoot3 = rootRadius
468: * (float) Math.sin(toothValleyStartAngle);
469: xRoot4 = rootRadius * (float) Math.cos(nextToothStartAngle);
470: yRoot4 = rootRadius * (float) Math.sin(nextToothStartAngle);
471:
472: // Compute normal for quad 1
473: tempCoordinate1.set(xRoot0, yRoot0, frontZ);
474: tempCoordinate2.set(xOuter1, yOuter1, toothTipFrontZ);
475: tempVector1.sub(tempCoordinate2, tempCoordinate1);
476: leftNormal.cross(frontNormal, tempVector1);
477: leftNormal.normalize();
478:
479: // Coordinate labeled 0 in the quad
480: coordinate.set(xRoot0, yRoot0, rearZ);
481: topGearTeeth.setCoordinate(index, coordinate);
482: topGearTeeth.setNormal(index, leftNormal);
483:
484: // Coordinate labeled 1 in the quad
485: coordinate.set(tempCoordinate1);
486: topGearTeeth.setCoordinate(index + 1, coordinate);
487: topGearTeeth.setNormal(index + 1, leftNormal);
488:
489: // Coordinate labeled 2 in the quad
490: topGearTeeth.setCoordinate(index + 2, tempCoordinate2);
491: topGearTeeth.setNormal(index + 2, leftNormal);
492: topGearTeeth.setCoordinate(index + 5, tempCoordinate2);
493:
494: // Coordinate labeled 3 in the quad
495: coordinate.set(xOuter1, yOuter1, toothTipRearZ);
496: topGearTeeth.setCoordinate(index + 3, coordinate);
497: topGearTeeth.setNormal(index + 3, leftNormal);
498: topGearTeeth.setCoordinate(index + 4, coordinate);
499:
500: // Compute normal for quad 2
501: tempCoordinate1.set(xOuter1, yOuter1, toothTipFrontZ);
502: tempCoordinate2.set(xOuter2, yOuter2, toothTipFrontZ);
503: tempVector1.sub(tempCoordinate2, tempCoordinate1);
504: outNormal.cross(frontNormal, tempVector1);
505: outNormal.normalize();
506:
507: topGearTeeth.setNormal(index + 4, outNormal);
508: topGearTeeth.setNormal(index + 5, outNormal);
509:
510: // Coordinate labeled 4 in the quad
511: topGearTeeth.setCoordinate(index + 6, tempCoordinate2);
512: topGearTeeth.setNormal(index + 6, outNormal);
513: topGearTeeth.setCoordinate(index + 9, tempCoordinate2);
514:
515: // Coordinate labeled 5 in the quad
516: coordinate.set(xOuter2, yOuter2, toothTipRearZ);
517: topGearTeeth.setCoordinate(index + 7, coordinate);
518: topGearTeeth.setNormal(index + 7, outNormal);
519: topGearTeeth.setCoordinate(index + 8, coordinate);
520:
521: // Compute normal for quad 3
522: tempCoordinate1.set(xOuter2, yOuter2, toothTipFrontZ);
523: tempCoordinate2.set(xRoot3, yRoot3, frontZ);
524: tempVector1.sub(tempCoordinate2, tempCoordinate1);
525: rightNormal.cross(frontNormal, tempVector1);
526: rightNormal.normalize();
527:
528: topGearTeeth.setNormal(index + 8, rightNormal);
529: topGearTeeth.setNormal(index + 9, rightNormal);
530:
531: // Coordinate labeled 7 in the quad
532: topGearTeeth.setCoordinate(index + 10, tempCoordinate2);
533: topGearTeeth.setNormal(index + 10, rightNormal);
534: topGearTeeth.setCoordinate(index + 13, tempCoordinate2);
535:
536: // Coordinate labeled 6 in the quad
537: coordinate.set(xRoot3, yRoot3, rearZ);
538: topGearTeeth.setCoordinate(index + 11, coordinate);
539: topGearTeeth.setNormal(index + 11, rightNormal);
540: topGearTeeth.setCoordinate(index + 12, coordinate);
541:
542: // Compute normal for quad 4
543: tempCoordinate1.set(xRoot3, yRoot3, frontZ);
544: tempCoordinate2.set(xRoot4, yRoot4, frontZ);
545: tempVector1.sub(tempCoordinate2, tempCoordinate1);
546: outNormal.cross(frontNormal, tempVector1);
547: outNormal.normalize();
548:
549: topGearTeeth.setNormal(index + 12, outNormal);
550: topGearTeeth.setNormal(index + 13, outNormal);
551:
552: // Coordinate labeled 9 in the quad
553: topGearTeeth.setCoordinate(index + 14, tempCoordinate2);
554: topGearTeeth.setNormal(index + 14, outNormal);
555:
556: // Coordinate labeled 8 in the quad
557: coordinate.set(xRoot4, yRoot4, rearZ);
558: topGearTeeth.setCoordinate(index + 15, coordinate);
559: topGearTeeth.setNormal(index + 15, outNormal);
560:
561: // Prepare for the loop by computing the new normal
562: toothTopStartAngle = nextToothStartAngle
563: + toothTopAngleIncrement;
564: xOuter1 = outsideRadius
565: * (float) Math.cos(toothTopStartAngle);
566: yOuter1 = outsideRadius
567: * (float) Math.sin(toothTopStartAngle);
568:
569: tempCoordinate1.set(xRoot4, yRoot4, toothTipFrontZ);
570: tempCoordinate2.set(xOuter1, yOuter1, toothTipFrontZ);
571: tempVector1.sub(tempCoordinate2, tempCoordinate1);
572: leftNormal.cross(frontNormal, tempVector1);
573: leftNormal.normalize();
574: }
575: newShape = new Shape3D(topGearTeeth, look);
576: this.addChild(newShape);
577: }
578:
579: }
|