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