How to make pictures using postscript programs (part 14) ----------------------------------------------------------------------------- To create a picture of a three-dimensional object, we need to perform the transformation from 3d to 2d ourselves: Postscipt just describes an image in the plane. Suppose we have a three-dimensional xyz coordinate system, and we stand at point (0,0,0), and the entire scene we want to view is beyond the plane (x,y,1), so all objects we want to see have z-coordinate larger than 1. Then we cannot distinguish from our viewpoint the three-dimensional scene from a picture drawn on that plane z=1, where each point (x,y,1) looks just like whatever object we would encounter if we followed the ray from our viewpoint (0,0,0) through that point (x,y,1) to that object. So each object generates an image on the plane (x,y,1) that is indistinguishable from the object itself, if we can look only from (0,0,0). The object point (x,y,z) is mapped on the point where the line of sight from (x,y,z) to (0,0,0) intersects our image plane, which is the point (x/z, y/z,1). This is the basic idea of ray-tracing: create a two-dimensional picture from the three-dimensional object by following the lines of sight, and mapping the object to the point on the image plane. The first major problem in realizing this idea is that the line of sight encounters several objects, and only the nearest contributes to our picture. This is known as hidden surface elimination; a ray-tracing system would do that automatically, we have to take care of it by building the scene back to front: the nearer object then overwrites the farther object. ---------------------------Example29------------------------------------------ %!PS-Adobe-2.0 EPSF %%BoundingBox: 0.0 0.0 300 300 %%Title: projected squares 50 50 translate /proj {/z exch def /y exch def /x exch def x z div y z div} def %proj replaces numbers z y z by z/z y/z 200 -10 10 { /z1 exch def newpath 500 500 z1 proj moveto 1500 500 z1 proj lineto 1500 1500 z1 proj lineto 500 1500 z1 proj lineto closepath gsave 0 setgray 1.0 setlinewidth stroke grestore 0.9 z1 220 div sub setgray fill } for showpage ----------------------------------------------------------------------------- This show a row of squares in space, farther and farther back. To make them distinguishable, I gave them a border (drawing their outline), and decreased the gray value. The three-dimensional coordinates of the top square are (500,500,10),(1500,500,10),(1500,1500,10),(500,1500,10) and the coordinates of the square farthest away are (500,500,200),(1500,500,200),(1500,1500,200),(500,1500,200) The farthest away square is drawn first, then the nearer ones. By the projection (x,y,z) -> (x/z,y/z), the nearest square is mapped to (50,50),(150,50),(150,150),(50,150) ----------------------------------------------------------------------------- To make the picture more impressive, we need more objects in the back. The next example gives a lattice arangement of squares in space.