      program megaminx
c
c     Mike Collins -- cinclodes@yahoo.com
c
c     This FORTRAN code simulates on the screen a generalization of 
c     Rubik's Cube to the dodecahedron. This puzzle is known as the
c     Megaminx. It has about 2.83x10^74 distinguishable configurations.
c     It was originally marketed by TOMY in 1982. It can be purchased 
c     at http://www.mefferts.com/index.html.
c
c     The output file megaminx.ps contains the display. After compiling 
c     the code, run it and enter zeros when prompted. The code will 
c     quit after you enter the second zero. This initializes the 
c     display file, which you can now open with your Postscript 
c     displayer. Keep the display open and run the code again. This 
c     time, you can enter a random integer to mix up the code or zero 
c     again if you want to start with the puzzle solved. Then you can 
c     make a series of moves by entering one integer per line. Enter
c     negatives to twist in the opposite directions. You can reopen 
c     the display after each move.  
c
      real vx(20),vy(20),vz(20),fx(12,5),fy(12,5),fz(12,5),
     >   nx(12),ny(12),nz(12),tilex(132,5),tiley(132,5)
      integer iclr(132),jclr(12)
      character*15 cname(12)
      pi=4.0*atan(1.0)
      theta=-18.0
    1 cname(1)=' blue'
      cname(2)=' yellow'
      cname(3)=' orange'
      cname(4)=' green'
      cname(5)=' purple' 
      cname(6)=' red'
      cname(7)=' slate'
      cname(8)=' lavender'
      cname(9)=' pine'
      cname(10)=' brown'
      cname(11)=' white'
      cname(12)=' aqua'
c
      n=0
      do 3 i=1,12
      jclr(i)=i
      do 2 j=1,11
      n=n+1
      iclr(n)=i
    2 continue
    3 continue
c
      call vrtx(vx,vy,vz,pi)
      call faces(vx,vy,vz,fx,fy,fz,nx,ny,nz)
      call fclr(fx,fy,fz,nx,ny,nz,theta,pi,tilex,tiley,1.0)
      call fclr(fx,fy,fz,nx,ny,nz,theta,pi,tilex,tiley,-1.0)
c
c     Mix up the cube.
c
      write(*,*)' '
      write(*,*)'   Randomly mix up the puzzle. Enter an integer seed'
      write(*,*)'   for the random number generator. Enter 0 if you'
      write(*,*)'   dont want to mix up the cube.'
      write(*,*)' '
      read(*,*)iseed
c
      if(iseed.ne.0)then
      do 4 i=1,1000
      xran=1.0+11.999*ran0(iseed)
      n=ifix(xran)
      call opera(iclr,n,1,jclr,cname)
    4 continue
      end if
c
      open(unit=1,status='unknown',file='megaminx.ps')
      call start(jclr,cname)
      call tclr(tilex,tiley,iclr)
      call frame(tilex,tiley)
      write(1,*)' showpage'
      close(1)
c
c     Solve the cube.
c
      write(*,*)' '
      write(*,*)' Enter an operator number one at a time.'
      write(*,*)' Definition of the operators is given in the display.'
      write(*,*)' Use negative numbers for inverse operators.'
      write(*,*)' Enter 99 to reset the cube. Enter 0 to quit.'
      write(*,*)' '
c
    5 read(*,*)i
      if(i.eq.0)go to 6
      k=1
      if(i.lt.0)then
      k=4
      i=-i
      end if
c
      call opera(iclr,i,k,jclr,cname)
      open(unit=1,status='unknown',file='megaminx.ps')
      call start(jclr,cname)
      call tclr(tilex,tiley,iclr)
      call frame(tilex,tiley)
      write(1,*)' showpage'
      close(1)
      if(i.eq.99)go to 1
      go to 5
c
    6 stop
      end
c
      subroutine opera(iclr,i,kin,jclr,cname)
      integer iclr(132),jclr(12)
      character*15 cname(12),ctemp
c
      k=kin
      if(k.lt.0)k=5+kin
c
      do 1 j=1,k
c
      if(i.eq.1)then
      call cycle(iclr,57,59,61,63,65)
      call cycle(iclr,58,60,62,64,66)
      call cycle(iclr,46,35,123,112,24)
      call cycle(iclr,47,36,124,113,25)
      call cycle(iclr,48,37,125,114,26)
      end if
c
      if(i.eq.2)then
      call cycle(iclr,32,24,26,28,30)
      call cycle(iclr,33,25,27,29,31)
      call cycle(iclr,6,48,63,120,81)
      call cycle(iclr,7,49,64,121,82)
      call cycle(iclr,8,50,65,112,83)
      end if
