#!/usr/bin/perl use Tk; use Tk::FileSelect; use Cwd; use Math::Trig; #### #### All Code by Steve Michel #### # print ################### & DefineVar; ################## & DefineArcDegrees; ##############DisplayFactor & DisplayFactor; $GearXcenter = 0; $GearYcenter = 0; $GearXnewCenter = 0; $GearYnewCenter = 0; $color = '#AAAAAAAAAAAA'; $color2 = '#BBBBBBBBBBBB'; $bg = '#9999EEEE9999'; my $mw = MainWindow->new; $mw->title ("Chainring Maker"); my $canvas = $mw->Canvas(-width => $WindowWidth, -height => $WindowHigh,-background => $bg)->grid; $mw->waitVisibility; $canvas->createPolygon ($WinCentX, ($WinCentY+$yRange), ($WinCentX+$xRange), ($WinCentY+$yRange), ($WinCentX+$xRange), $WinCentY, $WinCentX, $WinCentY, -fill => 'gray', -outline => 'black'); &DrawGrid; ################### Make Buttons $bttnXbig = $canvas->Button(-text => "Zoom Out", -relief => 'ridge', -foreground => "red", -command => sub { &bttnXbig }); $id = $canvas->createWindow(1150, 800, -window => $bttnXbig); $bttnXless = $canvas->Button(-text => "Zoom In", -relief => 'ridge', -foreground => "red", -command => sub { &bttnXless }); $id = $canvas->createWindow(1210, 800, -window => $bttnXless); $bttnTeethMore = $canvas->Button(-text => "More Teeth", -relief => 'ridge', -foreground => "red", -command => sub { &bttnTeethMore }); $id = $canvas->createWindow(100, 800, -window => $bttnTeethMore); $bttnTeethLess = $canvas->Button(-text => "Less Teeth", -relief => 'ridge', -foreground => "red", -command => sub { &bttnTeethLess }); $id = $canvas->createWindow(200, 800, -window => $bttnTeethLess); $ToothCountEnter = $canvas->Entry(-width => 8, -background => 'orange', -textvariable => \$toothEnter)->pack; $id = $canvas->createWindow(140, 825, -window => $ToothCountEnter); $ToothCountSpecific = $canvas->Button(-text => "Enter", -relief => 'ridge', -foreground => "red", -command => sub { &ToothCountSpecific }); $id = $canvas->createWindow(185, 825, -window => $ToothCountSpecific); $bttn = $canvas->Button(-text => " Exit ", -relief => 'ridge', -foreground => "red", -command => sub { exit }); $id = $canvas->createWindow(1210, 890, -window => $bttn); $BoltPatternMore = $canvas->Button(-text => "Increase BCD", -relief => 'ridge', -foreground => "red", -command => sub { &BoltPatternMore }); $id = $canvas->createWindow(100, 850, -window => $BoltPatternMore); $BoltPatternLess = $canvas->Button(-text => "Decrease BCD", -relief => 'ridge', -foreground => "red", -command => sub { &BoltPatternLess }); $id = $canvas->createWindow(200, 850, -window => $BoltPatternLess); $BoltPatternOneTen = $canvas->Button(-text => " 110 ", -relief => 'ridge', -foreground => "red", -command => sub { &BoltPatternOneTen }); $id = $canvas->createWindow(100, 880, -window => $BoltPatternOneTen); $BoltPatternOneThreeOh = $canvas->Button(-text => " 130 ", -relief => 'ridge', -foreground => "red", -command => sub { &BoltPatternOneThreeOh }); $id = $canvas->createWindow(150, 880, -window => $BoltPatternOneThreeOh); $BoltPatternOneThreeFive = $canvas->Button(-text => " 135 ", -relief => 'ridge', -foreground => "red", -command => sub { &BoltPatternOneThreeFive }); $id = $canvas->createWindow(200, 880, -window => $BoltPatternOneThreeFive); $writeOBJ = $canvas->Button(-text => "Write Circle OBJ", -relief => 'ridge', -foreground => "red", -command => sub { &writeOBJ }); $id = $canvas->createWindow(1000, 850, -window => $writeOBJ); $writeOBJellipse = $canvas->Button(-text => "Write Ellipse OBJ", -relief => 'ridge', -foreground => "red", -command => sub { &writeOBJellipse }); $id = $canvas->createWindow(1000, 800, -window => $writeOBJellipse); $EllipseStart = $canvas->Button(-text => "Ellipse", -relief => 'ridge', -foreground => "red", -command => sub { &EllipseStart }); $id = $canvas->createWindow(700, 850, -window => $EllipseStart); $EccentricityMore = $canvas->Button(-text => "Increase Ecc.", -relief => 'ridge', -foreground => "red", -command => sub { &EccentricityMore }); $id = $canvas->createWindow(650, 800, -window => $EccentricityMore); $EccentricityLess = $canvas->Button(-text => "Decrease Ecc.", -relief => 'ridge', -foreground => "red", -command => sub { &EccentricityLess }); $id = $canvas->createWindow(760, 800, -window => $EccentricityLess); $EccentricityEnter = $canvas->Entry(-width => 8, -background => 'orange', -textvariable => \$foo)->pack; $id = $canvas->createWindow(700, 825, -window => $EccentricityEnter); $EccentricitySpecific = $canvas->Button(-text => "Enter", -relief => 'ridge', -foreground => "red", -command => sub { &EccentricitySpecific }); $id = $canvas->createWindow(750, 825, -window => $EccentricitySpecific); &re_draw; &includeTextVal; ############################################################################## ############################################################################## MainLoop; sub bttnTeethMore{ $ER = "C"; $defaultTeeth = $defaultTeeth +1; &re_draw; } sub bttnTeethLess{ $ER = "C"; $defaultTeeth = $defaultTeeth -1; &re_draw; } sub ToothCountSpecific{ $ER = "C"; $defaultTeeth = int($toothEnter); if ($defaultTeeth < 4){$defaultTeeth = 4;} if ($defaultTeeth > 100){$defaultTeeth = 100;} $toothEnter = ""; &re_draw; } sub bttnXbig { $ER = "C"; $xX = $xX + 1; &re_draw; } sub bttnXless { $ER = "C"; $xX = $xX - 1; if ($xX == 0){ $xX = 1; } &re_draw; } sub BoltPatternMore { $ER = "C"; $BCD = $BCD +1; &re_draw; } sub BoltPatternLess { $ER = "C"; $BCD = $BCD -1; &re_draw; } sub BoltPatternOneTen { $ER = "C"; $BCD = 110; &re_draw; } sub BoltPatternOneThreeOh { $ER = "C"; $BCD = 130; &re_draw; } sub BoltPatternOneThreeFive { $ER = "C"; $BCD = 135; &re_draw; } sub EccentricityLess { $ER = "E"; $Eccentricity = $Eccentricity + .1; if ($Eccentricity > 1 ){ $Eccentricity = 1;} &EllipseStart; } sub EccentricityMore { $ER = "E"; $Eccentricity = $Eccentricity - .1; if ($Eccentricity < .4 ){ $Eccentricity = .4;} &EllipseStart; } sub EccentricitySpecific { $ER = "E"; $Eccentricity = $foo; if ($Eccentricity < .4 ){ $Eccentricity = .4;} if ($Eccentricity > 1 ){ $Eccentricity = 1;} $foo = ""; &EllipseStart; } sub re_draw { # $ER = "E"; # $ER = "R"; if ($ER eq "E"){ $UseThisColor = '#9999CC';} if ($ER eq "C"){ $UseThisColor = '#FF3300';} &UpdateToothVal; &DisplayFactor; &ClearScreen; &DrawGrid; &defineXpointAndYpoint; &includeTextVal; &ToothShapeDefine; &CalcBoltCircleDiameter; &ToothDraw; } #End re_draw sub DefineVar { ########### start DefineVar $OBJname = $defaultTeeth . "t_" . $defaultPitch . "p_" . $BCD . "_OBJ.obj"; $OBJellipsename = $defaultTeeth . "t_EllipseRatio_" . $Eccentricity . "_" . $defaultPitch . "p_" . $BCD. "_OBJ.obj"; $UseThisColor = 'red'; $UseThatColor = 'blue'; # $Eccentricity = 0.9; $Eccentricity = 1; $BCD = 110; $bcNumber = 5; $ChainRingBolt = 8; $DumbLoop = 0; $WindowWidth = 1280; $WindowHigh = 1024; $GearXcenter = 0; $GearYcenter = 0; $PiUse = 3.141592653589793238462643383; #establish pi $rad = 180/$PiUse; #establish radians $RadConvert = 0.0174532925; #establish radian conversion #$toothDetail = 11; $toothDetail = 7; $defaultTeeth = 38; # set initial number of teeth $defaultPitch = .5; #set initial chain Pitch $defaultRollerDia = 5/16; $defaultRollerRadius = .505 * $defaultRollerDia; $LinkRollOff = $defaultPitch - $defaultRollerRadius; $PitchDia = $defaultPitch / (sin($PiUse/$defaultTeeth)); $PitchRadius = $PitchDia /2; $PitchCircum = $PiUse * $PitchDia; $TipDia = $PitchDia + ($defaultPitch * ( 1 - (1.6 / $defaultTeeth))) - $defaultRollerDia; $TipRadius = $TipDia/2; $ShoulderVal = (int(($TipRadius * 0.99658749154106181575026160421653) * 1000000)) / 1000000; $ToothAngle = 360 / $defaultTeeth; $ToothAngleRad = $ToothAngle * 0.0174532925; $ArcDeg = 140 - (90 / $defaultTeeth); $ArcDegUse = $ArcDeg / $toothDetail; $MinMaterial = int($TipDia); $MinMaterial = $MinMaterial +1; $MinMaterial = $MinMaterial * 1.63; $MinMaterial = int($MinMaterial); $xX = $MinMaterial; $pltUnits = 1016; # PLT uses 1016 units per inch $xRange = 1143; $yRange = 698.5; $StartAngleThing = 90 + 180; } ## End DefineVar sub DefineArcDegrees{ #Start DefineArcDegrees $MultNumber= -1 * ($toothDetail-1) /2; for ($Looper=1;$Looper<=$toothDetail;$Looper++) { $ArcDegrees[$Looper] = $ArcDegUse * $MultNumber; $MultNumber = $MultNumber +1; } #End Looper } #End DefineArcDegrees sub DrawGrid{ ########### start DrawGrid #create Vert grid fine $GridVal = .1; $id = $canvas->createText ($WinCentX ,20, -text => " PLT values:"); for ($i=$GridVal;$i<=$xX;$i=$i+$GridVal) { $XVal = ($i * $Units)+ $WinCentX ; $PrintXVal = ($i * $Units); $canvas->createLine ($XVal, ($WinCentY+$yRange), $XVal, $WinCentY, -fill => $color); } #End i #create Horiz grid $HoriGridVal = $yY - $GridVal; for ($i=$GridVal;$i<=$HoriGridVal;$i=$i+$GridVal) { $YVal = ($i * $Units) + $WinCentY ; $inchThing = $yY - $i; $pltThing = ($inchThing * $Units); $canvas->createLine ($WinCentX, $YVal, ($WinCentX+$xRange), $YVal, -fill => $color); $Loop = $Loop - 1; } #End i #create Vert grid ############################# for ($i=0;$i<=$xX;$i++) { $XVal = ($i * $Units)+ $WinCentX ; $PrintXVal = ($i * $pltUnits); $canvas->createLine ($XVal, ($WinCentY+$yRange), $XVal, $WinCentY, -fill => 'blue'); if ($i >> 0){ $id = $canvas->createText ($XVal,20, -text => $PrintXVal);} $id = $canvas->createText ($XVal,($WinCentY+$yRange+10), -text => $i); } #End i #create Horiz grid ############################# $NewLine = int ($yY); $YTempOffSet = $yY - $NewLine; $yOffSet = $YTempOffSet * $Units; for ($i=0;$i<=$NewLine;$i++) { $YVal = ($i * $Units) + $WinCentY + $yOffSet; ########################## $inchThing = $NewLine - $i; $pltThing = ($inchThing * $pltUnits); $canvas->createLine ($WinCentX, $YVal, ($WinCentX+$xRange), $YVal, -fill => 'blue' ); $id = $canvas->createText (($WinCentX+$xRange)+15, $YVal, -text => $pltThing); $id = $canvas->createText (($WinCentX-10),$YVal, -text => $inchThing); $Loop = $Loop - 1; } } #End DrawGrid sub defineXpointAndYpoint{ ########### start defineXpointAndYpoint for ($Loop=1;$Loop<=$defaultTeeth;$Loop++) { $xPoint[$Loop] = $PitchRadius * cos($ToothAngleRad * $Loop); $yPoint[$Loop] = $PitchRadius * sin($ToothAngleRad * $Loop); $xPoint[$Loop] = int($xPoint[$Loop] * 10000 * $Units); $yPoint[$Loop] = int($yPoint[$Loop] * 10000 * $Units); $xPoint[$Loop] = $xPoint[$Loop] / 10000; $yPoint[$Loop] = $yPoint[$Loop] / 10000; $xPoint[$Loop] = $xPoint[$Loop]; $yPoint[$Loop] = $yPoint[$Loop]; } #End Loop } #End defineXpointAndYpoint sub DisplayFactor{ ########### start DisplayFactor $DisplayFactor = ($xX * $pltUnits) / $xRange; $Units = $pltUnits / $DisplayFactor; $yY = $yRange /$Units; $WinCentX = ($WindowWidth - $xRange)/2; $WinCentY = 40; } #End DisplayFactor sub includeTextVal{ ########### start includeTextVal $id = $canvas->createText (147, 800, -text => $defaultTeeth); $id = $canvas->createText (147, 850, -text => $BCD); $id = $canvas->createText (700, 800, -text => $Eccentricity); $id = $canvas->createText (1000, 820, -text => $OBJellipsename); $id = $canvas->createText (1000, 870, -text => $OBJname); } #End includeTextVal sub ClearScreen{ ########### start ClearScreen $canvas->createPolygon ( 1 , ($WindowHigh -1 ), ($WindowWidth - 1), ($WindowHigh -1), ($WindowWidth - 1), 1, 1, 1, -fill => '#9999EEEE9999'); $canvas->createPolygon ($WinCentX, ($WinCentY+$yRange), ($WinCentX+$xRange), ($WinCentY+$yRange), ($WinCentX+$xRange), $WinCentY, $WinCentX, $WinCentY, -fill => 'gray', -outline => 'black'); } # End ClearScreen sub UpdateToothVal{ ########### start UpdateToothVal $OBJname = $defaultTeeth . "t_" . $defaultPitch . "p_" . $BCD . "_OBJ.obj"; $OBJellipsename = $defaultTeeth . "t_EllipseRatio_" . $Eccentricity . "_" . $defaultPitch . "p_" . $BCD. "_OBJ.obj"; $ToothAngle = 360 / $defaultTeeth; $ToothAngleRad = $ToothAngle * 0.0174532925; $ArcDeg = 140 - (90 / $defaultTeeth); $ArcDegUse = $ArcDeg / $toothDetail; $PitchDia = $defaultPitch / (sin($PiUse/$defaultTeeth)); $PitchRadius = $PitchDia /2; $PitchCircum = $PiUse * $PitchDia; $TipDia = $PitchDia + ($defaultPitch * ( 1 - (1.6 / $defaultTeeth))) - $defaultRollerDia; $TipRadius = $TipDia/2; $TipShoulderTemp = $TipRadius * 0.996587491; $TipShoulderTemp = int($TipShoulderTemp * 10000); $TipShoulderVal = ($TipShoulderTemp/10000); $ShoulderVal = (int(($TipRadius * 0.99658749154106181575026160421653) * 1000000)) / 1000000; $TempThing = $RadConvert * (180/$defaultTeeth); $OutsideDia = $defaultPitch * (.6 + (1 / (tan($TempThing)))); $OutsideRad = $OutsideDia / 2; $TempThing2 = (360/$defaultTeeth) / 2; $TempThing3 = $RadConvert * $TempThing2; } # End UpdateToothVal sub ToothShapeDefine { ################ make one full tooth shape: ################ calculate points of arc first ################ offset points of arc by #teeth/2 ################ culculate outest most radius ################ calculate shoulder A/a = B/b ################ store all points - and rotate around center $MultNumber= -1 * ($toothDetail-1) /2; for ($Looper=1;$Looper<=$toothDetail;$Looper++) { $ArcDegrees[$Looper] = int(($StartAngleThing + ($ArcDegUse * $MultNumber)) * 100000); $ArcDegrees[$Looper] = $ArcDegrees[$Looper] / 100000; $ArcDegreesRad[$Looper] = int(($ArcDegrees[$Looper] * $RadConvert) * 100000); $ArcDegreesRad[$Looper] = $ArcDegreesRad[$Looper] / 100000; # print $ArcDegrees[$Looper] . " " . "\n"; $MultNumber = $MultNumber +1; } # End Looper for ($Loop=1;$Loop<=$toothDetail;$Loop++) { $xRollerTemp[$Loop] = $defaultRollerRadius * (cos($ArcDegreesRad[$Loop])); $yRollerTemp[$Loop] = $defaultRollerRadius * (sin($ArcDegreesRad[$Loop])); $xRollerVal[$Loop] = int($xRollerTemp[$Loop] * 100000 ); $yRollerVal[$Loop] = int($yRollerTemp[$Loop] * 100000 ); $xRollerVal[$Loop] = $xRollerVal[$Loop] / 100000; $yRollerVal[$Loop] = ($yRollerVal[$Loop] / 100000) + $PitchRadius; $xRollerValGen[$Loop] = $xRollerVal[$Loop]; $yRollerValGen[$Loop] = int(($yRollerVal[$Loop] - $PitchRadius)* 100000) /100000; }# End Loop # print "\n"; ##set roller into position for ($Loop=1;$Loop<=$toothDetail;$Loop++) { $xc = $xRollerVal[$Loop]; $yc = $yRollerVal[$Loop]; ## Roll (Z axis) $zr = ($RadConvert * ((360/$defaultTeeth)/2)) * -1; #### <---- works for circular ring - mod for ellipse $xd = $xc*cos($zr)-$yc*sin($zr); $yd = $xc*sin($zr)+$yc*cos($zr); $xRollerPosition[$Loop] = $xd; $yRollerPosition[$Loop] = $yd; } # End Loop ##find high point X = 0 , Y = OutSideDiam $HighX = 0; $HighY = $OutsideRad; ##find tip point X = 0 , Y = OutSideDiam $TipX = 0; $TipY = $TipRadius; $aaa = $xRollerPosition[1]; $bbb = $HighY - $yRollerPosition[1]; $BBB = $ShoulderVal - $yRollerPosition[1]; $AAA = ($BBB / $bbb) * $aaa; $xAAA = $aaa - $AAA; $ShoulderX = $xAAA; $ShoulderY = $ShoulderVal; $numberDetail = 3; $UsePointX[1] = $ShoulderX * -1; $UsePointY[1] = $ShoulderY; $UsePointX[2] = $TipX; $UsePointY[2] = $TipY; $UsePointX[3] = $ShoulderX; $UsePointY[3] = $ShoulderY; for ($Loop=1;$Loop<=$toothDetail;$Loop++) { $numberDetail = $numberDetail + 1; $UsePointX[$numberDetail] = $xRollerPosition[$Loop]; $UsePointY[$numberDetail] = $yRollerPosition[$Loop]; } # End Loop # for ($Loop=1;$Loop<=$numberDetail;$Loop++) { # print $UsePointX[$Loop] . " " . $UsePointY[$Loop] . "\n"; # } # End Loop ## Rotate UsePoint around center $StartStartStart = 0; for ($BigLoop=1;$BigLoop<=$defaultTeeth;$BigLoop++) { for ($Loop=1;$Loop<=$numberDetail;$Loop++) { $StartStartStart = $StartStartStart + 1; $xc = $UsePointX[$Loop]; $yc = $UsePointY[$Loop]; $zr = $RadConvert * ((360/$defaultTeeth) * ($BigLoop* -1)) ; $xd = $xc*cos($zr)-$yc*sin($zr); $yd = $xc*sin($zr)+$yc*cos($zr); $NewPointX[$StartStartStart] = (int ($xd * 100000)) / 100000; $NewPointY[$StartStartStart] = (int ($yd * 100000)) / 100000; } # End Loop } # End BigLoop # for ($Loop=1;$Loop<=$StartStartStart;$Loop++) { # print $NewPointX[$Loop] . " " . $NewPointY[$Loop] . "\n"; # } # End Loop } # End ToothShapeDefine sub CalcBoltCircleDiameter { #### Start CalcBoltCircleDiameter $BCDinch = $BCD / 25.4; $bcdRadius = $BCDinch / 2; $ChainRingBoltinch = ($ChainRingBolt / 25.4) / 2; $ChainHoleX = 0; $ChainHoleY = $ChainRingBoltinch; for ($Loop=1;$Loop<=24;$Loop++) { $xc = $ChainHoleX; $yc = $ChainHoleY; $zr = $RadConvert * ((360/24) * (($Loop)-1) ) ; $xd = $xc*cos($zr)-$yc*sin($zr); $yd = $xc*sin($zr)+$yc*cos($zr); $ChainHoleXuse[$Loop] = (int ($xd * 100000)) / 100000; $ChainHoleYuse[$Loop] = $bcdRadius + (int ($yd * 100000)) / 100000; }# End Loop for ($BigLoop=1;$BigLoop<=$bcNumber;$BigLoop++) { for ($Loop=1;$Loop<=24;$Loop++) { $xc = $ChainHoleXuse[$Loop]; $yc = $ChainHoleYuse[$Loop]; $zr = $RadConvert * ((360/$bcNumber) * (($BigLoop)-1) ) ; $xd = $xc*cos($zr)-$yc*sin($zr); $yd = $xc*sin($zr)+$yc*cos($zr); $ChainHoleXnew[$BigLoop][$Loop] = (int ($xd * 100000)) / 100000; $ChainHoleYnew[$BigLoop][$Loop] = (int ($yd * 100000)) / 100000; $ChainHoleXdraw[$BigLoop][$Loop] = $WinCentX + ($ChainHoleXnew[$BigLoop][$Loop] * $Units) + ($OutsideRad * $Units) + 10; $ChainHoleYdraw[$BigLoop][$Loop] = ($yRange + 40) - (($ChainHoleYnew[$BigLoop][$Loop] * $Units) + ($OutsideRad * $Units) + 10); }# End Loop }# End BigLoop }# End CalcBoltCircleDiameter sub ToothDraw { for ($Loop=1;$Loop<=$StartStartStart;$Loop++) { $DisplayPointX[$Loop] = $WinCentX + ($NewPointX[$Loop] * $Units) + ($OutsideRad * $Units) + 10; $DisplayPointY[$Loop] = ($yRange + 40) - (($NewPointY[$Loop] * $Units) + ($OutsideRad * $Units) + 10); }# End Loop $EndEndEnd = $StartStartStart +1; $DisplayPointX[$EndEndEnd] = $DisplayPointX[1]; $DisplayPointY[$EndEndEnd] = $DisplayPointY[1]; for ($Loop=1;$Loop<=$StartStartStart;$Loop++) { $canvas->createLine ($DisplayPointX[$Loop], $DisplayPointY[$Loop], $DisplayPointX[$Loop + 1], $DisplayPointY[$Loop + 1], -fill => $UseThisColor); } # End Loop for ($BigLoop=1;$BigLoop<=$bcNumber;$BigLoop++) { $ChainHoleXdraw[$BigLoop][25] = $ChainHoleXdraw[$BigLoop][1]; $ChainHoleYdraw[$BigLoop][25] = $ChainHoleYdraw[$BigLoop][1]; for ($Loop=1;$Loop<=24;$Loop++) { $canvas->createLine ($ChainHoleXdraw[$BigLoop][$Loop], $ChainHoleYdraw[$BigLoop][$Loop], $ChainHoleXdraw[$BigLoop][$Loop + 1], $ChainHoleYdraw[$BigLoop][$Loop + 1], -fill => 'red'); }# End Loop }# End BigLoop } # End ToothDraw sub writeOBJ { # Start writeOBJ open (FILE, ">" . $OBJname ); print FILE ("####" . "\n"); print FILE ("#" . "\n"); print FILE ("# OBJ File Generated by LightWave 3D(TM)" . "\n"); print FILE ("#" . "\n"); print FILE ("####" . "\n"); print FILE ("# Object: Unnamed" . "\n"); print FILE ("#" . "\n"); print FILE ("# Vertices: " . $VertexNumber . "\n"); print FILE ("# Points: 0" . "\n"); print FILE ("# Lines: 0" . "\n"); print FILE ("# Faces: 0" . "\n"); print FILE ("# Materials: 1" . "\n"); print FILE ("#" . "\n"); print FILE ("####" . "\n"); print FILE ("\n"); print FILE ("# o Unnamed" . "\n"); print FILE ("\n"); print FILE ("# Vertex list" . "\n"); print FILE ("\n"); $objVertexCount = 1; for ($Loop=1;$Loop<=$StartStartStart;$Loop++) { $NewPointX[$Loop] = $NewPointX[$Loop] /39.37007874015748031496062992126; $NewPointY[$Loop] = $NewPointY[$Loop] /39.37007874015748031496062992126; print FILE ("v " . $NewPointX[$Loop] . " " . $NewPointY[$Loop]); $objVertexCount = $objVertexCount + 1; print FILE ("\n"); } for ($BigLoop=1;$BigLoop<=$bcNumber;$BigLoop++) { for ($Loop=1;$Loop<=24;$Loop++) { $ChainHoleXnew[$BigLoop][$Loop] = $ChainHoleXnew[$BigLoop][$Loop] / ((1/25.4) * 1000); $ChainHoleYnew[$BigLoop][$Loop] = $ChainHoleYnew[$BigLoop][$Loop] / ((1/25.4) * 1000); print FILE ("v " . $ChainHoleXnew[$BigLoop][$Loop] . " " . $ChainHoleYnew[$BigLoop][$Loop]); print FILE ("\n"); }# End Loop }# End BigLoop print FILE ("# Face list" . "\n"); print FILE ("\n"); print FILE ("f "); for ($Loop=1;$Loop<=$StartStartStart;$Loop++) { print FILE ($Loop . " "); } print FILE ("\n"); for ($BigLoop=1;$BigLoop<=$bcNumber;$BigLoop++) { print FILE ("f "); for ($Loop=1;$Loop<=24;$Loop++) { print FILE ($objVertexCount . " "); $objVertexCount = $objVertexCount + 1; }# End Loop print FILE ("\n"); }# End BigLoop print FILE ("\n"); print FILE ("\n"); print FILE ("# End of file" . "\n"); close FILE; } # End writeOBJ sub EllipseStart { $ER = "E"; $UseThisColor = 'blue'; &re_draw; &Ellipse; &EllipseDivide; $UseThisColor = 'blue'; &EllipseDraw; &CalcEllipseAngles; } sub Ellipse{ ##################### Start Ellipse $a = ((2* ($PitchCircum / (2*$PiUse))**2)/(1+$Eccentricity**2))**.5; $b = $a * $Eccentricity; $a = int ($a * 1000000); $a = ($a / 1000000); $b = int ($b * 1000000); $b = ($b / 1000000); # print "Starting Values: " . "\n"; # print "C= " . $PitchCircum . " pi= " . $PiUse . "\n"; # print "a= " . $a . " b= " . $b . "\n"; # print "\n"; } # End Ellipse sub EllipseDivide{ # Start EllipseDivide $EvalTestLo = .001; $EvalTestHi = .001; $HiLo = 1; for ($Attempt=1;$Attempt<=100;$Attempt=$Attempt+1){ # print "Attempt " . $Attempt . "\n"; # print "a= " . $a . " b= " . $b . "\n"; $CircleCenterX = $a ; $CircleCenterY = 0; $PeriCrawlPhaseStart = 90; $PeriCrawlPhaseAdd = 0; $PeriCrawlStart = 0; $PeriCrawlEndLoop = 3600; for ($BigLoop = 1;$BigLoop<=$defaultTeeth;$BigLoop++){ # print "tooth # " . $BigLoop . " center at : " . $CircleCenterX . "," . $CircleCenterY . "\n"; $PeriCrawlStep = 1; for ($Loop=$PeriCrawlStart;$Loop<=$PeriCrawlEndLoop;$Loop = $Loop + $PeriCrawlStep) { $TestDeg = $Loop + $PeriCrawlPhaseStart + $PeriCrawlPhaseAdd; $TestDegUse = $RadConvert * $TestDeg; $xTempTemp = $defaultPitch*cos($TestDegUse); $yTempTemp = $defaultPitch*sin($TestDegUse); $xTempTest[$Loop] = ($xTempTemp + $CircleCenterX); $yTempTest[$Loop] = ($yTempTemp + $CircleCenterY); $SolveTestValTemp[$Loop] = (($xTempTest[$Loop]**2) / $a**2) + ($yTempTest[$Loop]**2) / $b**2; $SolveTestValTemp[$Loop] = int($SolveTestValTemp[$Loop] * 1000000); $SolveTestValTemp[$Loop] = $SolveTestValTemp[$Loop] / 1000000; $SecondTest[$Loop] = $SolveTestValTemp[$Loop] - 1; $SecondTest[$Loop] = abs($SecondTest[$Loop]); # print $TestDeg . " x " . $xTempTest[$Loop] . " y " . $yTempTest[$Loop] . " solve = " . $SolveTestValTemp[$Loop] ; # print " " . $SecondTest[$Loop] . "\n"; if ($SolveTestValTemp[$Loop] <= 1.01){ $PeriCrawlStep = .2; }# End if if ($SolveTestValTemp[$Loop] <= 1.003){ $PeriCrawlStep = .1; }# End if if ($SolveTestValTemp[$Loop] <= 1.0007){ $PeriCrawlStep = .01; }# End if if ($SolveTestValTemp[$Loop] <= 1.00005){ $PeriCrawlStep = .005; }# End if if ($SolveTestValTemp[$Loop] <= 1.00003){ $PeriCrawlStep = .001; }# End if if ($SolveTestValTemp[$Loop] <= 1.000008){ $PeriCrawlStep = .0005; }# End if if ($SolveTestValTemp[$Loop] <= 1){ $TempValueHolder = $Loop; $xIntersect = $xTempTest[$Loop]; $yIntersect = $yTempTest[$Loop]; $Loop = $PeriCrawlEndLoop; }# End if }# End Loop if ($SecondTest[$TempValueHolder-1] < $SecondTest[$TempValueHolder]){ $xIntersect = $xTempTest[$TempValueHolder-1]; $yIntersect = $yTempTest[$TempValueHolder-1]; }# End if $xIntTemp = (int($xIntersect * 10000)) / 10000; $yIntTemp = (int($yIntersect * 10000)) / 10000; # print $xIntTemp . " , " . $yIntTemp . "\n"; # print $yIntersect . "\n"; # print $TestDeg . "\n" ; $CircleCenterX = $xIntersect; $CircleCenterY = $yIntersect; $CircleCenterX[$BigLoop] = (int ($xIntersect * 10000))/10000; $CircleCenterY[$BigLoop] = (int ($yIntersect * 10000))/10000; $PeriCrawlPhaseStart = int($TestDeg); $IntersectDegreeUse[$BigLoop] = $TestDeg - 90; $IntersetVals = $BigLoop; }# End BigLoop $EvalTestTest = int($CircleCenterY[$defaultTeeth] * 10000); $EvalTester = $EvalTestTest / 10000; # print "EvalTester " . $EvalTester . "\n"; if ($EvalTester > 0.0001){ # print $EvalTester . " ellipse needs to be bigger" . "\n"; $a = $a * (1 + $EvalTestHi); if ($HiLo == 0){$EvalTestLo = $EvalTestLo /10;} $HiLo = 1; $b = $a * $Eccentricity; $a = int ($a * 1000000); $a = ($a / 1000000); $b = int ($b * 1000000); $b = ($b / 1000000); }# End if if ($EvalTester < -0.0001){ # print $EvalTester . " ellipse needs to be smaller" . "\n"; $a = $a * (1 - $EvalTestLo); if ($HiLo == 1){$EvalTestHi = $EvalTestHi /10;} $HiLo = 0; $b = $a * $Eccentricity; $a = int ($a * 1000000); $a = ($a / 1000000); $b = int ($b * 1000000); $b = ($b / 1000000); }# End if if ($EvalTester < 0.0001){ if ($EvalTester > -0.0001){ $Attempt = 101; # print "a= " . $a . " b= " . $b . "\n"; } }# End if } # End Attempt } # End EllipseDivide sub EllipseDraw{ #Start EllipseDraw for ($Loop=1;$Loop<=$defaultTeeth;$Loop++) { $EllipsePointX[$Loop] = $WinCentX + ($CircleCenterX[$Loop] * $Units) + ($OutsideRad * $Units) + 10; $EllipsePointY[$Loop] = ($yRange + 40) - (($CircleCenterY[$Loop] * $Units) + ($OutsideRad * $Units) + 10); #$EllipsePointX[$Loop] = int(($CircleCenterX[$Loop] * $Units)+500); #$EllipsePointY[$Loop] = int(($CircleCenterY[$Loop] * $Units)+300); }# End Loop $EndEndUse = $defaultTeeth +1; $EllipsePointX[$EndEndUse] = $EllipsePointX[1]; $EllipsePointY[$EndEndUse] = $EllipsePointY[1]; for ($Loop=1;$Loop<=$defaultTeeth;$Loop++) { # $canvas->createLine ($EllipsePointX[$Loop], $EllipsePointY[$Loop], $EllipsePointX[$Loop + 1], $EllipsePointY[$Loop + 1], -fill => 'orange'); } # End Loop }#End EllipseDraw sub CalcEllipseAngles{ #Start CalcEllipseAngles $CircleCenterY[0] = $CircleCenterY[$defaultTeeth]; $CircleCenterX[0] = $CircleCenterX[$defaultTeeth]; $CircleCenterY[$defaultTeeth+1] = $CircleCenterY[1]; $CircleCenterX[$defaultTeeth+1] = $CircleCenterX[1]; for ($Loop=1;$Loop<=$defaultTeeth;$Loop++) { #tan(A) = a/b $ThingValX[$Loop] = $CircleCenterX[$Loop+1] - $CircleCenterX[$Loop-1]; $ThingValY[$Loop] = $CircleCenterY[$Loop+1] - $CircleCenterY[$Loop-1]; $xyMidPointX[$Loop] = ($CircleCenterX[$Loop] + $CircleCenterX[$Loop-1])/2; $xyMidPointY[$Loop] = ($CircleCenterY[$Loop] + $CircleCenterY[$Loop-1])/2; if ($ThingValX[$Loop] < 0){ $aTangentThing = (atan($ThingValY[$Loop] / $ThingValX[$Loop])) / $RadConvert; } if ($ThingValX[$Loop] > 0){ $aTangentThing = (atan($ThingValY[$Loop] / $ThingValX[$Loop])) / $RadConvert; } if ($ThingValX[$Loop] == 0){ $aTangentThing = 90; } if ($ThingValX[$Loop] >= 0){ if ($ThingValY[$Loop] >= 0){ $aTangentThing = $aTangentThing; } } if ($ThingValX[$Loop] < 0){ if ($ThingValY[$Loop] >= 0){ $aTangentThing = (90 + $aTangentThing) + 90; } } if ($ThingValX[$Loop] <= 0){ if ($ThingValY[$Loop] < 0){ $aTangentThing = ($aTangentThing) + 180; } } if ($ThingValX[$Loop] > 0){ if ($ThingValY[$Loop] < 0){ $aTangentThing = (180 + $aTangentThing) + 180; } } $EllipseValAngle[$Loop] = ((int ($aTangentThing * 1000)) / 1000); if( $EllipseValAngle[$Loop] == 0){ if( $EllipseValAngle[$Loop-1] > 300){ $EllipseValAngle[$Loop] = 360; } } # print $Loop . "degrees " . $IntersectDegreeUse[$Loop] . " / " . $EllipseValAngle[$Loop] . "\n"; print $Loop . "degrees " . $EllipseValAngle[$Loop] . " ... " . $IntersectDegreeUse[$Loop] . "\n"; # print $Loop . "degrees " . $ThingValY[$Loop] . " / " . $ThingValX[$Loop] . " = " . $EllipseValAngle[$Loop] . "\n"; } # End Loop # print $numberDetail . "\n"; for ($Loop=1;$Loop<=3;$Loop++) { $xTipValGen[$Loop] = (int ($UsePointX[$Loop] * 100000)) / 100000; $yTipValGen[$Loop] = (int (($UsePointY[$Loop] - $PitchRadius)* 100000)) / 100000; # print $xTipValGen[$Loop] . " , " . $yTipValGen[$Loop] . "\n"; }# End Loop # print $toothDetail . "\n"; for ($Loop=1;$Loop<=$toothDetail;$Loop++) { # print "look at this " . $xRollerValGen[$Loop] . " , " . $yRollerValGen[$Loop] . "\n"; }# End Loop ############# make a loop here ############# create a tooth shape $xLookAtAngleNew[1] = $ShoulderX * -1; $yLookAtAngleNew[1] = $ShoulderY - $PitchRadius; $xLookAtAngleNew[2] = 0; $yLookAtAngleNew[2] = $UsePointY[2] - $PitchRadius; $xLookAtAngleNew[3] = $ShoulderX; $yLookAtAngleNew[3] = $ShoulderY - $PitchRadius; $compensator = 0; $compensator2 = 90; $IntersectDegreeUse[0] = $IntersectDegreeUse[$IntersetVals]; for ($BigLoop=1;$BigLoop<=$defaultTeeth;$BigLoop++) { for ($Loop=1;$Loop<=$toothDetail;$Loop++) { $xc = $xRollerValGen[$Loop]; $yc = $yRollerValGen[$Loop]; $zr = $RadConvert * -1 * ($EllipseValAngle[$BigLoop] + $compensator); $xd = $xc*cos($zr)-$yc*sin($zr); $yd = $xc*sin($zr)+$yc*cos($zr); $xRollerValTemp[$BigLoop][$Loop] = (int ($xd * 100000)) / 100000; $yRollerValTemp[$BigLoop][$Loop] = (int ($yd * 100000)) / 100000; } for ($Loop=1;$Loop<=3;$Loop++) { $xc = $xLookAtAngleNew[$Loop]; $yc = $yLookAtAngleNew[$Loop]; $zr = $RadConvert * -1 * ($IntersectDegreeUse[$BigLoop] + $compensator2); $xd = $xc*cos($zr)-$yc*sin($zr); $yd = $xc*sin($zr)+$yc*cos($zr); $LookAtAngleNewX[$BigLoop][$Loop] = (int ($xd * 100000)) / 100000; $LookAtAngleNewY[$BigLoop][$Loop] = (int ($yd * 100000)) / 100000; } }# End BigLoop for ($BigLoop=1;$BigLoop<=$defaultTeeth;$BigLoop++) { for ($Loop=1;$Loop<=$toothDetail;$Loop++) { $xRollerValNow[$BigLoop][$Loop] = ($CircleCenterX[$BigLoop] * $Units) + $WinCentX + ($xRollerValTemp[$BigLoop][$Loop] * $Units) + ($OutsideRad * $Units) + 10; $yRollerValNow[$BigLoop][$Loop] = ($CircleCenterY[$BigLoop] * $Units) + ($yRange + 40) - (($yRollerValTemp[$BigLoop][$Loop] * $Units) + ($OutsideRad * $Units) + 10); $xRollerOutPutUse[$BigLoop][$Loop] = ($CircleCenterX[$BigLoop]) + ($xRollerValTemp[$BigLoop][$Loop]); $yRollerOutPutUse[$BigLoop][$Loop] = ($CircleCenterY[$BigLoop]) - ($yRollerValTemp[$BigLoop][$Loop]); print $Loop . "\n"; }# End Loop for ($Loop=1;$Loop<=3;$Loop++) { $incrementTip = $toothDetail + $Loop; $xRollerValNow[$BigLoop][$incrementTip] = ($xyMidPointX[$BigLoop] * $Units) + $WinCentX + ($LookAtAngleNewX[$BigLoop][$Loop] * $Units) + ($OutsideRad * $Units) + 10; $yRollerValNow[$BigLoop][$incrementTip] = ($xyMidPointY[$BigLoop] * $Units) + ($yRange + 40) - (($LookAtAngleNewY[$BigLoop][$Loop] * $Units) + ($OutsideRad * $Units) + 10); $xRollerOutPutUse[$BigLoop][$incrementTip] = ($xyMidPointX[$BigLoop]) + ($LookAtAngleNewX[$BigLoop][$Loop]) ; $yRollerOutPutUse[$BigLoop][$incrementTip] = ($xyMidPointY[$BigLoop]) - (($LookAtAngleNewY[$BigLoop][$Loop])); print $incrementTip . "\n"; }# End Loop }# End BigLoop for ($BigLoop=1;$BigLoop<=$defaultTeeth;$BigLoop++) { for ($Loop=1;$Loop<=$toothDetail-1;$Loop++) { $canvas->createLine ($xRollerValNow[$BigLoop][$Loop], $yRollerValNow[$BigLoop][$Loop], $xRollerValNow[$BigLoop][$Loop + 1], $yRollerValNow[$BigLoop][$Loop + 1], -fill => 'red'); }# End Loop # $id = $canvas->createText ($xRollerValNow[$BigLoop][$Loop], $yRollerValNow[$BigLoop][$Loop], -text => $BigLoop); for ($Loop=$toothDetail+1;$Loop<=$incrementTip-1;$Loop++) { $canvas->createLine ($xRollerValNow[$BigLoop][$Loop], $yRollerValNow[$BigLoop][$Loop], $xRollerValNow[$BigLoop][$Loop + 1], $yRollerValNow[$BigLoop][$Loop + 1], -fill => 'red'); }# End Loop # $id = $canvas->createText ($xRollerValNow[$BigLoop][$Loop], $yRollerValNow[$BigLoop][$Loop], -text => $BigLoop); }# End BigLoop for ($BigLoop=1;$BigLoop<=$defaultTeeth;$BigLoop++) { if ($BigLoop < $defaultTeeth){ $canvas->createLine ($xRollerValNow[$BigLoop][$toothDetail], $yRollerValNow[$BigLoop][$toothDetail], $xRollerValNow[$BigLoop+1][$toothDetail+1], $yRollerValNow[$BigLoop+1][$toothDetail+1], -fill => 'red'); } if ($BigLoop == $defaultTeeth){ $canvas->createLine ($xRollerValNow[$BigLoop][$toothDetail], $yRollerValNow[$BigLoop][$toothDetail], $xRollerValNow[1][$toothDetail+1], $yRollerValNow[1][$toothDetail+1], -fill => 'red'); } $canvas->createLine ($xRollerValNow[$BigLoop][$incrementTip], $yRollerValNow[$BigLoop][$incrementTip], $xRollerValNow[$BigLoop][1], $yRollerValNow[$BigLoop][1], -fill => 'red'); }# End BigLoop } # End CalcEllipseAngles sub writeOBJellipse { # Start writeOBJellipse ##mod this and add buttton. Mod other write obj button. open (FILE, ">" . $OBJellipsename ); print FILE ("####" . "\n"); print FILE ("#" . "\n"); print FILE ("# OBJ File Generated by LightWave 3D(TM)" . "\n"); print FILE ("#" . "\n"); print FILE ("####" . "\n"); print FILE ("# Object: Unnamed" . "\n"); print FILE ("#" . "\n"); print FILE ("# Vertices: " . $VertexNumber . "\n"); print FILE ("# Points: 0" . "\n"); print FILE ("# Lines: 0" . "\n"); print FILE ("# Faces: 0" . "\n"); print FILE ("# Materials: 1" . "\n"); print FILE ("#" . "\n"); print FILE ("####" . "\n"); print FILE ("\n"); print FILE ("# o Unnamed" . "\n"); print FILE ("\n"); print FILE ("# Vertex list" . "\n"); print FILE ("\n"); for ($BigLoop=1;$BigLoop<=$defaultTeeth;$BigLoop++) { for ($Loop=1;$Loop<=$toothDetail;$Loop++) { $XEllipseThing[$BigLoop][$Loop] = $xRollerOutPutUse[$BigLoop][$Loop] /39.37007874015748031496062992126; $YEllipseThing[$BigLoop][$Loop] = $yRollerOutPutUse[$BigLoop][$Loop]/39.37007874015748031496062992126; print FILE ("v " . $XEllipseThing[$BigLoop][$Loop] . " " . $YEllipseThing[$BigLoop][$Loop]); print FILE ("\n"); }# End Loop for ($Loop=$toothDetail+1;$Loop<=$toothDetail+3;$Loop++) { if ($BigLoop < $defaultTeeth){ $XEllipseThing[$BigLoop][$Loop] = $xRollerOutPutUse[$BigLoop+1][$Loop] /39.37007874015748031496062992126; $YEllipseThing[$BigLoop][$Loop] = $yRollerOutPutUse[$BigLoop+1][$Loop] /39.37007874015748031496062992126; print FILE ("v " . $XEllipseThing[$BigLoop][$Loop] . " " . $YEllipseThing[$BigLoop][$Loop]); print FILE ("\n"); } if ($BigLoop == $defaultTeeth){ $XEllipseThing[$BigLoop][$Loop] = $xRollerOutPutUse[1][$Loop] /39.37007874015748031496062992126; $YEllipseThing[$BigLoop][$Loop] = $yRollerOutPutUse[1][$Loop] /39.37007874015748031496062992126; print FILE ("v " . $XEllipseThing[$BigLoop][$Loop] . " " . $YEllipseThing[$BigLoop][$Loop]); print FILE ("\n"); } }# End Loop }# End BigLoop print FILE ("# Face list" . "\n"); print FILE ("\n"); print FILE ("f "); for ($Loop=1;$Loop<=$StartStartStart;$Loop++) { print FILE ($Loop . " "); } print FILE ("\n"); print FILE ("\n"); print FILE ("# End of file" . "\n"); close FILE; } # End writeOBJellipse ################################## ##################################### __END__ :endofperl