| 1 | #!/usr/bin/tclsh | 
|---|
| 2 | # | 
|---|
| 3 | # This scripts displays the rolling sphere used in the tesselation procedure | 
|---|
| 4 | # to compute the molecular surface via VMD's graphics interface. | 
|---|
| 5 | # It is used during debugging and all its parameters are thrown out by an | 
|---|
| 6 | # error message in CandidateForTesselation.cpp. | 
|---|
| 7 |  | 
|---|
| 8 |  | 
|---|
| 9 | proc animate_sphere { molid atomid1 atomid2 atomid3 rad x1 y1 z1 x2 y2 z2 {step 25} } { | 
|---|
| 10 | global SphereRadius | 
|---|
| 11 | global vector1 | 
|---|
| 12 | global vector2 | 
|---|
| 13 | global CircleCenter | 
|---|
| 14 | global angle | 
|---|
| 15 | global radius | 
|---|
| 16 | global M_PI | 
|---|
| 17 | set SphereRadius $rad | 
|---|
| 18 |  | 
|---|
| 19 | # avoid some 'animate dup' bug | 
|---|
| 20 | set molid [molinfo $molid get id] | 
|---|
| 21 | # check molid | 
|---|
| 22 | if {[molinfo $molid get numframes] != 1} { | 
|---|
| 23 | error "Can't find $molid or more than 1 frame." | 
|---|
| 24 | } | 
|---|
| 25 | # step must be integer and greater 2 | 
|---|
| 26 | if {$step != int($step)} { | 
|---|
| 27 | error "step must be integer." | 
|---|
| 28 | } | 
|---|
| 29 | if {$step < 2} { | 
|---|
| 30 | error "step should be greater than 2." | 
|---|
| 31 | } | 
|---|
| 32 | # make step-1 copies of current frame | 
|---|
| 33 | for {set i 1} {$i <$step} {incr i} { | 
|---|
| 34 | animate dup frame 0 $molid | 
|---|
| 35 | } | 
|---|
| 36 |  | 
|---|
| 37 | # select both atoms | 
|---|
| 38 | incr atomid1 -1 | 
|---|
| 39 | incr atomid2 -1 | 
|---|
| 40 | incr atomid3 -1 | 
|---|
| 41 | set selid1 [atomselect $molid "index $atomid1" frame 0] | 
|---|
| 42 | set selid2 [atomselect $molid "index $atomid2" frame 0] | 
|---|
| 43 | set selid3 [atomselect $molid "index $atomid3" frame 0] | 
|---|
| 44 |  | 
|---|
| 45 | # calculate origin of rotation | 
|---|
| 46 | set Atom1 [$selid1 get {x y z}] | 
|---|
| 47 | puts "Atom1 is $Atom1." | 
|---|
| 48 | set Atom2 [$selid2 get {x y z}] | 
|---|
| 49 | puts "Atom2 is $Atom2." | 
|---|
| 50 | set Atom3 [$selid3 get {x y z}] | 
|---|
| 51 | puts "Atom3 is $Atom3." | 
|---|
| 52 | set CircleCenter [vecadd [vecscale 0.5 [expr $Atom1]] [vecscale 0.5 [expr $Atom2]]] | 
|---|
| 53 | set CircleCenter [vecadd [vecscale 0.5 [expr $Atom1]] [vecscale 0.5 [expr $Atom2]]] | 
|---|
| 54 | puts "CircleCenter is at $CircleCenter." | 
|---|
| 55 |  | 
|---|
| 56 | # calculate normal | 
|---|
| 57 | set Normaltmp [vecsub [expr $Atom1] [expr $Atom2]] | 
|---|
| 58 | set CirclePlaneNormal [vecnorm $Normaltmp] | 
|---|
| 59 | puts "CirclePlaneNormal is at $CirclePlaneNormal." | 
|---|
| 60 |  | 
|---|
| 61 | # calculate radius | 
|---|
| 62 | set SphereCenter [vecsub [list $x1 $y1 $z1] $CircleCenter] | 
|---|
| 63 | puts "SphereCenter is at $SphereCenter." | 
|---|
| 64 | set OtherSphereCenter [vecsub [list $x2 $y2 $z2] $CircleCenter] | 
|---|
| 65 | puts "OtherSphereCenter is at $OtherSphereCenter." | 
|---|
| 66 | set radius [veclength $SphereCenter] | 
|---|
| 67 | puts "Radius of circle is $radius." | 
|---|
| 68 | set vector1 [vecnorm $SphereCenter] | 
|---|
| 69 | puts "vector1 is $vector1." | 
|---|
| 70 |  | 
|---|
| 71 | # calculate other normal vector on plane, pointing out of triangle | 
|---|
| 72 | set vector2 [veccross $CirclePlaneNormal $vector1] | 
|---|
| 73 | set helper [vecsub $CircleCenter [expr $Atom3]] | 
|---|
| 74 | if {[vecdot $helper $vector2] < -1e-10} { | 
|---|
| 75 | puts "vector2 points inwards, rescaling." | 
|---|
| 76 | set vector2 [vecscale -1. $vector2] | 
|---|
| 77 | } | 
|---|
| 78 | puts "vector2 is $vector2." | 
|---|
| 79 |  | 
|---|
| 80 | # get angle | 
|---|
| 81 | set angle [expr acos([vecdot $SphereCenter $OtherSphereCenter]/[veclength $SphereCenter]/[veclength $OtherSphereCenter])] | 
|---|
| 82 |  | 
|---|
| 83 | # make angle in right direction (rotating outward in the sense of vector2 | 
|---|
| 84 | set SKP [vecdot $OtherSphereCenter $vector2] | 
|---|
| 85 | puts "SKP with SearchDirection is $SKP." | 
|---|
| 86 | if {$SKP < -1e-10} { | 
|---|
| 87 | set angle [expr 2.*$M_PI - $angle] | 
|---|
| 88 | } | 
|---|
| 89 | puts "angle is $angle." | 
|---|
| 90 |  | 
|---|
| 91 | global vmd_frame | 
|---|
| 92 | trace variable vmd_frame([molinfo top]) w update_current_sphere | 
|---|
| 93 | display update | 
|---|
| 94 | #enumerate_atoms 0 | 
|---|
| 95 | return | 
|---|
| 96 | } | 
|---|
| 97 |  | 
|---|
| 98 | proc update_current_sphere {name index op} { | 
|---|
| 99 | global SphereRadius | 
|---|
| 100 | global radius | 
|---|
| 101 | global angle | 
|---|
| 102 | global vector1 | 
|---|
| 103 | global vector2 | 
|---|
| 104 | global CircleCenter | 
|---|
| 105 | # draw sphere | 
|---|
| 106 | set CurrentAngle [expr ($angle/[expr [molinfo $index get numframes]-1])*[molinfo $index get frame]] | 
|---|
| 107 | set center [vecadd [vecscale $radius [vecadd [vecscale [expr cos($CurrentAngle)] $vector1] [vecscale [expr sin($CurrentAngle)] $vector2]]] $CircleCenter] | 
|---|
| 108 | #puts "center is now at $center with CurrentAngle is $CurrentAngle and radius $SphereRadius." | 
|---|
| 109 | draw material Transparent | 
|---|
| 110 | draw color silver | 
|---|
| 111 | if {[draw exists 2] != 0} { | 
|---|
| 112 | draw replace 2 | 
|---|
| 113 | } | 
|---|
| 114 | draw sphere $center radius [expr $SphereRadius] resolution 30 | 
|---|
| 115 | return | 
|---|
| 116 | } | 
|---|
| 117 |  | 
|---|
| 118 | proc animate_sphere_off {} { | 
|---|
| 119 | global vmd_frame | 
|---|
| 120 | trace vdelete vmd_frame([molinfo top]) w update_current_sphere | 
|---|
| 121 | draw delete all | 
|---|
| 122 | animate delete beg 1 end 25 skip 0 [molinfo top] | 
|---|
| 123 | return | 
|---|
| 124 | } | 
|---|
| 125 |  | 
|---|
| 126 | #enumerate_atoms 0 | 
|---|
| 127 | #animate_sphere 0 15 6 3. 4.00145 1.4968 1.28282 1.97354 -2.53854 -1.81601 | 
|---|