00001 00002 c 00003 c Copyright (c) 1986,1987,1988,1989,1990,1991,1992,1993, 00004 c by Steve McMillan, Drexel University, Philadelphia, PA. 00005 c 00006 c All rights reserved. 00007 c 00008 c Redistribution and use in source and binary forms are permitted 00009 c provided that the above copyright notice and this paragraph are 00010 c duplicated in all such forms and that any documentation, 00011 c advertising materials, and other materials related to such 00012 c distribution and use acknowledge that the software was developed 00013 c by the author named above. 00014 c 00015 c THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 00016 c IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 00017 c WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00018 c 00019 00020 subroutine plt3d(a,m,n,alt,az,xlen,xoff,ylen,yoff,zfac,zoff,ier) 00021 save 00022 c 00023 c--- 3d plot routine, adapted from the SAS-3 routine of the same name. 00024 c 00025 c--- calling sequence: 00026 c call plt3d (a,m,n,alt,az,xlen,xoff,ylen,yoff,zfac,zoff,ier) 00027 c 00028 c a - real data array, represents height of surface as 00029 c function of location in plane 00030 c m,n - dimensions of data array a 00031 c alt, az - altitude, azimuth viewing angles in degrees 00032 c xlen,ylen - length of unprojected x,y axes in inches 00033 c xoff,yoff - offset of origin in inches 00034 c zfac - scaling of z-axis from data units to unprojected inches 00035 c zoff - offset of z-origin in user units 00036 c ier - returns 0 for no error 00037 c 00038 c Altitude is measured from the x-y plane toward the positive z-axis. 00039 c Azimuth is measured around the z-axis (as seen from above), 00040 c counterclockwise from the positive x-axis. 00041 c 00042 c The origin (xoff, yoff), in screen coordinates, is the image of the 00043 c point at the CENTER of the x-y grid and at a height zoff above it 00044 c (in the units used for a). 00045 c 00046 dimension a(m,n) 00047 c 00048 c Note that the original user-provided work arrays are now internal 00049 c and static. 00050 c 00051 parameter (LDIM = 5000) 00052 dimension x(LDIM),y(LDIM) 00053 c 00054 common /plt3b/ a1,a2,a3,b1,b2,b3,b4,zoff1 00055 c 00056 parameter (PI = 3.141592654, PIDEG = PI/180.) 00057 c 00058 c Coordinate to plot conversions: 00059 c 00060 c (1,1) <--> (xmin,ymin) 00061 c (1,n) <--> (xmin,ymax) 00062 c (m,1) <--> (xmax,ymin) 00063 c (m,n) <--> (xmax,ymax) 00064 c 00065 xplot(i,j) = a1*i + a2*j + a3 00066 yplot(i,j) = b1*i + b2*j + b3*(a(i,j)-zoff1) + b4 00067 c 00068 lmax = 2*min(m,n) 00069 if (LDIM.lt.lmax) then 00070 write(0,*)'PLT3D: Array too big!' 00071 ier = 2 00072 return 00073 end if 00074 c 00075 taz = az*PIDEG 00076 talt = alt*PIDEG 00077 c 00078 saz = sin(taz) 00079 caz = cos(taz) 00080 sal = sin(talt) 00081 cal = cos(talt) 00082 c 00083 xsc = xlen/float(m-1) 00084 ysc = ylen/float(n-1) 00085 c 00086 c The viewing plane is such that the "horizontal" vector is 00087 c 00088 c x' = (-saz, caz, 0), 00089 c 00090 c and the "vertical" vector is 00091 c 00092 c y' = (-sal*caz, -sal*saz, cal). 00093 c 00094 a1 = -saz*xsc 00095 a2 = caz*ysc 00096 a3 = xoff - 0.5*(a1*float(m+1)+a2*float(n+1)) 00097 b1 = -caz*sal*xsc 00098 b2 = -saz*sal*ysc 00099 b3 = zfac*cal 00100 b4 = yoff - 0.5*(b1*float(m+1)+b2*float(n+1)) 00101 zoff1 = zoff 00102 c 00103 c Find which quadrant we are viewing from. 00104 c 00105 iaz = 1 00106 if (caz.le.0.0) iaz = iaz + 1 00107 if (saz.le.0.0) iaz = 5 - iaz 00108 c 00109 c Choose the direction of traversal of the plot based on view angle. 00110 c 00111 if (iaz.eq.2.or.iaz.eq.3) then 00112 ifirst = 1 00113 else 00114 ifirst = m 00115 end if 00116 ilast = m + 1 - ifirst 00117 istep = sign(1,ilast-ifirst) 00118 c 00119 if (iaz.ge.3) then 00120 jfirst = 1 00121 else 00122 jfirst = n 00123 end if 00124 jlast = n + 1 - jfirst 00125 jstep = sign(1,jlast-jfirst) 00126 c 00127 c Make sure the array sent to nxtvu is traversed from left to right. 00128 c 00129 if (iaz.eq.1.or.iaz.eq.3) then 00130 lli = -1 00131 else 00132 lli = 1 00133 end if 00134 c 00135 c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 00136 c 00137 ic = 0 00138 ibeg = ifirst+istep 00139 c 00140 c Traverse the plot region in a zig-zag motion, transverse to the 00141 c viewing direction (left to right), and from front to back. 00142 c The plotting routine "nxtvu" takes care of hidden line removal. 00143 c 00144 c First, deal with the "front" portion of the plot (i.e. nearest 00145 c the viewer). 00146 c 00147 70 lnth = min(2*iabs(ibeg-ifirst)+1,lmax) 00148 if (lli.eq.-1) then 00149 ll = lnth + 1 00150 else 00151 ll = 0 00152 end if 00153 c 00154 i = ibeg 00155 j = jfirst 00156 ll = ll+lli 00157 x(ll) = xplot(i,j) 00158 y(ll) = yplot(i,j) 00159 c 00160 80 i = i-istep 00161 ll = ll+lli 00162 x(ll) = xplot(i,j) 00163 y(ll) = yplot(i,j) 00164 if (j.ne.jlast) then 00165 j = j+jstep 00166 ll = ll+lli 00167 x(ll) = xplot(i,j) 00168 y(ll) = yplot(i,j) 00169 if (i.ne.ifirst) go to 80 00170 end if 00171 c 00172 call nxtvu(ic,x,y,lnth,ier) 00173 if (ier.ne.0) return 00174 ic = 1 00175 if (ibeg.ne.ilast) then 00176 ibeg = ibeg+istep 00177 go to 70 00178 end if 00179 c 00180 c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 00181 c 00182 c Now do the "rear" half of the figure in the same manner. 00183 c 00184 jbeg = jfirst 00185 c 00186 100 lnth = min(2*iabs(jbeg-jlast)+1,lmax) 00187 if (lli.eq.-1) then 00188 ll = lnth + 1 00189 else 00190 ll = 0 00191 end if 00192 c 00193 i = ilast 00194 j = jbeg 00195 ll = ll+lli 00196 x(ll) = xplot(i,j) 00197 y(ll) = yplot(i,j) 00198 c 00199 110 j = j+jstep 00200 ll = ll+lli 00201 x(ll) = xplot(i,j) 00202 y(ll) = yplot(i,j) 00203 if (i.ne.ifirst) then 00204 i = i-istep 00205 ll = ll+lli 00206 x(ll) = xplot(i,j) 00207 y(ll) = yplot(i,j) 00208 if (j.ne.jlast) go to 110 00209 end if 00210 c 00211 call nxtvu(1,x,y,lnth,ier) 00212 if (ier.ne.0) return 00213 jbeg = jbeg+jstep 00214 if (jbeg.eq.jlast) return 00215 go to 100 00216 c 00217 end 00218 00219 00220 function xplot3d(x,y,z) 00221 save 00222 c 00223 c Externally accessible version of the statement function in plt3d. 00224 c This will work only AFTER plt3d has been used, as that routine 00225 c sets up the common array. 00226 c 00227 c The coordinates x and y are expected to range from 1 to m and 00228 c 1 to n, respectively. 00229 c 00230 c Typical usage: xx = xplot3d(float(i),float(j),array(i,j)) 00231 c 00232 c Note that z is not used. 00233 c 00234 common /plt3b/ a1,a2,a3,b1,b2,b3,b4,zoff1 00235 c 00236 xplot3d = a1*x + a2*y + a3 00237 c 00238 end 00239 00240 00241 function yplot3d(x,y,z) 00242 save 00243 c 00244 c Externally accessible version of the statement function in plt3d. 00245 c This will work only AFTER plt3d has been used, as that routine 00246 c sets up the common array. 00247 c 00248 c The coordinates x and y are expected to range from 1 to m and 00249 c 1 to n, respectively. 00250 c 00251 common /plt3b/ a1,a2,a3,b1,b2,b3,b4,zoff1 00252 c 00253 c Typical usage: yy = yplot3d(float(i),float(j),array(i,j)) 00254 c 00255 yplot3d = b1*x + b2*y + b3*(z-zoff1) + b4 00256 c 00257 end