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