C  $Id: x28f.fm4 7911 2007-09-30 21:00:40Z airwin $
C
C   Demonstrates plotting text in 3D (plmtex3, plptex3)
C
C   Copyright (C) 2007  Alan W. Irwin
C
C   This file is part of PLplot.
C
C   PLplot is free software; you can redistribute it and/or modify
C   it under the terms of the GNU General Library Public License as
C   published by the Free Software Foundation; either version 2 of the
C   License, or (at your option) any later version.
C
C   PLplot is distributed in the hope that it will be useful,
C   but WITHOUT ANY WARRANTY; without even the implied warranty of
C   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
C   GNU Library General Public License for more details.
C
C   You should have received a copy of the GNU Library General Public
C   License along with PLplot; if not, write to the Free Software
C   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
C

      program x28f

      implicit none

      integer XPTS, YPTS, NREVOLUTION, NROTATION, NSHEAR
      parameter(XPTS = 2)
      parameter(YPTS = 2)
      parameter(NREVOLUTION = 16)
      parameter(NROTATION = 8)
      parameter(NSHEAR = 8)
      real*8 x(XPTS), y(YPTS), z(XPTS,YPTS)
      real*8 PI
      parameter (PI = 3.1415926535897932384d0)
      real*8 xmin, xmax, xmid, xrange
      parameter(xmin = 0.d0)
      parameter(xmax = 1.d0)
      parameter(xmid = 0.5d0*(xmax+xmin))
      parameter(xrange = xmax-xmin)
      real*8 ymin, ymax, ymid, yrange
      parameter(ymin = 0.d0)
      parameter(ymax = 1.d0)
      parameter(ymid = 0.5d0*(ymax+ymin))
      parameter(yrange = ymax-ymin)
      real*8 zmin, zmax, zmid, zrange
      parameter(zmin = 0.d0)
      parameter(zmax = 1.d0)
      parameter(zmid = 0.5d0*(zmax+zmin))
      parameter(zrange = zmax-zmin)


      real*8 x_inclination, y_inclination, z_inclination,
     &  x_shear, y_shear, z_shear,
     &  omega, sin_omega, cos_omega, domega
      integer i, j
      real*8 radius, pitch, xpos, ypos, zpos
      integer lnblnk
      integer PL_PARSE_FULL
      parameter(PL_PARSE_FULL = 1)
      integer DRAW_LINEXY
      parameter(DRAW_LINEXY = 3)

      character*80 pstring
      pstring =
     &  "The future of our civilization depends on software freedom."

      do i = 1,XPTS
      	 x(i) = xmin + dble(i-1)*(xmax-xmin)/dble(XPTS-1)
      enddo

      do j = 1,YPTS
      	 y(j) = ymin + dble(j-1)*(ymax-ymin)/dble(YPTS-1)
      enddo
       
      do j = 1,YPTS
        do i = 1,XPTS
          z(i,j) = 0.d0
        enddo
      enddo

C      Parse and process command line arguments

      call plparseopts(PL_PARSE_FULL)

      call plinit()

C      Page 1: Demonstrate inclination and shear capability pattern.

      call pladv(0)
      call plvpor(-0.15d0, 1.15d0, -0.05d0, 1.05d0)
      call plwind(-1.2d0, 1.2d0, -0.8d0, 1.5d0)
      call plw3d(1.0d0, 1.0d0, 1.0d0,
     &  xmin, xmax, ymin, ymax, zmin, zmax,
     &  20.d0, 45.d0)

      call plcol0(2)
      call plbox3("b",   "", xmax-xmin, 0,
     & "b",   "", ymax-ymin, 0,
     & "bcd", "", zmax-zmin, 0)

C      z = zmin.
      call plschr(0.d0, 1.0d0)
      do i = 1,NREVOLUTION
         omega = 2.d0*PI*(dble(i-1)/dble(NREVOLUTION))
      	 sin_omega = sin(omega)
      	 cos_omega = cos(omega)
         x_inclination = 0.5d0*xrange*cos_omega
         y_inclination = 0.5d0*yrange*sin_omega
         z_inclination = 0.d0
         x_shear = -0.5d0*xrange*sin_omega
         y_shear = 0.5d0*yrange*cos_omega
         z_shear = 0.d0
         call plptex3(
     &     xmid, ymid, zmin,
     &     x_inclination, y_inclination, z_inclination,
     &     x_shear, y_shear, z_shear,
     &     0.0d0, "  revolution")
      enddo

