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