[PREVIOUS] [NEXT] [UP]

Creating 3d Plots

This lesson will show you how to display data or render objects in 3 dimensions.

How to use the plot3d unit

The plot3d_unit is the main unit to create 3d displays. It provides a window into a scaled portion of three-dimensional space and displays a 3-dimensional coordinate system. However, beyond that it does not any further drawing. Therefore, it usually must work together with other units that draw some data into the plot3d window (e.g., the draw_sym or the draw_mesh units).

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).

How to transform 3d data into 2d screen coordinates

Sometimes it is important to know the 2d screen coordinates to which a 3d point gets projected. For instance, if we wish to select a 3d data object on the screen, we must relate the 2d-cursor coordinates to the screen coordinates of the 3d object. The trf3dto2d unit performs the necessary transformation from 3d coordinates to 2d window pixel coordinates.

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.

How to draw an isosurface

(to be written; until then, you may wish to inspect the 'e'-example that comes with the iso_surface unit).

How to create postscript output

The window_to_eps unit allows to convert the drawings of most NST drawing units (except the view3d and camera_unit) into encapsulated postscript.

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.

How the plot3d unit differs from the view3d unit

The plot3d unit is based on colormap line graphics, while the view3d unit is based on GL graphics that allows the rendering of solid surfaces with lighting. Therefore, the plot3d unit is more restricted in its rendering capabilities than the view3d unit. It is mainly suited for graphics that can be drawn with lines, markers and points. As soon as shaded surfaces are needed, you may wish to use the view3d unit. For its simplicity, the plot3d unit also offers a few advantages: the window_to_eps unit allows to convert the plot3d drawings into smooth postscript vector graphics (images of the view3d unit can only be saved as pixel bitmaps). Also, the other drawing units draw_sym, draw_mesh, draw_str and draw_pix are intended to work together with the plot3d unit; they will not work well with the view3d unit (this is due to the different organisation of the bitplanes and due to different scaling parameters). The iso_surface unit exist in two versions: one for line graphics with the plot3d unit, and one for smooth shaded surfaces with GL graphics.

The next chapter will explain the capabilities of the GL based view3d graphics and its related units.


[PREVIOUS] [NEXT] [UP]