1 /*
2  * $Id: demo5.i,v 1.1 2005-09-18 22:05:55 dhmunro Exp $
3  * Demonstration of 3D plots with pl3d.i, plwf.i, slice3.i
4  */
5 /* Copyright (c) 2005, The Regents of the University of California.
6  * All rights reserved.
7  * This file is part of yorick (http://yorick.sourceforge.net).
8  * Read the accompanying LICENSE file for details.
9  */
10 
11 require, "plwf.i"
12 require, "slice3.i"
13 
14 require, "movie.i";
15 
16 window3;
17 palette, "gray.gp";
18 
demo5(itest)19 func demo5(itest)
20 /* DOCUMENT demo5
21          or demo5, i
22      Run examples of use of pl3d.i, plwf.i, and slice3.i.  With
23      argument I = 1, 2, or 3, run that particular demonstration.
24      Read the source code to understand the details of how the
25      various effects are obtained.
26 
27      demo5,1  demonstrates the various effects which can be obtained
28      with the plwf (plot wire frame) function.
29      demo5,2  demonstrates shading effects controlled by the light3
30      function
31      demo5,3  demonstrates the slice3, slice2, and pl3tree functions,
32      as well as changing the orientation of the 3D object
33 
34   SEE ALSO: plwf (plwf.i), light3, rot3, orient3, spin3 (pl3d.i),
35             mesh3, slice3, slice2, pl3tree, pl3surf (slice3.i)
36  */
37 {
38   if (!itest || itest==1) {
39     x= span(-1,1,64)(,-:1:64);
40     y= transpose(x);
41     z= (x+y)*exp(-6*(x^2+y^2));
42     write, "(plot wire frame) plwf,z,y,x";
43     orient3;
44     light3;
45     cage3, 0;
46     plwf, z, y, x;
47     draw3,1;  /* not necessary interactively */
48     rdline,prompt="hit RET or Enter to continue";
49     write, "plwf,z,y,x, shade=1,ecolor=\"red\"";
50     plwf, z, y, x, shade=1,ecolor="red";
51     draw3,1;  /* not necessary interactively */
52     rdline,prompt="hit RET or Enter to continue";
53     write, "cage3,1; plwf,z,y,x, shade=1,ecolor=\"red\"";
54     cage3,1; plwf, z, y, x, shade=1,ecolor="red";
55     draw3,1;  /* not necessary interactively */
56     rdline,prompt="hit RET or Enter to continue";
57     limits;
58     write, "cage3,0; plwf,z,y,x, shade=1,edges=0";
59     cage3,0; plwf, z, y, x, shade=1,edges=0;
60     draw3,1;  /* not necessary interactively */
61     rdline,prompt="hit RET or Enter to continue";
62   }
63 
64   if (!itest || itest==2) {
65     x= span(-1,1,64)(,-:1:64);
66     y= transpose(x);
67     z= (x+y)*exp(-6*(x^2+y^2));
68     write, "light3 function demo- default lighting";
69     orient3;
70     light3;
71     plwf, z, y, x, shade=1,edges=0;
72     draw3,1;  /* not necessary interactively */
73     rdline,prompt="hit RET or Enter to continue";
74     write, "light3,diffuse=.2,specular=1";
75     light3,diffuse=.2,specular=1;
76     limits;
77     draw3,1;  /* not necessary interactively */
78     rdline,prompt="hit RET or Enter to continue";
79     write, "light3,sdir=[cos(theta),.25,sin(theta)]  -- movie";
80     movie, demo5_light;
81     fma; demo5_light, 1;
82     rdline,prompt="hit RET or Enter to continue";
83     light3;
84   }
85 
86   if (!itest || itest==3) {
87     nx= demo5_n(1);
88     ny= demo5_n(2);
89     nz= demo5_n(3);
90     xyz= array(0.0, 3, nx,ny,nz);
91     xyz(1,..)= span(-1,1,nx);
92     xyz(2,..)= span(-1,1,nx)(-,);
93     xyz(3,..)= span(-1,1,nx)(-,-,);
94     r= abs(xyz(1,..),xyz(2,..),xyz(3,..));
95     theta= acos(xyz(3,..)/r);
96     phi= atan(xyz(2,..),xyz(1,..)+(!r));
97     y32= sin(theta)^2*cos(theta)*cos(2*phi);
98     m3= mesh3(xyz, r*(1.+y32));
99     r= theta= phi= xyz= y32= [];
100 
101     write, "   test uses "+pr1((nx-1)*(ny-1)*(nz-1))+" cells";
102     elapsed= [0.,0.,0.];
103     timer, elapsed;
104     elapsed0= elapsed;
105 
106     slice3, m3, 1,value=.5, nv,xyzv;  /* inner isosurface */
107     slice3, m3, 1,value=1., nw,xyzw;  /* outer isosurface */
108     pxy= plane3([0,0,1],[0,0,0]);
109     pyz= plane3([1,0,0],[0,0,0]);
110     vp= slice3(m3, pyz, np,xyzp, 1);  /* pseudo-colored slice */
111     local nvb,xyzvb,nwb,xyzwb;
112     slice2, pxy, np,xyzp,vp;          /* cut slice in half */
113     slice2x, pxy, nv,xyzv,, nvb,xyzvb;  /* split inner in halves */
114     slice2, -pyz, nv,xyzv;       /* ...halve one of those halves */
115     slice2x, pxy, nw,xyzw,, nwb,xyzwb;  /* split outer in halves */
116     slice2, -pyz, nw,xyzw;       /* ...halve one of those halves */
117 
118     timer, elapsed;
119     timer_print,"slicing time",elapsed-elapsed0;
120 
121     fma;
122     write, "split_palette,\"earth.gp\" -- generate palette for pl3tree";
123     split_palette, "earth.gp";
124     write, "gnomon -- turn on gnomon";
125     gnomon, 1;
126 
127     write, "pl3tree with 1 slicing plane, 2 isosurfaces";
128     clear3;
129     pl3tree, np,xyzp,vp,pyz;
130     pl3tree, nvb,xyzvb;
131     pl3tree, nwb,xyzwb;
132     pl3tree, nv,xyzv;
133     pl3tree, nw,xyzw;
134     orient3;
135     light3,diffuse=.2,specular=1;
136     limits;
137     demo5_light, 1;
138     rdline,prompt="hit RET or Enter to continue";
139 
140     write, "spin3 animated rotation, use rot3 or orient3 for one frame";
141     /* don't want limits to autoscale during animation */
142     lims= limits();
143     dx= 1.1*max(lims(2),-lims(1));
144     dy= 1.1*max(lims(4),-lims(3));
145     limits, -dx,dx,-dy,dy;
146     spin3;
147     limits;  /* back to autoscaling */
148     demo5_light, 1;
149     rdline,prompt="hit RET or Enter to continue";
150 
151     light3;
152     gnomon, 0;
153     palette, "gray.gp";
154   }
155 }
156 
157 demo5_n= [20,20,20];
158 
159 /* movie frame display function for third demo5 */
demo5_light(i)160 func demo5_light(i)
161 {
162   if (i>=30) return 0;
163 
164   theta= pi/4 + (i-1)*2*pi/29;
165   light3, sdir=[cos(theta),.25,sin(theta)];
166 
167   /* without an explicit call to draw3, the light3 function would
168    * cause no changes until Yorick paused for input from the keyboard,
169    * since unlike the primitive plotting functions (plg, plf, plfp, ...)
170    * the fma call made by the movie function will not trigger the
171    * 3D display list
172    * any movie frame display function which uses the 3D drawing
173    * functions in pl3d.i will need to do this
174    * the !making_movie flag supresses the fma in draw3 if this function
175    * is called by movie (which issues its own fma), but allows it
176    * otherwise */
177   draw3, !making_movie;
178 
179   return 1;
180 }
181