# Scripts to save (and restore) VMD viewpoints and animate # a smooth 'camera move' between them. # #VMD --- start of VMD description block #Name: # view_change #Synopsis: # Four commands to save (and restore) VMD viewpoints, and animate # a smooth 'camera move' between them. #Version: # 1.0 #Uses VMD version: # 1.1 #Ease of use: # 2 #Procedures: #
  • save_viewpoint - save current viewpoint #
  • restore_viewpoint - change current viewpoint to a saved one #
  • move_view - smoothly move between saved viewpoints (see Warning) #
  • write_viewpoints - write viewpoints to a disk file (read back in via 'source') # # Warning: this script does the math cheaply, i.e. only interpolates # transformation matrices, many sorts of extreme viewpoint changes will look # odd to bizzare. This is often cured by segmenting a drastic camera move into # smaller ones. # # # # Usage: # In the vmd console type # save_viewpoint 1 # to save your current viewpoint # # type # restore_viewpoint 1 # to restore that viewpoint (You can replace '1' with an integer < 10000) # # After you've saved more than 1 viewpoint # move_view 1 43 # will restore viewpoint 1, then smoothly move to viewpoint 43. # Note warning above. Extreme moves that cause obvious protein distortion #can be done in two or three steps. # # To specify animation frames used, use # move_view 1 43 200 # will move from viewpoint 1 to 43 in 200 steps. If this is not specified, a # default 50 frames is used # # To specify smooth/jerky accelaration, use # move_view 1 43 200 smooth # or # move_view 1 43 200 sharp # # the 'smooth' option accelerates and deccelrates the transformation # the 'sharp' option gives constant velocity # # To write viewpoints to a file, # write_viewpoints my_viewpoint_file.tcl # # viewpoints with integer numbers 0-10000 are saved # # To restore viewpoints from a file, # source my_viewpoint_file.tcl # # #See also: # the VMD user's guide #Author: # Barry Isralewitz <barryi@ks.uiuc.edu> #Url: # http://www.ks.uiuc.edu/Research/vmd/script_library/view_change/ #\VMD --- end of block proc scale_mat {mat scaling} { set bigger "" set outmat "" for {set i 0} {$i<=3} {incr i} { set r "" for {set j 0} {$j<=3} {incr j} { lappend r [expr $scaling * [lindex [lindex [lindex $mat 0] $i] $j] ] } lappend outmat $r } lappend bigger $outmat return $bigger } proc div_mat {mat1 mat2} { set bigger "" set outmat "" for {set i 0} {$i<=3} {incr i} { set r "" for {set j 0} {$j<=3} {incr j} { lappend r [expr (0.0 + [lindex [lindex [lindex $mat1 0] $i] $j]) / ( [lindex [lindex [lindex $mat2 0] $i] $j] )] } lappend outmat $r } lappend bigger $outmat return $bigger } proc sub_mat {mat1 mat2} { set bigger "" set outmat "" for {set i 0} {$i<=3} {incr i} { set r "" for {set j 0} {$j<=3} {incr j} { lappend r [expr (0.0 + [lindex [lindex [lindex $mat1 0] $i] $j]) - ( [lindex [lindex [lindex $mat2 0] $i] $j] )] } lappend outmat $r } lappend bigger $outmat return $bigger } proc power_mat {mat thePower} { set bigger "" set outmat "" for {set i 0} {$i<=3} {incr i} { set r "" for {set j 0} {$j<=3} {incr j} { lappend r [expr pow( [lindex [lindex [lindex $mat 0] $i] $j], $thePower)] } lappend outmat $r } lappend bigger $outmat return $bigger } proc mult_mat {mat1 mat2} { set bigger "" set outmat "" for {set i 0} {$i<=3} {incr i} { set r "" for {set j 0} {$j<=3} {incr j} { lappend r [expr (0.0 + [lindex [lindex [lindex $mat1 0] $i] $j]) * [lindex [lindex [lindex $mat2 0] $i] $j] ] } lappend outmat $r } lappend bigger $outmat return $bigger } proc add_mat {mat1 mat2} { set bigger "" set outmat "" for {set i 0} {$i<=3} {incr i} { set r "" for {set j 0} {$j<=3} {incr j} { lappend r [expr (0.0 + [lindex [lindex [lindex $mat1 0] $i] $j]) + [lindex [lindex [lindex $mat2 0] $i] $j] ] } lappend outmat $r } lappend bigger $outmat return $bigger } proc write_viewpoints {filename} { global viewpoints set myfile [open $filename w] puts $myfile "\#This file contains viewpoints for a VMD script, view_change.tcl.\n\#Type 'source $filename' from the VMD command window to load these viewpoints.\n" foreach mol [molinfo list] { for {set v 0} {$v<=10000} {incr v} { if [info exists viewpoints($v,$mol,0)] { for {set mat 0} {$mat <= 3} {incr mat} { puts $myfile "set viewpoints($v,$mol,$mat) { $viewpoints($v,$mol,$mat) }\n " } } } } puts $myfile "puts \"\\nLoaded viewpoints file $filename \\n\"\n" close $myfile } proc save_viewpoint {view_num} { global viewpoints if [info exists viewpoints($view_num)] {unset viewpoints($view_num)} # get the current matricies foreach mol [molinfo list] { set viewpoints($view_num,$mol,0) [molinfo $mol get rotate_matrix] set viewpoints($view_num,$mol,1) [molinfo $mol get center_matrix] set viewpoints($view_num,$mol,2) [molinfo $mol get scale_matrix] set viewpoints($view_num,$mol,3) [molinfo $mol get global_matrix] } } proc restore_viewpoint {view_num} { global viewpoints foreach mol [molinfo list] { if [info exists viewpoints($view_num,$mol,0)] { molinfo $mol set rotate_matrix $viewpoints($view_num,$mol,0) molinfo $mol set center_matrix $viewpoints($view_num,$mol,1) molinfo $mol set scale_matrix $viewpoints($view_num,$mol,2) molinfo $mol set global_matrix $viewpoints($view_num,$mol,3) } else { puts "View $view_num was not saved"} } } proc move_view {start end {morph_frames 50} {accel smooth} } { global viewpoints foreach mol [molinfo list] { if [info exists viewpoints($start,$mol,0)] { set old_rotate($mol) $viewpoints($start,$mol,0) set old_center($mol) $viewpoints($start,$mol,1) set old_scale($mol) $viewpoints($start,$mol,2) set old_global($mol) $viewpoints($start,$mol,3) } else { puts "Starting view $start was not saved"} if [info exists viewpoints($end,$mol,0)] { set new_rotate($mol) $viewpoints($end,$mol,0) set new_center($mol) $viewpoints($end,$mol,1) set new_scale($mol) $viewpoints($end,$mol,2) set new_global($mol) $viewpoints($end,$mol,3) } else { puts "Ending view $end was not saved"} #leave if don't have both viewpoints if {! ([info exists viewpoints($start,$mol,0)] && [info exists viewpoints($end,$mol,0)]) } { error "move_view failed" } set old_rotate($mol) $viewpoints($start,$mol,0) set old_center($mol) $viewpoints($start,$mol,1) set old_scale($mol) $viewpoints($start,$mol,2) set old_global($mol) $viewpoints($start,$mol,3) restore_viewpoint $start set needed_rotate($mol) [sub_mat $new_rotate($mol) $old_rotate($mol)] set needed_center($mol) [sub_mat $new_center($mol) $old_center($mol)] set needed_scale($mol) [sub_mat $new_scale($mol) $old_scale($mol)] set needed_global($mol) [sub_mat $new_global($mol) $old_global($mol)] } for {set j 0} {$j<= ($morph_frames - 1)} {incr j} { foreach mol [molinfo list] { #set scaling to apply for this individual frame if {$accel == "smooth"} { #accelerate smoothkly to start and stop set theta [expr 3.1415927 * (0.0 + $j)/($morph_frames - 1)] set scale_factor [expr (1 -cos ($theta) ) /2] } else { #infinite acceleration to start and stop set scale_factor [expr (0.0 + $j)/($morph_frames - 1)] } if {$j == $morph_frames} { #correct for roundoff errors, so ends in correct position set scale_factor 1.0 } set current_rotate($mol) [add_mat $old_rotate($mol) [ scale_mat $needed_rotate($mol) $scale_factor] ] set current_center($mol) [add_mat $old_center($mol) [ scale_mat $needed_center($mol) $scale_factor] ] set current_scale($mol) [add_mat $old_scale($mol) [ scale_mat $needed_scale($mol) $scale_factor] ] set current_global($mol) [add_mat $old_global($mol) [ scale_mat $needed_global($mol) $scale_factor] ] molinfo $mol set rotate_matrix $current_rotate($mol) molinfo $mol set center_matrix $current_center($mol) molinfo $mol set scale_matrix $current_scale($mol) molinfo $mol set global_matrix $current_global($mol) } display update } }