c
      if(i.eq.3)then
      call cycle(iclr,52,54,46,48,50)
      call cycle(iclr,51,53,55,47,49)
      call cycle(iclr,4,17,37,65,32)
      call cycle(iclr,5,18,38,66,33)
      call cycle(iclr,6,19,39,57,24)
      end if
c
      if(i.eq.4)then
      call cycle(iclr,35,37,39,41,43)
      call cycle(iclr,36,38,40,42,44)
      call cycle(iclr,59,46,17,107,127)
      call cycle(iclr,58,55,16,106,126)
      call cycle(iclr,57,54,15,105,125)
      end if
c
      if(i.eq.5)then
      call cycle(iclr,2,4,6,8,10)
      call cycle(iclr,3,5,7,9,11)
      call cycle(iclr,21,52,32,81,70)
      call cycle(iclr,20,51,31,80,69)
      call cycle(iclr,19,50,30,79,68)
      end if
c
      if(i.eq.6)then
      call cycle(iclr,13,15,17,19,21)
      call cycle(iclr,14,16,18,20,22)
      call cycle(iclr,41,54,4,68,109)
      call cycle(iclr,40,53,3,77,108)
      call cycle(iclr,39,52,2,76,107)
      end if
c
      if(i.eq.7)then
      call cycle(iclr,112,114,116,118,120)
      call cycle(iclr,113,115,117,119,121)
      call cycle(iclr,123,94,85,28,63)
      call cycle(iclr,132,93,84,27,62)
      call cycle(iclr,131,92,83,26,61)
      end if
c
      if(i.eq.8)then
      call cycle(iclr,123,125,127,129,131)
      call cycle(iclr,124,126,128,130,132)
      call cycle(iclr,105,96,116,61,35)
      call cycle(iclr,104,95,115,60,44)
      call cycle(iclr,103,94,114,59,43)
      end if
c
      if(i.eq.9)then
      call cycle(iclr,79,81,83,85,87)
      call cycle(iclr,80,82,84,86,88)
      call cycle(iclr,120,92,72,10,30)
      call cycle(iclr,119,91,71,9,29)
      call cycle(iclr,118,90,70,8,28)
      end if
c
      if(i.eq.10)then
      call cycle(iclr,90,92,94,96,98)
      call cycle(iclr,91,93,95,97,99)
      call cycle(iclr,118,131,103,74,87)
      call cycle(iclr,117,130,102,73,86)
      call cycle(iclr,116,129,101,72,85)
      end if
c
      if(i.eq.11)then
      call cycle(iclr,101,103,105,107,109)
      call cycle(iclr,102,104,106,108,110)
      call cycle(iclr,76,98,129,43,15)
      call cycle(iclr,75,97,128,42,14)
      call cycle(iclr,74,96,127,41,13)
      end if
c
      if(i.eq.12)then
      call cycle(iclr,68,70,72,74,76)
      call cycle(iclr,69,71,73,75,77)
      call cycle(iclr,79,90,101,13,2)
      call cycle(iclr,88,99,110,22,11)
      call cycle(iclr,87,98,109,21,10)
      end if
c
      if(i.eq.13)then
      call cycle(iclr,57,59,61,63,65)
      call cycle(iclr,58,60,62,64,66)
      call cycle(iclr,23,45,34,122,111)
      call cycle(iclr,24,46,35,123,112)
      call cycle(iclr,25,47,36,124,113)
      call cycle(iclr,26,48,37,125,114)
      call cycle(iclr,27,49,38,126,115)
      call cycle(iclr,28,50,39,127,116)
      call cycle(iclr,29,51,40,128,117)
      call cycle(iclr,30,52,41,129,118)
      call cycle(iclr,31,53,42,130,119)
      call cycle(iclr,32,54,43,131,120)
      call cycle(iclr,33,55,44,132,121)
      call cycle(iclr,1,12,100,89,78)
      call cycle(iclr,2,13,101,90,79)
      call cycle(iclr,3,14,102,91,80)
      call cycle(iclr,4,15,103,92,81)
      call cycle(iclr,5,16,104,93,82)
      call cycle(iclr,6,17,105,94,83)
      call cycle(iclr,7,18,106,95,84)
      call cycle(iclr,8,19,107,96,85)
      call cycle(iclr,9,20,108,97,86)
      call cycle(iclr,10,21,109,98,87)
      call cycle(iclr,11,22,110,99,88)
      call cycle(iclr,76,74,72,70,68)
      call cycle(iclr,77,75,73,71,69)
      ctemp=cname(3)
      cname(3)=cname(2)
      cname(2)=cname(7)
      cname(7)=cname(8)
      cname(8)=cname(4)
      cname(4)=ctemp
      ctemp=cname(5)
      cname(5)=cname(9)
      cname(9)=cname(10)
      cname(10)=cname(11)
      cname(11)=cname(6)
      cname(6)=ctemp
      end if
