[Top] [Prev] [Next] [Bottom]

## 2.3 movie.py: PyGist 3-D Animation

The module movie.py supports 3-D 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 3-D 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)
# (pseudo-colored 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
# 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 real-time animation. It is not possible to illustrate that here.

[Top] [Prev] [Next] [Bottom]

support@icf.llnl.gov