Hi Mike,

I use a nifty little script from Laurence Pearl/ Lieven Buts called camera_view_travel, which creates smooth transitions between multiple views of your molecule. I then call their script from my movie script.

Here is my movie.pml

and below that is camera_view_travel.py

I hope this works for you.

Scott

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~

cmd.load("mypdb.pdb","qzr")
view1 = (\
              -0.002949848,   -0.698055983,   -0.716037512,\
              -0.740279794,   -0.479865283,    0.470865071,\
              -0.672290206,    0.531456172,   -0.515342116,\
               0.000092939,   -0.000034094, -227.434707642,\
              38.637485504,   38.187019348,   22.477689743,\
            -460.678192139,  915.540405273,    0.000000000 )
view2 = (\
              -0.150803298,   -0.738771021,    0.656000018,\
               0.031662170,   -0.666754782,   -0.744000018,\
               0.987798572,   -0.091690503,    0.125000000,\
               0.000000000,   -0.000000000,  -48.466648102,\
              99.343437195,  106.416229248,   49.609577179,\
              43.268760681,   55.180572510,    0.000000000 )
view3 = (\
              -0.651145101,   -0.722359359,   -0.231482551,\
               0.758700788,   -0.608253777,   -0.234109432,\
               0.028105801,   -0.327993184,    0.943701327,\
              -0.000000000,   -0.000000000, -328.826995850,\
             105.788002014,  119.598999023,   45.796001434,\
             262.966003418,  413.899993896,    0.000000000 )
view4 = (\
               0.567574024,   -0.024119442,   -0.822590053,\
               0.327888340,   -0.910298526,    0.253481865,\
              -0.754531145,   -0.413324833,   -0.508710921,\
              -0.034031108,    0.024049886, -295.808410645,\
             103.350708008,  111.262390137,   42.889659882,\
             230.753021240,  383.078033447,    0.000000000 )    
cmd.set_view(view1)
cmd.hide("all")
cmd.show("lines","n;c,ca,n")
cmd.mset("1 x525")
camera_view_travel(1,99,view2)
camera_view_travel(125,100,view1)
camera_view_travel(250,50,view3)
camera_view_travel(325,50,view4)
camera_view_travel(400,50,view3)
camera_view_travel(475,50,view1)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

and here is camera_view_travel.py

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# camera_travel - Laurence Pearl, November 2003
#     Pythonized by Lieven Buts, November 2003

import cmd
from math import sqrt,acos,sin

def quaternion(view):
        """
        Returns a quaternion representation of a view matrix.
        """

        nxt = [1,2,0]
        q = [0.0,0.0,0.0,1.0]

        tr = view[0]+view[4]+view[8]

        if tr > 0.0 :
                s = sqrt(tr + 1.0)
                qw1 = s / 2.0
                s = 0.5 / s
                return ( (view[5] - view[7]) * s,
                         (view[6] - view[2]) * s,
                         (view[1] - view[3]) * s,
                         qw1                      )
        else :
                i = 0
                if (view[4] > view[0]):     i = 1
                if (view[8] > view[i+3*i]): i = 2
                j = nxt[i]
                k = nxt[j]
s = sqrt ((view[i+i*3] - (view[j+j*3] + view[k+k*3])) + 1.0)
                q[i] = s * 0.5
                if (s != 0.0): s = 0.5 / s
                q[3] = (view[k+3*j] - view[j+3*k]) * s
                q[j] = (view[j+3*i] + view[i+3*j]) * s
                q[k] = (view[k+3*i] + view[i+3*k]) * s
                return q

def camera_travel(first,nframes=30,sel='(all)',zflag=0,zlevel=2):
        """
        Generate progressive view matrices to move the camera smoothly
        from the current view to a view defined by a PyMol selection.

        first   - start frame
        nframes - duration
sel - atom selection that defines the orientation at the end of the
                  sequence
        zflag   - flag to indicate whether the final view should be 'zoomed'
                  or not
        zlevel  - buffer space for zooming final view (as in cmd.zoom)
        """

        try:
                first=int(first)
        except:
                print "camera_travel: first frame must be an integer"
                return -1
        
        try:
                nframes=int(nframes)
        except:
                print "camera_travel: number of frames"

        ff=float(1.0/nframes)

        old_view = cmd.get_view(2)