c
      if(i.eq.14)then
      call cycle(iclr,32,24,26,28,30)
      call cycle(iclr,33,25,27,29,31)
      call cycle(iclr,1,45,56,111,78)
      call cycle(iclr,2,54,59,116,87)
      call cycle(iclr,3,55,60,117,88)
      call cycle(iclr,4,46,61,118,79)
      call cycle(iclr,5,47,62,119,80)
      call cycle(iclr,6,48,63,120,81)
      call cycle(iclr,7,49,64,121,82)
      call cycle(iclr,8,50,65,112,83)
      call cycle(iclr,9,51,66,113,84)
      call cycle(iclr,10,52,57,114,85)
      call cycle(iclr,11,53,58,115,86)
      call cycle(iclr,12,34,122,89,67)
      call cycle(iclr,13,41,127,96,74)
      call cycle(iclr,14,42,128,97,75)
      call cycle(iclr,15,43,129,98,76)
      call cycle(iclr,16,44,130,99,77)
      call cycle(iclr,17,35,131,90,68)
      call cycle(iclr,18,36,132,91,69)
      call cycle(iclr,19,37,123,92,70)
      call cycle(iclr,20,38,124,93,71)
      call cycle(iclr,21,39,125,94,72)
      call cycle(iclr,22,40,126,95,73)
      call cycle(iclr,109,107,105,103,101)
      call cycle(iclr,110,108,106,104,102)
      ctemp=cname(3)
      cname(3)=cname(5)
      cname(5)=cname(9)
      cname(9)=cname(7)
      cname(7)=cname(1)
      cname(1)=ctemp
      ctemp=cname(6)
      cname(6)=cname(12)
      cname(12)=cname(10)
      cname(10)=cname(8)
      cname(8)=cname(4)
      cname(4)=ctemp
      end if
c
    1 continue
c
      return
      end
c
      subroutine cycle(iclr,i1,i2,i3,i4,i5)
      integer iclr(132)
c
      temp=iclr(i5)
      iclr(i5)=iclr(i4)
      iclr(i4)=iclr(i3)
      iclr(i3)=iclr(i2)
      iclr(i2)=iclr(i1)
      iclr(i1)=temp
c
      return
      end
c
      subroutine fclr(fx,fy,fz,nx,ny,nz,theta,pi,tilex,tiley,sign)
      real fx(12,5),fy(12,5),fz(12,5),nx(12),ny(12),nz(12),
     >   tilex(132,5),tiley(132,5),x(20),y(20)
c
      wx=cos(theta*pi/180.0)
      wy=0.0
      wz=sin(theta*pi/180.0)
c
      if(sign.gt.0.0)itile=0
      if(sign.lt.0.0)itile=66
      do 1 i=1,12
      dot=wx*nx(i)+wy*ny(i)+wz*nz(i)
      if(sign*dot.gt.0.0)then
      x(1)=fy(i,1)
      y(1)=fz(i,1)*cos(theta*pi/180.0)-fx(i,1)*sin(theta*pi/180.0)
      x(2)=fy(i,2)
      y(2)=fz(i,2)*cos(theta*pi/180.0)-fx(i,2)*sin(theta*pi/180.0)
      x(3)=fy(i,3)
      y(3)=fz(i,3)*cos(theta*pi/180.0)-fx(i,3)*sin(theta*pi/180.0)
      x(4)=fy(i,4)
      y(4)=fz(i,4)*cos(theta*pi/180.0)-fx(i,4)*sin(theta*pi/180.0)
      x(5)=fy(i,5)
      y(5)=fz(i,5)*cos(theta*pi/180.0)-fx(i,5)*sin(theta*pi/180.0)
