c
c
c     ###################################################
c     ##  COPYRIGHT (C)  1991  by  Jay William Ponder  ##
c     ##              All Rights Reserved              ##
c     ###################################################
c
c     ###############################################################
c     ##                                                           ##
c     ##  function dihedral  --  torsion angle between four atoms  ##
c     ##                                                           ##
c     ###############################################################
c
c
c     "dihedral" finds the value of the dihedral angle in the
c     range from -180 to +180 degrees defined by four input atoms
c
c
      function dihedral (ia,ib,ic,id)
      implicit none
      include 'sizes.i'
      include 'atoms.i'
      include 'math.i'
      integer ia,ib,ic,id
      real*8 xba,yba,zba
      real*8 xcb,ycb,zcb
      real*8 xdc,ydc,zdc
      real*8 xt,yt,zt
      real*8 xu,yu,zu
      real*8 rt2,ru2,rtru
      real*8 dihedral,cosine,sign
c
c
c     set default in case atoms are colinear or degenerate
c
      dihedral = 0.0d0
c
c     compute the value in degrees of the dihedral angle
c
      xba = x(ib) - x(ia)
      yba = y(ib) - y(ia)
      zba = z(ib) - z(ia)
      xcb = x(ic) - x(ib)
      ycb = y(ic) - y(ib)
      zcb = z(ic) - z(ib)
      xdc = x(id) - x(ic)
      ydc = y(id) - y(ic)
      zdc = z(id) - z(ic)
      xt = yba*zcb - ycb*zba
      yt = xcb*zba - xba*zcb
      zt = xba*ycb - xcb*yba
      xu = ycb*zdc - ydc*zcb
      yu = xdc*zcb - xcb*zdc
      zu = xcb*ydc - xdc*ycb
      rt2 = xt*xt + yt*yt + zt*zt
      ru2 = xu*xu + yu*yu + zu*zu
      rtru = sqrt(rt2 * ru2)
      if (rtru .ne. 0.0d0) then
         cosine = (xt*xu + yt*yu + zt*zu) / rtru
         cosine = min(1.0d0,max(-1.0d0,cosine))
         dihedral = radian * acos(cosine)
         sign = xba*xu + yba*yu + zba*zu
         if (sign .lt. 0.0d0)  dihedral = -dihedral
      end if
      return
      end
