The Python module pl3d.py contains the basic 3-D plotting algorithms and is the workhorse of the PyGist 3-D graphics. The philosophy behind 3-D plotting is to instruct the 3-D plotting functions to accumulate information about the plot until such time as the information is complete, and then ask that the picture be drawn. The information about the plot is stored in a Python list containing the following information:
The first and third items above default to reasonable values if the user does not call functions (e. g., rot3, mov3, aim3, set3_light., etc.) to set them. The list described in the second bullet is built by a set of one or more calls to the various plotting functions, which create the list of arguments for each call and then add the function name and argument list pair to the plot list for future execution. When the list is complete, a call to draw3 causes the list to be traversed, and at this point each plotting function on the list executes with the argument list that was built when it was first called.
The main function of interest in plwf.py is the function plwf (``plot wire frame''), which enables the user to plot an arbitrary wire frame on a quadrilateral grid. The grid may be see-through or not (cells filled with the background color). In the latter case, the drawing order of the zones is determined by a simple ``painter's algorithm'', which works fairly well if the mesh is reasonably nearly rectilinear, but can fail even then if the viewpoint is chosen to produce extreme fisheye perspective effects. One must look at the resulting plot carefully to be sure the algorithm has correctly rendered the model in each case.
A 3-D wire mesh can also be plotted using shading and lighting effects as determined by values set in the pl3d module; or the zones can be colored (using the current palette) by their average height or by the values of some function, which may be zone-centered or node-centered.
The following is a fairly simple example of a wire mesh plot.
Calling set_draw3_ with argument zero tells the 3d plotting routines not to draw the graph until asked (by a call to draw3). orient3 and light3 set the orientation and lighting parameters to default values when called with no arguments. (light3 is irrelevant for this durface, since it is not shaded.) The plwf call puts this surface on the drawing list (plwf = ``plot wire frame.'') The draw3 call then causes the drawing list to be plotted. draw3 returns the maxima and minima of the x and y variables, which must then be sent to the limits function to prevent the plot appearing distorted. (Ah, the perils of using low level graphics.)
Module slice3.py contains two plotting functions of interest. First, pl3surf can be used for graphing surfaces on an arbitrary two-dimensional mesh with filled cells and no mesh lines. (Currently plwf can be used to do the same thing in the case of a mesh all of whose cells are quadrilateral, and has more flexibility, in that it allows mesh lines to be drawn and/or allows for the mesh to be see-through.) Secondly, pl3tree is a plotting function that can be called multiple times in order to have several surfaces drawn on the same graph. pl3tree (as its name suggests) creates a tree of values sorted as to when they will be plotted on the screen; if the algorithm works correctly, then more distant cells are plotted first, then covered by closer cells which are plotted later, giving the surface the correct appearance.
Surfaces to be plotted by pl3surf or pl3tree can be generated by taking plane sections of an arbitrary mesh or by creating isosurfaces for some function or functions defined on the mesh. These planes and isosurfaces can themselves be sliced and portions discarded, to enhance visibility of the interior. The functions mesh3 and slice3mesh take raw input data and put it into the form accepted by slice3, which can form plane sections or isosurfaces through the mesh. Functions slice2 (which returns the portion of a surface in front of the slicing plane) and slice2x (which returns the two parts of a surface sliced by a plane) complete the triumvirate of slicing functions.
The algorithms in slice3 are independent of the underlying graphics. Thus slice3 may equally well be used with Narcisse graphics.