c
      x(6)=2.0*x(1)/3.0+x(2)/3.0
      y(6)=2.0*y(1)/3.0+y(2)/3.0
      x(7)=x(1)/3.0+2.0*x(2)/3.0
      y(7)=y(1)/3.0+2.0*y(2)/3.0
      x(8)=2.0*x(2)/3.0+x(3)/3.0
      y(8)=2.0*y(2)/3.0+y(3)/3.0
      x(9)=x(2)/3.0+2.0*x(3)/3.0
      y(9)=y(2)/3.0+2.0*y(3)/3.0
      x(10)=2.0*x(3)/3.0+x(4)/3.0
      y(10)=2.0*y(3)/3.0+y(4)/3.0
      x(11)=x(3)/3.0+2.0*x(4)/3.0
      y(11)=y(3)/3.0+2.0*y(4)/3.0
      x(12)=2.0*x(4)/3.0+x(5)/3.0
      y(12)=2.0*y(4)/3.0+y(5)/3.0
      x(13)=x(4)/3.0+2.0*x(5)/3.0
      y(13)=y(4)/3.0+2.0*y(5)/3.0
      x(14)=2.0*x(5)/3.0+x(1)/3.0
      y(14)=2.0*y(5)/3.0+y(1)/3.0
      x(15)=x(5)/3.0+2.0*x(1)/3.0
      y(15)=y(5)/3.0+2.0*y(1)/3.0
c
      xa=x(13)
      ya=y(13)
      xb=x(6)
      yb=y(6)
      xc=x(15)
      yc=y(15)
      xd=x(8)
      yd=y(8)
      call lines(xa,ya,xb,yb,xc,yc,xd,yd,xint,yint)
      x(16)=xint
      y(16)=yint
c
      xa=x(15)
      ya=y(15)
      xb=x(8)
      yb=y(8)
      xc=x(7)
      yc=y(7)
      xd=x(10)
      yd=y(10)
      call lines(xa,ya,xb,yb,xc,yc,xd,yd,xint,yint)
      x(17)=xint
      y(17)=yint
c
      xa=x(7)
      ya=y(7)
      xb=x(10)
      yb=y(10)
      xc=x(9)
      yc=y(9)
      xd=x(12)
      yd=y(12)
      call lines(xa,ya,xb,yb,xc,yc,xd,yd,xint,yint)
      x(18)=xint
      y(18)=yint
c
      xa=x(9)
      ya=y(9)
      xb=x(12)
      yb=y(12)
      xc=x(11)
      yc=y(11)
      xd=x(14)
      yd=y(14)
      call lines(xa,ya,xb,yb,xc,yc,xd,yd,xint,yint)
      x(19)=xint
      y(19)=yint
c
      xa=x(11)
      ya=y(11)
      xb=x(14)
      yb=y(14)
      xc=x(13)
      yc=y(13)
      xd=x(6)
      yd=y(6)
      call lines(xa,ya,xb,yb,xc,yc,xd,yd,xint,yint)
      x(20)=xint
      y(20)=yint
c
      call scale(x,y,sign)
c
      itile=itile+1
      tilex(itile,1)=x(16)
      tiley(itile,1)=y(16)
      tilex(itile,2)=x(17)
      tiley(itile,2)=y(17)
      tilex(itile,3)=x(18)
      tiley(itile,3)=y(18)
      tilex(itile,4)=x(19)
      tiley(itile,4)=y(19)
      tilex(itile,5)=x(20)
      tiley(itile,5)=y(20)
c
      itile=itile+1
      tilex(itile,1)=x(1)
      tiley(itile,1)=y(1)
      tilex(itile,2)=x(6)
      tiley(itile,2)=y(6)
      tilex(itile,3)=x(16)
      tiley(itile,3)=y(16)
      tilex(itile,4)=0.5*(x(16)+x(15))
      tiley(itile,4)=0.5*(y(16)+y(15))
      tilex(itile,5)=x(15)
      tiley(itile,5)=y(15)
c
      itile=itile+1
      tilex(itile,1)=x(6)
      tiley(itile,1)=y(6)
      tilex(itile,2)=x(7)
      tiley(itile,2)=y(7)
      tilex(itile,3)=x(17)
      tiley(itile,3)=y(17)
      tilex(itile,4)=0.5*(x(16)+x(17))
      tiley(itile,4)=0.5*(y(16)+y(17))
      tilex(itile,5)=x(16)
      tiley(itile,5)=y(16)
c
      itile=itile+1
      tilex(itile,1)=x(7)
      tiley(itile,1)=y(7)
      tilex(itile,2)=x(2)
      tiley(itile,2)=y(2)
      tilex(itile,3)=x(8)
      tiley(itile,3)=y(8)
      tilex(itile,4)=0.5*(x(8)+x(17))
      tiley(itile,4)=0.5*(y(8)+y(17))
      tilex(itile,5)=x(17)
      tiley(itile,5)=y(17)
