[Top] [Prev] [Next] [Bottom]
2.3 movie.py: PyGist 3D Animation
The module movie.py supports 3D real time animation. Function movie accepts as argument the name of a drawing function which has as its single argument a frame number; movie then calls this drawing function within a loop, halting when the function returns zero. The idea is that the drawing function increments from the previous frame and draws the new frame, returning zero when some predefined event takes place, e. g., some set number of frames has been drawn, or a certain amount of time has elapsed. The function spin3 in module pl3d calls movie; the drawing function _spin3 draws the successive frames of a rotating 3D plot. The demonstration module demo5.py contains an example of a shaded surface with a moving light source; the drawing function, demo5_light, moves the light and draws the next frame.
Examples
The following example is explained by comments in the code. It is taken from demo5.py. (To repeat, demo5_light is a function which appears in demo5.py.)
 # First we define the mesh and functions on it.
 # (Note: nx == ny == nz == 20)
 xyz = zeros ( (3, nx, ny, nz), Float)
 xyz [0] = multiply.outer ( span (1, 1, nx),
 ones ( (ny, nz), Float))
 xyz [1] = multiply.outer ( ones (nx, Float),
 multiply.outer ( span (1, 1, ny), ones (nz, Float)))
 xyz [2] = multiply.outer ( ones ( (nx, ny), Float),
 span (1, 1, nz))
 r = sqrt (xyz [0] ** 2 + xyz [1] **2 + xyz [2] **2)
 theta = arccos (xyz [2] / r)
 phi = arctan2 (xyz [1] , xyz [0] + logical_not (r))
 y32 = sin (theta) ** 2 * cos (theta) * cos (2 * phi)
 # mesh3 creates an object which slice3 can slice. The
 # isosurfaces will be with respect to constant values
 # of the function r * (1. + y32)].
 m3 = mesh3 (xyz, funcs = [r * (1. + y32)])
 [nv, xyzv, dum] = slice3 (m3, 1, None, None, value = .50)
 # (inner isosurface)
 [nw, xyzw, dum] = slice3 (m3, 1, None, None, value = 1.)
 # (outer isosurface)
 pxy = plane3 ( array ([0, 0, 1], Float ), zeros (3, Float))
 pyz = plane3 ( array ([1, 0, 0], Float ), zeros (3, Float))
 [np, xyzp, vp] = slice3 (m3, pyz, None, None, 1)
 # (pseudocolored plane slice)
 [np, xyzp, vp] = slice2 (pxy, np, xyzp, vp)
 # (cut slice in half, discard "back" part)
 [nv, xyzv, d1, nvb, xyzvb, d2] = \
 slice2x (pxy, nv, xyzv, None) # halve inner isosurface
 [nv, xyzv, d1] = \
 slice2 ( pyz, nv, xyzv, None)
 # (...halve one of those halves)
 [nw, xyzw, d1, nwb, xyzwb, d2] = \
 slice2x ( pxy , nw, xyzw, None)
 # (split outer isosurface in halves)
 [nw, xyzw, d1] = \
 slice2 ( pyz, nw, xyzw, None) # discard half of one half
 fma () # frame advance
 # split_palette causes isosurfaces to be shaded in grey
 # scale, plane sections to be colored by function values
 split_palette ("earth.gp")
 gnomon (1) # show small set of axes
 clear3 () # clears drawing list
 set_draw3_ (0) # Make sure we don't draw till ready
 # Create a tree of objects and put on drawing list
 pl3tree (np, xyzp, vp, pyz)
 pl3tree (nvb, xyzvb)
 pl3tree (nwb, xyzwb)
 pl3tree (nv, xyzv)
 pl3tree (nw, xyzw)
 orient3 ()
 # set lighting parameters for isosurfaces
 light3 (diffuse = .2, specular = 1)
 limits (square=1)
 demo5_light (1) # Causes drawing to appear

demo5.py also contains code which rotates the above object in realtime animation. It is not possible to illustrate that here.
[Top] [Prev] [Next] [Bottom]
support@icf.llnl.gov
Copyright © 1997,Regents of the University of California. All rights
reserved.