1! Demonstrates plotting text in 3D (plmtex3, plptex3) 2! 3! Copyright (C) 2007-2016 Alan W. Irwin 4! 5! This file is part of PLplot. 6! 7! PLplot is free software; you can redistribute it and/or modify 8! it under the terms of the GNU Library General Public License as 9! published by the Free Software Foundation; either version 2 of the 10! License, or (at your option) any later version. 11! 12! PLplot is distributed in the hope that it will be useful, 13! but WITHOUT ANY WARRANTY; without even the implied warranty of 14! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15! GNU Library General Public License for more details. 16! 17! You should have received a copy of the GNU Library General Public 18! License along with PLplot; if not, write to the Free Software 19! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20! 21! N.B. the pl_test_flt parameter used in this code is only 22! provided by the plplot module to allow convenient developer 23! testing of either kind(1.0) or kind(1.0d0) floating-point 24! precision regardless of the floating-point precision of the 25! PLplot C libraries. We do not guarantee the value of this test 26! parameter so it should not be used by users, and instead user 27! code should replace the pl_test_flt parameter by whatever 28! kind(1.0) or kind(1.0d0) precision is most convenient for them. 29! For further details on floating-point precision issues please 30! consult README_precision in this directory. 31! 32 33program x28f 34 use plplot, double_PI => PL_PI 35 36 implicit none 37 38 real(kind=pl_test_flt), parameter :: PI = double_PI 39 integer, parameter :: XPTS = 2 40 integer, parameter :: YPTS = 2 41 integer, parameter :: NREVOLUTION = 16 42 integer, parameter :: NROTATION = 8 43 integer, parameter :: NSHEAR = 8 44 45 real(PLFLT), dimension(:), allocatable :: x, y 46 real(PLFLT), dimension(:,:), allocatable :: z 47 48 real(PLFLT), parameter :: xmin=0., xmax=1.0, & 49 xmid = 0.5*(xmax + xmin), xrange = xmax - xmin, & 50 ymin=0., ymax=1.0, ymid = 0.5*(ymax + ymin), yrange = ymax - ymin, & 51 zmin=0., zmax=1.0, zmid = 0.5*(zmax + zmin), zrange = zmax - zmin 52 real(PLFLT), parameter :: & 53 ysmin = ymin + 0.1 * yrange, & 54 ysmax = ymax - 0.1 * yrange, & 55 ysrange = ysmax - ysmin, & 56 dysrot = ysrange / ( NROTATION - 1 ), & 57 dysshear = ysrange / ( NSHEAR - 1 ), & 58 zsmin = zmin + 0.1 * zrange, & 59 zsmax = zmax - 0.1 * zrange, & 60 zsrange = zsmax - zsmin, & 61 dzsrot = zsrange / ( NROTATION - 1 ), & 62 dzsshear = zsrange / ( NSHEAR - 1 ) 63 real(PLFLT) :: ys, zs, & 64 x_inclination, y_inclination, z_inclination, & 65 x_shear, y_shear, z_shear, & 66 omega, sin_omega, cos_omega, domega 67 integer :: i, j 68 integer :: plparseopts_rc 69 real(PLFLT) :: radius, pitch, xpos, ypos, zpos 70 71 ! N.B. Need to append PL_END_OF_STRING so spaces get 72 ! properly plotted. 73 character(len=2) :: p1string = "O"//PL_END_OF_STRING 74 character(len=80) :: pstring = & 75 "The future of our civilization depends on software freedom." 76 77 ! Allocate and define the minimal x, y, and z to insure 3D box 78 allocate( x(XPTS) ) 79 allocate( y(YPTS) ) 80 allocate( z(XPTS,YPTS) ) 81 82 do i = 1,XPTS 83 x(i) = xmin + (i-1) * (xmax-xmin)/(XPTS-1) 84 enddo 85 86 do j = 1,YPTS 87 y(j) = ymin + (j-1) * (ymax-ymin)/(YPTS-1) 88 enddo 89 90 z = 0.0 91 92 ! Parse and process command line arguments 93 94 plparseopts_rc = plparseopts(PL_PARSE_FULL) 95 if(plparseopts_rc .ne. 0) stop "plparseopts error" 96 97 call plinit 98 99 ! Page 1: Demonstrate inclination and shear capability pattern. 100 101 call pladv(0) 102 call plvpor(-0.15_pl_test_flt, 1.15_pl_test_flt, -0.05_pl_test_flt, 1.05_pl_test_flt) 103 call plwind(-1.2_pl_test_flt, 1.2_pl_test_flt, -0.8_pl_test_flt, 1.5_pl_test_flt) 104 call plw3d(1.0_pl_test_flt, 1.0_pl_test_flt, 1.0_pl_test_flt, & 105 xmin, xmax, ymin, ymax, zmin, zmax, 20._pl_test_flt, 45._pl_test_flt) 106 107 call plcol0(2) 108 call plbox3("b", "", xmax-xmin, 0, & 109 "b", "", ymax-ymin, 0, & 110 "bcd", "", zmax-zmin, 0) 111 112 ! z = zmin. 113 call plschr(0.0_pl_test_flt, 1.0_pl_test_flt) 114 do i = 1,NREVOLUTION 115 omega = 2.*PI*((i-1)/real(NREVOLUTION,kind=pl_test_flt)) 116 sin_omega = sin(omega) 117 cos_omega = cos(omega) 118 x_inclination = 0.5*xrange*cos_omega 119 y_inclination = 0.5*yrange*sin_omega 120 z_inclination = 0. 121 x_shear = -0.5*xrange*sin_omega 122 y_shear = 0.5*yrange*cos_omega 123 z_shear = 0. 124 call plptex3( & 125 xmid, ymid, zmin, & 126 x_inclination, y_inclination, z_inclination, & 127 x_shear, y_shear, z_shear, & 128 0.0_pl_test_flt, " revolution") 129 enddo 130 131 ! x = xmax. 132 call plschr(0._pl_test_flt, 1.0_pl_test_flt) 133 do i = 1,NREVOLUTION 134 omega = 2.*PI*((i-1)/real(NREVOLUTION,kind=pl_test_flt)) 135 sin_omega = sin(omega) 136 cos_omega = cos(omega) 137 x_inclination = 0. 138 y_inclination = -0.5*yrange*cos_omega 139 z_inclination = 0.5*zrange*sin_omega 140 x_shear = 0. 141 y_shear = 0.5*yrange*sin_omega 142 z_shear = 0.5*zrange*cos_omega 143 call plptex3( & 144 xmax, ymid, zmid, & 145 x_inclination, y_inclination, z_inclination, & 146 x_shear, y_shear, z_shear, & 147 0.0_pl_test_flt, " revolution") 148 enddo 149 150 ! y = ymax. 151 call plschr(0.0_pl_test_flt, 1.0_pl_test_flt) 152 do i = 1,NREVOLUTION 153 omega = 2.*PI*(i-1)/real(NREVOLUTION,kind=pl_test_flt) 154 sin_omega = sin(omega) 155 cos_omega = cos(omega) 156 x_inclination = 0.5*xrange*cos_omega 157 y_inclination = 0. 158 z_inclination = 0.5*zrange*sin_omega 159 x_shear = -0.5*xrange*sin_omega 160 y_shear = 0. 161 z_shear = 0.5*zrange*cos_omega 162 call plptex3( & 163 xmid, ymax, zmid, & 164 x_inclination, y_inclination, z_inclination, & 165 x_shear, y_shear, z_shear, & 166 0.0_pl_test_flt, " revolution") 167 enddo 168 169 ! Draw minimal 3D grid to finish defining the 3D box. 170 call plmesh(x, y, z, DRAW_LINEXY) 171 172 ! Page 2: Demonstrate rotation of string around its axis. 173 call pladv(0) 174 call plvpor(-0.15_pl_test_flt, 1.15_pl_test_flt, -0.05_pl_test_flt, 1.05_pl_test_flt) 175 call plwind(-1.2_pl_test_flt, 1.2_pl_test_flt, -0.8_pl_test_flt, 1.5_pl_test_flt) 176 call plw3d(1.0_pl_test_flt, 1.0_pl_test_flt, 1.0_pl_test_flt, xmin, xmax, ymin, ymax, & 177 zmin, zmax, 20._pl_test_flt, 45._pl_test_flt) 178 179 call plcol0(2) 180 call plbox3("b", "", xmax-xmin, 0, & 181 "b", "", ymax-ymin, 0, & 182 "bcd", "", zmax-zmin, 0) 183 184 ! y = ymax. 185 call plschr(0.0_pl_test_flt, 1.0_pl_test_flt) 186 x_inclination = 1. 187 y_inclination = 0. 188 z_inclination = 0. 189 x_shear = 0. 190 do i = 1,NROTATION 191 omega = 2.*PI*(i-1)/real(NROTATION,kind=pl_test_flt) 192 sin_omega = sin(omega) 193 cos_omega = cos(omega) 194 y_shear = 0.5*yrange*sin_omega 195 z_shear = 0.5*zrange*cos_omega 196 zs = zsmax - dzsrot * real(i-1,kind=pl_test_flt) 197 call plptex3( & 198 xmid, ymax, zs, & 199 x_inclination, y_inclination, z_inclination, & 200 x_shear, y_shear, z_shear, & 201 0.5_pl_test_flt, "rotation for y = y#dmax#u") 202 enddo 203 204 ! x = xmax. 205 call plschr(0.0_pl_test_flt, 1.0_pl_test_flt) 206 x_inclination = 0.0 207 y_inclination = -1.0 208 z_inclination = 0.0 209 y_shear = 0.0 210 do i = 1,NROTATION 211 omega = 2.*PI*((i-1)/real(NROTATION,kind=pl_test_flt)) 212 sin_omega = sin(omega) 213 cos_omega = cos(omega) 214 x_shear = 0.5*xrange*sin_omega 215 z_shear = 0.5*zrange*cos_omega 216 zs = zsmax - dzsrot * real(i-1,kind=pl_test_flt) 217 call plptex3( & 218 xmax, ymid, zs, & 219 x_inclination, y_inclination, z_inclination, & 220 x_shear, y_shear, z_shear, & 221 0.5_pl_test_flt, "rotation for x = x#dmax#u") 222 enddo 223 224 ! z = zmin. 225 call plschr(0.0_pl_test_flt, 1.0_pl_test_flt) 226 x_inclination = 1. 227 y_inclination = 0. 228 z_inclination = 0. 229 x_shear = 0. 230 do i = 1,NROTATION 231 omega = 2.*PI*((i-1)/real(NROTATION,kind=pl_test_flt)) 232 sin_omega = sin(omega) 233 cos_omega = cos(omega) 234 y_shear = 0.5*yrange*cos_omega 235 z_shear = 0.5*zrange*sin_omega 236 ys = ysmax - dysrot * real(i-1,kind=pl_test_flt) 237 call plptex3( & 238 xmid, ys, zmin, & 239 x_inclination, y_inclination, z_inclination, & 240 x_shear, y_shear, z_shear, & 241 0.5_pl_test_flt, "rotation for z = z#dmin#u") 242 enddo 243 ! Draw minimal 3D grid to finish defining the 3D box. 244 call plmesh(x, y, z, DRAW_LINEXY) 245 246 ! Page 3: Demonstrate shear of string along its axis. 247 ! Work around xcairo and pngcairo (but not pscairo) problems for 248 ! shear vector too close to axis of string. (N.B. no workaround 249 ! would be domega = 0.) 250 domega = 0.05 251 call pladv(0) 252 call plvpor(-0.15_pl_test_flt, 1.15_pl_test_flt, -0.05_pl_test_flt, 1.05_pl_test_flt) 253 call plwind(-1.2_pl_test_flt, 1.2_pl_test_flt, -0.8_pl_test_flt, 1.5_pl_test_flt) 254 call plw3d(1.0_pl_test_flt, 1.0_pl_test_flt, 1.0_pl_test_flt, xmin, xmax, ymin, ymax, & 255 zmin, zmax, 20._pl_test_flt, 45._pl_test_flt) 256 257 call plcol0(2) 258 call plbox3("b", "", xmax-xmin, 0, & 259 "b", "", ymax-ymin, 0, & 260 "bcd", "", zmax-zmin, 0) 261 262 ! y = ymax. 263 call plschr(0.0_pl_test_flt, 1.0_pl_test_flt) 264 x_inclination = 1. 265 y_inclination = 0. 266 z_inclination = 0. 267 y_shear = 0. 268 do i = 1,NSHEAR 269 omega = domega + 2.*PI*((i-1)/real(NSHEAR,kind=pl_test_flt)) 270 sin_omega = sin(omega) 271 cos_omega = cos(omega) 272 x_shear = 0.5*xrange*sin_omega 273 z_shear = 0.5*zrange*cos_omega 274 zs = zsmax - dzsshear * real(i-1,kind=pl_test_flt) 275 call plptex3( & 276 xmid, ymax, zs, & 277 x_inclination, y_inclination, z_inclination, & 278 x_shear, y_shear, z_shear, & 279 0.5_pl_test_flt, "shear for y = y#dmax#u") 280 enddo 281 282 ! x = xmax. 283 call plschr(0.0_pl_test_flt, 1.0_pl_test_flt) 284 x_inclination = 0. 285 y_inclination = -1. 286 z_inclination = 0. 287 x_shear = 0. 288 do i = 1,NSHEAR 289 omega = domega + 2.*PI*((i-1)/real(NSHEAR,kind=pl_test_flt)) 290 sin_omega = sin(omega) 291 cos_omega = cos(omega) 292 y_shear = -0.5*yrange*sin_omega 293 z_shear = 0.5*zrange*cos_omega 294 zs = zsmax - dzsshear * real(i-1,kind=pl_test_flt) 295 call plptex3( & 296 xmax, ymid, zs, & 297 x_inclination, y_inclination, z_inclination, & 298 x_shear, y_shear, z_shear, & 299 0.5_pl_test_flt, "shear for x = x#dmax#u") 300 enddo 301 302 ! z = zmin. 303 call plschr(0.0_pl_test_flt, 1.0_pl_test_flt) 304 x_inclination = 1. 305 y_inclination = 0. 306 z_inclination = 0. 307 z_shear = 0. 308 do i = 1,NSHEAR 309 omega = domega + 2.*PI*((i-1)/real(NSHEAR,kind=pl_test_flt)) 310 sin_omega = sin(omega) 311 cos_omega = cos(omega) 312 y_shear = 0.5*yrange*cos_omega 313 x_shear = 0.5*xrange*sin_omega 314 ys = ysmax - dysshear * real(i-1,kind=pl_test_flt) 315 call plptex3( & 316 xmid, ys, zmin, & 317 x_inclination, y_inclination, z_inclination, & 318 x_shear, y_shear, z_shear, & 319 0.5_pl_test_flt, "shear for z = z#dmin#u") 320 enddo 321 ! Draw minimal 3D grid to finish defining the 3D box. 322 call plmesh(x, y, z, DRAW_LINEXY) 323 324 ! Page 4: Demonstrate drawing a string on a 3D path. 325 call pladv(0) 326 call plvpor(-0.15_pl_test_flt, 1.15_pl_test_flt, -0.05_pl_test_flt, 1.05_pl_test_flt) 327 call plwind(-1.2_pl_test_flt, 1.2_pl_test_flt, -0.8_pl_test_flt, 1.5_pl_test_flt) 328 call plw3d(1.0_pl_test_flt, 1.0_pl_test_flt, 1.0_pl_test_flt, & 329 xmin, xmax, ymin, ymax, zmin, zmax, 40._pl_test_flt, -30._pl_test_flt) 330 331 call plcol0(2) 332 call plbox3("b", "", xmax-xmin, 0, & 333 "b", "", ymax-ymin, 0, & 334 "bcd", "", zmax-zmin, 0) 335 336 call plschr(0.0_pl_test_flt, 1.2_pl_test_flt) 337 ! domega controls the spacing between the various characters of the 338 ! string and also the maximum value of omega for the given number 339 ! of characters in pstring. 340 domega = 2.*PI/len_trim(pstring) 341 omega = 0. 342 ! 3D function is a helix of the given radius and pitch 343 radius = 0.5 344 pitch = 1./(2.*PI) 345 do i = 1,len_trim(pstring) 346 sin_omega = sin(omega) 347 cos_omega = cos(omega) 348 xpos = xmid + radius*sin_omega 349 ypos = ymid - radius*cos_omega 350 zpos = zmin + pitch*omega 351 ! In general, the inclination is proportional to the derivative of 352 ! the position wrt theta. 353 x_inclination = radius*cos_omega 354 y_inclination = radius*sin_omega 355 z_inclination = pitch 356 ! The shear vector should be perpendicular to the 3D line with Z 357 ! component maximized, but for low pitch a good approximation is 358 ! a constant vector that is parallel to the Z axis. 359 x_shear = 0. 360 y_shear = 0. 361 z_shear = 1. 362 p1string(1:1) = pstring(i:i) 363 call plptex3( & 364 xpos, ypos, zpos, & 365 x_inclination, y_inclination, z_inclination, & 366 x_shear, y_shear, z_shear, & 367 0.5_pl_test_flt, p1string) 368 omega = omega + domega 369 enddo 370 ! Draw minimal 3D grid to finish defining the 3D box. 371 call plmesh(x, y, z, DRAW_LINEXY) 372 373 ! Page 5: Demonstrate plmtex3 axis labelling capability 374 call pladv(0) 375 call plvpor(-0.15_pl_test_flt, 1.15_pl_test_flt, -0.05_pl_test_flt, 1.05_pl_test_flt) 376 call plwind(-1.2_pl_test_flt, 1.2_pl_test_flt, -0.8_pl_test_flt, 1.5_pl_test_flt) 377 call plw3d(1.0_pl_test_flt, 1.0_pl_test_flt, 1.0_pl_test_flt, & 378 xmin, xmax, ymin, ymax, zmin, zmax, 20._pl_test_flt, 45._pl_test_flt) 379 380 call plcol0(2) 381 call plbox3("b", "", xmax-xmin, 0, & 382 "b", "", ymax-ymin, 0, & 383 "bcd", "", zmax-zmin, 0) 384 385 call plschr(0.0_pl_test_flt, 1.0_pl_test_flt) 386 call plmtex3("xp", 3.0_pl_test_flt, 0.5_pl_test_flt, 0.5_pl_test_flt, "Arbitrarily displaced") 387 call plmtex3("xp", 4.5_pl_test_flt, 0.5_pl_test_flt, 0.5_pl_test_flt, "primary X-axis label") 388 call plmtex3("xs", -2.5_pl_test_flt, 0.5_pl_test_flt, 0.5_pl_test_flt, "Arbitrarily displaced") 389 call plmtex3("xs", -1.0_pl_test_flt, 0.5_pl_test_flt, 0.5_pl_test_flt, "secondary X-axis label") 390 call plmtex3("yp", 3.0_pl_test_flt, 0.5_pl_test_flt, 0.5_pl_test_flt, "Arbitrarily displaced") 391 call plmtex3("yp", 4.5_pl_test_flt, 0.5_pl_test_flt, 0.5_pl_test_flt, "primary Y-axis label") 392 call plmtex3("ys", -2.5_pl_test_flt, 0.5_pl_test_flt, 0.5_pl_test_flt, "Arbitrarily displaced") 393 call plmtex3("ys", -1.0_pl_test_flt, 0.5_pl_test_flt, 0.5_pl_test_flt, "secondary Y-axis label") 394 call plmtex3("zp", 4.5_pl_test_flt, 0.5_pl_test_flt, 0.5_pl_test_flt, "Arbitrarily displaced") 395 call plmtex3("zp", 3.0_pl_test_flt, 0.5_pl_test_flt, 0.5_pl_test_flt, "primary Z-axis label") 396 call plmtex3("zs", -2.5_pl_test_flt, 0.5_pl_test_flt, 0.5_pl_test_flt, "Arbitrarily displaced") 397 call plmtex3("zs", -1.0_pl_test_flt, 0.5_pl_test_flt, 0.5_pl_test_flt, "secondary Z-axis label") 398 ! Draw minimal 3D grid to finish defining the 3D box. 399 call plmesh(x, y, z, DRAW_LINEXY) 400 401 ! Clean up. 402 deallocate( x, y, z ) 403 call plend 404 stop 405end program x28f 406