|
@@ -0,0 +1,634 @@
|
|
1
|
+#ifndef __MATPLOT_VTK
|
|
2
|
+#define __MATPLOT_VTK
|
|
3
|
+
|
|
4
|
+/*
|
|
5
|
+ * MatPlot_VTK
|
|
6
|
+ *
|
|
7
|
+ * Simple plotting of vectors and matrices based on
|
|
8
|
+ * the VTK libraries.
|
|
9
|
+ *
|
|
10
|
+ * Four classes:
|
|
11
|
+ * Plot2D_VTK - 2d plotting akin to plot(x,y)
|
|
12
|
+ * Surf_VTK - Surface plotting akin to surf(x,y,z)
|
|
13
|
+ * Contour_VTK - Contour plotting
|
|
14
|
+ * Quiver_VTK - Vector field plot
|
|
15
|
+ *
|
|
16
|
+ * See examples.cpp for usage instructions.
|
|
17
|
+ *
|
|
18
|
+ * These classes are released "as is", without any implied
|
|
19
|
+ * warranty or fitness for any particular purpose.
|
|
20
|
+ *
|
|
21
|
+ * Dag Lindbo, dag@csc.kth.se, 2007-12-09
|
|
22
|
+ */
|
|
23
|
+
|
|
24
|
+// matrix size functions
|
|
25
|
+// #include "ublas_dims.h"
|
|
26
|
+//#include "mtl4_dims.h"
|
|
27
|
+
|
|
28
|
+// system includes
|
|
29
|
+#include <assert.h>
|
|
30
|
+#include <string>
|
|
31
|
+#include <cmath>
|
|
32
|
+
|
|
33
|
+// vtk includes used by templates
|
|
34
|
+#include "vtkFloatArray.h"
|
|
35
|
+#include "vtkPointData.h"
|
|
36
|
+#include "vtkPoints.h"
|
|
37
|
+#include "vtkRectilinearGrid.h"
|
|
38
|
+#include "vtkRenderer.h"
|
|
39
|
+#include "vtkStructuredGrid.h"
|
|
40
|
+#include "vtkXYPlotActor.h"
|
|
41
|
+
|
|
42
|
+namespace matplot {
|
|
43
|
+
|
|
44
|
+ enum SCALE {LINEAR, LOG10};
|
|
45
|
+
|
|
46
|
+ void render_interactive(vtkRenderer *rend, int xPix, int yPix);
|
|
47
|
+
|
|
48
|
+ void render_interactive_camera(vtkRenderer *rend, int xPix, int yPix,
|
|
49
|
+ vtkCamera* mycam);
|
|
50
|
+
|
|
51
|
+ void render_interactive_cam(vtkRenderer *rend, int xPix, int yPix,
|
|
52
|
+ double cam[3], double focal[3]);
|
|
53
|
+
|
|
54
|
+ void render_to_png(vtkRenderer *rend, int xPix, int yPix,std::string fname);
|
|
55
|
+
|
|
56
|
+ void render_to_png_cam(vtkRenderer *rend, int xPix, int yPix,
|
|
57
|
+ std::string fname, double cam[3], double focal[3]);
|
|
58
|
+
|
|
59
|
+ /** Plot vectors x versus y.
|
|
60
|
+ * Inspired by "plot" in Matlab.
|
|
61
|
+ *
|
|
62
|
+ * Notes:
|
|
63
|
+ *
|
|
64
|
+ * Call plot(x,y,<...>) multiple times before show() to
|
|
65
|
+ * get multiple curves in one figure.
|
|
66
|
+ *
|
|
67
|
+ * \author Dag Lindbo
|
|
68
|
+ */
|
|
69
|
+ class Plot2D_VTK {
|
|
70
|
+
|
|
71
|
+ public:
|
|
72
|
+
|
|
73
|
+ Plot2D_VTK(std::string x_label="x", std::string y_label="y",
|
|
74
|
+ int xpix = 800, int ypix = 600, bool semilogx=false );
|
|
75
|
+ ~Plot2D_VTK();
|
|
76
|
+
|
|
77
|
+ /** Insert curve x vs.\ y into plot.
|
|
78
|
+ * - Default color is blue, {0 , 0, 1}.
|
|
79
|
+ * - Default line style is solid line, "-".
|
|
80
|
+ */
|
|
81
|
+ template<typename Vec_t>
|
|
82
|
+ void plot(const Vec_t &x, const Vec_t &y) {
|
|
83
|
+ double color[3] = { 0, 0, 1.0 };
|
|
84
|
+ plot(x, y, color, "-");
|
|
85
|
+ }
|
|
86
|
+
|
|
87
|
+ /** Insert curve x vs.\ y into plot (specify color and line style).
|
|
88
|
+ * Color specification:
|
|
89
|
+ * - RGB (normalized decimal), {0.32, 0.1, 0.0}
|
|
90
|
+ *
|
|
91
|
+ * Line style specification:
|
|
92
|
+ * - "-" solid line
|
|
93
|
+ * - "." dotted line
|
|
94
|
+ * - ".-" or "-." solid line with dots
|
|
95
|
+ */
|
|
96
|
+ template<typename Vec_t>
|
|
97
|
+ void plot(const Vec_t &x, const Vec_t &y, const double col[3],
|
|
98
|
+ const std::string linespec) {
|
|
99
|
+
|
|
100
|
+ int i, N = x.size(), plot_points = 0, plot_lines = 0;
|
|
101
|
+
|
|
102
|
+ vtkRectilinearGrid *curve;
|
|
103
|
+ vtkFloatArray *yVal;
|
|
104
|
+ vtkFloatArray *xVal;
|
|
105
|
+
|
|
106
|
+ // determine line style
|
|
107
|
+ if (linespec == "-")
|
|
108
|
+ plot_lines = 1;
|
|
109
|
+ else if (linespec == ".")
|
|
110
|
+ plot_points = 1;
|
|
111
|
+ else if (linespec == ".-" || linespec == "-.") {
|
|
112
|
+ plot_points = 1;
|
|
113
|
+ plot_lines = 1;
|
|
114
|
+ }
|
|
115
|
+
|
|
116
|
+ // put (x,y) into VTK FloatArrays
|
|
117
|
+ xVal = vtkFloatArray::New();
|
|
118
|
+ yVal = vtkFloatArray::New();
|
|
119
|
+
|
|
120
|
+ for (i=0; i<N; i++) {
|
|
121
|
+ xVal->InsertNextTuple1(x[i]);
|
|
122
|
+ yVal->InsertNextTuple1(y[i]);
|
|
123
|
+ }
|
|
124
|
+
|
|
125
|
+ // Make a VTK Rectlinear grid from arrays
|
|
126
|
+ curve = vtkRectilinearGrid::New();
|
|
127
|
+ curve->SetDimensions(N, 1, 1);
|
|
128
|
+ curve->SetXCoordinates(xVal);
|
|
129
|
+ curve->GetPointData()->SetScalars(yVal);
|
|
130
|
+
|
|
131
|
+ // attach gridfunction to plot
|
|
132
|
+ xyplot->AddDataSetInput(curve);
|
|
133
|
+
|
|
134
|
+ if (semilogx) {
|
|
135
|
+ xyplot->LogxOn();
|
|
136
|
+ }
|
|
137
|
+ // VTK doesn't have this? :(
|
|
138
|
+ //xyplot->LogyOn();
|
|
139
|
+
|
|
140
|
+ // how to read data
|
|
141
|
+ xyplot->SetXValuesToValue();
|
|
142
|
+
|
|
143
|
+ // set attributes
|
|
144
|
+ xyplot->SetPlotColor(plot_no, col[0], col[1], col[2]);
|
|
145
|
+ xyplot->SetPlotLines(plot_no, plot_lines);
|
|
146
|
+ xyplot->SetPlotPoints(plot_no, plot_points);
|
|
147
|
+
|
|
148
|
+ plot_no++;
|
|
149
|
+
|
|
150
|
+ xVal->Delete();
|
|
151
|
+ yVal->Delete();
|
|
152
|
+ curve->Delete();
|
|
153
|
+ }
|
|
154
|
+
|
|
155
|
+ void show();
|
|
156
|
+ void draw_to_png(std::string filename);
|
|
157
|
+
|
|
158
|
+ private:
|
|
159
|
+
|
|
160
|
+ int xPix;
|
|
161
|
+ int yPix;
|
|
162
|
+ bool semilogx;
|
|
163
|
+ int plot_no;
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+ vtkRenderer* rend;
|
|
167
|
+ vtkXYPlotActor* xyplot;
|
|
168
|
+ };
|
|
169
|
+
|
|
170
|
+ /** Plot z = f(x,y) surface.
|
|
171
|
+ * Inspired by "surf" in Matlab
|
|
172
|
+ *
|
|
173
|
+ * \author Dag Lindbo
|
|
174
|
+ */
|
|
175
|
+ class Surf_VTK
|
|
176
|
+ {
|
|
177
|
+ public:
|
|
178
|
+
|
|
179
|
+ Surf_VTK(int px = 800, int py = 600);
|
|
180
|
+ ~Surf_VTK();
|
|
181
|
+
|
|
182
|
+ /** Create surface plot.
|
|
183
|
+ * Matrix z, with respect to vectors x and y.
|
|
184
|
+ */
|
|
185
|
+ template<typename Vec_t, typename Mat_t>
|
|
186
|
+ void surf(const Vec_t &x, const Vec_t &y, const Mat_t &z)
|
|
187
|
+ {
|
|
188
|
+ geometry(x, y, z);
|
|
189
|
+ renderer(false, true, true, false);
|
|
190
|
+ render_interactive(rend, xPix, yPix);
|
|
191
|
+ }
|
|
192
|
+
|
|
193
|
+ /** Create surface plot.
|
|
194
|
+ * Matrix z, with respect to vectors x and y.
|
|
195
|
+ *
|
|
196
|
+ * Warp z-axis to produce better fit:
|
|
197
|
+ * - do_warp = true
|
|
198
|
+ */
|
|
199
|
+ template<typename Vec_t, typename Mat_t>
|
|
200
|
+ void surf(const Vec_t &x, const Vec_t &y, const Mat_t &z, bool do_warp)
|
|
201
|
+ {
|
|
202
|
+ geometry(x, y, z);
|
|
203
|
+ renderer(false, true, true, do_warp);
|
|
204
|
+ render_interactive(rend, xPix, yPix);
|
|
205
|
+ }
|
|
206
|
+
|
|
207
|
+ /** Create surface plot.
|
|
208
|
+ * Matrix z, with respect to vectors x and y.
|
|
209
|
+ *
|
|
210
|
+ * Warp z-axis to produce better fit:
|
|
211
|
+ * - do_warp = true
|
|
212
|
+ *
|
|
213
|
+ * Camera control:
|
|
214
|
+ * - specify camera position: cam = { -15.0, 10.0, 12.0 }
|
|
215
|
+ * - specify focal point: focal = { 0, 0, 0 }
|
|
216
|
+ */
|
|
217
|
+ template<typename Vec_t, typename Mat_t>
|
|
218
|
+ void surf(const Vec_t &x, const Vec_t &y, const Mat_t &z, bool do_warp,
|
|
219
|
+ double observer[3], double focal[3])
|
|
220
|
+ {
|
|
221
|
+ geometry(x, y, z);
|
|
222
|
+ renderer(false, true, true, do_warp);
|
|
223
|
+ render_interactive_cam(rend, xPix, yPix, observer, focal);
|
|
224
|
+ }
|
|
225
|
+
|
|
226
|
+ /** Create surface plot and render to file
|
|
227
|
+ * Matrix z, with respect to vectors x and y.
|
|
228
|
+ *
|
|
229
|
+ * Warp z-axis to produce better fit:
|
|
230
|
+ * - do_warp = true
|
|
231
|
+ *
|
|
232
|
+ * Camera control:
|
|
233
|
+ * - specify camera position: cam = { -15.0, 10.0, 12.0 }
|
|
234
|
+ * - specify focal point: focal = { 0, 0, 0 }
|
|
235
|
+ */
|
|
236
|
+ template<typename Vec_t, typename Mat_t>
|
|
237
|
+ void surf_to_file(const Vec_t &x, const Vec_t &y, const Mat_t &z,
|
|
238
|
+ bool do_warp, std::string fname, double observer[3],
|
|
239
|
+ double focal[3])
|
|
240
|
+ {
|
|
241
|
+ geometry(x, y, z);
|
|
242
|
+ renderer(false, true, true, do_warp);
|
|
243
|
+ render_to_png_cam(rend, xPix, yPix, fname, observer, focal);
|
|
244
|
+ }
|
|
245
|
+
|
|
246
|
+ void purge();
|
|
247
|
+
|
|
248
|
+ private:
|
|
249
|
+ vtkStructuredGrid *gridfunc;
|
|
250
|
+ vtkRenderer *rend;
|
|
251
|
+
|
|
252
|
+ double Lxy, Lz;
|
|
253
|
+ bool has_data;
|
|
254
|
+
|
|
255
|
+ int xPix, yPix;
|
|
256
|
+
|
|
257
|
+ template<typename Vec_t, typename Mat_t>
|
|
258
|
+ void geometry(const Vec_t &x, const Vec_t &y, const Mat_t &z)
|
|
259
|
+ {
|
|
260
|
+ const unsigned int Nx = x.size(); //vec_dim(x);
|
|
261
|
+ const unsigned int Ny = y.size(); //vec_dim(y);
|
|
262
|
+ unsigned int i, j, k;
|
|
263
|
+
|
|
264
|
+ // make sure the input is ok and that this surfaceplot is free
|
|
265
|
+ assert(Nx == z.rows() );
|
|
266
|
+ assert(Ny == z.cols() );
|
|
267
|
+ assert(!has_data);
|
|
268
|
+
|
|
269
|
+ // determine x-y range of data
|
|
270
|
+ if (x(Nx-1)-x(0) > y(Ny-1)-y(0))
|
|
271
|
+ Lxy = x(Nx-1)-x(0);
|
|
272
|
+ else
|
|
273
|
+ Lxy = y(Ny-1)-y(0);
|
|
274
|
+ double z_low = 10000, z_upp = -10000;
|
|
275
|
+
|
|
276
|
+ // put data, z, into a 2D structured grid
|
|
277
|
+ gridfunc->SetDimensions(Nx, Ny, 1);
|
|
278
|
+
|
|
279
|
+ vtkPoints *points = vtkPoints::New();
|
|
280
|
+ for (j = 0; j < Ny; j++)
|
|
281
|
+ {
|
|
282
|
+ for (i = 0; i < Nx; i++)
|
|
283
|
+ {
|
|
284
|
+ points->InsertNextPoint(x(i), y(j), z(i, j));
|
|
285
|
+
|
|
286
|
+ if (z(i, j)< z_low)
|
|
287
|
+ z_low = z(i, j);
|
|
288
|
+ if (z(i, j)> z_upp)
|
|
289
|
+ z_upp = z(i, j);
|
|
290
|
+ }
|
|
291
|
+ }
|
|
292
|
+ gridfunc->SetPoints(points);
|
|
293
|
+
|
|
294
|
+ // get scalar field from z-values
|
|
295
|
+ vtkFloatArray *colors = vtkFloatArray::New();
|
|
296
|
+ colors->SetNumberOfComponents(1);
|
|
297
|
+ colors->SetNumberOfTuples(Nx*Ny);
|
|
298
|
+ k = 0;
|
|
299
|
+ for (j = 0; j < Ny; j++)
|
|
300
|
+ for (i = 0; i < Nx; i++)
|
|
301
|
+ {
|
|
302
|
+ colors->InsertComponent(k, 0, z(i, j));
|
|
303
|
+ k++;
|
|
304
|
+ }
|
|
305
|
+
|
|
306
|
+ gridfunc->GetPointData()->SetScalars(colors);
|
|
307
|
+
|
|
308
|
+ points->Delete();
|
|
309
|
+ colors->Delete();
|
|
310
|
+
|
|
311
|
+ has_data = true;
|
|
312
|
+ Lz = z_upp-z_low;
|
|
313
|
+ }
|
|
314
|
+
|
|
315
|
+ void renderer(bool, bool, bool, bool);
|
|
316
|
+
|
|
317
|
+ };
|
|
318
|
+
|
|
319
|
+ /** Plot contour lines for a function in the plane.
|
|
320
|
+ * Inspired by "contour" in Matlab
|
|
321
|
+ *
|
|
322
|
+ * \author Dag Lindbo
|
|
323
|
+ */
|
|
324
|
+
|
|
325
|
+ class Contour_VTK {
|
|
326
|
+
|
|
327
|
+ public:
|
|
328
|
+
|
|
329
|
+ Contour_VTK(int px = 800, int py = 600);
|
|
330
|
+
|
|
331
|
+ // specify linear or log on bars
|
|
332
|
+ Contour_VTK(int px = 800, int py = 600, SCALE xscale=LINEAR, SCALE
|
|
333
|
+ yscale=LINEAR);
|
|
334
|
+
|
|
335
|
+ ~Contour_VTK();
|
|
336
|
+
|
|
337
|
+ /** Create contour plot.
|
|
338
|
+ * Matrix z vs. vectors x and y.
|
|
339
|
+ * Produces a default number of contour lines (10) and
|
|
340
|
+ * colors the lines instead of the underlying surface.
|
|
341
|
+ */
|
|
342
|
+ template<typename Vec_t, typename Mat_t>
|
|
343
|
+ void contour(const Vec_t &x, const Vec_t &y, const Mat_t &z) {
|
|
344
|
+ geometry(x, y, z);
|
|
345
|
+ renderer(true, false, 10);
|
|
346
|
+ render_interactive(rend, xPix, yPix);
|
|
347
|
+ }
|
|
348
|
+
|
|
349
|
+ /**Create contour plot.
|
|
350
|
+ * Matrix z vs. vectors x and y.
|
|
351
|
+ *
|
|
352
|
+ * Number of contour lines:
|
|
353
|
+ * - num_lines
|
|
354
|
+ *
|
|
355
|
+ * Coloring:
|
|
356
|
+ * - draw_surf = false: color contour lines and omits underlying surface
|
|
357
|
+ * - draw_surf = true: draw contour lines white and color the
|
|
358
|
+ * underlying surface
|
|
359
|
+ */
|
|
360
|
+ template<typename Vec_t, typename Mat_t>
|
|
361
|
+ void contour(const Vec_t &x, const Vec_t &y, const Mat_t &z,
|
|
362
|
+ bool draw_surf, int num_lines) {
|
|
363
|
+ geometry(x, y, z);
|
|
364
|
+ renderer(true, draw_surf, num_lines);
|
|
365
|
+ render_interactive(rend, xPix, yPix);
|
|
366
|
+ }
|
|
367
|
+
|
|
368
|
+ /**Create contour plot and render to file.
|
|
369
|
+ * Matrix z vs. vectors x and y.
|
|
370
|
+ *
|
|
371
|
+ * Number of contour lines:
|
|
372
|
+ * - num_lines
|
|
373
|
+ *
|
|
374
|
+ * Coloring:
|
|
375
|
+ * - draw_surf = false: color contour lines and omits underlying surface
|
|
376
|
+ * - draw_surf = true: draw contour lines white and color the
|
|
377
|
+ * underlying surface
|
|
378
|
+ */
|
|
379
|
+
|
|
380
|
+ template<typename Vec_t, typename Mat_t>
|
|
381
|
+ void contour_to_file(const Vec_t &x, const Vec_t &y, const Mat_t &z,
|
|
382
|
+ bool draw_surf, int num_lines, std::string fname)
|
|
383
|
+ {
|
|
384
|
+ geometry(x, y, z);
|
|
385
|
+ renderer(true, draw_surf, num_lines);
|
|
386
|
+ render_to_png(rend, xPix, yPix, fname);
|
|
387
|
+ }
|
|
388
|
+
|
|
389
|
+ void purge();
|
|
390
|
+
|
|
391
|
+ void SetXLabel(const std::string &xlab);
|
|
392
|
+ void SetYLabel(const std::string &ylab);
|
|
393
|
+
|
|
394
|
+ private:
|
|
395
|
+
|
|
396
|
+ SCALE XScale;
|
|
397
|
+ SCALE YScale;
|
|
398
|
+
|
|
399
|
+ vtkRectilinearGrid *gridfunc;
|
|
400
|
+ vtkRenderer *rend;
|
|
401
|
+
|
|
402
|
+ bool has_data;
|
|
403
|
+
|
|
404
|
+ int xPix, yPix;
|
|
405
|
+ double axscale;
|
|
406
|
+ double ymin;
|
|
407
|
+ double ymax;
|
|
408
|
+ std::string xlabel;
|
|
409
|
+ std::string ylabel;
|
|
410
|
+
|
|
411
|
+ template<typename Vec_t, typename Mat_t>
|
|
412
|
+
|
|
413
|
+ void geometry(const Vec_t &x, const Vec_t &y, const Mat_t &z) {
|
|
414
|
+
|
|
415
|
+ const unsigned int Nx = x.size();
|
|
416
|
+ const unsigned int Ny = y.size();
|
|
417
|
+ unsigned int i, j, k;
|
|
418
|
+
|
|
419
|
+ // make sure the input is ok and that this contourplot is free
|
|
420
|
+ assert(Nx == z.rows() );
|
|
421
|
+ assert(Ny == z.cols() );
|
|
422
|
+ assert(!has_data);
|
|
423
|
+
|
|
424
|
+ // x and y vectors go into vtkFloatArray
|
|
425
|
+ vtkFloatArray *xcoord = vtkFloatArray::New();
|
|
426
|
+ xcoord->SetNumberOfComponents(1);
|
|
427
|
+ xcoord->SetNumberOfTuples(Nx);
|
|
428
|
+ vtkFloatArray *ycoord = vtkFloatArray::New();
|
|
429
|
+ ycoord->SetNumberOfComponents(1);
|
|
430
|
+ ycoord->SetNumberOfTuples(Ny);
|
|
431
|
+
|
|
432
|
+ // We want the two axis to be equal, not squashed
|
|
433
|
+ // normalize axis ratio
|
|
434
|
+ axscale = 1.;
|
|
435
|
+ ymin = y.minCoeff();
|
|
436
|
+ ymax = y.maxCoeff();
|
|
437
|
+
|
|
438
|
+ if (YScale == LINEAR && XScale == LINEAR)
|
|
439
|
+ axscale = (x.maxCoeff() - x.minCoeff()) /
|
|
440
|
+ (y.maxCoeff() - y.minCoeff()) ;
|
|
441
|
+
|
|
442
|
+ if (YScale == LOG10 && XScale == LINEAR)
|
|
443
|
+ axscale = ( x.maxCoeff() - x.minCoeff() ) /
|
|
444
|
+ (std::log10(y.maxCoeff()) - std::log10(y.minCoeff())) ;
|
|
445
|
+
|
|
446
|
+ if (YScale == LOG10 && XScale == LOG10)
|
|
447
|
+ axscale = ( (std::log10(x.maxCoeff()) - std::log10(x.minCoeff())) /
|
|
448
|
+ (std::log10(y.maxCoeff()) - std::log10(y.minCoeff())) );
|
|
449
|
+
|
|
450
|
+ if (YScale == LINEAR && XScale == LOG10)
|
|
451
|
+ axscale = (std::log10(x.maxCoeff()) - std::log10(x.minCoeff())) /
|
|
452
|
+ ( y.maxCoeff() - y.minCoeff() ) ;
|
|
453
|
+
|
|
454
|
+ if (XScale == LINEAR) {
|
|
455
|
+ for (i=0; i<Nx; i++)
|
|
456
|
+ xcoord->InsertComponent(i, 0, x(i));
|
|
457
|
+ } else {
|
|
458
|
+ for (i=0; i<Nx; i++)
|
|
459
|
+ xcoord->InsertComponent(i, 0, std::log10(x(i)));
|
|
460
|
+ }
|
|
461
|
+
|
|
462
|
+ if (YScale == LINEAR) {
|
|
463
|
+ for (i=0; i<Ny; i++)
|
|
464
|
+ ycoord->InsertComponent(i, 0, axscale*y(i));
|
|
465
|
+ } else {
|
|
466
|
+ for (i=0; i<Ny; i++)
|
|
467
|
+ ycoord->InsertComponent(i, 0, axscale*std::log10(y(i)));
|
|
468
|
+ }
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+ // Create rectilinear grid
|
|
472
|
+ gridfunc->SetDimensions(Nx, Ny, 1);
|
|
473
|
+ gridfunc->SetXCoordinates(xcoord);
|
|
474
|
+ gridfunc->SetYCoordinates(ycoord);
|
|
475
|
+
|
|
476
|
+ // add z-values as scalars to grid
|
|
477
|
+ vtkFloatArray *colors = vtkFloatArray::New();
|
|
478
|
+ colors->SetNumberOfComponents(1);
|
|
479
|
+ colors->SetNumberOfTuples(Nx*Ny);
|
|
480
|
+ k = 0;
|
|
481
|
+ for (j = 0; j < Ny; j++)
|
|
482
|
+ for (i = 0; i < Nx; i++) {
|
|
483
|
+ colors->InsertComponent(k, 0, z(i, j));
|
|
484
|
+ k++;
|
|
485
|
+ }
|
|
486
|
+
|
|
487
|
+ gridfunc->GetPointData()->SetScalars(colors);
|
|
488
|
+
|
|
489
|
+ colors->Delete();
|
|
490
|
+ xcoord->Delete();
|
|
491
|
+ ycoord->Delete();
|
|
492
|
+
|
|
493
|
+ has_data = true;
|
|
494
|
+ }
|
|
495
|
+
|
|
496
|
+ void renderer(bool, bool, int);
|
|
497
|
+ };
|
|
498
|
+
|
|
499
|
+ /** Plot vector-valued function in the plane.
|
|
500
|
+ * Inspired by "quiver" in Matlab
|
|
501
|
+ *
|
|
502
|
+ * \author Dag Lindbo
|
|
503
|
+ */
|
|
504
|
+ class Quiver_VTK
|
|
505
|
+ {
|
|
506
|
+ public:
|
|
507
|
+
|
|
508
|
+ Quiver_VTK(int px = 800, int py = 600);
|
|
509
|
+ ~Quiver_VTK();
|
|
510
|
+
|
|
511
|
+ /** Create vector arrow plot (quiver).
|
|
512
|
+ * Pointwise vecotrs in matrices u and v, at grid
|
|
513
|
+ * points given by vectors x and y. Color by magnitude.
|
|
514
|
+ * Defaults to no scaling of arrow lengths.
|
|
515
|
+ */
|
|
516
|
+ template<typename Vec_t, typename Mat_t>
|
|
517
|
+ void quiver(const Vec_t &x, const Vec_t &y, const Mat_t &u,
|
|
518
|
+ const Mat_t &v)
|
|
519
|
+ {
|
|
520
|
+ geometry(x, y, u, v);
|
|
521
|
+ renderer(1.0);
|
|
522
|
+ render_interactive(rend, xPix, yPix);
|
|
523
|
+ }
|
|
524
|
+
|
|
525
|
+ /** Create vector arrow plot (quiver).
|
|
526
|
+ * Pointwise vectors in matrices u and v, at grid
|
|
527
|
+ * points given by vectors x and y. Color by magnitude.
|
|
528
|
+ *
|
|
529
|
+ * Scales arrows by a factor s.
|
|
530
|
+ */
|
|
531
|
+ template<typename Vec_t, typename Mat_t>
|
|
532
|
+ void quiver(const Vec_t &x, const Vec_t &y, const Mat_t &u,
|
|
533
|
+ const Mat_t &v, double s)
|
|
534
|
+ {
|
|
535
|
+ geometry(x, y, u, v);
|
|
536
|
+ renderer(s);
|
|
537
|
+ render_interactive(rend, xPix, yPix);
|
|
538
|
+ }
|
|
539
|
+
|
|
540
|
+ /** Create vector arrow plot (quiver) and render to file.
|
|
541
|
+ * Pointwise vectors in matrices u and v, at grid
|
|
542
|
+ * points given by vectors x and y. Color by magnitude
|
|
543
|
+ *
|
|
544
|
+ * Scales arrows by a factor s.
|
|
545
|
+ */
|
|
546
|
+ template<typename Vec_t, typename Mat_t>
|
|
547
|
+ void quiver_to_file(const Vec_t &x, const Vec_t &y, const Mat_t &u,
|
|
548
|
+ const Mat_t &v, double s, std::string filename)
|
|
549
|
+ {
|
|
550
|
+ geometry(x, y, u, v);
|
|
551
|
+ renderer(s);
|
|
552
|
+ render_to_png(rend, xPix, yPix, filename);
|
|
553
|
+ }
|
|
554
|
+
|
|
555
|
+ void purge();
|
|
556
|
+
|
|
557
|
+ private:
|
|
558
|
+ vtkRectilinearGrid *gridfunc;
|
|
559
|
+ vtkRenderer *rend;
|
|
560
|
+
|
|
561
|
+ bool has_data;
|
|
562
|
+
|
|
563
|
+ int xPix, yPix;
|
|
564
|
+
|
|
565
|
+ template<typename Vec_t, typename Mat_t>
|
|
566
|
+ void geometry(const Vec_t& x, const Vec_t& y, const Mat_t& u,
|
|
567
|
+ const Mat_t& v)
|
|
568
|
+ {
|
|
569
|
+ const unsigned int Nx = x.size(); //vec_dim(x);
|
|
570
|
+ const unsigned int Ny = y.size(); //vec_dim(y);
|
|
571
|
+ unsigned int i, j, k;
|
|
572
|
+
|
|
573
|
+ // make sure the input is ok and that this contourplot is free
|
|
574
|
+ assert(Nx == u.rows());
|
|
575
|
+ assert(Ny == u.cols());
|
|
576
|
+ assert(Nx == v.rows());
|
|
577
|
+ assert(Ny == v.cols());
|
|
578
|
+ assert(!has_data);
|
|
579
|
+
|
|
580
|
+ // x and y vectors go into vtkFloatArray
|
|
581
|
+ vtkFloatArray *xcoord = vtkFloatArray::New();
|
|
582
|
+ xcoord->SetNumberOfComponents(1);
|
|
583
|
+ xcoord->SetNumberOfTuples(Nx);
|
|
584
|
+ vtkFloatArray *ycoord = vtkFloatArray::New();
|
|
585
|
+ ycoord->SetNumberOfComponents(1);
|
|
586
|
+ ycoord->SetNumberOfTuples(Ny);
|
|
587
|
+
|
|
588
|
+ for (i=0; i<Nx; i++)
|
|
589
|
+ xcoord->InsertComponent(i, 0, x(i));
|
|
590
|
+ for (i=0; i<Ny; i++)
|
|
591
|
+ ycoord->InsertComponent(i, 0, y(i));
|
|
592
|
+
|
|
593
|
+ // Create rectilinear grid
|
|
594
|
+ gridfunc->SetDimensions(Nx, Ny, 1);
|
|
595
|
+ gridfunc->SetXCoordinates(xcoord);
|
|
596
|
+ gridfunc->SetYCoordinates(ycoord);
|
|
597
|
+
|
|
598
|
+ // add magnitude of (u,v) as scalars to grid
|
|
599
|
+ vtkFloatArray *colors = vtkFloatArray::New();
|
|
600
|
+ colors->SetNumberOfComponents(1);
|
|
601
|
+ colors->SetNumberOfTuples(Nx*Ny);
|
|
602
|
+
|
|
603
|
+ // add vector (u,v) to grid
|
|
604
|
+ vtkFloatArray *vectors = vtkFloatArray::New();
|
|
605
|
+ vectors->SetNumberOfComponents(3);
|
|
606
|
+ vectors->SetNumberOfTuples(Nx*Ny);
|
|
607
|
+
|
|
608
|
+ k = 0;
|
|
609
|
+ for (j = 0; j < Ny; j++)
|
|
610
|
+ for (i = 0; i < Nx; i++)
|
|
611
|
+ {
|
|
612
|
+ colors->InsertTuple1(k,sqrt(u(i,j)*u(i,j)+v(i,j)*v(i,j)));
|
|
613
|
+ vectors->InsertTuple3(k, u(i, j), v(i, j), 0.0);
|
|
614
|
+ k++;
|
|
615
|
+ }
|
|
616
|
+
|
|
617
|
+ gridfunc->GetPointData()->SetScalars(colors);
|
|
618
|
+ gridfunc->GetPointData()->SetVectors(vectors);
|
|
619
|
+
|
|
620
|
+ vectors->Delete();
|
|
621
|
+ colors->Delete();
|
|
622
|
+ xcoord->Delete();
|
|
623
|
+ ycoord->Delete();
|
|
624
|
+
|
|
625
|
+ has_data = true;
|
|
626
|
+ }
|
|
627
|
+
|
|
628
|
+ void renderer(double);
|
|
629
|
+
|
|
630
|
+ };
|
|
631
|
+
|
|
632
|
+}
|
|
633
|
+
|
|
634
|
+#endif
|