#       print ( "view : (" + "%8.3f, "*17 + "%8.3f)" ) % (old_view)
# print "oldtran : %8.3f %8.3f %8.3f" % (old_view[12], old_view[13], old_view[14])

#       do orient operation on selection
        cmd.orient(sel,0)

#       if zoom to selection is required add this into view matrix
        if zflag:
                cmd.zoom(sel,zlevel,0,1)

#       get new view
        new_view = cmd.get_view()

#       capture new zoom/clip parameters
        ozc1 = new_view[11]
        ozc2 = new_view[15]
        ozc3 = new_view[16]

#       calculate shift in zoom/clip parameters
        dzc1 = (ozc1 - old_view[11]) * ff
        dzc2 = (ozc2 - old_view[15]) * ff
        dzc3 = (ozc3 - old_view[16]) * ff

        ozc1 = old_view[11]
        ozc2 = old_view[15]
        ozc3 = old_view[16]

#       capture new translation vector component
        ox = new_view[12]
        oy = new_view[13]
        oz = new_view[14]

#       calculate shift vector
        dx = ox - old_view[12]
        dy = oy - old_view[13]
        dz = oz - old_view[14]

        dx = dx*ff
        dy = dy*ff
        dz = dz*ff

        ox = old_view[12]
        oy = old_view[13]
        oz = old_view[14]


# capture old and new rotation matrix components in quaternion form

#       m[0][0] = v[0]  m[0][1] = v[1]  m[0][2] = v[2]
#       m[1][0] = v[3]  m[1][1] = v[4]  m[1][2] = v[5]
#       m[2][0] = v[6]  m[2][1] = v[7]  m[2][2] = v[8]

        qx1,qy1,qz1,qw1 = quaternion(old_view)
        qx2,qy2,qz2,qw2 = quaternion(new_view)

#       calc cosine
        cosom = qx1 * qx2 + qy1 * qy2 + qz1 * qz2 + qw1 * qw2

        limit = 0.001
        if cosom>1.0+limit:
                raise ValueError,"Cosine of omega way out of range (positive)"
        elif cosom>1.0:
                print "Warning: cosom corrected from ",cosom,"to",
                cosom = 1.0
                print cosom

        if cosom<-1.0-limit:
                raise ValueError,"Cosine of omega way out of range (negative)"
        elif cosom<-1.0:
                print "Warning: cosom corrected from ",cosom,"to",
                cosom = 1.0
                print cosom

#       adjust signs
        if (cosom < 0.0):
                cosom = -cosom
                to0 = -qx2
                to1 = -qy2
                to2 = -qz2
                to3 = -qw2
        else:
                to0 = qx2
                to1 = qy2
                to2 = qz2
                to3 = qw2

#       calc coefficients
        omega = acos(cosom)
        sinom = sin(omega)
        if sinom==0.0:
                sinom=limit
                print "Warning: sinom corrected!"

#       restore old view
        cmd.set_view( ("%8.3f, " * 17 + "%8.3f") % tuple(old_view) )

# loop interpolating over nframes generating interpolated quaternion
        for a in range(nframes+1):
                scale0 = sin((1.0 - float(a*ff)) * omega) / sinom
                scale1 = sin(float(a*ff) * omega) / sinom
                rx = scale0 * qx1 + scale1 * to0;
                ry = scale0 * qy1 + scale1 * to1;
                rz = scale0 * qz1 + scale1 * to2;
                rw = scale0 * qw1 + scale1 * to3;

                # convert back to matrix
                x2 = rx + rx
                y2 = ry + ry
                z2 = rz + rz
                xx = rx * x2
                xy = rx * y2
                xz = rx * z2
                yy = ry * y2
                yz = ry * z2
                zz = rz * z2
                wx = rw * x2
                wy = rw * y2
                wz = rw * z2

                nv0 = 1.0 - (yy + zz)
                nv3 = xy - wz
                nv6 = xz + wy

                nv1 = xy + wz
                nv4 = 1.0 - (xx + zz)
                nv7 = yz - wx

                nv2 = xz - wy
                nv5 = yz + wx
                nv8 = 1.0 - (xx + yy)

                # update translation vector
                ox = ox + dx
                oy = oy + dy
                oz = oz + dz

                # update zoom/clip parameters if required

                if zflag:
                        ozc1 = ozc1 + dzc1
                        ozc2 = ozc2 + dzc2
                        ozc3 = ozc3 + dzc3

