### DodHamSweep.slf
### Sweep along 20 edges on a Dodecahedron
### CHS 2004/10/15

### The polyline sweep in SLIDE is not properly done ==> FIX IT !
### there is a small twist occurring on each segment - 
### but there is no reason for it, and when the sweep curve is "open",
### and torsion minimization is enabled, then there should be no twist whatsoever!

###  I suspect a bad mapping of the profile through the joint!
#
# The way this _should_ be done is:
# look at the "sweep_curve" (polyline) tangent, TI,  of the segment going into a joint 
# and at TO, the tangent of the segment going out of it.
# When sweeping the profile through a joint,
# first turn the tangent only through half the total angle change,
# so that it is then perpendicular to the angle bisector plane at that joint.
# Now intersect the prismatic cross section of the incoming beam with this bisector plane
# to establish the vertices that need to be generated for forming a properly mitred corner.
#
# This intersection can be done cheaply, by taking the (constant) cross section 
# and simply stretching it non-uniformly (in the right direction) 
# by an amount equal to 1/cos(half angle of turn at joint).
# The tricky part is to establich the _direction_ of this non-uniform scaling!
# It shoud always be along the normal line which points directly into and out of the joint.
# One way to find this direction is to always establish a new coordinate system 
# at each subsequent joint, so that at the joint the x-axis is always the curve normal 
# pointing into the turn made by the sweep curve at that joint. 
# Let's further assume that the z-axis is always in the forward direction of the tangent.
# Then the actual turn of the sweep path at the joint is a turn around the local y axis.
#
# Now, as we go from one joint to the next, this local (Frenet-) frame 
# of the polyline sweep curve may need to make a torsional twist around the z-axis,
# so as to align the x-axis with the normal in each joint.
# The amount of the necessary twisting is determined by projecting the normal vector 
# from the previous joint and also the one from the current joint onto the normal plane
# of the sweep segment going into the current joint
# and measuring the angle between them in that normal plane.
# The cross sectional profile can now be rotated in its defining x-y-plane 
# by this amount, and then be temporarily stretched by 1/cos(half-angle),
# to define where the vertices of this mitred beam corner must be placed in 3D spce.
#
# I suspect that there might be something wrong with this angle calculation.
#############################################################################


tclinit {
  set winName .slfWINDOW
  
  source SLIDEUI.tcl
  source MATH.tcl
  
  proc CreateSliders { 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 profile [CreateScale $name $root profile "profile"     2.0  0.1  4.0  0.1  1 horizontal]
    set azim [CreateScale $name $root azim "azimuth"           0 -270 270 1 1 horizontal]
    set twist [CreateScale $name $root twist "overall twist"   0 -180 180 0.1  1 horizontal]
    pack  $profile  $azim  $twist   -side top -fill x
  }
  
  CreateSliders $winName slider
}

####################
# Profile
####################

point 	Y ( 0 {expr $slider_profile*0.1}  0) endpoint
point 	A ( {expr -$slider_profile*0.1}  0 0) endpoint
point 	B ( 0 {expr -$slider_profile*0.2}  0 ) endpoint
point 	X ( {expr $slider_profile*0.1}  0 0 ) endpoint

polyline crossx
  pointlist ( B X Y A B )
endpolyline

crosssection profile
  type polyline crossx
endcrosssection

crosssection circ
  type circle
  radius {expr $slider_profile*0.1}
  slices 4
endcrosssection

####################
# Path
####################