C      x = xmax.
      call plschr(0.d0, 1.0d0)
      do i = 1,NREVOLUTION
         omega = 2.d0*PI*(dble(i-1)/dble(NREVOLUTION))
      	 sin_omega = sin(omega)
      	 cos_omega = cos(omega)
         x_inclination = 0.d0
         y_inclination = -0.5d0*yrange*cos_omega
         z_inclination = 0.5d0*zrange*sin_omega
         x_shear = 0.d0
         y_shear = 0.5d0*yrange*sin_omega
         z_shear = 0.5d0*zrange*cos_omega
         call plptex3(
     &     xmax, ymid, zmid,
     &     x_inclination, y_inclination, z_inclination,
     &     x_shear, y_shear, z_shear,
     &     0.0d0, "  revolution")
      enddo

C      y = ymax.
      call plschr(0.d0, 1.0d0)
      do i = 1,NREVOLUTION
         omega = 2.d0*PI*(dble(i-1)/dble(NREVOLUTION))
      	 sin_omega = sin(omega)
      	 cos_omega = cos(omega)
         x_inclination = 0.5d0*xrange*cos_omega
         y_inclination = 0.d0
         z_inclination = 0.5d0*zrange*sin_omega
         x_shear = -0.5d0*xrange*sin_omega
         y_shear = 0.d0
         z_shear = 0.5d0*zrange*cos_omega
         call plptex3(
     &     xmid, ymax, zmid,
     &     x_inclination, y_inclination, z_inclination,
     &     x_shear, y_shear, z_shear,
     &     0.0d0, "  revolution")
      enddo
C      Draw minimal 3D grid to finish defining the 3D box.
      call plmesh(x, y, z, XPTS, YPTS, DRAW_LINEXY, XPTS)

C      Page 2: Demonstrate rotation of string around its axis.
      call pladv(0)
      call plvpor(-0.15d0, 1.15d0, -0.05d0, 1.05d0)
      call plwind(-1.2d0, 1.2d0, -0.8d0, 1.5d0)
      call plw3d(1.0d0, 1.0d0, 1.0d0,
     &  xmin, xmax, ymin, ymax, zmin, zmax,
     &  20.d0, 45.d0)

      call plcol0(2)
      call plbox3("b",   "", xmax-xmin, 0,
     & "b",   "", ymax-ymin, 0,
     & "bcd", "", zmax-zmin, 0)

C      y = ymax.
      call plschr(0.d0, 1.0d0)
      x_inclination = 1.d0
      y_inclination = 0.d0
      z_inclination = 0.d0
      x_shear = 0.d0
      do i = 1,NROTATION
         omega = 2.d0*PI*dble(i-1)/dble(NROTATION)
      	 sin_omega = sin(omega)
      	 cos_omega = cos(omega)
         y_shear = 0.5d0*yrange*sin_omega
         z_shear = 0.5d0*zrange*cos_omega
         call plptex3(
     &     xmid,
     &     ymax,
     &     zmax -(zmax-0.2d0)*(dble(i-1)/dble(NROTATION-1)),
     &     x_inclination, y_inclination, z_inclination,
     &     x_shear, y_shear, z_shear,
     &     0.5d0, "rotation for y = y#dmax#u")
      enddo

C      x = xmax.
      call plschr(0.d0, 1.0d0)
      x_inclination = 0.d0
      y_inclination = -1.d0
      z_inclination = 0.d0
      y_shear = 0.d0
      do i = 1,NROTATION
         omega = 2.d0*PI*dble(i-1)/dble(NROTATION)
      	 sin_omega = sin(omega)
      	 cos_omega = cos(omega)
         x_shear = 0.5d0*xrange*sin_omega
         z_shear = 0.5d0*zrange*cos_omega
         call plptex3(
     &     xmax,
     &     ymid,
     &     zmax -(zmax-0.2d0)*(dble(i-1)/dble(NROTATION-1)),
     &     x_inclination, y_inclination, z_inclination,
     &     x_shear, y_shear, z_shear,
     &     0.5d0, "rotation for x = x#dmax#u")
      enddo

