For construction of image, a “glass cube” is helpful for snapping points. An additional tool displays one.
namespace eval GlassCube { namespace import ::tcl::mathfunc::* ::tcl::mathop::* proc p3D {x y z} { dict create\ x [+ 125.0 $x]\ y [+ 125.0 $y]\ z [+ 125.0 $z] } variable center [p3D 0 0 0] variable baseCube [list\ [p3D -50 -50 -50]\ [p3D 50 -50 -50]\ [p3D 50 50 -50]\ [p3D -50 50 -50]\ [p3D -50 -50 50]\ [p3D 50 -50 50]\ [p3D 50 50 50]\ [p3D -50 50 50]] proc dotOptions 3Dpoint { list -x [dict get $3Dpoint x] -y [dict get $3Dpoint y] } variable dots [lmap pt $baseCube {obj new dot {*}[dotOptions $pt]}] proc line {a b} { variable dots obj new line [lindex $dots $a] [lindex $dots $b] } variable group [obj new group -constraint { gravity noprint linecolor linewidth } [line 4 5] [line 5 6] [line 6 7] [line 7 4]\ [line 0 4] [line 1 5] [line 2 6] [line 3 7]\ [line 0 1] [line 1 2] [line 2 3] [line 3 0]] variable phi 0 variable chi 0 }
proc GlassCube::rotate {x y phi cX cY} { # coords x, y rotated by phi around cX, cY set c [cos $phi] set s [sin $phi] list\ [expr {($x - $cX) * $c - ($y - $cY) * $s + $cX}]\ [expr {($y - $cY) * $c + ($x - $cX) * $s + $cY}] }
proc GlassCube::rotateYaxis {3Dpoint phi} { variable center set cX [dict get $center x] set cY [dict get $center z] set x [dict get $3Dpoint x] set y [dict get $3Dpoint z] lassign [rotate $x $y $phi $cX $cY] x y dict set 3Dpoint x $x dict set 3Dpoint z $y }
proc GlassCube::rotateXaxis {3Dpoint phi} { variable center set cX [dict get $center z] set cY [dict get $center y] set x [dict get $3Dpoint z] set y [dict get $3Dpoint y] lassign [rotate $x $y $phi $cX $cY] x y dict set 3Dpoint z $x dict set 3Dpoint y $y }
proc GlassCube::rotateCube {cube phi chi} { set cube [lmap pt $cube {rotateYaxis $pt $phi}] set cube [lmap pt $cube {rotateXaxis $pt $chi}] }
proc GlassCube::glassCube {} { variable phi variable chi variable group variable baseCube variable dots foreach dot $dots p3d [rotateCube $baseCube [degree $phi] [degree $chi]] { $dot configure {*}[dotOptions $p3d] } $group draw }
proc GlassCube::pi args [subst -novariable {expr "[acos -1] $args"}]
proc GlassCube::slider {canvas {onoff on}} { destroy $canvas.horizontal $canvas.vertical if {$onoff} then { variable group foreach element [$group elements] { if {[incr i] < 5} then { $element configure -outline grey72 } elseif {$i < 9} then { $element configure -outline grey60 } else { $element configure -outline grey30 } } set horizontal [scale $canvas.horizontal -orient horizontal\ -from -90 -to 90 -resolution -1 -showvalue no\ -variable [namespace current]::phi\ -command [list apply [list num { glassCube } [namespace current]]]] set vertical [scale $canvas.vertical -orient vertical\ -from 90 -to -90 -resolution -1 -showvalue no\ -variable [namespace current]::chi\ -command [list apply [list num { glassCube } [namespace current]]]] place $horizontal -anchor sw -relwidth 1.0 -relx 0.0 -rely 1.0\ -width -[winfo reqwidth $vertical] place $vertical -anchor ne -relheight 1.0 -relx 1.0 -rely 0.0\ -height -[winfo reqheight $horizontal] bind $horizontal <<ControlClick>> "$horizontal set 0; break" bind $vertical <<ControlClick>> "$vertical set 0; break" set group } }
© Wolf-Dieter Busch | Home | Sitemap | Urheber | A-Z