Previous chapter LLUs Home Next chapter IndexThe Threed utility allows you to define a perspective transformation (a projection) from a three-dimensional space to a two-dimensional space and then to draw the perspective images of objects (points, lines, curves, perimeters, and character strings) defined in three dimensions.
Note: Threed has been essentially unchanged since the early 1970s. There are plans to replace it with a new package that has a more consistent and modern interface. This new package will unify the functionality of all three of the utilities Threed, Surface, and Isosurface.
1 CALL SET3 (.1,.9,.1,.9,UMIN,UMAX,VMIN,VMAX,WMIN,WMAX,PEYE)
CALL SET3 (XMIN, XMAX, YMIN, YMAX, UMIN, UMAX, VMIN, VMAX, WMIN, + WMAX, PEYE)
The array PEYE specifies the position of the eye, which may be referred to as the "viewpoint" or "center" of the projection.
The "line of sight" runs from the point
(PEYE(1),PEYE(2),PEYE(3))(the eye position) to the point
(UCEN, VCEN, WCEN)(the point at the center of the projected box---UCEN=.5*(UMIN+UMAX), VCEN=.5*(VMIN+VMAX), and WCEN=.5*(VMIN+VMAX))
The "image plane" is perpendicular to the line of sight and may be thought of as passing through the point at the center of the projected box. The projection of an arbitrary point P in 3-space is the point where the straight line from the eye position to P passes through the image plane. The projection of a more complicated object is just the union of the projections of its constituent points.
The projection in the image plane of the box specified by the arguments UMIN, UMAX, VMIN, VMAX, WMIN, and WMAX will be scaled to fit in the viewport specified by the arguments XMIN, XMAX, YMIN, and YMAX. The projected box will retain its natural aspect ratio; typically, it will just touch the left and right edges of the viewport, or the top and bottom of the viewport, but not both.
The image of the box will be rotated so that the projection of a unit vector based at the center of the box and pointing in the direction of the positive W axis will be made to point upward in the viewport. However, if the line of sight is very nearly parallel to the W axis, so that the projection of this unit vector shrinks almost to a point, then a unit vector based at the center of the box and pointing in the direction of the positive V axis will be made to point upward in the viewport instead. One implication of this is that, if you are making a movie by letting the eye "fly around" the objects being projected and it gets too close to being directly above or below the center of the box, there may be a sudden disconcerting rotation of the projected image.
1 CALL PERIM3 (10,2,10,2,1,0.) 2 CALL PERIM3 (10,2,10,2,2,0.) 3 CALL PERIM3 (10,4,10,4,3,0.)
CALL PERIM3 (MAJOR1, MINOR1, MAJOR2, MINOR2, IAXIS, VALUE)
Each of the arguments MAJOR1 and MAJOR2 refers to the number of major divisions (spaces between ticks) rather than to the number of major ticks; counting those at the ends, there will be one more major tick than there are major divisions.
Each of the arguments MINOR1 and MINOR2 refers to the number of minor divisions (spaces between ticks) rather than to the number of minor ticks; in a given major interval, there will be one fewer minor tick than there are minor divisions.
The fthex01 example shows three different perimeters, one for each coordinate plane; the perimeters are placed on the far sides of the box. The rectangle itself is drawn in the current polyline color, as determined by the last call to the GKS routine GSPLCI; by default, color index 1 is used. Major ticks and minor ticks are drawn in the colors implied by the values of the variables ITHRMJ and ITHRMN in the Threed COMMON block
COMMON /THRINT/ ITHRMJ,ITHRMN,ITHRTXThe default value of both ITHRMJ and ITHRMN is 1; user code may change these values. All lines are drawn using the current GKS line width scale factor, as set by the last call to the GKS routine GSLWSC.
1 CALL TICK43 (12,8,24,16,48,32)
CALL TICK43 (MAJORU, MINORU, MAJORV, MINORV, MAJORW, MINORW)
The fthex01 example uses default-size tick marks on perimeter sides parallel to the U axis, double-size tick marks on perimeter sides parallel to the V axis, and quadruple-size tick marks on perimeter sides parallel to the W axis.
1 DO 108 I=1,11 2 PTMP=REAL(I-1)/10. 3 DO 107 J=1,101 4 QTMP=REAL(J-1)/100. 5 CALL POINT3 (PTMP,QTMP,0.) 6 CALL POINT3 (QTMP,PTMP,0.) 7 CALL POINT3 (PTMP,0.,QTMP) 8 CALL POINT3 (QTMP,0.,PTMP) 9 CALL POINT3 (0.,PTMP,QTMP) 10 CALL POINT3 (0.,QTMP,PTMP) 11 107 CONTINUE 12 108 CONTINUE
CALL POINT3 (UPOS, VPOS, WPOS)
Each point is drawn by calling the GKS routine GPM to draw a polymarker of type 1. Points are therefore drawn in the current polymarker color, as determined by the last call to the GKS routine GSPMCI; by default, color index 1 is the one used.
Calling the GKS routine GSMKSC to change the polymarker size does not normally affect polymarkers of type 1, so there is no good way to make the points bigger; if you want to do this, you should use LINE3 (or perhaps FRST3 and VECT3) instead of POINT3 to draw an object of the desired size.
1 WFUN(U,V)=.5+.25*SIN(5.*U)+.25*COS(5.*V) 2 CALL PLOTIF (0.,0.,2) 3 CALL GSLWSC (2.) 4 DO 110 I=1,11 5 UTMP=REAL(I-1)/10. 6 CALL FRST3 (UTMP,0.,WFUN(UTMP,0.)) 7 DO 109 J=2,11 8 VTMP=REAL(J-1)/10. 9 CALL VECT3 (UTMP,VTMP,WFUN(UTMP,VTMP)) 10 109 CONTINUE 11 110 CONTINUE 12 DO 112 J=1,11 13 VTMP=REAL(J-1)/10. 14 CALL FRST3 (0.,VTMP,WFUN(0.,VTMP)) 15 DO 111 I=2,11 16 UTMP=REAL(I-1)/10. 17 CALL VECT3 (UTMP,VTMP,WFUN(UTMP,VTMP)) 18 111 CONTINUE 19 112 CONTINUE
CALL FRST3 (UPOS, VPOS, WPOS) CALL VECT3 (UPOS, VPOS, WPOS)
Each call to FRST3 moves a conceptual "pen" to the new starting point for a sequence of line draws. Each call to VECT3 draws a line from the current pen position to a new pen position and then makes that the current pen position.
Line segments are drawn in the current polyline color, as determined by the last call to the GKS routine GSPLCI; by default, color index 1 is used. Line width is determined by the last call to the GKS routine GSLWSC; by default, the value of the line width scale factor is 1.
Note that the routines FRST3 and VECT3 do not flush the SPPS polyline buffer. In fact, to have them do so would entirely defeat the purpose of that buffer. Therefore, if your last call was to the routine VECT3 and you are about to call GKS routines to change color or line width, you must first call PLOTIF (as shown on line 2) to flush the buffer; otherwise, the color and line width changes will affect line draws flushed from the buffer later.
1 WFUN(U,V)=.5+.25*SIN(5.*U)+.25*COS(5.*V) 2 CALL PLOTIF (0.,0.,2) 3 CALL GSLWSC (2.) 4 DO 114 I=1,21,2 5 UTMP=REAL(I-1)/20. 6 DO 113 J=1,21,2 7 VTMP=REAL(J-1)/20. 8 WTMP=WFUN(UTMP,VTMP) 9 CALL LINE3 (UTMP-.04,VTMP,WTMP,UTMP+.04,VTMP,WTMP) 10 CALL LINE3 (UTMP,VTMP-.04,WTMP,UTMP,VTMP+.04,WTMP) 11 CALL LINE3 (UTMP,VTMP,WTMP-.04,UTMP,VTMP,WTMP+.04) 12 113 CONTINUE 13 114 CONTINUE
CALL LINE3 (UPOS1, VPOS1, WPOS1, UPOS2, VPOS2, WPOS2)
The statement:
CALL LINE3 (UPOS1, VPOS1, WPOS1, UPOS2, VPOS2, WPOS2)is equivalent to the three statements:
CALL FRST3 (UPOS1, VPOS1, WPOS1) CALL VECT3 (UPOS2, VPOS2, WPOS2) CALL PLOTIF (0.,0.,2)but is slightly more efficient. To approximate a curve defined by three or more points, though, it is not efficient to use LINE3, because the first point of each line segment after the first will be a repeat of the second point of the previous line segment and will therefore be repeated in the metafile. Thus, to approximate a curve, you should use FRST3 and VECT3 (or CURVE3, which is described in the next module).
Straight-line segments drawn by LINE3 are drawn in the current polyline color, as determined by the last call to the GKS routine GSPLCI; by default, color index 1 is used. Line width is determined by the last call to the GKS routine GSLWSC; by default, the line width scale factor is 1.
1 WFUN(U,V)=.5+.25*SIN(5.*U)+.25*COS(5.*V) 2 CALL PLOTIF (0.,0.,2) 3 CALL GSLWSC (2.) 4 DO 113 I=1,361 5 TEMP=5.*REAL(I-1) 6 UCRV(I)=.5+TEMP/3600.*COS(.017453292519943*TEMP) 7 VCRV(I)=.5+TEMP/3600.*SIN(.017453292519943*TEMP) 8 WCRV(I)=WFUN(UCRV(I),VCRV(I)) 9 113 CONTINUE 10 CALL CURVE3 (UCRV,VCRV,WCRV,361)
CALL CURVE3 (UCURVE, VCURVE, WCURVE, NPNTS)
Line 2 flushes the SPPS polyline buffer, so that lines waiting in that buffer to be drawn will not be affected by the change in line width that is requested by the GKS call on line 3. (Note: CURVE3 flushes the SPPS polyline buffer after drawing a curve, so you needn't worry about its leaving anything in the buffer.)
Lines 4 through 9 define the input arrays, and line 10 calls CURVE3.
Curves drawn by CURVE3 are drawn in the current polyline color, as determined by the last call to the GKS routine GSPLCI; by default, color index 1 is used. Line width is determined by the last call to the GKS routine GSLWSC; by default, the line width scale factor is 1.
1 WFUN(U,V)=.5+.25*SIN(5.*U)+.25*COS(5.*V) 2 CALL PLOTIF (0.,0.,2) 3 CALL GSLWSC (2.) 4 DO 109 I=1,361 5 TEMP=5.*REAL(I-1) 6 UCRV(I)=.5+TEMP/3600.*COS(.017453292519943*TEMP) 7 VCRV(I)=.5+TEMP/3600.*SIN(.017453292519943*TEMP) 8 WCRV(I)=WFUN(UCRV(I),VCRV(I)) 9 109 CONTINUE 10 CALL FENCE3 (UCRV,VCRV,WCRV,361,3,0.)
CALL FENCE3 (UCURVE, VCURVE, WCURVE, NPNTS, IOREN, BOTTOM)
The call on line 2 flushes the SPPS polyline buffer, so that lines waiting in that buffer to be drawn will not be affected by the change in line width that is requested by the GKS call on line 3. (Note: FENCE3 flushes the SPPS polyline buffer after drawing a curve, so you needn't worry about its leaving anything in the buffer.)
Lines 4 through 9 define the input arrays, and line 10 calls FENCE3.
The curve and the fence are drawn in the colors implied by the values of the variables ITHRMJ and ITHRMN, respectively, in the Threed COMMON block:
COMMON /THRINT/ ITHRMJ,ITHRMN,ITHRTXThe default value of both ITHRMJ and ITHRMN is 1; user code may change these values.
1 CHARACTER*8 CHRS 2 CALL PWRZT (.5,0.,1.1,'U',1,3,-1,+3,0) 3 DO 102 ILAB=1,10 4 UPOS=REAL(ILAB)/10. 5 WRITE (CHRS,'(F8.1)') UPOS 6 IBEG=0 7 DO 101 ICHR=1,8 8 IF (CHRS(ICHR:ICHR).NE.' ') THEN 9 IF (IBEG.EQ.0) THEN 10 IBEG=ICHR 11 END IF 12 IEND=ICHR 13 END IF 14 101 CONTINUE 15 IF (CHRS(IBEG:IBEG).EQ.'0') IBEG=MIN(IBEG+1,IEND) 16 CALL PWRZT (UPOS,0.,1.05,CHRS(IBEG:IEND),IEND-IBEG+1, 17 + 3,-1,+3,0) 18 102 CONTINUE
CALL PWRZT (UPOS, VPOS, WPOS, CHRS, LCHRS, ISIZE, IDIR, ITOP, ICEN)
Line 1 defines a character variable in which label strings may be formed. Line 2 writes an appropriate label for the U axis. The loop on Lines 3 through 17 writes 10 numeric labels for the U axis. The inner loop on lines 7 through 14 just finds the start and end of the numeric label in the character variable.
Because characters drawn by PWRZT are stroked using the GKS polyline primitive (so that they can be projected from 3-D to 2-D), they are drawn in the current polyline color, as determined by the last call to the GKS routine GSPLCI; by default, color index 1 is used. Line width is determined by the last call to the GKS routine GSLWSC; by default, the line width scale factor is 1.
1 COMMON /TEMPRT/ RZRO 2 COMMON /SRFIP1/ IFR,ISTP,IROTS,IDRX,IDRY,IDRZ,IUPPER,ISKIRT, 3 + NCLA,THETA,HSKIRT,CHI,CLO,CINC,ISPVAL 4 DIMENSION PEYE(6) 5 DIMENSION U(21),V(21),W(21,21),RWRK(882) 6 IFR=0 7 ISKIRT=1 8 HSKIRT=0. 9 (set U, V, W, UMIN, UMAX, VMIN, VMAX, WMIN, WMAX, and RZRO) 10 PEYE(4)=.5*(UMIN+UMAX) 11 PEYE(5)=.5*(VMIN+VMAX) 12 PEYE(6)=.5*(WMIN+WMAX) 13 CALL SETR(UMIN,UMAX,VMIN,VMAX,WMIN,WMAX,RZRO) 14 CALL SET3(.0087976,.9902248,.0087976,.9902248, 15 UMIN,UMAX,VMIN,VMAX,WMIN,WMAX,PEYE) 16 CALL PLOTIF (0.,0.,2) 17 CALL GSLWSC (2.) 18 CALL SRFACE (U,V,W,RWRK,21,21,21,PEYE,0.)
Part 1: Line 1 declares a Threed COMMON block in which it is possible to communicate to the package a value RZRO which, when set nonzero, selects a different internal scaling option. The same value is passed to Surface by the call on line 13 and performs the same function in that package. The value of RZRO is that distance from which the box defined by the values of UMIN, UMAX, VMIN, VMAX, WMIN, and WMAX, when viewed from the direction that makes it largest, is to just touch the edges of the viewport in the image plane. Using an eye position closer to the center of the box than RZRO will result in a larger image and using an eye position further from the center of the box than RZRO will result in a smaller image.
Part 2: Line 4 declares an array in which to put the eye position for Threed (elements 1, 2, and 3) and both the eye position (elements 1, 2, and 3) and the position of the point looked at (elements 4, 5, and 6) for Surface. On lines 10, 11, and 12, the position of the point looked at is set to the value that Threed will use by default (the center of the box defined by UMIN, UMAX, VMIN, VMAX, WMIN, and WMAX), so that Surface will do the same thing.
Part 3: The first four arguments in the call to SET3, on lines 14 and 15, have just the right values required to ensure that Threed will use exactly the same viewport that Surface will use.
Lines 2 and 3 declare a Surface COMMON block providing access to internal parameters controlling various aspects of its behavior. Lines 6, 7, and 8 set parameters to turn off frame advances, to turn on the drawing of a "skirt," and to specify the level at the bottom of the "skirt."
Line 5 defines arrays to be used as arguments in the call to SRFACE. Three of these define the surface to be drawn and the final one is a workspace array.
Lines 16 and 17 flush the SPPS polyline buffer and double the GKS line width, so that the surface drawn by the call to SRFACE, on line 18, will be bolder than the rest of the plot.
Previous chapter LLUs Home Next chapter Index