C      z = zmin.
      call plschr(0.d0, 1.0d0)
      x_inclination = 1.d0
      y_inclination = 0.d0
      z_inclination = 0.d0
      x_shear = 0.d0
      do i = 1,NROTATION
         omega = 2.d0*PI*dble(i-1)/dble(NROTATION)
      	 sin_omega = sin(omega)
      	 cos_omega = cos(omega)
         y_shear = 0.5d0*yrange*cos_omega
         z_shear = 0.5d0*zrange*sin_omega
         call plptex3(
     &     xmid,
     &     ymax -(zmax-0.2d0)*(dble(i-1)/dble(NROTATION-1)),
     &     zmin,
     &     x_inclination, y_inclination, z_inclination,
     &     x_shear, y_shear, z_shear,
     &     0.5d0, "rotation for z = z#dmin#u")
      enddo
C      Draw minimal 3D grid to finish defining the 3D box.
      call plmesh(x, y, z, XPTS, YPTS, DRAW_LINEXY, XPTS)

C      Page 3: Demonstrate shear of string along its axis.
C      Work around xcairo and pngcairo (but not pscairo) problems for
C      shear vector too close to axis of string. (N.B. no workaround
C      would be domega = 0.d0.)
      domega = 0.05d0
      call pladv(0)
      call plvpor(-0.15d0, 1.15d0, -0.05d0, 1.05d0)
      call plwind(-1.2d0, 1.2d0, -0.8d0, 1.5d0)
      call plw3d(1.0d0, 1.0d0, 1.0d0,
     &  xmin, xmax, ymin, ymax, zmin, zmax,
     &  20.d0, 45.d0)

      call plcol0(2)
      call plbox3("b",   "", xmax-xmin, 0,
     & "b",   "", ymax-ymin, 0,
     & "bcd", "", zmax-zmin, 0)

C      y = ymax.
      call plschr(0.d0, 1.0d0)
      x_inclination = 1.d0
      y_inclination = 0.d0
      z_inclination = 0.d0
      y_shear = 0.d0
      do i = 1,NSHEAR
         omega = domega + 2.d0*PI*dble(i-1)/dble(NSHEAR)
      	 sin_omega = sin(omega)
      	 cos_omega = cos(omega)
         x_shear = 0.5d0*xrange*sin_omega
         z_shear = 0.5d0*zrange*cos_omega
         call plptex3(
     &     xmid,
     &     ymax,
     &     zmax -(zmax-0.2d0)*(dble(i-1)/dble(NSHEAR-1)),
     &     x_inclination, y_inclination, z_inclination,
     &     x_shear, y_shear, z_shear,
     &     0.5d0, "shear for y = y#dmax#u")
      enddo

C      x = xmax.
      call plschr(0.d0, 1.0d0)
      x_inclination = 0.d0
      y_inclination = -1.d0
      z_inclination = 0.d0
      x_shear = 0.d0
      do i = 1,NSHEAR
         omega = domega + 2.d0*PI*dble(i-1)/dble(NSHEAR)
      	 sin_omega = sin(omega)
      	 cos_omega = cos(omega)
         y_shear = -0.5d0*yrange*sin_omega
         z_shear = 0.5d0*zrange*cos_omega
         call plptex3(
     &     xmax,
     &     ymid,
     &     zmax -(zmax-0.2d0)*(dble(i-1)/dble(NSHEAR-1)),
     &     x_inclination, y_inclination, z_inclination,
     &     x_shear, y_shear, z_shear,
     &     0.5d0, "shear for x = x#dmax#u")
      enddo

C      z = zmin.
      call plschr(0.d0, 1.0d0)
      x_inclination = 1.d0
      y_inclination = 0.d0
      z_inclination = 0.d0
      z_shear = 0.d0
      do i = 1,NSHEAR
         omega = domega + 2.d0*PI*dble(i-1)/dble(NSHEAR)
      	 sin_omega = sin(omega)
      	 cos_omega = cos(omega)
         y_shear = 0.5d0*yrange*cos_omega
         x_shear = 0.5d0*xrange*sin_omega
         call plptex3(
     &     xmid,
     &     ymax -(ymax-0.2d0)*(dble(i-1)/dble(NSHEAR-1)),
     &     zmin,
     &     x_inclination, y_inclination, z_inclination,
     &     x_shear, y_shear, z_shear,
     &     0.5d0, "shear for z = z#dmin#u")
      enddo

C      Draw minimal 3D grid to finish defining the 3D box.
      call plmesh(x, y, z, XPTS, YPTS, DRAW_LINEXY, XPTS)