cmd.mdo("%d" % (first), ("set_view (" + "%8.3f, "*17 + "%8.3f)") % (nv0,nv1,nv2,nv3,nv4,nv5,nv6,nv7,nv8,old_view[9],old_view[10],ozc1,
                       ox,oy,oz,ozc2,ozc3,old_view[17]))
                first += 1

        cmd.set_view( ("%8.3f, "*17 + "%8.3f") %
(nv0,nv1,nv2,nv3,nv4,nv5,nv6,nv7,nv8,old_view[9],old_view[10],ozc1,
                    ox,oy,oz,ozc2,ozc3,old_view[17]))


def camera_view_travel(first,nframes=30,new_view=(\
1.000000000, 0.000000000, 0.000000000,\
                                                      0.000000000,    
1.000000000,    0.000000000,\
                                                      0.000000000,    
0.000000000,    1.000000000,\
                                                      0.000000000,    
0.000000000,  -50.000000000,\
                                                      0.000000000,    
0.000000000,    0.000000000,\
                                                      40.000000000,  
100.000000000,    0.000000000 )):
        """
        Generate progressive view matrices to move the camera smoothly
        from the current view to a new view provided as an argument.

        first   - start frame
        nframes - duration
new_view - PyMol view matrix that defines the view at the end of the sequence
        """

        try:
                first=int(first)
        except:
                print "camera_travel: first frame must be an integer"
                return -1
        
        try:
                nframes=int(nframes)
        except:
                print "camera_travel: number of frames"

        ff=float(1.0/nframes)

        old_view = cmd.get_view(2)

#       print ( "view : (" + "%8.3f, "*17 + "%8.3f)" ) % (old_view)
# print "oldtran : %8.3f %8.3f %8.3f" % (old_view[12], old_view[13], old_view[14])

#       capture new zoom/clip parameters
        ozc1 = new_view[11]
        ozc2 = new_view[15]
        ozc3 = new_view[16]

#       calculate shift in zoom/clip parameters
        dzc1 = (ozc1 - old_view[11]) * ff
        dzc2 = (ozc2 - old_view[15]) * ff
        dzc3 = (ozc3 - old_view[16]) * ff

        ozc1 = old_view[11]
        ozc2 = old_view[15]
        ozc3 = old_view[16]

#       capture new translation vector component
        ox = new_view[12]
        oy = new_view[13]
        oz = new_view[14]

#       calculate shift vector
        dx = ox - old_view[12]
        dy = oy - old_view[13]
        dz = oz - old_view[14]

        dx = dx*ff
        dy = dy*ff
        dz = dz*ff

        ox = old_view[12]
        oy = old_view[13]
        oz = old_view[14]


# capture old and new rotation matrix components in quaternion form

#       m[0][0] = v[0]  m[0][1] = v[1]  m[0][2] = v[2]
#       m[1][0] = v[3]  m[1][1] = v[4]  m[1][2] = v[5]
#       m[2][0] = v[6]  m[2][1] = v[7]  m[2][2] = v[8]

        qx1,qy1,qz1,qw1 = quaternion(old_view)
        qx2,qy2,qz2,qw2 = quaternion(new_view)

#       calc cosine
        cosom = qx1 * qx2 + qy1 * qy2 + qz1 * qz2 + qw1 * qw2

        limit = 0.001
        if cosom>1.0+limit:
                raise ValueError,"Cosine of omega way out of range (positive)"
        elif cosom>1.0:
                print "Warning: cosom corrected from ",cosom,"to",
                cosom = 1.0
                print cosom

        if cosom<-1.0-limit:
                raise ValueError,"Cosine of omega way out of range (negative)"
        elif cosom<-1.0:
                print "Warning: cosom corrected from ",cosom,"to",
                cosom = 1.0
                print cosom

#       adjust signs
        if (cosom < 0.0):
                cosom = -cosom
                to0 = -qx2
                to1 = -qy2
                to2 = -qz2
                to3 = -qw2
        else:
                to0 = qx2
                to1 = qy2
                to2 = qz2
                to3 = qw2

