Example#1 shows the typical set-up. Here, the drawing is added by a draw_mesh unit, which here just draws a simple 10x10 mesh of z values specified as an array at its main input connector 0 (in our simple example the input connector is not fed anything and all z-values are therefore zero). Note that the draw_mesh unit must specify the window it wants to plot into; as usual, this specification is made by giving the window title of the target window. In addition, there is an input_window unit with three sliders that allow to set viewing focus and viewing direction (two angles) interactively Each slider has the plot3d bound as a callback that is executed to update its view whenever the slider value changes. Note that it is not necessary to include the draw_mesh unit among the callbacks. The plot3d unit "knows" the NST units that are drawing into it and will automatically call them for redraw whenever its view changes (including the draw_mesh among the callbacks would, therefore, draw the mesh twice and only waste time). The viewing parameters are fed to the control input connector of the plot3d unit (without the input_window unit, the viewing parameters could only be set as numeric values in the parameter dialog for the plot3d unit).
Example#3 illustrates its use to allow the picking of a 3d data point with the mouse cursor. The prog_unit inside the container pick iterates through all 3d data points, feeds them to the trf3dto2d unit, receives back for each point its projected 2d pixel coordinates, compares them with the mouse pointer coordinates and finds the best matching point. This point then is marked with a little circle symbol.
Example#4 illustrates how to generate a postscript output from a plot3d picture (for 2-dimensional graphics units everything would work in an analogous way). The example also will illustrate some further important properties of the draw_sym unit, see below.
First, execute the for_op of the leftmost subcircuit. This will
generate a number of random data points, drawn sequentially by the draw_sym
unit. To view them, execute the input_window unit from the middle
subcircuit next. You now can control the 3d view of the data points with
the sliders in the input_window.
This is achieved with the analogous set-up as explained in the first
example. Finally, execute the window_to_eps
unit (at the right). This will produce a new file out.eps
in your current directory, containing a picture of the plot window.
For the postscript output, you may wish to change the simple default scaling of 1 pixel linewidth on the screen to 1 point line width in the postscript image. This can be done by specifying the option %w:sL (with two numeric parameters w and s) in the window_to_eps unit. This will scale a screen line width of P pixels to a postscript line width of w+s*P points. In particular, %wL (i.e, no second argument given) will make all lines w points thick.
The window_to_eps unit works by requesting a redraw of the window it is associated with, but before the redraw is carried out, all screen graphics output routines are temporarily replaced by corresponding postscript routines to create a postscript file.
Therefore, the plotting must be set up such that a redraw will actually reproduce the entire drawing. Since the draw_sym unit this time is executed sequentially, adding single point for single point, the usual result would be that only the last plotted point would appear in the redrawn image. However, in the present example the draw_sym unit is created with the option %B (for "buffering"). This makes it to store all drawn points for later redraws, so that our set up can work as desired. If you wish at some point to make the draw_sym forget the stored points, issue an NST_INIT control call for it. To this end, the circuit contains a ctrl_op unit, which, when executed, provides this control call to its operand(s). However, you will notice that the ctrl_op unit acts on the plot3d unit, not on the draw_sym unit, as might be expected. In fact, either way would work, but using the plot3d unit as the target is better, since it will always pass the control calls automatically to all the graphics units that draw into it and, after that, will automatically update the drawing (the graphics update would have to be made extra when the control call is passed to the drawing units individually).
We could have avoided the complication with the %B buffering option by offering all the points to the draw_sym unit simultaneously (instead of the sequential drawing), using a single long array of xyz-triples. In this case, the draw_sym needs to store nothing, since all the data are held at its input. However, we wished to explain the serial drawing technique as well, and this was our example.
The next chapter will explain the capabilities of the GL based view3d
graphics and its related units.