1-- Demo of multiple stream/window capability (requires Tk or Tcl-DP).
2
3--      Maurice LeBrun
4--      IFS, University of Texas at Austin
5
6-- Copyright (C) 2008 Jerry Bauck
7
8-- This file is part of PLplot.
9
10-- PLplot is free software; you can redistribute it and/or modify
11-- it under the terms of the GNU Library General Public License as published
12-- by the Free Software Foundation; either version 2 of the License, or
13-- (at your option) any later version.
14
15-- PLplot is distributed in the hope that it will be useful,
16-- but WITHOUT ANY WARRANTY; without even the implied warranty of
17-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18-- GNU Library General Public License for more details.
19
20-- You should have received a copy of the GNU Library General Public License
21-- along with PLplot; if not, write to the Free Software
22-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
24with
25    System,
26    Ada.Text_IO,
27    Ada.Strings,
28    Ada.Strings.Fixed,
29    Ada.Strings.Unbounded,
30    Ada.Numerics,
31    Ada.Numerics.Long_Elementary_Functions,
32    PLplot_Auxiliary,
33    PLplot_Standard;
34use
35    Ada.Text_IO,
36    Ada.Numerics,
37    Ada.Strings,
38    Ada.Strings.Fixed,
39    Ada.Strings.Unbounded,
40    Ada.Numerics.Long_Elementary_Functions,
41    PLplot_Auxiliary,
42    PLplot_Standard;
43
44------------------------------------------------------------------------------
45-- Plots several simple functions from other example programs.
46--
47-- This version sends the output of the first 4 plots (one page) to two
48-- independent streams.
49------------------------------------------------------------------------------
50
51procedure xstandard14a is
52    -- Select either TK or DP driver and use a small window
53    -- Using DP results in a crash at the end due to some odd cleanup problems
54    -- The geometry strings MUST be in writable memory
55    geometry_master : String := "500x410+100+200";
56    geometry_slave  : String := "500x410+650+200";
57    driver : Unbounded_String;
58    digmax : Integer;
59    xscale, yscale, xoff, yoff : Long_Float;
60    xs, ys : Real_Vector(0 .. 5);
61    space0 : Integer_Array_1D(1 .. 1) := (Others => 0);
62    mark0  : Integer_Array_1D(1 .. 1) := (Others => 0);
63    space1 : Integer_Array_1D(1 .. 1) := (Others => 1500);
64    mark1  : Integer_Array_1D(1 .. 1) := (Others => 1500);
65    fam : Boolean;
66    num, bmax : Integer;
67    xp0, yp0 : Long_Float;
68    xleng0, yleng0, xoff0, yoff0 : Integer;
69    valid_geometry : Boolean;
70
71    procedure plot1 is
72        xmin, xmax, ymin, ymax : Long_Float;
73        x, y : Real_Vector(0 .. 59);
74    begin
75        for i in x'range loop
76            x(i) := xoff + xscale * Long_Float(i + 1) / Long_Float(x'Length);
77            y(i) := yoff + yscale * x(i) * x(i);
78        end loop;
79
80        xmin := x(x'First);
81        xmax := x(x'Last);
82        ymin := y(y'First);
83        ymax := y(y'Last);
84
85        for i in xs'range loop
86            xs(i) := x(i * 10 + 3);
87            ys(i) := y(i * 10 + 3);
88        end loop;
89
90        -- Set up the viewport and window using PLENV. The range in X is
91        -- 0.0 to 6.0, and the range in Y is 0.0 to 30.0. The axes are
92        -- scaled separately (just := 0), and we just draw a labelled
93        -- box (axis := 0).
94        Set_Pen_Color(Red);
95        Set_Environment(xmin, xmax, ymin, ymax, Not_Justified, Linear_Box_Plus);
96        Set_Pen_Color(Wheat);
97        Write_Labels("(x)", "(y)", "#frPLplot Example 1 - y=x#u2");
98
99        -- Plot the data points
100        Set_Pen_Color(Blue);
101        Draw_Points(xs, ys, 9);
102
103        -- Draw the line through the data
104        Set_Pen_Color(Aquamarine);
105        Draw_Curve(x, y);
106        Flush_Output_Stream;
107    end plot1;
108
109    -- ================================================================
110
111
112    procedure plot2 is
113        x, y : Real_Vector(0 .. 99);
114    begin
115        -- Set up the viewport and window using PLENV. The range in X is -2.0 to
116        -- 10.0, and the range in Y is -0.4 to 2.0. The axes are scaled separately
117        -- (just = 0), and we draw a box with axes (axis = 1).
118        Set_Pen_Color(Red);
119        Set_Environment(-2.0, 10.0, -0.4, 1.2, Not_Justified, Linear_Zero_Axes);
120        Set_Pen_Color(Yellow);
121        Write_Labels("(x)", "sin(x)/x", "#frPLplot Example 1 - Sinc Function");
122
123        -- Fill up the arrays
124        for i in x'range loop
125            x(i) := (Long_Float(i) - 19.0) / 6.0;
126            y(i) := 1.0;
127            if x(i) /= 0.0 then
128                y(i) := sin(x(i)) / x(i);
129            end if;
130        end loop;
131
132        -- Draw the line
133        Set_Pen_Color(Green);
134        Draw_Curve(x, y);
135        Flush_Output_Stream;
136    end plot2;
137
138    -- ================================================================
139
140
141    procedure plot3 is
142        x, y : Real_Vector(0 .. 100);
143    begin
144        -- For the final graph we wish to override the default tick intervals, and
145        -- so do not use PLENV
146
147        Advance_To_Subpage(Next_Subpage);
148
149        -- Use standard viewport, and define X range from 0 to 360 degrees, Y range
150        -- from -1.2 to 1.2.
151        Set_Viewport_Standard;
152        Set_Viewport_World(0.0, 360.0, -1.2, 1.2);
153
154        -- Draw a box with ticks spaced 60 degrees apart in X, and 0.2 in Y.
155        Set_Pen_Color(Red);
156        Box_Around_Viewport("bcnst", 60.0, 2, "bcnstv", 0.2, 2);
157
158        -- Superimpose a dashed line grid, with 1.5 mm marks and spaces.
159        Set_Line_Style(mark1, space1);
160        Set_Pen_Color(Yellow);
161        Box_Around_Viewport("g", 30.0, 0, "g", 0.2, 0);
162        Set_Line_Style(Default_Continuous_Line);
163
164        Set_Pen_Color(Green);
165        Write_Labels("Angle (degrees)", "sine", "#frPLplot Example 1 - Sine function");
166
167        for i in x'range loop
168            x(i) := 3.6 * Long_Float(i);
169            y(i) := sin(x(i) * pi / 180.0);
170        end loop;
171
172        Set_Pen_Color(Aquamarine);
173        Draw_Curve(x, y);
174        Flush_Output_Stream;
175        end plot3;
176
177    -- ================================================================
178
179
180    procedure plot4 is
181        dtr, theta, dx, dy, r : Long_Float;
182        x, y, x0, y0 : Real_Vector(0 .. 360);
183    begin
184        dtr := pi / 180.0;
185        for i in x0'range loop
186            x0(i) := cos(dtr * Long_Float(i));
187            y0(i) := sin(dtr * Long_Float(i));
188        end loop;
189
190        -- Set up viewport and window, but do not draw box
191        Set_Environment(-1.3, 1.3, -1.3, 1.3, Justified, No_Box);
192        for i in 1 .. 10 loop
193            for j in x'range loop
194                x(j) := 0.1 * Long_Float(i) * x0(j);
195                y(j) := 0.1 * Long_Float(i) * y0(j);
196            end loop;
197
198            -- Draw circles for polar grid
199            Draw_Curve(x, y);
200        end loop;
201
202        Set_Pen_Color(Yellow);
203        for i in 0 .. 11 loop
204            theta := 30.0 * Long_Float(i);
205            dx := cos(dtr * theta);
206            dy := sin(dtr * theta);
207
208            -- Draw radial spokes for polar grid
209            Draw_Line(0.0, 0.0, dx, dy);
210
211            -- Write labels for angle
212            -- Slightly off zero to avoid floating point logic flips at 90 and 270 deg.
213            if dx >= -0.00001 then
214                Write_Text_World(dx, dy, dx, dy, -0.15, Trim(Integer'image(Integer(theta)), Left));
215            else
216                Write_Text_World(dx, dy, -dx, -dy, 1.15, Trim(Integer'image(Integer(theta)), Left));
217            end if;
218        end loop;
219
220        -- Draw the graph
221        for i in x'range loop
222            r := sin(dtr * Long_Float(5 * i));
223            x(i) := x0(i) * r;
224            y(i) := y0(i) * r;
225        end loop;
226        Set_Pen_Color(Green);
227        Draw_Curve(x, y);
228
229        Set_Pen_Color(Aquamarine);
230        Write_Text_Viewport("t", 2.0, 0.5, 0.5, "#frPLplot Example 3 - r(#gh)=sin 5#gh");
231        Flush_Output_Stream;
232    end plot4;
233
234    -- ================================================================
235
236
237    -- Demonstration of contour plotting
238    procedure plot5 is
239        XPTS : constant Integer := 35;
240        YPTS : constant Integer := 46;
241        -- Transformation function
242        XSPA : Long_Float := 2.0 / Long_Float(XPTS - 1);
243        YSPA : Long_Float := 2.0 / Long_Float(YPTS - 1);
244        tr : Real_Vector(0 .. 5) := (XSPA, 0.0, -1.0, 0.0, YSPA, -1.0);
245        xx, yy : Long_Float;
246        mark  : Integer_Array_1D(1 .. 1) := (Others => 1500);
247        space : Integer_Array_1D(1 .. 1) := (Others => 1500);
248        z, w : Real_Matrix(0 .. XPTS -1, 0 .. YPTS - 1);
249        clevel : Real_Vector(0 .. 10) :=
250            (-1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0);
251
252        procedure mypltr -- This spec is necessary to accommodate pragma Convention(C...).
253           (x, y : Long_Float;
254            tx, ty : out Long_Float;
255            pltr_data : PL_Pointer);
256        pragma Convention(Convention => C, Entity => mypltr);
257
258        procedure mypltr
259           (x, y : Long_Float;
260            tx, ty : out Long_Float;
261            pltr_data : PL_Pointer)
262        is
263        begin
264            tx := tr(0) * x + tr(1) * y + tr(2);
265            ty := tr(3) * x + tr(4) * y + tr(5);
266        end mypltr;
267
268    begin
269        for i in z'range(1) loop
270            xx := Long_Float(i - (XPTS / 2)) / Long_Float(XPTS / 2);
271            for j in z'range(2) loop
272                yy := Long_Float(j - (YPTS / 2)) / Long_Float(YPTS / 2) - 1.0;
273                z(i, j) := xx * xx - yy * yy;
274                w(i, j) := 2.0 * xx * yy;
275            end loop;
276        end loop;
277
278        Set_Environment(-1.0, 1.0, -1.0, 1.0, Not_Justified, Linear_Box_Plus);
279        Set_Pen_Color(Yellow);
280        Contour_Plot(z, 1, XPTS, 1, YPTS, clevel, mypltr'Unrestricted_Access, System.Null_Address);
281        Set_Line_Style(mark, space);
282        Set_Pen_Color(Green);
283        Contour_Plot(w, 1, XPTS, 1, YPTS, clevel, mypltr'Unrestricted_Access, System.Null_Address);
284        Set_Pen_Color(Red);
285        Write_Labels("X Coordinate", "Y Coordinate", "Streamlines of flow");
286        Flush_Output_Stream;
287    end plot5;
288
289
290begin
291    -- plplot initialization
292    -- Parse and process command line arguments
293    Parse_Command_Line_Arguments(Parse_Full);
294
295    driver := To_Unbounded_String(Get_Device_Name);
296    Get_File_Family_Parameters(fam, num, bmax);
297
298    Put_Line("Demo of multiple output streams via the " & Get_Device_Name & " driver.");
299    Put_Line("Running with the second stream as slave to the first.");
300    New_Line;
301
302    -- If valid geometry specified on command line, use it for both streams.
303    Get_Page_Parameters(xp0, yp0, xleng0, yleng0, xoff0, yoff0);
304    valid_geometry := (xleng0 > 0 and yleng0 > 0);
305
306    -- Set up first stream
307    if valid_geometry then
308      Set_Page_Parameters(xp0, yp0, xleng0, yleng0, xoff0, yoff0);
309    else
310      Set_Command_Line_Option("geometry", geometry_master);
311    end if;
312
313    Set_Device_Name(To_String(driver));
314    Set_Number_Of_Subpages(2, 2);
315    Initialize_PLplot;
316
317    -- Start next stream
318    Set_Stream_Number(1);
319
320    if valid_geometry then
321      Set_Page_Parameters(xp0, yp0, xleng0, yleng0, xoff0, yoff0);
322    else
323      Set_Command_Line_Option("geometry", geometry_slave);
324    end if;
325
326    -- Turn off pause to make this a slave (must follow master)
327    Set_Pause(False);
328    Set_Device_Name(To_String(driver));
329    Set_File_Family_Parameters(fam, num, bmax);
330    Set_Command_Line_Option("fflen","2");
331    Initialize_PLplot;
332
333    -- Set up the data & plot
334    -- Original case
335    Set_Stream_Number(0);
336
337    xscale := 6.0;
338    yscale := 1.0;
339    xoff := 0.0;
340    yoff := 0.0;
341    plot1;
342
343    -- Set up the data & plot
344    xscale := 1.0;
345    yscale := 1.0e+6;
346    plot1;
347
348    -- Set up the data & plot
349    xscale := 1.0;
350    yscale := 1.0e-6;
351    digmax := 2;
352    Set_Floating_Point_Display_Y(digmax, 0);
353    plot1;
354
355    -- Set up the data & plot
356    xscale := 1.0;
357    yscale := 0.0014;
358    yoff := 0.0185;
359    digmax := 5;
360    Set_Floating_Point_Display_Y(digmax, 0);
361    plot1;
362
363    -- To slave
364    -- The Eject_Current_Page ensures the eop indicator gets lit.
365    Set_Stream_Number(1);
366    plot4;
367    Eject_Current_Page;
368
369    -- Back to master
370    Set_Stream_Number(0);
371    plot2;
372    plot3;
373
374    -- To slave
375    Set_Stream_Number(1);
376    plot5;
377    Eject_Current_Page;
378
379    -- Back to master to wait for user to advance
380    Set_Stream_Number(0);
381    Eject_Current_Page;
382
383    -- Call End_PLplot to finish off.
384    End_PLplot;
385end xstandard14a;
386