c
      itile=itile+1
      tilex(itile,1)=x(8)
      tiley(itile,1)=y(8)
      tilex(itile,2)=x(9)
      tiley(itile,2)=y(9)
      tilex(itile,3)=x(18)
      tiley(itile,3)=y(18)
      tilex(itile,4)=0.5*(x(18)+x(17))
      tiley(itile,4)=0.5*(y(18)+y(17))
      tilex(itile,5)=x(17)
      tiley(itile,5)=y(17)
c
      itile=itile+1
      tilex(itile,1)=x(9)
      tiley(itile,1)=y(9)
      tilex(itile,2)=x(3)
      tiley(itile,2)=y(3)
      tilex(itile,3)=x(10)
      tiley(itile,3)=y(10)
      tilex(itile,4)=0.5*(x(10)+x(18))
      tiley(itile,4)=0.5*(y(10)+y(18))
      tilex(itile,5)=x(18)
      tiley(itile,5)=y(18)
c
      itile=itile+1
      tilex(itile,1)=x(10)
      tiley(itile,1)=y(10)
      tilex(itile,2)=x(11)
      tiley(itile,2)=y(11)
      tilex(itile,3)=x(19)
      tiley(itile,3)=y(19)
      tilex(itile,4)=0.5*(x(19)+x(18))
      tiley(itile,4)=0.5*(y(19)+y(18))
      tilex(itile,5)=x(18)
      tiley(itile,5)=y(18)
c
      itile=itile+1
      tilex(itile,1)=x(11)
      tiley(itile,1)=y(11)
      tilex(itile,2)=x(4)
      tiley(itile,2)=y(4)
      tilex(itile,3)=x(12)
      tiley(itile,3)=y(12)
      tilex(itile,4)=0.5*(x(12)+x(19))
      tiley(itile,4)=0.5*(y(12)+y(19))
      tilex(itile,5)=x(19)
      tiley(itile,5)=y(19)
c
      itile=itile+1
      tilex(itile,1)=x(19)
      tiley(itile,1)=y(19)
      tilex(itile,2)=x(12)
      tiley(itile,2)=y(12)
      tilex(itile,3)=x(13)
      tiley(itile,3)=y(13)
      tilex(itile,4)=0.5*(x(13)+x(20))
      tiley(itile,4)=0.5*(y(13)+y(20))
      tilex(itile,5)=x(20)
      tiley(itile,5)=y(20)
c
      itile=itile+1
      tilex(itile,1)=x(20)
      tiley(itile,1)=y(20)
      tilex(itile,2)=x(13)
      tiley(itile,2)=y(13)
      tilex(itile,3)=x(5)
      tiley(itile,3)=y(5)
      tilex(itile,4)=0.5*(x(5)+x(14))
      tiley(itile,4)=0.5*(y(5)+y(14))
      tilex(itile,5)=x(14)
      tiley(itile,5)=y(14)
c
      itile=itile+1
      tilex(itile,1)=x(20)
      tiley(itile,1)=y(20)
      tilex(itile,2)=x(14)
      tiley(itile,2)=y(14)
      tilex(itile,3)=x(15)
      tiley(itile,3)=y(15)
      tilex(itile,4)=0.5*(x(16)+x(15))
      tiley(itile,4)=0.5*(y(16)+y(15))
      tilex(itile,5)=x(16)
      tiley(itile,5)=y(16)

      end if
    1 continue
c
      return
      end
c
      subroutine lines(xa,ya,xb,yb,xc,yc,xd,yd,xint,yint)
      a=xd-xc
      b=xa-xb
      c=yd-yc
      d=ya-yb
      r1=xa-xc
      r2=ya-yc
      s=(d*r1-b*r2)/(a*d-b*c)
      xint=xc+s*(xd-xc)
      yint=yc+s*(yd-yc)
      return
      end
c
      subroutine scale(x,y,sign)
      real x(20),y(20)
c
      do 1 i=1,20
      if(sign.gt.0.0)then
      x(i)=410.0+85.0*x(i)
      y(i)=560.0+85.0*y(i)
      else
      x(i)=410.0+85.0*x(i)
      y(i)=280.0+85.0*y(i)
      end if
    1 continue
      return
      end
c
      subroutine tclr(tilex,tiley,iclr)
      real tilex(132,5),tiley(132,5)
      integer iclr(132)
