1 //      plmtex3, plptex3 demo.
2 //
3 // Copyright (C) 2007, 2008, 2009 Alan W. Irwin
4 //
5 // This file is part of PLplot.
6 //
7 // PLplot is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU Library General Public License as published
9 // by the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // PLplot is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU Library General Public License for more details.
16 //
17 // You should have received a copy of the GNU Library General Public License
18 // along with PLplot; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 //
21 //
22 
23 #include "plcdemos.h"
24 // Choose these values to correspond to tick marks.
25 #define XPTS           2
26 #define YPTS           2
27 #define NREVOLUTION    16
28 #define NROTATION      8
29 #define NSHEAR         8
30 
31 //--------------------------------------------------------------------------
32 // main
33 //
34 // Demonstrates plotting text in 3D.
35 //--------------------------------------------------------------------------
36 
37 
main(int argc,char * argv[])38 int main( int argc, char *argv[] )
39 {
40     PLFLT *x, *y, **z,
41            xmin     = 0., xmax = 1.0, xmid = 0.5 * ( xmax + xmin ), xrange = xmax - xmin,
42            ymin     = 0., ymax = 1.0, ymid = 0.5 * ( ymax + ymin ), yrange = ymax - ymin,
43            zmin     = 0., zmax = 1.0, zmid = 0.5 * ( zmax + zmin ), zrange = zmax - zmin,
44            ysmin    = ymin + 0.1 * yrange,
45            ysmax    = ymax - 0.1 * yrange,
46            ysrange  = ysmax - ysmin,
47            dysrot   = ysrange / (PLFLT) ( NROTATION - 1 ),
48            dysshear = ysrange / (PLFLT) ( NSHEAR - 1 ),
49            zsmin    = zmin + 0.1 * zrange,
50            zsmax    = zmax - 0.1 * zrange,
51            zsrange  = zsmax - zsmin,
52            dzsrot   = zsrange / (PLFLT) ( NROTATION - 1 ),
53            dzsshear = zsrange / (PLFLT) ( NSHEAR - 1 ),
54            ys, zs,
55            x_inclination, y_inclination, z_inclination,
56            x_shear, y_shear, z_shear,
57            omega, sin_omega, cos_omega, domega;
58     int   i, j;
59     PLFLT radius, pitch, xpos, ypos, zpos;
60     // p1string must be exactly one character + the null termination
61     // character.
62     char          p1string[] = "O";
63     PLCHAR_VECTOR pstring    = "The future of our civilization depends on software freedom.";
64     // Allocate and define the minimal x, y, and z to insure 3D box
65     x = (PLFLT *) calloc( XPTS, sizeof ( PLFLT ) );
66     y = (PLFLT *) calloc( YPTS, sizeof ( PLFLT ) );
67 
68     plAlloc2dGrid( &z, XPTS, YPTS );
69     for ( i = 0; i < XPTS; i++ )
70     {
71         x[i] = xmin + (PLFLT) i * ( xmax - xmin ) / (PLFLT) ( XPTS - 1 );
72     }
73 
74     for ( j = 0; j < YPTS; j++ )
75         y[j] = ymin + (PLFLT) j * ( ymax - ymin ) / (PLFLT) ( YPTS - 1 );
76 
77     for ( i = 0; i < XPTS; i++ )
78     {
79         for ( j = 0; j < YPTS; j++ )
80         {
81             z[i][j] = 0.;
82         }
83     }
84 
85     // Parse and process command line arguments
86 
87     (void) plparseopts( &argc, argv, PL_PARSE_FULL );
88 
89     plinit();
90 
91     // Page 1: Demonstrate inclination and shear capability pattern.
92 
93     pladv( 0 );
94     plvpor( -0.15, 1.15, -0.05, 1.05 );
95     plwind( -1.2, 1.2, -0.8, 1.5 );
96     plw3d( 1.0, 1.0, 1.0, xmin, xmax, ymin, ymax, zmin, zmax,
97         20., 45. );
98 
99     plcol0( 2 );
100     plbox3( "b", "", xmax - xmin, 0,
101         "b", "", ymax - ymin, 0,
102         "bcd", "", zmax - zmin, 0 );
103 
104     // z = zmin.
105     plschr( 0., 1.0 );
106     for ( i = 0; i < NREVOLUTION; i++ )
107     {
108         omega         = 2. * M_PI * ( (PLFLT) i / (PLFLT) NREVOLUTION );
109         sin_omega     = sin( omega );
110         cos_omega     = cos( omega );
111         x_inclination = 0.5 * xrange * cos_omega;
112         y_inclination = 0.5 * yrange * sin_omega;
113         z_inclination = 0.;
114         x_shear       = -0.5 * xrange * sin_omega;
115         y_shear       = 0.5 * yrange * cos_omega;
116         z_shear       = 0.;
117         plptex3(
118             xmid, ymid, zmin,
119             x_inclination, y_inclination, z_inclination,
120             x_shear, y_shear, z_shear,
121             0.0, "  revolution" );
122     }
123 
124     // x = xmax.
125     plschr( 0., 1.0 );
126     for ( i = 0; i < NREVOLUTION; i++ )
127     {
128         omega         = 2. * M_PI * ( (PLFLT) i / (PLFLT) NREVOLUTION );
129         sin_omega     = sin( omega );
130         cos_omega     = cos( omega );
131         x_inclination = 0.;
132         y_inclination = -0.5 * yrange * cos_omega;
133         z_inclination = 0.5 * zrange * sin_omega;
134         x_shear       = 0.;
135         y_shear       = 0.5 * yrange * sin_omega;
136         z_shear       = 0.5 * zrange * cos_omega;
137         plptex3(
138             xmax, ymid, zmid,
139             x_inclination, y_inclination, z_inclination,
140             x_shear, y_shear, z_shear,
141             0.0, "  revolution" );
142     }
143 
144     // y = ymax.
145     plschr( 0., 1.0 );
146     for ( i = 0; i < NREVOLUTION; i++ )
147     {
148         omega         = 2. * M_PI * ( (PLFLT) i / (PLFLT) NREVOLUTION );
149         sin_omega     = sin( omega );
150         cos_omega     = cos( omega );
151         x_inclination = 0.5 * xrange * cos_omega;
152         y_inclination = 0.;
153         z_inclination = 0.5 * zrange * sin_omega;
154         x_shear       = -0.5 * xrange * sin_omega;
155         y_shear       = 0.;
156         z_shear       = 0.5 * zrange * cos_omega;
157         plptex3(
158             xmid, ymax, zmid,
159             x_inclination, y_inclination, z_inclination,
160             x_shear, y_shear, z_shear,
161             0.0, "  revolution" );
162     }
163     // Draw minimal 3D grid to finish defining the 3D box.
164     plmesh( x, y, (PLFLT_MATRIX) z, XPTS, YPTS, DRAW_LINEXY );
165 
166     // Page 2: Demonstrate rotation of string around its axis.
167     pladv( 0 );
168     plvpor( -0.15, 1.15, -0.05, 1.05 );
169     plwind( -1.2, 1.2, -0.8, 1.5 );
170     plw3d( 1.0, 1.0, 1.0, xmin, xmax, ymin, ymax, zmin, zmax,
171         20., 45. );
172 
173     plcol0( 2 );
174     plbox3( "b", "", xmax - xmin, 0,
175         "b", "", ymax - ymin, 0,
176         "bcd", "", zmax - zmin, 0 );
177 
178     // y = ymax.
179     plschr( 0., 1.0 );
180     x_inclination = 1.;
181     y_inclination = 0.;
182     z_inclination = 0.;
183     x_shear       = 0.;
184     for ( i = 0; i < NROTATION; i++ )
185     {
186         omega     = 2. * M_PI * ( (PLFLT) i / (PLFLT) NROTATION );
187         sin_omega = sin( omega );
188         cos_omega = cos( omega );
189         y_shear   = 0.5 * yrange * sin_omega;
190         z_shear   = 0.5 * zrange * cos_omega;
191         zs        = zsmax - dzsrot * (PLFLT) i;
192         plptex3(
193             xmid, ymax, zs,
194             x_inclination, y_inclination, z_inclination,
195             x_shear, y_shear, z_shear,
196             0.5, "rotation for y = y#dmax#u" );
197     }
198 
199     // x = xmax.
200     plschr( 0., 1.0 );
201     x_inclination = 0.;
202     y_inclination = -1.;
203     z_inclination = 0.;
204     y_shear       = 0.;
205     for ( i = 0; i < NROTATION; i++ )
206     {
207         omega     = 2. * M_PI * ( (PLFLT) i / (PLFLT) NROTATION );
208         sin_omega = sin( omega );
209         cos_omega = cos( omega );
210         x_shear   = 0.5 * xrange * sin_omega;
211         z_shear   = 0.5 * zrange * cos_omega;
212         zs        = zsmax - dzsrot * (PLFLT) i;
213         plptex3(
214             xmax, ymid, zs,
215             x_inclination, y_inclination, z_inclination,
216             x_shear, y_shear, z_shear,
217             0.5, "rotation for x = x#dmax#u" );
218     }
219 
220     // z = zmin.
221     plschr( 0., 1.0 );
222     x_inclination = 1.;
223     y_inclination = 0.;
224     z_inclination = 0.;
225     x_shear       = 0.;
226     for ( i = 0; i < NROTATION; i++ )
227     {
228         omega     = 2. * M_PI * ( (PLFLT) i / (PLFLT) NROTATION );
229         sin_omega = sin( omega );
230         cos_omega = cos( omega );
231         y_shear   = 0.5 * yrange * cos_omega;
232         z_shear   = 0.5 * zrange * sin_omega;
233         ys        = ysmax - dysrot * (PLFLT) i;
234         plptex3(
235             xmid, ys, zmin,
236             x_inclination, y_inclination, z_inclination,
237             x_shear, y_shear, z_shear,
238             0.5, "rotation for z = z#dmin#u" );
239     }
240     // Draw minimal 3D grid to finish defining the 3D box.
241     plmesh( x, y, (PLFLT_MATRIX) z, XPTS, YPTS, DRAW_LINEXY );
242 
243     // Page 3: Demonstrate shear of string along its axis.
244     // Work around xcairo and pngcairo (but not pscairo) problems for
245     // shear vector too close to axis of string. (N.B. no workaround
246     // would be domega = 0.)
247     domega = 0.05;
248     pladv( 0 );
249     plvpor( -0.15, 1.15, -0.05, 1.05 );
250     plwind( -1.2, 1.2, -0.8, 1.5 );
251     plw3d( 1.0, 1.0, 1.0, xmin, xmax, ymin, ymax, zmin, zmax,
252         20., 45. );
253 
254     plcol0( 2 );
255     plbox3( "b", "", xmax - xmin, 0,
256         "b", "", ymax - ymin, 0,
257         "bcd", "", zmax - zmin, 0 );
258 
259     // y = ymax.
260     plschr( 0., 1.0 );
261     x_inclination = 1.;
262     y_inclination = 0.;
263     z_inclination = 0.;
264     y_shear       = 0.;
265     for ( i = 0; i < NSHEAR; i++ )
266     {
267         omega     = domega + 2. * M_PI * ( (PLFLT) i / (PLFLT) NSHEAR );
268         sin_omega = sin( omega );
269         cos_omega = cos( omega );
270         x_shear   = 0.5 * xrange * sin_omega;
271         z_shear   = 0.5 * zrange * cos_omega;
272         zs        = zsmax - dzsshear * (PLFLT) i;
273         plptex3(
274             xmid, ymax, zs,
275             x_inclination, y_inclination, z_inclination,
276             x_shear, y_shear, z_shear,
277             0.5, "shear for y = y#dmax#u" );
278     }
279 
280     // x = xmax.
281     plschr( 0., 1.0 );
282     x_inclination = 0.;
283     y_inclination = -1.;
284     z_inclination = 0.;
285     x_shear       = 0.;
286     for ( i = 0; i < NSHEAR; i++ )
287     {
288         omega     = domega + 2. * M_PI * ( (PLFLT) i / (PLFLT) NSHEAR );
289         sin_omega = sin( omega );
290         cos_omega = cos( omega );
291         y_shear   = -0.5 * yrange * sin_omega;
292         z_shear   = 0.5 * zrange * cos_omega;
293         zs        = zsmax - dzsshear * (PLFLT) i;
294         plptex3(
295             xmax, ymid, zs,
296             x_inclination, y_inclination, z_inclination,
297             x_shear, y_shear, z_shear,
298             0.5, "shear for x = x#dmax#u" );
299     }
300 
301     // z = zmin.
302     plschr( 0., 1.0 );
303     x_inclination = 1.;
304     y_inclination = 0.;
305     z_inclination = 0.;
306     z_shear       = 0.;
307     for ( i = 0; i < NSHEAR; i++ )
308     {
309         omega     = domega + 2. * M_PI * ( (PLFLT) i / (PLFLT) NSHEAR );
310         sin_omega = sin( omega );
311         cos_omega = cos( omega );
312         y_shear   = 0.5 * yrange * cos_omega;
313         x_shear   = 0.5 * xrange * sin_omega;
314         ys        = ysmax - dysshear * (PLFLT) i;
315         plptex3(
316             xmid, ys, zmin,
317             x_inclination, y_inclination, z_inclination,
318             x_shear, y_shear, z_shear,
319             0.5, "shear for z = z#dmin#u" );
320     }
321     // Draw minimal 3D grid to finish defining the 3D box.
322     plmesh( x, y, (PLFLT_MATRIX) z, XPTS, YPTS, DRAW_LINEXY );
323 
324     // Page 4: Demonstrate drawing a string on a 3D path.
325     pladv( 0 );
326     plvpor( -0.15, 1.15, -0.05, 1.05 );
327     plwind( -1.2, 1.2, -0.8, 1.5 );
328     plw3d( 1.0, 1.0, 1.0, xmin, xmax, ymin, ymax, zmin, zmax,
329         40., -30. );
330 
331     plcol0( 2 );
332     plbox3( "b", "", xmax - xmin, 0,
333         "b", "", ymax - ymin, 0,
334         "bcd", "", zmax - zmin, 0 );
335 
336     plschr( 0., 1.2 );
337     // domega controls the spacing between the various characters of the
338     // string and also the maximum value of omega for the given number
339     // of characters in *pstring.
340     domega = 2. * M_PI / (PLFLT) strlen( pstring );
341     omega  = 0.;
342     // 3D function is a helix of the given radius and pitch
343     radius = 0.5;
344     pitch  = 1. / ( 2. * M_PI );
345     while ( *pstring )
346     {
347         sin_omega = sin( omega );
348         cos_omega = cos( omega );
349         xpos      = xmid + radius * sin_omega;
350         ypos      = ymid - radius * cos_omega;
351         zpos      = zmin + pitch * omega;
352         // In general, the inclination is proportional to the derivative of
353         // the position wrt theta.
354         x_inclination = radius * cos_omega;;
355         y_inclination = radius * sin_omega;
356         z_inclination = pitch;
357         // The shear vector should be perpendicular to the 3D line with Z
358         // component maximized, but for low pitch a good approximation is
359         // a constant vector that is parallel to the Z axis.
360         x_shear   = 0.;
361         y_shear   = 0.;
362         z_shear   = 1.;
363         *p1string = *pstring;
364         plptex3(
365             xpos, ypos, zpos,
366             x_inclination, y_inclination, z_inclination,
367             x_shear, y_shear, z_shear,
368             0.5, p1string );
369         pstring++;
370         omega += domega;
371     }
372     // Draw minimal 3D grid to finish defining the 3D box.
373     plmesh( x, y, (PLFLT_MATRIX) z, XPTS, YPTS, DRAW_LINEXY );
374 
375     // Page 5: Demonstrate plmtex3 axis labelling capability
376     pladv( 0 );
377     plvpor( -0.15, 1.15, -0.05, 1.05 );
378     plwind( -1.2, 1.2, -0.8, 1.5 );
379     plw3d( 1.0, 1.0, 1.0, xmin, xmax, ymin, ymax, zmin, zmax,
380         20., 45. );
381 
382     plcol0( 2 );
383     plbox3( "b", "", xmax - xmin, 0,
384         "b", "", ymax - ymin, 0,
385         "bcd", "", zmax - zmin, 0 );
386 
387     plschr( 0., 1.0 );
388     plmtex3( "xp", 3.0, 0.5, 0.5, "Arbitrarily displaced" );
389     plmtex3( "xp", 4.5, 0.5, 0.5, "primary X-axis label" );
390     plmtex3( "xs", -2.5, 0.5, 0.5, "Arbitrarily displaced" );
391     plmtex3( "xs", -1.0, 0.5, 0.5, "secondary X-axis label" );
392     plmtex3( "yp", 3.0, 0.5, 0.5, "Arbitrarily displaced" );
393     plmtex3( "yp", 4.5, 0.5, 0.5, "primary Y-axis label" );
394     plmtex3( "ys", -2.5, 0.5, 0.5, "Arbitrarily displaced" );
395     plmtex3( "ys", -1.0, 0.5, 0.5, "secondary Y-axis label" );
396     plmtex3( "zp", 4.5, 0.5, 0.5, "Arbitrarily displaced" );
397     plmtex3( "zp", 3.0, 0.5, 0.5, "primary Z-axis label" );
398     plmtex3( "zs", -2.5, 0.5, 0.5, "Arbitrarily displaced" );
399     plmtex3( "zs", -1.0, 0.5, 0.5, "secondary Z-axis label" );
400     // Draw minimal 3D grid to finish defining the 3D box.
401     plmesh( x, y, (PLFLT_MATRIX) z, XPTS, YPTS, DRAW_LINEXY );
402 
403     // Clean up.
404     free( (void *) x );
405     free( (void *) y );
406     plFree2dGrid( z, XPTS, YPTS );
407     plend();
408     exit( 0 );
409 }
410