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