
/* ------------------------------------------------------------ */
/* smooth  --  simulate random smoothing (raindrops?) in hf[]   */
/*             not linear; points move down faster than up      */
/* ------------------------------------------------------------ */

void smooth(float rate)
{
  int i,ix,iy;
  PTYPE h,dh,avg,sum1,sum2;
  PTYPE afac, n1, n2;
  PTYPE *hf2;
  PTYPE af1, af2;

  hf2 = (PTYPE *) malloc((size_t)sizeof(PTYPE)*(xsize+2)*(ysize+2));
   if (hf2 == NULL) {
     fprintf(stderr,"Could not allocate hf buffer memory.\n");
     exit(1);
   }

   for (iy = 0; iy<ysize; iy++) {  /* skip the edges */
    for (ix = 0; ix<xsize; ix++) {
     h = Ehn(hf,ix,iy);
      sum1 = 0;          /* sum of elevation differences */
      sum2 = 0;
      af1 = 4;          /* number of differences summed */
      af2 = 4;
      for (i=1;i<9;i+=2) {
       n1 = Ehn(hf,ix+xo[i+1],iy+yo[i+1]) - h; /* adj. neighbors */
       if (n1 < 0) {  /* count lower elements more */
           n1 *= 2.0;
           af1 += 1;     }
       n2 = Ehn(hf,ix+xo[i],iy+yo[i]) - h;     /* diagonal neighbors */  
       if (n2 < h) {
           n2 *= 2.0;
           af2 += 1;     }
       sum1 += n1;
       sum2 += n2;
      } /* end for i... */

      /* avg = 0.5858*(sum1/af1) + 0.4142*(sum2/af2); */
      avg = 0.8*(sum1/af1) + 0.2*(sum2/af2); /* weight closest neighbors heavily */
      dh = avg;   /* difference between this point and avg of neighbors */
      if (h > 1.0) h = 1;
      if (h < 0.0) h = 0;
                /* sign convention: positive afac = addition to elevation */
      afac = dh * rate ;
      if (pow_fac != 0)
        afac *= (1 - (pow_offset + pow(h,pow_fac)));   /* altitude-dependent smoothing */
      if (h < er_thresh) {        /* only smooth terrain below altitude limit */
       Ehn(hf2,ix,iy) = h + afac;
       El(bn,ix,iy) += afac;            /* record addition */
      } else {          /* if above threshold, NO erosion */
       Ehn(hf2,ix,iy) = h;
      }
    } /* end for ix */
   } /* end for iy */

   for (iy = 0; iy<ysize; iy++) {  /* copy entire matrix(minus edges) to hf*/
    for (ix = 0; ix<xsize; ix++) {
     Ehn(hf,ix,iy) = Ehn(hf2,ix,iy);
    } /* end for ix */
   } /* end for iy */

  free(hf2);
} /* end smooth() */