c
c
      do 1 i=1,132
      write(1,*)tilex(i,1),tiley(i,1),' moveto'
      write(1,*)tilex(i,2),tiley(i,2),' lineto'
      write(1,*)tilex(i,3),tiley(i,3),' lineto'
      write(1,*)tilex(i,4),tiley(i,4),' lineto'
      write(1,*)tilex(i,5),tiley(i,5),' lineto'
      write(1,*)' closepath'
      n=iclr(i)
      call color(n)
      write(1,*)' fill'
    1 continue
    2 continue
c
      return
      end
c
      subroutine frame(tilex,tiley)
      real tilex(132,5),tiley(132,5)
c
      do 1 i=1,132
      write(1,*)tilex(i,1),tiley(i,1),' moveto'
      write(1,*)tilex(i,2),tiley(i,2),' lineto'
      write(1,*)tilex(i,3),tiley(i,3),' lineto'
      write(1,*)tilex(i,4),tiley(i,4),' lineto'
      write(1,*)tilex(i,5),tiley(i,5),' lineto'
      write(1,*)' closepath'
      call color(99)
      write(1,*)' stroke'
    1 continue
    2 continue
c
      return
      end
c
      subroutine color(n)
c
      if(n.eq.12)write(1,*)' 0.75 0.4 1 sethsbcolor'
      if(n.eq.2)write(1,*)' 0 1 1 sethsbcolor'
      if(n.eq.10)write(1,*)' 1 1 1  setrgbcolor'
      if(n.eq.4)write(1,*)' 0.333 1 1 sethsbcolor'
      if(n.eq.5)write(1,*)' 0.1 1 1 sethsbcolor'
      if(n.eq.7)write(1,*)' 0.55 1 1  sethsbcolor'
      if(n.eq.1)write(1,*)' 0.75 1 1 sethsbcolor'
      if(n.eq.11)write(1,*)' 0.35 0.35 0.35 setrgbcolor'
      if(n.eq.3)write(1,*)' 0.167 1 1 sethsbcolor'
      if(n.eq.8)write(1,*)' 0.333 1 0.5 sethsbcolor'
      if(n.eq.9)write(1,*)' 0.1 1 0.6 sethsbcolor'
      if(n.eq.6)write(1,*)' 0.667 1 1  sethsbcolor'
      if(n.eq.44)write(1,*)' 1 1 1 setrgbcolor'
      if(n.eq.99)write(1,*)' 0 0 0 setrgbcolor'
c
      return
      end
c
      subroutine vrtx(vx,vy,vz,pi)
      real vx(20),vy(20),vz(20)
      cost=cos(72.0*pi/180.0)
      sint=sin(72.0*pi/180.0)
      cost2=cos(36.0*pi/180.0)
      sint2=sin(36.0*pi/180.0)
c
      vx(1)=-0.5/sin(36.0*pi/180.0)
      vy(1)=0.0
      vz(1)=0.0
      do 1 i=2,5
      vx(i)=cost*vx(i-1)-sint*vy(i-1)
      vy(i)=sint*vx(i-1)+cost*vy(i-1)
      vz(i)=0.0
    1 continue
c
      alpha=cos(108.0*pi/180.0)/cos(54.0*pi/180.0)
      dz1=sqrt(1.0-alpha**2)
      vx(6)=vx(1)+alpha
      vy(6)=0.0
      vz(6)=dz1
      do 2 i=7,10
      vx(i)=cost*vx(i-1)-sint*vy(i-1)
      vy(i)=sint*vx(i-1)+cost*vy(i-1)
      vz(i)=vz(6)
    2 continue
c
      dz2=dz1*cos(54.0*pi/180.0)/sin(72.0*pi/180.0)
      vx(11)=cost2*vx(6)-sint2*vy(6)
      vy(11)=sint2*vx(6)+cost2*vy(6)
      vz(11)=dz1+dz2
      do 3 i=12,15
      vx(i)=cost*vx(i-1)-sint*vy(i-1)
      vy(i)=sint*vx(i-1)+cost*vy(i-1)
      vz(i)=vz(11)
    3 continue
c
      vx(16)=cost2*vx(1)-sint2*vy(1)
      vy(16)=sint2*vx(1)+cost2*vy(1)
      vz(16)=2.0*dz1+dz2
      do 4 i=17,20
      vx(i)=cost*vx(i-1)-sint*vy(i-1)
      vy(i)=sint*vx(i-1)+cost*vy(i-1)
      vz(i)=vz(16)
    4 continue
c
      return
      end