C      Page 4: Demonstrate drawing a string on a 3D path.
      call pladv(0)
      call plvpor(-0.15d0, 1.15d0, -0.05d0, 1.05d0)
      call plwind(-1.2d0, 1.2d0, -0.8d0, 1.5d0)
      call plw3d(1.0d0, 1.0d0, 1.0d0,
     &  xmin, xmax, ymin, ymax, zmin, zmax,
     &  40.d0, -30.d0)

      call plcol0(2)
      call plbox3("b",   "", xmax-xmin, 0,
     & "b",   "", ymax-ymin, 0,
     & "bcd", "", zmax-zmin, 0)

      call plschr(0.d0, 1.2d0)
C      domega controls the spacing between the various characters of the
C      string and also the maximum value of omega for the given number
C      of characters in pstring.
      domega = 2.d0*PI/lnblnk(pstring)
      omega = 0.d0
C      3D function is a helix of the given radius and pitch
      radius = 0.5d0
      pitch = 1.d0/(2.d0*PI)
      do i = 1,lnblnk(pstring)
      	 sin_omega = sin(omega)
      	 cos_omega = cos(omega)
      	 xpos = xmid + radius*sin_omega
      	 ypos = ymid - radius*cos_omega
      	 zpos = zmin + pitch*omega
C         In general, the inclination is proportional to the derivative of
C         the position wrt theta.
      	 x_inclination = radius*cos_omega
      	 y_inclination = radius*sin_omega
      	 z_inclination = pitch
C         The shear vector should be perpendicular to the 3D line with Z
C 	  component maximized, but for low pitch a good approximation is
C 	  a constant vector that is parallel to the Z axis.
         x_shear = 0.d0
         y_shear = 0.d0
         z_shear = 1.d0
         call plptex3(
     &     xpos, ypos, zpos,
     &     x_inclination, y_inclination, z_inclination,
     &     x_shear, y_shear, z_shear,
     &     0.5d0, pstring(i:i))
      	   omega = omega + domega
      enddo
C      Draw minimal 3D grid to finish defining the 3D box.
      call plmesh(x, y, z, XPTS, YPTS, DRAW_LINEXY, XPTS)

C Page 5: Demonstrate plmtex3 axis labelling capability
      call pladv(0)
      call plvpor(-0.15d0, 1.15d0, -0.05d0, 1.05d0)
      call plwind(-1.2d0, 1.2d0, -0.8d0, 1.5d0)
      call plw3d(1.0d0, 1.0d0, 1.0d0,
     &  xmin, xmax, ymin, ymax, zmin, zmax,
     &  20.d0, 45.d0)

      call plcol0(2)
      call plbox3("b",   "", xmax-xmin, 0,
     & "b",   "", ymax-ymin, 0,
     & "bcd", "", zmax-zmin, 0)

      call plschr(0.d0, 1.0d0)
      call plmtex3("xp", 3.0d0, 0.5d0, 0.5d0, "Arbitrarily displaced")
      call plmtex3("xp", 4.5d0, 0.5d0, 0.5d0, "primary X-axis label")
      call plmtex3("xs", -2.5d0, 0.5d0, 0.5d0, "Arbitrarily displaced")
      call plmtex3("xs", -1.0d0, 0.5d0, 0.5d0, "secondary X-axis label")
      call plmtex3("yp", 3.0d0, 0.5d0, 0.5d0, "Arbitrarily displaced")
      call plmtex3("yp", 4.5d0, 0.5d0, 0.5d0, "primary Y-axis label")
      call plmtex3("ys", -2.5d0, 0.5d0, 0.5d0, "Arbitrarily displaced")
      call plmtex3("ys", -1.0d0, 0.5d0, 0.5d0, "secondary Y-axis label")
      call plmtex3("zp", 4.5d0, 0.5d0, 0.5d0, "Arbitrarily displaced")
      call plmtex3("zp", 3.0d0, 0.5d0, 0.5d0, "primary Z-axis label")
      call plmtex3("zs", -2.5d0, 0.5d0, 0.5d0, "Arbitrarily displaced")
      call plmtex3("zs", -1.0d0, 0.5d0, 0.5d0, "secondary Z-axis label")
C      Draw minimal 3D grid to finish defining the 3D box.
      call plmesh(x, y, z, XPTS, YPTS, DRAW_LINEXY, XPTS)

      call plend()
      stop
      end
