1TriD(3) User Contributed Perl Documentation TriD(3)
2
3
4
6 PDL::Graphics::TriD -- PDL 3D interface
7
9 use PDL::Graphics::TriD;
10
11 # Generate a somewhat interesting sequence of points:
12 $t = sequence(100)/10;
13 $x = sin($t); $y = cos($t), $z = $t;
14 $coords = cat($x, $y, $z)->xchg(0,1);
15 my $red = cos(2*$t); my $green = sin($t); my $blue = $t;
16 $colors = cat($red, $green, $blue)->xchg(0,1);
17
18 # After each graph, let the user rotate and
19 # wait for him to press 'q', then make new graph
20 line3d($coords); # $coords = (3,n,...)
21 line3d($coords,$colors); # $colors = (3,n,...)
22 line3d([$x,$y,$z]);
23
24 # Generate a somewhat interesting sequence of surfaces
25 $surf1 = (rvals(100, 100) / 50)**2 + sin(xvals(100, 100) / 10);
26 $surf2 = sqrt(rvals(zeroes(50,50))/2);
27 $x = sin($surface); $y = cos($surface), $z = $surface;
28 $coords = cat($x, $y, $z)->xchg(0,1);
29 $red = cos(2*$surface); $green = sin($surface); $blue = $surface;
30 $colors = cat($red, $green, $blue)->xchg(0,1);
31 imagrgb([$red,$green,$blue]); # 2-d piddles
32 lattice3d([$surf1]);
33 points3d([$x,$y,$z]);
34 spheres3d([$x,$y,$z]); # preliminary implementation
35
36 hold3d(); # the following graphs are on top of each other and the previous
37 line3d([$x,$y,$z]);
38 line3d([$x,$y,$z+1]);
39 $pic = grabpic3d(); # Returns the picture in a (3,$x,$y) float piddle (0..1).
40
41 release3d(); # the next graph will again wipe out things.
42
44 These modules are still in a somewhat unfocused state: don't use them
45 yet if you don't know how to make them work if they happen to do
46 something strange.
47
49 This module implements a generic 3D plotting interface for PDL.
50 Points, lines and surfaces (among other objects) are supported.
51
52 With OpenGL, it is easy to manipulate the resulting 3D objects with the
53 mouse in real time - this helps data visualization a lot.
54
56 The default device for TriD is currently OpenGL. You can specify a
57 different device either in your program or in the environment variable
58 "PDL_3D_DEVICE". The one specified in the program takes priority.
59
60 The currently available devices are
61
62 GL OpenGL
63
64 GLpic OpenGL but off-line (pixmap) rendering and writing to a
65 graphics file.
66
67 VRML ( Not available this release )
68 VRML objects rendering. This writes a VRML file describing the
69 scene. This VRML file can then be read with a browser.
70
72 TriD offers both on- and off-line visualization. Currently the
73 interface w.r.t. this division is still much in motion.
74
75 For OpenGL you can select either on- or off-line rendering. VRML is
76 currently always offline (this may change later, if someone bothers to
77 write the java(script) code to contact PDL and wait for the next
78 PDL image over the network.
79
81 Specifying a set of coordinates is generally a context-dependent
82 operation. For a traditional 3D surface plot, you'll want two of the
83 coordinates to have just the xvals and yvals of the piddle,
84 respectively. For a line, you would generally want to have one
85 coordinate held at zero and the other advancing.
86
87 This module tries to make a reasonable way of specifying the context
88 while letting you do whatever you want by overriding the default
89 interpretation.
90
91 The alternative syntaxes for specifying a set of coordinates (or
92 colors) are
93
94 $piddle # MUST have 3 as first dim.
95 [$piddle]
96 [$piddle1,$piddle2]
97 [$piddle1,$piddle2,$piddle3]
98 [CONTEXT,$piddle]
99 [CONTEXT,$piddle1,$piddle2]
100 [CONTEXT,$piddle1,$piddle2,$piddle3]
101
102 where "CONTEXT" is a string describing in which context you wish these
103 piddles to be interpreted. Each routine specifies a default context
104 which is explained in the routines documentation. Context is usually
105 used only to understand what the user wants when he/she specifies less
106 than 3 piddles.
107
108 The following contexts are currently supported:
109
110 SURF2D A 2-D lattice. " [$piddle] " is interpreted as the Z coordinate
111 over a lattice over the first dimension. Equivalent to
112 "[$piddle->xvals, $piddle->yvals, $piddle]".
113
114 POLAR2D A 2-D polar coordinate system. " [$piddle] " is interpreted as
115 the z coordinate over theta and r (theta = the first dimension
116 of the piddle).
117
118 COLOR A set of colors. " [$piddle] " is interpreted as grayscale
119 color (equivalent to " [$piddle,$piddle,$piddle] ").
120
121 LINE A line made of 1 or 2 coordinates. " [$piddle] " is interpreted
122 as "[$piddle->xvals,$piddle,0]". " [$piddle1,$piddle2] " is
123 interpreted as "[$piddle1,$piddle2,$piddle1->xvals]".
124
125 What makes contexts useful is that if you want to plot points instead
126 of the full surface you plotted with
127
128 imag3d([$zcoords]);
129
130 you don't need to start thinking about where to plot the points:
131
132 points3d([SURF2D,$zcoords]);
133
134 will do exactly the same.
135
136 Wrapping your head around 3d surface specifications
137 Let's begin by thnking about how you might make a 2d data plot. If you
138 sampled your data at regular intervals, you would have a time serires
139 y(t) = (y0, y1, y2, ...). You could plot y vs t by computing t0 = 0,
140 t1 = dt, t2 = 2 * dt, and then plotting (t0, y0), (t1, y1), etc.
141
142 Next suppose that you measured x(t) and y(t). You can still plot y vs
143 t, but you can also plot y vs x by plotting (x0, y0), (x1, y1), etc.
144 The x-values don't have to increase monotonically: they could back-
145 track on each other, for example, like the latitude and longitude of a
146 boat on a lake. If you use plplot, you would plot this data using
147 "$pl->xyplot($x, $y, PLOTTYPE => 'POINTS')".
148
149 Good. Now let's add a third coordinate, z(t). If you actually sampled
150 x and y at regular intervals, so that x and y lie on a grid, then you
151 can construct a grid for z(x, y), and you would get a surface. This is
152 the situation in which you would use "mesh3d([$surface])".
153
154 Of course, your data is not required to be regularly gridded. You
155 could, for example, be measuring the flight path of a bat flying after
156 mosquitos, which could be wheeling and arching all over the space.
157 This is what you might plot using "line3d([$x, $y, $z])". You could
158 plot the trajectories of multiple bats, in which case $x, $y, and $z
159 would have multiple columns, but in general you wouldn't expect them to
160 be coordinated.
161
162 Finally, imagine that you have an air squadron flying in formation.
163 Your (x, y, z) data is not regularly gridded, but the (x, y, z) data
164 for each plane should be coordinated and we can imagine that their
165 flight path sweep out a surface. We could draw this data using
166 "line3d([$x, $y, $z])", where each column in the variables corresponds
167 to a different plane, but it would also make sense to draw this data
168 using "mesh3d([$x, $y, $z])", since the planes' proximity to each other
169 should be fairly consistent. In other words, it makes sense to think
170 of the planes as sweeping out a coordinated surface, which "mesh3d"
171 would draw for you, whereas you would not expect the trajectories of
172 the various bats to describe a meaningful surface (unless you're into
173 fractals, perhaps).
174
175 #!/usr/bin/perl
176
177 use PDL;
178 use PDL::Graphics::TriD;
179
180 # Draw out a trajectory in three-space
181 $t = sequence(100)/10;
182 $x = sin($t); $y = cos($t); $z = $t;
183
184 # Plot the trajectory as (x(t), y(t), z(t))
185 print "using line3d to plot a trajectory (press q when you're done twiddling)\n";
186 line3d [$x,$y,$z];
187
188 # If you give it a single piddle, it expects
189 # the data to look like
190 # ((x1, y1, z1), (x2, y2, z2), ...)
191 # which is why we have to do the exchange:
192 $coords = cat($x, $y, $z)->xchg(0,1);
193 print "again, with a different coordinate syntax (press q when you're done twiddling)\n";
194 line3d $coords;
195
196 # Draw a regularly-gridded surface:
197 $surface = sqrt(rvals(zeroes(50,50))/2);
198 print "draw a mesh of a regularly-gridded surface using mesh3d\n";
199 mesh3d [$surface];
200 print "draw a regularly-gridded surface using imag3d\n";
201 imag3d [$surface], {Lines=>0};
202
203 # Draw a mobius strip:
204 $two_pi = 8 * atan2(1,1);
205 $t = sequence(50) / 50 * $two_pi;
206 # We want two paths:
207 $mobius1_x = cos($t) + 0.5 * sin($t/2);
208 $mobius2_x = cos($t);
209 $mobius3_x = cos($t) - 0.5 * sin($t/2);
210 $mobius1_y = sin($t) + 0.5 * sin($t/2);
211 $mobius2_y = sin($t);
212 $mobius3_y = sin($t) - 0.5 * sin($t/2);
213 $mobius1_z = $t - $two_pi/2;
214 $mobius2_z = zeroes($t);
215 $mobius3_z = $two_pi/2 - $t;
216
217 $mobius_x = cat($mobius1_x, $mobius2_x, $mobius3_x);
218 $mobius_y = cat($mobius1_y, $mobius2_y, $mobius3_y);
219 $mobius_z = cat($mobius1_z, $mobius2_z, $mobius3_z);
220
221 $mobius_surface = cat($mobius_x, $mobius_y, $mobius_z)->mv(2,0);
222
223 print "A mobius strip using line3d one way\n";
224 line3d $mobius_surface;
225 print "A mobius strip using line3d the other way\n";
226 line3d $mobius_surface->xchg(1,2);
227 print "A mobius strip using mesh3d\n";
228 mesh3d $mobius_surface;
229 print "The same mobius strip using imag3d\n";
230 imag3d $mobius_surface, {Lines => 0};
231
233 Because using the whole object-oriented interface for doing all your
234 work might be cumbersome, the following shortcut routines are
235 supported:
236
238 line3d
239 3D line plot, defined by a variety of contexts.
240
241 line3d piddle(3,x), {OPTIONS}
242 line3d [CONTEXT], {OPTIONS}
243
244 Example:
245
246 pdl> line3d [sqrt(rvals(zeroes(50,50))/2)]
247 - Lines on surface
248 pdl> line3d [$x,$y,$z]
249 - Lines over X, Y, Z
250 pdl> line3d $coords
251 - Lines over the 3D coordinates in $coords.
252
253 Note: line plots differ from mesh plots in that lines only go in one
254 direction. If this is unclear try both!
255
256 See module documentation for more information on contexts and options
257
258 imag3d
259 3D rendered image plot, defined by a variety of contexts
260
261 imag3d piddle(3,x,y), {OPTIONS}
262 imag3d [piddle,...], {OPTIONS}
263
264 Example:
265
266 pdl> imag3d [sqrt(rvals(zeroes(50,50))/2)], {Lines=>0};
267
268 - Rendered image of surface
269
270 See module documentation for more information on contexts and options
271
272 mesh3d
273 3D mesh plot, defined by a variety of contexts
274
275 mesh3d piddle(3,x,y), {OPTIONS}
276 mesh3d [piddle,...], {OPTIONS}
277
278 Example:
279
280 pdl> mesh3d [sqrt(rvals(zeroes(50,50))/2)]
281
282 - mesh of surface
283
284 Note: a mesh is defined by two sets of lines at right-angles (i.e. this
285 is how is differs from line3d).
286
287 See module documentation for more information on contexts and options
288
289 lattice3d
290 alias for mesh3d
291
292 points3d
293 3D points plot, defined by a variety of contexts
294
295 points3d piddle(3), {OPTIONS}
296 points3d [piddle,...], {OPTIONS}
297
298 Example:
299
300 pdl> points3d [sqrt(rvals(zeroes(50,50))/2)];
301 - points on surface
302
303 See module documentation for more information on contexts and options
304
305 spheres3d
306 3D spheres plot (preliminary implementation)
307
308 spheres3d piddle(3), {OPTIONS}
309 spheres3d [piddle,...], {OPTIONS}
310
311 Example:
312
313 pdl> spheres3d ndcoords(10,10,10)->clump(1,2,3)
314
315 - lattice of spheres at coordinates on 10x10x10 grid
316
317 This is a preliminary implementation as a proof of concept. It has
318 fixed radii for the spheres being drawn and no control of color or
319 transparency.
320
321 imagrgb
322 2D RGB image plot (see also imag2d)
323
324 imagrgb piddle(3,x,y), {OPTIONS}
325 imagrgb [piddle,...], {OPTIONS}
326
327 This would be used to plot an image, specifying red, green and blue
328 values at each point. Note: contexts are very useful here as there are
329 many ways one might want to do this.
330
331 e.g.
332
333 pdl> $x=sqrt(rvals(zeroes(50,50))/2)
334 pdl> imagrgb [0.5*sin(8*$x)+0.5,0.5*cos(8*$x)+0.5,0.5*cos(4*$x)+0.5]
335
336 imagrgb3d
337 2D RGB image plot as an object inside a 3D space
338
339 imagrdb3d piddle(3,x,y), {OPTIONS}
340 imagrdb3d [piddle,...], {OPTIONS}
341
342 The piddle gives the colors. The option allowed is Points, which should
343 give 4 3D coordinates for the corners of the polygon, either as a
344 piddle or as array ref. The default is
345 [[0,0,0],[1,0,0],[1,1,0],[0,1,0]].
346
347 e.g.
348
349 pdl> imagrgb3d $colors, {Points => [[0,0,0],[1,0,0],[1,0,1],[0,0,1]]};
350 - plot on XZ plane instead of XY.
351
352 grabpic3d
353 Grab a 3D image from the screen.
354
355 $pic = grabpic3d();
356
357 The returned piddle has dimensions (3,$x,$y) and is of type float
358 (currently). XXX This should be altered later.
359
360 hold3d, release3d
361 Keep / don't keep the previous objects when plotting new 3D objects
362
363 hold3d();
364 release3d();
365
366 or
367
368 hold3d(1);
369 hold3d(0);
370
371 keeptwiddling3d, nokeeptwiddling3d
372 Wait / don't wait for 'q' after displaying a 3D image.
373
374 Usually, when showing 3D images, the user is given a chance to rotate
375 it and then press 'q' for the next image. However, sometimes (for e.g.
376 animation) this is undesirable and it is more desirable to just run one
377 step of the event loop at a time.
378
379 keeptwiddling3d();
380 nokeeptwiddling3d();
381
382 or
383
384 keeptwiddling3d(1);
385 keeptwiddling3d(0);
386
387 When an image is added to the screen, keep twiddling it until user
388 explicitly presses 'q'.
389
390 keeptwiddling3d();
391 imag3d(..);
392 nokeeptwiddling3d();
393 $o = imag3d($c);
394 while(1) {
395 $c .= nextfunc($c);
396 $o->data_changed();
397 twiddle3d(); # animate one step, then return.
398 }
399
400 twiddle3d
401 Wait for the user to rotate the image in 3D space.
402
403 Let the user rotate the image in 3D space, either for one step or until
404 (s)he presses 'q', depending on the 'keeptwiddling3d' setting. If
405 'keeptwiddling3d' is not set the routine returns immediately and
406 indicates that a 'q' event was received by returning 1. If the only
407 events received were mouse events, returns 0.
408
410 The key concepts (object types) of TriD are explained in the following:
411
412 Object
413 In this 3D abstraction, everything that you can "draw" without using
414 indices is an Object. That is, if you have a surface, each vertex is
415 not an object and neither is each segment of a long curve. The whole
416 curve (or a set of curves) is the lowest level Object.
417
418 Transformations and groups of Objects are also Objects.
419
420 A Window is simply an Object that has subobjects.
421
422 Twiddling
423 Because there is no eventloop in Perl yet and because it would be
424 hassleful to do otherwise, it is currently not possible to e.g. rotate
425 objects with your mouse when the console is expecting input or the
426 program is doing other things. Therefore, you need to explicitly say
427 "$window->twiddle()" in order to display anything.
428
430 The following types of objects are currently supported. Those that do
431 not have a calling sequence described here should have their own manual
432 pages.
433
434 There are objects that are not mentioned here; they are either internal
435 to PDL3D or in rapidly changing states. If you use them, you do so at
436 your own risk.
437
438 The syntax "PDL::Graphics::TriD::Scale(x,y,z)" here means that you
439 create an object like
440
441 $c = new PDL::Graphics::TriD::Scale($x,$y,$z);
442
443 PDL::Graphics::TriD::LineStrip
444 This is just a line or a set of lines. The arguments are 3 1-or-more-D
445 piddles which describe the vertices of a continuous line and an
446 optional color piddle (which is 1-D also and simply defines the color
447 between red and blue. This will probably change).
448
449 PDL::Graphics::TriD::Lines
450 This is just a line or a set of lines. The arguments are 3 1-or-more-D
451 piddles where each contiguous pair of vertices describe a line segment
452 and an optional color piddle (which is 1-D also and simply defines the
453 color between red and blue. This will probably change).
454
455 PDL::Graphics::TriD::Image
456 This is a 2-dimensional RGB image consisting of colored rectangles.
457 With OpenGL, this is implemented by texturing so this should be
458 relatively memory and execution-time-friendly.
459
460 PDL::Graphics::TriD::Lattice
461 This is a 2-D set of points connected by lines in 3-space. The
462 constructor takes as arguments 3 2-dimensional piddles.
463
464 PDL::Graphics::TriD::Points
465 This is simply a set of points in 3-space. Takes as arguments the x, y
466 and z coordinates of the points as piddles.
467
468 PDL::Graphics::TriD::Scale(x,y,z)
469 Self-explanatory
470
471 PDL::Graphics::TriD::Translation(x,y,z)
472 Ditto
473
474 PDL::Graphics::TriD::Quaternion(c,x,y,z)
475 One way of representing rotations is with quaternions. See the
476 appropriate man page.
477
478 PDL::Graphics::TriD::ViewPort
479 This is a special class: in order to obtain a new viewport, you need to
480 have an earlier viewport on hand. The usage is:
481
482 $new_vp = $old_vp->new_viewport($x0,$y0,$x1,$y1);
483
484 where $x0 etc are the coordinates of the upper left and lower right
485 corners of the new viewport inside the previous (relative to the
486 previous viewport in the (0,1) range.
487
488 Every implementation-level window object should implement the
489 new_viewport method.
490
493 Not enough is there yet.
494
496 Copyright (C) 1997 Tuomas J. Lukka (lukka@husc.harvard.edu).
497 Documentation contributions from Karl Glazebrook
498 (kgb@aaoepp.aao.gov.au). All rights reserved. There is no warranty.
499 You are allowed to redistribute this software / documentation under
500 certain conditions. For details, see the file COPYING in the PDL
501 distribution. If this file is separated from the PDL distribution, the
502 copyright notice should be included in the file.
503
504
505
506perl v5.30.2 2020-04-02 TriD(3)