1 // 3-d plot demo.
2 //
3 // Copyright (C) 2008 Werner Smekal
4 // Copyright (C) 2004 Alan W. Irwin
5 // Copyright (C) 2004 Rafael Laboissiere
6 //
7 // This file is part of PLplot.
8 //
9 // PLplot is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU Library General Public License as published
11 // by the Free Software Foundation; either version 2 of the License, or
12 // (at your option) any later version.
13 //
14 // PLplot is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU Library General Public License for more details.
18 //
19 // You should have received a copy of the GNU Library General Public License
20 // along with PLplot; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23
24 import plplot;
25 import std.string;
26 import std.math;
27 import std.c.stdlib;
28
29 //--------------------------------------------------------------------------
30 // cmap1_init1
31 //
32 // Initializes color map 1 in HLS space.
33 // Basic grayscale variation from half-dark (which makes more interesting
34 // looking plot compared to dark) to light.
35 // An interesting variation on this:
36 // s[1] = 1.0
37 //--------------------------------------------------------------------------
cmap1_init(bool gray)38 void cmap1_init( bool gray )
39 {
40 PLFLT[2] i, h, l, s;
41
42 i[] = [ 0.0, 1.0 ]; // boundaries
43
44 if ( gray )
45 {
46 h[] = [ 0.0, 0.0 ]; // hue -- low: red (arbitrary if s=0), high: red (arbitrary if s=0)
47 l[] = [ 0.5, 1.0]; // lightness -- low: half-dark, high: light
48 s[] = [ 0.0, 0.0 ]; // minimum saturation
49 }
50 else
51 {
52 h[] = [ 240.0, 0.0 ]; // blue -> green -> yellow -> red
53 l[] = [ 0.6, 0.6 ];
54 s[] = [ 0.8, 0.8 ];
55 }
56
57 plscmap1n( 256 );
58 c_plscmap1l( 0, 2, cast(PLFLT*) i, cast(PLFLT*) h, cast(PLFLT*) l,
59 cast(PLFLT*) s, null );
60 }
61
62
63 //--------------------------------------------------------------------------
64 // main
65 //
66 // Does a series of 3-d plots for a given data set, with different
67 // viewing options in each plot.
68 //--------------------------------------------------------------------------
main(char[][]args)69 int main( char[][] args )
70 {
71 const nlevel = 10;
72 const XPTS = 35; // Data points in x
73 const YPTS = 45; // Data points in y
74
75 PLFLT xx, yy, r;
76 bool rosen = false;
77
78 const PLFLT dx = 2. / cast(PLFLT) ( XPTS - 1 );
79 const PLFLT dy = 2. / cast(PLFLT) ( YPTS - 1 );
80
81 const indexxmin = 0;
82 const indexxmax = XPTS;
83 // parameters of ellipse (in x, y index coordinates) that limits the data.
84 // x0, y0 correspond to the exact floating point centre of the index
85 // range.
86 const PLFLT x0 = 0.5 * cast(PLFLT) ( XPTS - 1 );
87 const PLFLT a = 0.9 * x0;
88 const PLFLT y0 = 0.5 * cast(PLFLT) ( YPTS - 1 );
89 const PLFLT b = 0.7 * y0;
90 PLFLT square_root;
91
92 PLFLT[] alt = [ 60.0, 40.0 ];
93 PLFLT[] az = [ 30.0, -30.0 ];
94
95 string title[] = [ "#frPLplot Example 8 - Alt=60, Az=30",
96 "#frPLplot Example 8 - Alt=40, Az=-30" ];
97
98 // Parse and process command line arguments
99 plparseopts( args, PL_PARSE_FULL );
100
101 // Initialize plplot
102 plinit();
103
104 // Allocate data structures
105 PLFLT[XPTS] x;
106 PLFLT[YPTS] y;
107 PLINT[XPTS] indexymin;
108 PLINT[XPTS] indexymax;
109
110 PLFLT[][] z = new PLFLT[][XPTS];
111 PLFLT[][] zlimited = new PLFLT[][XPTS];
112 for ( int i = 0; i < XPTS; i++ )
113 {
114 z[i] = new PLFLT[YPTS];
115 zlimited[i] = new PLFLT[YPTS];
116 }
117
118 for ( int i = 0; i < XPTS; i++ )
119 {
120 x[i] = -1. + cast(PLFLT) i * dx;
121 if ( rosen )
122 x[i] *= 1.5;
123 }
124
125 for ( int i = 0; i < YPTS; i++ )
126 {
127 y[i] = -1. + cast(PLFLT) i * dy;
128 if ( rosen )
129 y[i] += 0.5;
130 }
131
132 for ( size_t i = 0; i < XPTS; i++ )
133 {
134 xx = x[i];
135 for ( size_t j = 0; j < YPTS; j++ )
136 {
137 yy = y[j];
138 if ( rosen )
139 {
140 z[i][j] = pow( 1. - xx, 2. ) + 100. * pow( yy - pow( xx, 2. ), 2. );
141 // The log argument may be zero for just the right grid.
142 if ( z[i][j] > 0. )
143 z[i][j] = log( z[i][j] );
144 else
145 z[i][j] = -5.; // -MAXFLOAT would mess-up up the scale
146 }
147 else
148 {
149 r = sqrt( xx * xx + yy * yy );
150 z[i][j] = exp( -r * r ) * cos( 2.0 * PI * r );
151 }
152 }
153 }
154
155 for ( size_t i = indexxmin; i < indexxmax; i++ )
156 {
157 square_root = sqrt( 1. - fmin( 1., pow( ( cast(PLFLT) i - x0 ) / a, 2. ) ) );
158 // Add 0.5 to find nearest integer and therefore preserve symmetry
159 // with regard to lower and upper bound of y range.
160 indexymin[i] = cast(PLINT) fmax( 0, cast(PLINT) ( 0.5 + y0 - b * square_root ) );
161 // indexymax calculated with the convention that it is 1
162 // greater than highest valid index.
163 indexymax[i] = cast(PLINT) fmin( YPTS, 1 + cast(PLINT) ( 0.5 + y0 + b * square_root ) );
164
165 for ( size_t j = indexymin[i]; j < indexymax[i]; j++ )
166 zlimited[i][j] = z[i][j];
167 }
168
169 PLFLT zmin, zmax;
170 f2mnmx( z, zmin, zmax );
171
172 PLFLT step = ( zmax - zmin ) / ( nlevel + 1 );
173 PLFLT[nlevel] clevel;
174 for ( size_t i = 0; i < nlevel; i++ )
175 clevel[i] = zmin + step + step * i;
176
177 pllightsource( 1., 1., 1. );
178
179 for ( size_t k = 0; k < 2; k++ )
180 {
181 for ( size_t ifshade = 0; ifshade < 5; ifshade++ )
182 {
183 pladv( 0 );
184 plvpor( 0.0, 1.0, 0.0, 0.9 );
185 plwind( -1.0, 1.0, -0.9, 1.1 );
186 plcol0( 3 );
187 plmtex( "t", 1.0, 0.5, 0.5, title[k] );
188 plcol0( 1 );
189 if ( rosen )
190 plw3d( 1.0, 1.0, 1.0, -1.5, 1.5, -0.5, 1.5, zmin, zmax, alt[k], az[k] );
191 else
192 plw3d( 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, zmin, zmax, alt[k], az[k] );
193
194 plbox3( "bnstu", "x axis", 0.0, 0,
195 "bnstu", "y axis", 0.0, 0,
196 "bcdmnstuv", "z axis", 0.0, 0 );
197 plcol0( 2 );
198
199 switch ( ifshade )
200 {
201 case 0:
202 // diffuse light surface plot
203 cmap1_init( 1 );
204 plsurf3d( x, y, z, 0 );
205 break;
206 case 1:
207 // magnitude colored plot
208 cmap1_init( 0 );
209 plsurf3d( x, y, z, MAG_COLOR );
210 break;
211 case 2:
212 // magnitude colored plot with faceted squares
213 cmap1_init( 0 );
214 plsurf3d( x, y, z, MAG_COLOR | FACETED );
215 break;
216 case 3:
217 // magnitude colored plot with contours
218 cmap1_init( 0 );
219 plsurf3d( x, y, z, MAG_COLOR | SURF_CONT | BASE_CONT, clevel );
220 break;
221 default:
222 // magnitude colored plot with contours and index limits.
223 cmap1_init( 0 );
224 plsurf3dl( x, y, zlimited, MAG_COLOR | SURF_CONT | BASE_CONT, clevel, indexxmin, indexxmax, indexymin, indexymax );
225 break;
226 }
227 }
228 }
229
230 plend();
231 return 0;
232 }
233
234 //--------------------------------------------------------------------------
235 // f2mnmx
236 //
237 // Returns min & max of input 2d array.
238 //--------------------------------------------------------------------------
f2mnmx(PLFLT[][]f,out PLFLT fmn,out PLFLT fmx)239 void f2mnmx( PLFLT[][] f, out PLFLT fmn, out PLFLT fmx )
240 {
241 fmx = f[0][0];
242 fmn = fmx;
243
244 for ( int i = 0; i < f.length; i++ )
245 {
246 for ( int j = 0; j < f[i].length; j++ )
247 {
248 fmx = fmax( fmx, f[i][j] );
249 fmn = fmin( fmn, f[i][j] );
250 }
251 }
252 }
253