This subdirectory provides you with an initial distribution of the Plot.c source code as well as other goodies: Makefile: Creates the plot object code as "Plot.o" which can then be linked to a driver. Plot.c: The initial distribution. It compiles cleanly but does not plot anything. You have to fill in those details. Plot.h: Necessary definitions that you should include. This discussion uses Turing as an example, but the C discussion is identical except that the calling syntax is slightly different. Lines and Projections I'd like to provide you with a little more background on the data types in the Plot.t or Plot.c code so you know what the chain of events should be. You do not have have to touch anything outside of Plot2D and Plot3D. This message just explains how to use all those other procedures and functions. You don't even have to understand how those other procedures work. That's what "information hiding" is all about. This will sound complicated, but it's not, and it gives you an idea of what you have to do in real graphics systems. Notation: let R2 denote the real plane, R3 denote the real volume, both expressed in cartesian co-ordinates. Plot2D evaluates parametric functions to create a point in R2. That point can be stored in a variable of type "RealPoint2D". If you get two such points P0 and P1, both of type RealPoint2D, then you can draw a line between them by invoking "Line(P0,P1)". Notice that to really draw something, the procedure Line in converts your values to screen co-ordinates by applying a user provided scale and offset. See the driver programs for examples of how this is done. This allows me to plot objects on different parts of the screen and in different sizes. So, in code, you do this. var P0, P1: RealPoint2D To get a point on the curve: P0.x := x(s,t) P0.y := y(s,t) % x and y are passed to Plot2D Similarly for P1. To draw a line: Line(P0,P1) Plotting 3D points and lines is more complicated. You start by invoking the user provided functions x(s,t),y(s,t) and z(s,t). Putting these values together for a specific (s,t) gives you a single point of type RealPoint3D. Now this points sits out in R3 somewhere and can't be plotted like that directly. We need to get it into a 2-D form. The procedure R3DtoR2D does exactly this. The input is a point of type RealPoint3D and the output is of type RealPoint2D. You could then draw a line between two such converted points. However, the user can specify a *rotation* of the whole object so that it can be viewed from different angles. To make this work, you simply invoke ApplyRotations to the points on the surface. Here's the order of operations. var Q0, Q1: RealPoint3D var R0, R1: RealPoint3D var P0, P1: RealPoint2D To get a real point on the surface at value (s,t): Q0.x := x(s,t) Q0.y := y(s,t) % x,y and z are passed to Plot3D Q0.z := z(s,t) Similarly for Q1 as appropriate. To apply a rotation: R0 := ApplyRotations(Q0) R1 := ApplyRotations(Q1) % Note: rotations are in 3D! To convert to 2D: P0 := R3DtoR2D(R0) P1 := R3DtoR2D(R1) To draw a line: Line(P0,P1) Notice that you can actually compose these operations if you really want, but it might not be more efficient to do so: Line(R3DtoR2D(ApplyRotations(Q0), R3DtoR2D(ApplyRotations(Q1)) assuming you have already computed Q0 and Q1 as points on the surface. -- Eugene Fiume, elf@dgp.toronto.edu, elf@cdf