# finalVer.slf # Code for sculpture of 12 cylinders that are just touching each other # WM 6/1/2001 ####################################################################### tclinit { set winName .slfWindow source SLIDEUI.tcl source MATH.tcl set to_rad [expr $SLF_PI/180.0 ] CreateGroupUI $winName gRoot } tclinit { ### Calculate the angle alpha that makes the cylinder just touch the z-axis proc update { value } { global to_rad base_cl base_cr base_sr base_alf base_scal base_hh base_ss base_delta base_s2 base_angleW base_s3 base_angleV #### CALCULATING THE ANGLE ALPHA WHERE 2 CYLINDERS JUST TOUCH EACH OTHER set dd [expr $base_sr + $base_cr ] set uu [expr sqrt( $dd*$dd - $base_cr*$base_cr )* $base_cr / $dd ] set d2 [expr ( $dd*$dd - $base_cr*$base_cr )/ $dd ] set qq [expr $d2 / tan(30*$to_rad) ] set rat [expr $uu / $qq ] puts "" puts "INFORMATION ABOUT THE 2 CYLINDERS THAT ARE JUST TOUCHING" puts "========================================================" set base_alf [expr asin($uu/$qq)/$to_rad ] puts "Angle alpha rotation of the cylinders = $base_alf (ALPHA)" #### HEIGHT IN THE Z-AXIS WHERE THE 2 CYLINDERS JUST TOUCH set base_hh [expr (($dd*$dd)-($base_cr*$base_cr))/($dd*cos(60*$to_rad))] puts "Height in z-axis of the touching point = $base_hh" #### THE SIDE LENGTH OF THE CUBE set base_scal [expr $base_hh/0.707] #### LENGTH OF A CYLINDER WHERE THE 2 CYLINDERS JUST TOUCH #### THIS LENGTH IS MEASURED FROM CENTER OF CYLINDER set base_ss [expr sqrt( ($base_hh*$base_hh)-($dd*$dd)+($base_cr*$base_cr))] puts "Distance from the cylinder's center to the touching point= $base_ss (S1)" #### ANGLE ROTATION OF THE CYLINDER RADIUS TO THE POSITION WHERE THE 2 CYLINDERS #### JUST TOUCH set base_delta [expr -(180+(asin(-$base_ss*tan($base_alf*$to_rad)/$base_cr)/$to_rad))] puts "Angle delta rotation of cylinder's radius = $base_delta (DELTA)" #### CALCULATING THE POINTS THAT HAVE THE SHORTEST DISTANCE THAT CONNECTED #### BETWEEN 2 CYLINDERS set p1x [expr $base_cl*cos((35.24-$base_alf)*$to_rad)] set p1y [expr (-($base_sr + $base_cr)*cos(45*$to_rad))+($base_cl*sin(45*$to_rad)*sin((35.24-$base_alf)*$to_rad)) ] set p1z [expr (-($base_sr + $base_cr)*sin(45*$to_rad))-($base_cl*cos(45*$to_rad)*sin((35.24-$base_alf)*$to_rad)) ] set p2x [expr -$base_cl*cos((35.24-$base_alf)*$to_rad)] set p2y [expr (-($base_sr + $base_cr)*cos(45*$to_rad))-($base_cl*sin(45*$to_rad)*sin((35.24-$base_alf)*$to_rad)) ] set p2z [expr (-($base_sr + $base_cr)*sin(45*$to_rad))+($base_cl*cos(45*$to_rad)*sin((35.24-$base_alf)*$to_rad)) ] set rx3 [expr ($dd*cos(-30*$to_rad))+($base_cl*sin(-30*$to_rad)*cos($base_alf*$to_rad))] set ry3 [expr (-$dd*sin(-30*$to_rad))+($base_cl*cos(-30*$to_rad)*cos($base_alf*$to_rad))] set rz3 [expr $base_cl*sin($base_alf*$to_rad)] set p3x [expr ($rx3*cos(35.24*$to_rad))+($rz3*sin(35.24*$to_rad))] set p3y [expr ($ry3*cos(-45*$to_rad))-(sin(-45*$to_rad)*((-$rx3*sin(35.24*$to_rad))+($rz3*cos(35.24*$to_rad))))] set p3z [expr ($ry3*sin(-45*$to_rad))+(cos(-45*$to_rad)*((-$rx3*sin(35.24*$to_rad))+($rz3*cos(35.24*$to_rad))))] set rx4 [expr ($dd*cos(-30*$to_rad))-($base_cl*sin(-30*$to_rad)*cos($base_alf*$to_rad))] set ry4 [expr (-$dd*sin(-30*$to_rad))-($base_cl*cos(-30*$to_rad)*cos($base_alf*$to_rad))] set rz4 [expr -$base_cl*sin($base_alf*$to_rad)] set p4x [expr ($rx4*cos(35.24*$to_rad))+($rz4*sin(35.24*$to_rad))] set p4y [expr ($ry4*cos(-45*$to_rad))-(sin(-45*$to_rad)*((-$rx4*sin(35.24*$to_rad))+($rz4*cos(35.24*$to_rad))))] set p4z [expr ($ry4*sin(-45*$to_rad))+(cos(-45*$to_rad)*((-$rx4*sin(35.24*$to_rad))+($rz4*cos(35.24*$to_rad))))] set d1343 [expr (($p1x-$p3x)*($p4x-$p3x))+(($p1y-$p3y)*($p4y-$p3y))+(($p1z-$p3z)*($p4z-$p3z))] set d4321 [expr (($p4x-$p3x)*($p2x-$p1x))+(($p4y-$p3y)*($p2y-$p1y))+(($p4z-$p3z)*($p2z-$p1z))] set d1321 [expr (($p1x-$p3x)*($p2x-$p1x))+(($p1y-$p3y)*($p2y-$p1y))+(($p1z-$p3z)*($p2z-$p1z))] set d4343 [expr (($p4x-$p3x)*($p4x-$p3x))+(($p4y-$p3y)*($p4y-$p3y))+(($p4z-$p3z)*($p4z-$p3z))] set d2121 [expr (($p2x-$p1x)*($p2x-$p1x))+(($p2y-$p1y)*($p2y-$p1y))+(($p2z-$p1z)*($p2z-$p1z))] set mua [expr (($d1343*$d4321)-($d1321*$d4343))/(($d2121*$d4343)-($d4321*$d4321))] set mub [expr ($d1343 + ($mua * $d4321))/$d4343] puts "INFORMATION ABOUT THE SHORTEST DISTANCE BETWEEN 2 CYLINDERS" puts "===========================================================" set pax [expr $p1x + ($mua*($p2x-$p1x))] set pay [expr $p1y + ($mua*($p2y-$p1y))] set paz [expr $p1z + ($mua*($p2z-$p1z))] #puts "The first point = ($pax, $pay, $paz)" set pbx [expr $p3x + ($mub*($p4x-$p3x))] set pby [expr $p3y + ($mub*($p4y-$p3y))] set pbz [expr $p3z + ($mub*($p4z-$p3z))] #puts "The second point = ($pbx, $pby, $pbz)" set dt [expr sqrt(($pax-$pbx)*($pax-$pbx)+($pay-$pby)*($pay-$pby)+($paz-$pbz)*($paz-$pbz))] puts "The shortest distance between 2 cylinders = $dt" puts "The old cylinder radius = $base_cr" set base_cr [expr $dt/2] puts "The new cylinder radius = $base_cr" #### THE MIDDLE POINT OF THE SHORTEST LINE set mx [expr $pax - (0.5 * ($pax-$pbx))] set my [expr $pay - (0.5 * ($pay-$pby))] set mz [expr $paz - (0.5 * ($paz-$pbz))] #puts "The middle point = ($mx, $my, $mz)" ##### THE FIRST TOUCHING POINT puts "First Touching Point -->" ##### FINDING DISTANCE OF THE SHORTEST LINE THAT CONNECTED ANY 2 CYLINDERS ##### THIS DISTANCE IS FROM THE CENTER OF CYLINDER set dist2_x [expr ($mua*($p2x-$p1x))] set dist2_y [expr ($mua*($p2y-$p1y))] set dist2_z [expr ($mua*($p2z-$p1z))] set base_s3 [expr -(sqrt(($dist2_x*$dist2_x)+($dist2_y*$dist2_y)+($dist2_z*$dist2_z))-$base_cl)] puts "Distance from cylinder's center = $base_s3 (S3)" ##### FINDING ANGLE W OF THE SHORTEST LINE THAT CONNECTED ANY 2 CYLINDERS ##### THIS ANGLE IS CALCULATED WITH RESPECT TO X-AXIS OF THE CYLINDER set p1x [expr ($base_s3*cos(-$base_alf*$to_rad)*cos(35.24*$to_rad))-($base_s3*sin(-$base_alf*$to_rad)*sin(35.24*$to_rad))] set p1y [expr (-($base_cr+$dd)*cos(45*$to_rad))+($base_s3*cos(-$base_alf*$to_rad)*sin(35.24*$to_rad)*sin(45*$to_rad))+($base_s3*sin(-$base_alf*$to_rad)*cos(35.24*$to_rad)*sin(45*$to_rad))] set p1z [expr (-($base_cr+$dd)*sin(45*$to_rad))-($base_s3*cos(-$base_alf*$to_rad)*sin(35.24*$to_rad)*cos(45*$to_rad))-($base_s3*sin(-$base_alf*$to_rad)*cos(35.24*$to_rad)*cos(45*$to_rad))] set A [expr sqrt(($mx-$pax)*($mx-$pax)+($my-$pay)*($my-$pay)+($mz-$paz)*($mz-$paz))] set B [expr sqrt(($mx-$p1x)*($mx-$p1x)+($my-$p1y)*($my-$p1y)+($mz-$p1z)*($mz-$p1z))] set C [expr sqrt(($p1x-$pax)*($p1x-$pax)+($p1y-$pay)*($p1y-$pay)+($p1z-$paz)*($p1z-$paz))] set base_angleV [expr (acos((($A*$A)+($C*$C)-($B*$B))/(2*$A*$C))/$to_rad)] puts "Angle v rotation of the cylinder's radius = $base_angleV (V)" ##### THE SECOND TOUCHING POINT puts "Second Touching Point -->" ##### FINDING DISTANCE OF THE SHORTEST LINE THAT CONNECTED ANY 2 CYLINDERS ##### THIS DISTANCE IS FROM THE CENTER OF CYLINDER set dist_x [expr ($mub*($p4x-$p3x))] set dist_y [expr ($mub*($p4y-$p3y))] set dist_z [expr ($mub*($p4z-$p3z))] set base_s2 [expr -(sqrt(($dist_x*$dist_x)+($dist_y*$dist_y)+($dist_z*$dist_z))-$base_cl)] puts "Distance from cylinder's center = $base_s2 (S2)" ##### FINDING ANGLE W OF THE SHORTEST LINE THAT CONNECTED ANY 2 CYLINDERS ##### THIS ANGLE IS CALCULATED WITH RESPECT TO X-AXIS OF THE CYLINDER set rx [expr (cos(-30*$to_rad)*($base_cr+$dd))+($base_s2*cos($base_alf*$to_rad)*sin(-30*$to_rad))] set ry [expr (-sin(-30*$to_rad)*($base_cr+$dd))+($base_s2*cos($base_alf*$to_rad)*cos(-30*$to_rad))] set rz [expr $base_s2*sin($base_alf*$to_rad)] set p0x [expr ($rx*cos(35.24*$to_rad))+($rz*(sin(35.24*$to_rad)))] set p0y [expr ($ry*cos(-45*$to_rad))-(sin(-45*$to_rad)*((-$rx*sin(35.24*$to_rad))+($rz*cos(35.24*$to_rad))))] set p0z [expr ($ry*sin(-45*$to_rad))+(cos(-45*$to_rad)*((-$rx*sin(35.24*$to_rad))+($rz*cos(35.24*$to_rad))))] set A [expr sqrt(($mx-$pbx)*($mx-$pbx)+($my-$pby)*($my-$pby)+($mz-$pbz)*($mz-$pbz))] set B [expr sqrt(($mx-$p0x)*($mx-$p0x)+($my-$p0y)*($my-$p0y)+($mz-$p0z)*($mz-$p0z))] set C [expr sqrt(($p0x-$pbx)*($p0x-$pbx)+($p0y-$pby)*($p0y-$pby)+($p0z-$pbz)*($p0z-$pbz))] set base_angleW [expr -acos((($A*$A)+($C*$C)-($B*$B))/(2*$A*$C))/$to_rad] puts "Angle w rotation of the cylinder's radius = $base_angleW (W)" } proc CreateBaseUI { parent name } { set subname "slf_[subst $name]" if { $parent == {} } { set root .$subname } elseif { $parent == "." } { set root .$subname } else { set root $parent.$subname } toplevel $root set sr [CreateScaleCmd $name $root sr "sphere radius" 1 0.1 2.0 0.01 1 horizontal update] set cl [CreateScaleCmd $name $root cl "cylinder length" 1.25 0.2 5.0 0.01 1 horizontal update] set cr [CreateScaleCmd $name $root cr "cylinder radius" 0.265 0.1 2.0 0.001 1 horizontal update] set alf [CreateScale $name $root alf "rot angle alpha" 0 -90 90 1 1 horizontal] set slices [CreateScale $name $root slices "slices" 10 10 100 1 1 horizontal] set scal [CreateScaleCmd $name $root scal "scale factor" 0.1 0 10 0.001 1 horizontal update] set hh [CreateScaleCmd $name $root hh "height" 0.1 0 5 0.1 1 horizontal update] set ss [CreateScaleCmd $name $root ss "length1" 0.1 -5 5 0.01 1 horizontal update] set delta [CreateScaleCmd $name $root delta "angle1" 0 -180 180 1 1 horizontal update] set s2 [CreateScaleCmd $name $root s2 "length2" 0.1 -10 10 0.01 1 horizontal update] set angleW [CreateScaleCmd $name $root angleW "angle2" 0 -180 180 1 1 horizontal update] set s3 [CreateScaleCmd $name $root s3 "length3" 0.1 -10 10 0.01 1 horizontal update] set angleV [CreateScaleCmd $name $root angleV "angle3" 0 -180 180 1 1 horizontal update] pack $sr $cl $cr $alf $slices $scal $hh $ss $delta $s2 $angleW $s3 $angleV -side top -fill x } CreateBaseUI $winName base } surface BLU color (0.7 0.9 1.0) endsurface surface RED color (1 0 0) endsurface surface GREEN color (0 1 0) endsurface surface PURPLE color (1 0 1) endsurface cylinder cyl radius {expr $base_cr} zmin {expr -2*$base_cl} zmax {expr 2*$base_cl} begincap 1 endcap 1 thetaslices {expr $base_slices } endcylinder cylinder cyl2 radius {expr $base_cr} zmin 0 zmax {expr $base_cl} begincap 1 endcap 1 thetaslices {expr $base_slices } endcylinder sphere sph radius {expr $base_sr} zslices {expr $base_slices } thetaslices {expr $base_slices } endsphere cylinder cyl3 radius {expr $base_cr} zmin 0 zmax {expr $base_cr} begincap 1 endcap 1 thetaslices {expr $base_slices} endcylinder cylinder cyl4 radius {expr $base_cr} zmin 0 zmax {expr $base_ss} begincap 1 endcap 1 thetaslices {expr $base_slices} endcylinder ###1 cylinders with all its touching point (there are 6 points in total) group oneCylinder ###the cylinder instance cyl translate ( {expr $base_sr + $base_cr} 0 0) rotate ( 1 0 0 ) ({expr $base_alf}) rotate ( 0 1 0 ) ({expr -30}) endinstance ###distance from center of cylinders to the touching point (first end) instance cyl4 scale (0.02 0.02 1) translate ( {expr $base_sr + $base_cr} 0 0) rotate ( 1 0 0 ) ({expr $base_alf}) rotate ( 0 1 0 ) (-30) endinstance ###the point where the 2 cylinders touch (first touching point) instance cyl3 scale (0.02 0.02 1) rotate (1 0 0) ({expr $base_delta}) rotate (0 1 0) (90) translate ( { expr $base_sr + $base_cr} 0 {expr $base_ss}) rotate (1 0 0) ({expr $base_alf}) rotate (0 1 0) (-30) endinstance ###distance from center of cylinders to the touching point (second end) instance cyl4 scale (0.02 0.02 1) rotate ( 1 0 0) (180) translate ( {expr $base_sr + $base_cr} 0 0) rotate ( 1 0 0 ) ({expr $base_alf}) rotate ( 0 1 0 ) (-30) endinstance ###the point where the 2 cylinders touch (second touching point) instance cyl3 scale (0.02 0.02 1) rotate (1 0 0) ({expr -$base_delta}) rotate (0 1 0) (90) translate ( { expr $base_sr + $base_cr} 0 {expr -$base_ss}) rotate (1 0 0) ({expr $base_alf}) rotate (0 1 0) (-30) endinstance ###the point where the shortest distance between 2 cylinders are 2*cylinder's radius ###(third touching point) instance cyl3 scale (0.01 0.01 1) #rotate (0 1 0) (180) rotate (1 0 0) ({expr -$base_angleW}) rotate (0 1 0) (90) translate ( { expr $base_sr + $base_cr} 0 {expr -$base_s2}) rotate (1 0 0) ({expr $base_alf}) rotate (0 1 0) (-30) endinstance ###the point where the shortest distance between 2 cylinders are 2*cylinder's radius ###(forth touching point) instance cyl3 scale (0.01 0.01 1) rotate (1 0 0) ({expr $base_angleW}) rotate (0 1 0) (90) translate ( { expr $base_sr + $base_cr} 0 {expr $base_s2}) rotate (1 0 0) ({expr $base_alf}) rotate (0 1 0) (-30) endinstance ###the point where the shortest distance between 2 cylinders are 2*cylinder's radius ###(fifth touching point) instance cyl3 scale (0.01 0.01 1) rotate (1 0 0) ({expr -$base_angleV}) rotate (0 1 0) (90) translate ( { expr $base_sr + $base_cr} 0 {expr -$base_s3}) rotate (1 0 0) ({expr $base_alf}) rotate (0 1 0) (-30) endinstance ###the point where the shortest distance between 2 cylinders are 2*cylinder's radius ###(sixth touching point) instance cyl3 scale (0.01 0.01 1) rotate (1 0 0) ({expr $base_angleV}) rotate (0 1 0) (90) translate ( { expr $base_sr + $base_cr} 0 {expr $base_s3}) rotate (1 0 0) ({expr $base_alf}) rotate (0 1 0) (-30) endinstance endgroup ###group of 3 cylinders group threeCylinder instance oneCylinder ###extra rotation rotate ( 1 0 0) (-90) endinstance instance oneCylinder rotate (0 0 1) (180) ###extra rotation rotate ( 1 0 0) (-90) endinstance instance oneCylinder rotate (0 1 0) (30) rotate (1 0 0) ({expr -$base_alf}) translate ( {expr -($base_sr+$base_cr)} 0 0) rotate ( 0 1 0 ) (90) translate ( 0 0 {expr -($base_sr + $base_cr)} ) rotate ( 0 0 1) ({expr -$base_alf}) ###extra rotation rotate ( 1 0 0) (-90) endinstance endgroup ###the cube point p1 ( {expr 0.5*$base_scal} {expr 0.5*$base_scal} {expr 0.5*$base_scal} ) endpoint point p2 ( {expr -0.5*$base_scal} {expr 0.5*$base_scal} {expr 0.5*$base_scal} ) endpoint point p3 ( {expr 0.5*$base_scal} {expr -0.5*$base_scal} {expr 0.5*$base_scal} ) endpoint point p4 ( {expr -0.5*$base_scal} {expr -0.5*$base_scal} {expr 0.5*$base_scal} ) endpoint point p5 ( {expr 0.5*$base_scal} {expr 0.5*$base_scal} {expr -0.5*$base_scal} ) endpoint point p6 ( {expr -0.5*$base_scal} {expr 0.5*$base_scal} {expr -0.5*$base_scal} ) endpoint point p7 ( {expr 0.5*$base_scal} {expr -0.5*$base_scal} {expr -0.5*$base_scal} ) endpoint point p8 ( {expr -0.5*$base_scal} {expr -0.5*$base_scal} {expr -0.5*$base_scal} ) endpoint face f1 ( p1 p3 p7 p5 ) endface face f2 ( p2 p6 p8 p4 ) endface face f3 ( p1 p5 p6 p2 ) endface face f4 ( p3 p4 p8 p7 ) endface face f5 ( p1 p2 p4 p3 ) endface face f6 ( p5 p7 p8 p6 ) endface object cube ( f1 f2 f3 f4 f5 f6) endobject ###the instance of 4 triangles of cylinders group finalResult instance threeCylinder surface RED rotate (0 1 0) (35.24) rotate (1 0 0) (45) endinstance instance threeCylinder surface BLU rotate (0 1 0) (35.24) rotate (1 0 0) (-45) endinstance instance threeCylinder surface PURPLE rotate (0 0 1) (90) rotate (1 0 0) (-35.24) rotate (0 1 0) (-45) endinstance instance threeCylinder surface GREEN rotate (0 0 1) (-90) rotate (1 0 0) (35.24) rotate (0 1 0) (-45) endinstance instance cube shading SLF_WIRE endinstance endgroup group assembly ### final version instance finalResult shading SLF_WIRE endinstance endgroup ##################################### include "viewing.slf" #####################################