# Demo Gear Generator #3 -- Building a complete usable face. # This is based on standard gear design techniques; Ref. J. E. Shigley. # It is still hacked to accommodate procedural generation of cog instances # To do this right, see Instancing.slf # Here I make a single tooth at once by rotating the involute # so that the tooth lies symmetrical about the x-axis, # and by going up one side of the cog -- and then down the other. # C.H. Sequin, 2/29/00 ######################################################################## tclinit { #______________ UI _____________________ set rootWindow ".slfWindow" toplevel $rootWindow.carloUI puts __start__tclinit__ proc ValueUpdate { value } { global to_deg to_rad fModule fPressAngle fOffset nSamples fSepar \ TA fPitchRadA fBaseRadA fSweepA fSweepFactorA fFacetA nTeethA fPitchA fTurnA fGapA fScaleA fBottomA fBotA fTopA \ TB fPitchRadB fBaseRadB fSweepB fSweepFactorB fFacetB nTeethB fPitchB fTurnB fGapB fScaleB fBottomB fBotB fTopB \ topA topB botA botB bottomA bottomB axleA axleB fAxle filletA filletB ### Basic Gear Dimensions -- calculated base on unit modulus ### --- scaled later to fit given axle separation. ### pitch radii are of two smooth touching rollers of appropriate ratio set fPitchRadA [expr 0.5*$fModule*$nTeethA ] set fPitchRadB [expr 0.5*$fModule*$nTeethB ] ### base radius, on which involute will be calculated set fBaseRadA [expr cos($fPressAngle/57.296)*$fPitchRadA ] set fBaseRadB [expr cos($fPressAngle/57.296)*$fPitchRadB ] ### custormary addendum circle: set fTopA [expr $fPitchRadA + $fModule ] set fTopB [expr $fPitchRadB + $fModule ] ### custormary dedendum circle: set fBottomA [expr $fPitchRadA - 1.25*$fModule ] set fBottomB [expr $fPitchRadB - 1.25*$fModule ] ### absolute minimum inner circle with no clearance: set fBotA [expr $fPitchRadA - $fModule ] set fBotB [expr $fPitchRadB - $fModule ] ### values normalized to unit circle: set topA [expr $fTopA/$fBaseRadA ] set topB [expr $fTopB/$fBaseRadB ] set botA [expr $fBotA/$fBaseRadA ] set botB [expr $fBotB/$fBaseRadB ] set bottomA [expr $fBottomA/$fBaseRadA ] set bottomB [expr $fBottomB/$fBaseRadB ] set axleA [expr $fAxle/$fBaseRadA ] set axleB [expr $fAxle/$fBaseRadB ] set filletA [expr 0.25*$fModule/$fBottomA] set filletB [expr 0.25*$fModule/$fBottomB] ### axle spacing set fSepar [expr $fPitchRadA + $fPitchRadB ] ### fSweep is the angle through which the involute has been unwound ### it is being calculated to sweep from unit-size base circle ### up to the properly scaled addendum circle ### fSweep in degrees: set fSweepA [expr $to_deg * sqrt( $topA*$topA - 1.0 )] set fSweepB [expr $to_deg * sqrt( $topB*$topB - 1.0 )] ### make (nSamples) facets on this involute set fFacetA [expr $fSweepFactorA *$fSweepA/$nSamples] set fFacetB [expr $fSweepFactorB *$fSweepB/$nSamples] ### turn faceting step into radians set TA [expr $fFacetA * $to_rad] set TB [expr $fFacetB * $to_rad] ### Set proper wheel rotation phase for touching at Pitch point # deviation in degrees of base point of cog face from intersection with pitch circle # (difference of wound-up half-action-line and projection of it). set fOffset [expr (57.296*tan($fPressAngle/57.296)-$fPressAngle ) ] ### basic wheel period in degrees set fPitchA [expr 360.0/$nTeethA] set fPitchB [expr 360.0/$nTeethB] ### set proper gap width between teeth at base circle set fGapA [expr 0.5*$fPitchA - 2.0*$fOffset] set fGapB [expr 0.5*$fPitchB - 2.0*$fOffset] ### the amount of turn required to place the wheel symmetrically about the x-axis ### in radians: set fTurnA [expr -$to_rad *(0.25*$fPitchA + $fOffset)] set fTurnB [expr -$to_rad *(0.25*$fPitchB + $fOffset)] } #---end ValueUpdate--- puts __ValueUpdate_defined__ ### some frequently used constants set to_deg [expr 180.0/$SLF_PI ] set to_rad [expr $SLF_PI/180.0 ] ### Some reasonable defaults -- could be made adjustable set nSamples 8 set fModule 1.0 set nTeethA 12 scale $rootWindow.carloUI.var1 -label "# of TEETH : A" -variable nTeethA \ -from 3 -to 20 -resolution 1 -tickint 4 -length 400 -orient horizontal \ -command ValueUpdate set nTeethB 9 scale $rootWindow.carloUI.var2 -label "# of TEETH : B" -variable nTeethB \ -from 3 -to 20 -resolution 1 -tickint 4 -length 400 -orient horizontal \ -command ValueUpdate set fPressAngle 25.0 scale $rootWindow.carloUI.var3 -label "GEAR SYSTEM FORCE ANGLE (degrees)" -variable fPressAngle \ -from 10.0 -to 80.0 -resolution 1.0 -tickint 10 -length 400 -orient horizontal \ -command ValueUpdate set fSweepFactorA 1.0 scale $rootWindow.carloUI.var4 -label "COG FACE SWEEP FACTOR : A " -variable fSweepFactorA \ -from 0.1 -to 1.9 -resolution 0.1 -tickint 0.3 -length 400 -orient horizontal \ -command ValueUpdate set fSweepFactorB 1.0 scale $rootWindow.carloUI.var5 -label "COG FACE SWEEP FACTOR : B " -variable fSweepFactorB \ -from 0.1 -to 1.9 -resolution 0.1 -tickint 0.3 -length 400 -orient horizontal \ -command ValueUpdate set fAxle 0.5 scale $rootWindow.carloUI.var6 -label "AXLE DIAMETER " -variable fAxle \ -from 0.1 -to 1.0 -resolution 0.1 -tickint 0.1 -length 400 -orient horizontal \ -command ValueUpdate set fRot 0.0 scale $rootWindow.carloUI.var7 -label "ROTATION -- SEE THE WHEELS TURN !" -variable fRot \ -from -1000.0 -to 1000.0 -resolution 0.1 -tickint 500.0 -length 400 -orient horizontal pack \ $rootWindow.carloUI.var1 \ $rootWindow.carloUI.var2 \ $rootWindow.carloUI.var3 \ $rootWindow.carloUI.var4 \ $rootWindow.carloUI.var5 \ $rootWindow.carloUI.var6 \ $rootWindow.carloUI.var7 \ -side top -fill x puts __sliders_established__ ValueUpdate 1.0 puts __again_ValueUpdate ### --- Make the cog faces ---- ### Calculations are based on a unit-radius base circle. The half-wheel is caled later. ### Turn the wheel through: -(0.25*pitch + offset) slide create point "ha0" [list [list expr ( {$axleA} * cos( $to_rad * 180 / {$nTeethA} ) ) ] \ [list expr ( {$axleA} * -sin( $to_rad * 180 / {$nTeethA} ) ) ] 0.0 ] lappend FA "ha0" slide create point "ha1" [list [list expr ( {$bottomA} * cos( $to_rad * 180 / {$nTeethA} ) ) ] \ [list expr ( {$bottomA} * -sin( $to_rad * 180 / {$nTeethA} ) ) ] 0.0 ] lappend FA "ha1" slide create point "ha2" [list [list expr ( {$bottomA} * cos( {$fTurnA} - {$filletA} ) ) ] \ [list expr ( {$bottomA} * sin( {$fTurnA} - {$filletA} ) ) ] 0.0 ] lappend FA "ha2" slide create point "ha3" [list [list expr ( {$botA} * cos( {$fTurnA} ) ) ] \ [list expr ( {$botA} * sin( {$fTurnA} ) ) ] 0.0 ] lappend FA "ha3" for { set i 0 } { $i <= $nSamples } { incr i } { slide create point "a[subst $i]" [list [list expr ( ( cos( $i * {$TA} + {$fTurnA} ) + $i * {$TA} * sin( $i * {$TA} + {$fTurnA} ) ) ) ] \ [list expr ( ( sin( $i * {$TA} + {$fTurnA} ) - $i * {$TA} * cos( $i * {$TA} + {$fTurnA} ) ) ) ] 0.0 ] lappend FA "a[subst $i]" } ### other side of tooth for { set i $nSamples } { $i >= 0 } { incr i -1 } { slide create point "aa[subst $i]" [list [list expr ( ( cos( $i * {$TA} + {$fTurnA} ) + $i * {$TA} * sin( $i * {$TA} + {$fTurnA} ) ) ) ] \ [list expr ( ( -sin( $i * {$TA} + {$fTurnA} ) + $i * {$TA} * cos( $i * {$TA} + {$fTurnA} ) ) ) ] 0.0 ] lappend FA "aa[subst $i]" } slide create point "haa3" [list [list expr ( {$botA} * cos( {$fTurnA} ) ) ] \ [list expr ( {$botA} * -sin( {$fTurnA} ) ) ] 0.0 ] lappend FA "haa3" slide create point "haa2" [list [list expr ( {$bottomA} * cos( {$fTurnA} - {$filletA} ) ) ] \ [list expr ( {$bottomA} * -sin( {$fTurnA} - {$filletA} ) ) ] 0.0 ] lappend FA "haa2" slide create point "haa1" [list [list expr ( {$bottomA} * cos( $to_rad * 180 / {$nTeethA} ) ) ] \ [list expr ( {$bottomA} * sin( $to_rad * 180 / {$nTeethA} ) ) ] 0.0 ] lappend FA "haa1" slide create point "haa0" [list [list expr ( {$axleA} * cos( $to_rad * 180 / {$nTeethA} ) ) ] \ [list expr ( {$axleA} * sin( $to_rad * 180 / {$nTeethA} ) ) ] 0.0 ] lappend FA "haa0" slide create face FaceA $FA ### the other wheel -- without the hob and fillets -- "just cogs" for { set i 0 } { $i <= $nSamples } { incr i } { slide create point "b[subst $i]" [list [list expr ( ( cos( $i * {$TB} + {$fTurnB} ) + $i * {$TB} * sin( $i * {$TB} + {$fTurnB} ) ) ) ] \ [list expr ( ( sin( $i * {$TB} + {$fTurnB} ) - $i * {$TB} * cos( $i * {$TB} + {$fTurnB} ) ) ) ] 0.0 ] lappend FB "b[subst $i]" } for { set i $nSamples } { $i >= 0 } { incr i -1 } { slide create point "bb[subst $i]" [list [list expr ( ( cos( $i * {$TB} + {$fTurnB} ) + $i * {$TB} * sin( $i * {$TB} + {$fTurnB} ) ) ) ] \ [list expr ( ( -sin( $i * {$TB} + {$fTurnB} ) + $i * {$TB} * cos( $i * {$TB} + {$fTurnB} ) ) ) ] 0.0 ] lappend FB "bb[subst $i]" } slide create point "bc" { 0 0 0 } lappend FB "bc" slide create face FaceB $FB # --- instantiate the cog faces into a wheel proc TeethLOD { i var } { global $var SLF_FULL SLF_OFF if { $i < [subst $$var] } then { expr $SLF_FULL } else { expr $SLF_OFF } } set nTeethAMax 20 slide create group halfgearA ### This V "1" suppresses the first cog to show visually how individual cogs are constructed. for {set i 1} {$i < $nTeethAMax} {incr i} { puts [list -lod [list TeethLOD $i nTeethA]] slide create instance iA halfgearA cogA \ -lod [list TeethLOD $i nTeethA] \ -xforms [list [list rotate 0 0 1 [list expr ( $i * {$fPitchA} )]]] } set nTeethBMax 20 slide create group halfgearB for {set i 0} {$i < $nTeethBMax} {incr i} { slide create instance iB halfgearB cogB \ -lod [list TeethLOD $i nTeethB] \ -xforms [list [list rotate 0 0 1 [list expr ( $i * {$fPitchB} )]]] } puts __prototype_gears_done__ puts __tclinit_done } surface RED color (0.9 0.1 0.3) endsurface surface ORANGE color (0.8 0.4 0.2) endsurface surface YELLOW color (0.9 0.8 0) endsurface surface CYAN color (0 0.9 0.9) endsurface surface GREEN color (0.3 0.9 0.3) endsurface surface BLUE color (0.3 0.3 0.9) endsurface ###__define_some_simple_geometrical_primitives__ point L1 ( 0 1 0) endpoint point L0 ( 0 -1 0) endpoint polyline actionline pointlist (L0 L1) surface YELLOW endpolyline ### unit circle cone ring radius 1.0 height 0.01 zmax 0.01 zmin 0.0 zslices 1 thetaslices 40 shading SLF_FLAT endcone ### unit disk cone disk radius 1.0 height 0.01 zmax 1.0 zmin 0.0 zslices 1 thetaslices 40 shading SLF_FLAT endcone ###__build_the_actual_gears__ object cogA (FaceA) shading SLF_FLAT solid SLF_HOLLOW endobject object cogB (FaceB) shading SLF_FLAT solid SLF_HOLLOW endobject group gearA instance halfgearA scale ( {expr $fBaseRadA} {expr $fBaseRadA} 1 ) endinstance #instance halfgearA # scale ( {expr $fBaseRadA} {expr -$fBaseRadA} 1 ) #endinstance instance ring scale ( {expr $fBaseRadA} {expr $fBaseRadA} 1 ) translate (0 0 0.1) surface GREEN endinstance instance ring scale ( {expr $fPitchRadA} {expr $fPitchRadA} 1 ) translate (0 0 0.1) surface CYAN endinstance instance ring scale ( {expr $fTopA} {expr $fTopA} 1 ) translate (0 0 0.1) surface RED endinstance instance ring scale ( {expr $fBotA} {expr $fBotA} 1 ) translate ( 0 0 0.1 ) surface RED endinstance instance ring scale ( {expr $fBottomA} {expr $fBottomA} 1 ) translate ( 0 0 0.05 ) surface RED endinstance endgroup group gearB instance halfgearB scale ( {expr $fBaseRadB} {expr $fBaseRadB} 1 ) endinstance #instance halfgearB # scale ( {expr $fBaseRadB} {expr -$fBaseRadB} 1 ) #endinstance instance ring scale ( {expr $fBaseRadB} {expr $fBaseRadB} 1 ) translate (0 0 0.1) surface GREEN endinstance instance ring scale ( {expr $fPitchRadB} {expr $fPitchRadB} 1 ) translate (0 0 0.1) surface CYAN endinstance instance ring scale ( {expr $fTopB} {expr $fTopB} 1 ) translate (0 0 0.1) surface BLUE endinstance instance ring scale ( {expr $fBotB} {expr $fBotB} 1 ) translate ( 0 0 0.1 ) surface BLUE endinstance instance ring scale ( {expr $fBottomB} {expr $fBottomB} 1 ) translate ( 0 0 0.05 ) surface BLUE endinstance endgroup group gearpair instance gearA rotate ( 0 0 1) ( {expr -$fRot/$nTeethA } ) translate ( {expr -$fPitchRadA} 0 0 ) surface RED endinstance instance gearB rotate ( 0 0 1) ( {expr ($fRot + 180)/$nTeethB + 180 } ) translate ( {expr $fPitchRadB} 0 0 ) surface BLUE endinstance endgroup group assembly instance gearpair scale ( {expr 2.0/$fSepar} {expr 2.0/$fSepar} 1 ) shading SLF_WIRE endinstance instance actionline rotate ( 0 0 1) ( {expr $fPressAngle } ) endinstance instance actionline rotate ( 0 0 1) ( {expr -$fPressAngle } ) endinstance endgroup ###__world_has_been_defined__ ########################################## #include "viewing.slf" # A generic setup for viewing SLF objects ########################################## light amb type SLF_AMBIENT color (1 1 1) endlight group world instance assembly scale (0.05 0.05 0.05) translate (0 0 0) endinstance instance amb id the_amb endinstance endgroup camera cam projection SLF_PARALLEL frustum ( -0.2 -0.2 -4 ) ( 0.2 0.2 -0.01 ) endcamera group gCam instance cam id iCam translate ( 0.0 0.0 1.75 ) endinstance endgroup window Window background (1 1 1) endwindow viewport vp Window endviewport render vp gCam.iCam.cam world light world.the_amb.amb endrender ###__viewing_and_rendering_defined__ ####################################