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