c
      subroutine faces(vx,vy,vz,fx,fy,fz,nx,ny,nz)
      real vx(20),vy(20),vz(20),fx(12,5),fy(12,5),fz(12,5),
     >   nx(12),ny(12),nz(12)
c
      call setfc(vx,vy,vz,fx,fy,fz,1,1,1)
      call setfc(vx,vy,vz,fx,fy,fz,1,2,2)
      call setfc(vx,vy,vz,fx,fy,fz,1,3,3)
      call setfc(vx,vy,vz,fx,fy,fz,1,4,4)
      call setfc(vx,vy,vz,fx,fy,fz,1,5,5)
c
      call setfc(vx,vy,vz,fx,fy,fz,2,1,1)
      call setfc(vx,vy,vz,fx,fy,fz,2,2,6)
      call setfc(vx,vy,vz,fx,fy,fz,2,3,11)
      call setfc(vx,vy,vz,fx,fy,fz,2,4,7)
      call setfc(vx,vy,vz,fx,fy,fz,2,5,2)
c
      call setfc(vx,vy,vz,fx,fy,fz,3,1,2)
      call setfc(vx,vy,vz,fx,fy,fz,3,2,7)
      call setfc(vx,vy,vz,fx,fy,fz,3,3,12)
      call setfc(vx,vy,vz,fx,fy,fz,3,4,8)
      call setfc(vx,vy,vz,fx,fy,fz,3,5,3)
c
      call setfc(vx,vy,vz,fx,fy,fz,4,1,3)
      call setfc(vx,vy,vz,fx,fy,fz,4,2,8)
      call setfc(vx,vy,vz,fx,fy,fz,4,3,13)
      call setfc(vx,vy,vz,fx,fy,fz,4,4,9)
      call setfc(vx,vy,vz,fx,fy,fz,4,5,4)
c
      call setfc(vx,vy,vz,fx,fy,fz,5,1,4)
      call setfc(vx,vy,vz,fx,fy,fz,5,2,9)
      call setfc(vx,vy,vz,fx,fy,fz,5,3,14)
      call setfc(vx,vy,vz,fx,fy,fz,5,4,10)
      call setfc(vx,vy,vz,fx,fy,fz,5,5,5)
c
      call setfc(vx,vy,vz,fx,fy,fz,6,1,5)
      call setfc(vx,vy,vz,fx,fy,fz,6,2,10)
      call setfc(vx,vy,vz,fx,fy,fz,6,3,15)
      call setfc(vx,vy,vz,fx,fy,fz,6,4,6)
      call setfc(vx,vy,vz,fx,fy,fz,6,5,1)
c
      call setfc(vx,vy,vz,fx,fy,fz,7,1,16)
      call setfc(vx,vy,vz,fx,fy,fz,7,2,17)
      call setfc(vx,vy,vz,fx,fy,fz,7,3,12)
      call setfc(vx,vy,vz,fx,fy,fz,7,4,7)
      call setfc(vx,vy,vz,fx,fy,fz,7,5,11)
c
      call setfc(vx,vy,vz,fx,fy,fz,8,1,17)
      call setfc(vx,vy,vz,fx,fy,fz,8,2,18)
      call setfc(vx,vy,vz,fx,fy,fz,8,3,13)
      call setfc(vx,vy,vz,fx,fy,fz,8,4,8)
      call setfc(vx,vy,vz,fx,fy,fz,8,5,12)
c
      call setfc(vx,vy,vz,fx,fy,fz,9,1,18)
      call setfc(vx,vy,vz,fx,fy,fz,9,2,19)
      call setfc(vx,vy,vz,fx,fy,fz,9,3,14)
      call setfc(vx,vy,vz,fx,fy,fz,9,4,9)
      call setfc(vx,vy,vz,fx,fy,fz,9,5,13)
c
      call setfc(vx,vy,vz,fx,fy,fz,10,1,19)
      call setfc(vx,vy,vz,fx,fy,fz,10,2,20)
      call setfc(vx,vy,vz,fx,fy,fz,10,3,15)
      call setfc(vx,vy,vz,fx,fy,fz,10,4,10)
      call setfc(vx,vy,vz,fx,fy,fz,10,5,14)
c
      call setfc(vx,vy,vz,fx,fy,fz,11,1,20)
      call setfc(vx,vy,vz,fx,fy,fz,11,2,16)
      call setfc(vx,vy,vz,fx,fy,fz,11,3,11)
      call setfc(vx,vy,vz,fx,fy,fz,11,4,6)
      call setfc(vx,vy,vz,fx,fy,fz,11,5,15)
