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