| 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
 | 
|---|