c
      call setfc(vx,vy,vz,fx,fy,fz,12,1,20)
      call setfc(vx,vy,vz,fx,fy,fz,12,2,19)
      call setfc(vx,vy,vz,fx,fy,fz,12,3,18)
      call setfc(vx,vy,vz,fx,fy,fz,12,4,17)
      call setfc(vx,vy,vz,fx,fy,fz,12,5,16)
c
      do 1 i=1,12
      x1=fx(i,2)-fx(i,1)
      y1=fy(i,2)-fy(i,1)
      z1=fz(i,2)-fz(i,1)
      x2=fx(i,3)-fx(i,2)
      y2=fy(i,3)-fy(i,2)
      z2=fz(i,3)-fz(i,2)
      nx(i)=y1*z2-y2*z1
      ny(i)=-x1*z2+x2*z1
      nz(i)=x1*y2-x2*y1
    1 continue
c
      return
      end
c
      subroutine setfc(vx,vy,vz,fx,fy,fz,i,j,k)
      real vx(20),vy(20),vz(20),fx(12,5),fy(12,5),fz(12,5)
      fx(i,j)=vx(k)
      fy(i,j)=vy(k)
      fz(i,j)=vz(k)
      return
      end
c
      subroutine start(jclr,cname)
      integer jclr(12)
      character*15 cname(12)
c
      x=40
      z=800
      write(1,*)'%!'
      write(1,*)' /Times-Roman findfont'
      write(1,*)' 14 scalefont setfont'
      z=z-40
      write(1,*)x,z,' moveto'
      write(1,*)' (Rotate a face:) show'
      z=z-20
      write(1,*)x,z,' moveto'
      write(1,*)' (  1 =',cname(jclr(1)),' ) show'
      z=z-20
      write(1,*)x,z,' moveto'
      write(1,*)' (  2 =',cname(jclr(2)),' ) show'
      z=z-20
      write(1,*)x,z,' moveto'
      write(1,*)' (  3 =',cname(jclr(3)),' ) show'
      z=z-20
      write(1,*)x,z,' moveto'
      write(1,*)' (  4 =',cname(jclr(4)),' ) show'
      z=z-20
      write(1,*)x,z,' moveto'
      write(1,*)' (  5 =',cname(jclr(5)),' ) show'
      z=z-20
      write(1,*)x,z,' moveto'
      write(1,*)' (  6 =',cname(jclr(6)),' ) show'
      z=z-20
      write(1,*)x,z,' moveto'
      write(1,*)' (  7 =',cname(jclr(7)),' ) show'
      z=z-20
      write(1,*)x,z,' moveto'
      write(1,*)' (  8 =',cname(jclr(8)),' ) show'
      z=z-20
      write(1,*)x,z,' moveto'
      write(1,*)' (  9 =',cname(jclr(9)),' ) show'
      z=z-20
      write(1,*)x,z,' moveto'
      write(1,*)' (  10 =',cname(jclr(10)),' ) show'
      z=z-20
      write(1,*)x,z,' moveto'
      write(1,*)' (  11 =',cname(jclr(11)),' ) show'
      z=z-20
      write(1,*)x,z,' moveto'
      write(1,*)' (  12 =',cname(jclr(12)),' ) show'
c
      z=z-40
      write(1,*)x,z,' moveto'
      write(1,*)' (Rotate the entire dodecahedron:) show'
      z=z-20
      write(1,*)x,z,' moveto'
      write(1,*)' (  13 = about the vertical axis) show'
      z=z-20
      write(1,*)x,z,' moveto'
      write(1,*)' (  14 = about the 2-11 axis) show'
c
      z=z-40
      write(1,*)x,z,' moveto'
      write(1,*)' (All rotations are counterclockwise.) show'
      z=z-20
      write(1,*)x,z,' moveto'
      write(1,*)' (Rotations of back faces appear clockwise.) show'
c
      x=300
      z=515
      write(1,*)x,z,' moveto'
      write(1,*)' (Above: Direct view of the front faces.) show'
      z=z-20
      write(1,*)x,z,' moveto'
      write(1,*)' (Below: Mirror view of the back faces.) show'
c
      return
      end
c
      function ran0(iseed)
      if(iseed.eq.0)iseed=178544878
      m=2147483647
      n=16807
      k=iseed/127773
      iseed=n*(iseed-k*127773)-k*2836
      if(iseed.lt.0)iseed=iseed+m
      ran0=float(iseed)/float(m)
      return
      end
