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