#       calc coefficients
        omega = acos(cosom)
        sinom = sin(omega)
        if sinom==0.0:
                sinom=limit
                print "Warning: sinom corrected!"

#       restore old view
        cmd.set_view( ("%8.3f, " * 17 + "%8.3f") % tuple(old_view) )

# loop interpolating over nframes generating interpolated quaternion
        for a in range(nframes+1):
                scale0 = sin((1.0 - float(a*ff)) * omega) / sinom
                scale1 = sin(float(a*ff) * omega) / sinom
                rx = scale0 * qx1 + scale1 * to0;
                ry = scale0 * qy1 + scale1 * to1;
                rz = scale0 * qz1 + scale1 * to2;
                rw = scale0 * qw1 + scale1 * to3;

                # convert back to matrix
                x2 = rx + rx
                y2 = ry + ry
                z2 = rz + rz
                xx = rx * x2
                xy = rx * y2
                xz = rx * z2
                yy = ry * y2
                yz = ry * z2
                zz = rz * z2
                wx = rw * x2
                wy = rw * y2
                wz = rw * z2

                nv0 = 1.0 - (yy + zz)
                nv3 = xy - wz
                nv6 = xz + wy

                nv1 = xy + wz
                nv4 = 1.0 - (xx + zz)
                nv7 = yz - wx

                nv2 = xz - wy
                nv5 = yz + wx
                nv8 = 1.0 - (xx + yy)

                # update translation vector
                ox = ox + dx
                oy = oy + dy
                oz = oz + dz

                # update zoom/clip parameters

                ozc1 = ozc1 + dzc1
                ozc2 = ozc2 + dzc2
                ozc3 = ozc3 + dzc3

cmd.mdo("%d" % (first), ("set_view (" + "%8.3f, "*17 + "%8.3f)") % (nv0,nv1,nv2,nv3,nv4,nv5,nv6,nv7,nv8,old_view[9],old_view[10],ozc1,
                       ox,oy,oz,ozc2,ozc3,old_view[17]))
                first += 1

        cmd.set_view( ("%8.3f, "*17 + "%8.3f") %
(nv0,nv1,nv2,nv3,nv4,nv5,nv6,nv7,nv8,old_view[9],old_view[10],ozc1,
                    ox,oy,oz,ozc2,ozc3,old_view[17]))



def fly_sequence(object,first,last):
        """
        Visit all residues in an object consecutively.
        
        Requires 15 movie frames per residue.

        object -
        first -
        last -
        """
        
        fr=1
        for ires in range(int(first),int(last)+1):
                res = "(" + object + (" and resi %d" % (ires,)) + ")"
                camera_travel(fr,9,res,1,2)
                fr = fr + 15


# Install new PyMol commands
cmd.extend("seqfly",fly_sequence)
cmd.extend("camtrav",camera_travel)
cmd.extend("camvtrav",camera_view_travel)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

On Apr 13, 2005, at 11:37 PM, Mike Osborne wrote:

Hello again pymolers
I have a question about the view matrices. Basically I would like to go from
one view to another view gradually in a movie.
Is there a way to calculate from the view matrices, how much I need to rotate
around x,y, and Z and move in x, y and z?
I'm sure it can be done, but haven't figured it out.
Thanks in advance
Mike

--
Mike Osborne
Iric-Institut de Recherche en Immunovirologie et Cancérologie
Université de Montréal
2950 Chemin Polytechnique
Pavillon Marcelle-Coutu
Bureau S2-122
Montreal, Quebec, H3T 1J4
michael.osbo...@umontreal.ca
Ph: (514) 343 6111 ext. 0534 (NMR)/ 0595 (Office)
Fax: (514) 343 7379



-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id396&op=click
_______________________________________________
PyMOL-users mailing list
PyMOL-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/pymol-users


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  Scott Classen, Ph.D.
  ACS Postdoctoral Fellow
  Department of Molecular & Cell Biology
  University of California, Berkeley
  237 Hildebrand Hall #3206
  Berkeley, CA 94720-3206
  LAB 510.643.9491
  FAX 510.643.9290
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Reply via email to