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