point 	Zx (	 0.381966  0  1 ) endpoint
point 	Za (	 -0.381966  0  1 ) endpoint
point 	Xy (	 1  0.381966  0 ) endpoint
point 	Xb (	 1  -0.381966  0 ) endpoint
point 	Ay (	 -1  0.381966  0 ) endpoint
point 	Ab (	 -1  -0.381966  0 ) endpoint
point 	Yz (	 0  1  0.381966 ) endpoint
point 	YY (	 0  1  0.1) endpoint
point 	Y0 (	 0  1  0) endpoint
point 	Yc (	 0  1  -0.381966 ) endpoint
point 	Bz (	 0  -1  0.381966 ) endpoint
point 	Bc (	 0  -1  -0.381966 ) endpoint
point 	Cx (	 0.381966  0  -1 ) endpoint
point 	Ca (	 -0.381966  0  -1 ) endpoint
point 	XYZ (	 0.618034  0.618034  0.618034 ) endpoint
point 	XBZ (	 0.618034  -0.618034  0.618034 ) endpoint
point 	AYZ (	 -0.618034  0.618034  0.618034 ) endpoint
point 	ABZ (	 -0.618034  -0.618034  0.618034 ) endpoint
point 	XYC (	 0.618034  0.618034  -0.618034 ) endpoint
point 	XBC (	 0.618034  -0.618034  -0.618034 ) endpoint
point 	AYC (	 -0.618034  0.618034  -0.618034 ) endpoint
point 	ABC (	 -0.618034  -0.618034  -0.618034 ) endpoint

polyline hampath
  pointlist ( Y0 YY Yz AYZ Ay AYC Ca Cx XBC Xb XBZ Bz Bc ABC Ab ABZ Za Zx XYZ Xy XYC Yc Y0 )
endpolyline

sweep beam
  path hampath 
     minimizetorsion 1  ## these two together should garantee that no segment is twisted !!
     closed 0
    azimuth {expr $slider_azim}
    twist {expr $slider_twist}  ## of course this must be kept at zero !
 endpath
  crosssection profile
    #crosssection circ
  endcrosssection
    #solid SLF_HOLLOW
endsweep


###########################################################


group assembly
  instance beam surface Y endinstance
(*  instance beam surface G 
    rotate( 0.309006 0.5 0 )(36)
    translate(0.894402 1.447238 0)
  endinstance
*)
endgroup

#################### VIEWING ###############################

surface K color (0.0 0.0 0.0) endsurface
surface R color (0.9 0.0 0.0) endsurface
surface B color (0.0 0.0 1.0) endsurface
surface Y color (1.0 1.0 0.1) endsurface
surface W color (1.0 1.0 1.0) endsurface
surface C color (0.0 1.0 1.0) endsurface
surface G color (0.0 1.0 0.0) endsurface
surface M color (1.0 0.0 1.0) endsurface
surface O color (1.0 0.6 0.0) endsurface
surface X color (0.5 0.5 0.5) endsurface

group World
  instance assembly
    scale (0.15 0.15 0.15)
    #shading SLF_WIRE
  endinstance
endgroup

#### CAMERA
camera cam
  projection SLF_PARALLEL
  #projection SLF_PERSPECTIVE
  frustum (-0.2 -0.2 -2) (0.2 0.2 -0.2)
endcamera

group gCamera
  instance cam
    id instCam
    translate (0.0 0.0 1.0)
  endinstance
endgroup

#### LIGHT
light lite
  type SLF_DIRECTIONAL
endlight

group gLight0
  instance lite
    id instLite0
    lookat
      eye (1.0 1.0 1.0)
      target (0.0 0.0 0.0)
      up (0.0 1.0 0.0)
    endlookat
  endinstance
endgroup

group gLight1
  instance lite
    id instLite1
    lookat
      eye (-1.0 -1.0 0.0)
      target (0.0 0.0 0.0)
      up (0.0 1.0 0.0)
    endlookat
  endinstance
endgroup


light lite2
  type SLF_AMBIENT
  color (0.3 0.3 0.3)
endlight

group gLight2
  instance lite2
    id instLite2
  endinstance
endgroup

#### RENDER

window WINDOW
  background (0.1 0.2 0.4)
endwindow

viewport VIEWPORT WINDOW
  origin (0.0 0.0)
  size (1.0 1.0)
endviewport

render VIEWPORT gCamera.instCam.cam World
  light gLight0.instLite0.lite
  light gLight1.instLite1.lite
  light gLight2.instLite2.lite2
endrender

######################################################################