[0773bd] | 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
|
---|