home *** CD-ROM | disk | FTP | other *** search
/ Chip 2011 November / CHIP_2011_11.iso / Programy / Inne / Gry / Atomic_Tanks / Atomic-Tanks-5.1.exe / src / perlin.cpp < prev    next >
C/C++ Source or Header  |  2009-01-28  |  4KB  |  159 lines

  1. /*
  2.  * atanks - obliterate each other with oversize weapons
  3.  * Copyright (C) 2003  Thomas Hudson
  4.  *
  5.  * This program is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU General Public License
  7.  * as published by the Free Software Foundation; either version 2
  8.  * of the License, or (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  * */
  19.  
  20. /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  21. perlin.cc
  22.  
  23. Provides noise and interpolation functionality, as prototyped in main.h
  24. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
  25.  
  26. #include "main.h"
  27.  
  28.  
  29.  
  30. /*****************************************************************************
  31. Noise, Noise2D
  32.  
  33. A floating point pseudorandom number generator.  Given a seed input value,
  34. returns a randomized double in the range [-1.0,+1.0] .  Maintains no state.
  35.  
  36. Noise2D requires and uses two integer parameters.
  37. *****************************************************************************/
  38. double Noise (int x)
  39. {
  40.   x = (x<<13) ^ x;
  41.   return ( 1.0 - ((x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff)
  42.            / 1073741824.0);
  43. }
  44.  
  45. double Noise2D (int x, int y)
  46. {
  47.   int n;
  48.  
  49.   n = x + y * 57;
  50.   n = (n << 13) ^ n;
  51.   return ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff)
  52.            / 1073741824.0);
  53. }
  54.  
  55.  
  56.  
  57. /*****************************************************************************
  58. interpolate
  59.  
  60. Performs a cosine interpolation between two points.  Given two y values
  61. and a distance between them, return the interpolated y.  x1 and x2 are the y
  62. values (sorry, it's the best I could explain it).  i is the distance,
  63. expressed as a percentage of the wave length, ie 0<=i<1 .
  64. *****************************************************************************/
  65. /*
  66. double interpolate (double x1, double x2, double i)
  67. {
  68.     double ft = i * M_PI;
  69.     double f = (1 - cos(ft)) * 0.5;
  70.  
  71.     return (x1 * (1 - f) + (x2 * f));
  72. }
  73. */
  74.  
  75.  
  76. double interpolate (double x1, double x2, double i)
  77. {
  78.   double ft = i * M_PI;
  79.   double f = (1 - cos(ft)) * 0.5;
  80.   double result = (x1 * (1 - f) + (x2 * f));
  81.  
  82.   if (isnan(x1)||isnan(x2))
  83.     return 0.0;
  84.   if (isnan(result))
  85.     return (x1+x2)/2.0; /* fall back to linear interpolation */
  86.   return result;
  87. }
  88.  
  89.  
  90.  
  91.  
  92. /*
  93. *
  94. * For a really good explanation of perlin noise (and where most of this
  95. *   perlin code was adapted from) see:
  96. *
  97. * http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
  98. *
  99. * It must be good because I understood it <:-)
  100. *
  101. * - Tom Hudson
  102. *
  103. */
  104. double perlin2DPoint (double amplitude, double scale, double xo, double yo,
  105.                       double lambda, int octaves)
  106. {
  107.   double    maxH = 0;
  108.   double    h = 0;
  109.   for (int iteration = 1; iteration <= octaves; iteration++)
  110.     {
  111.       double    zoom = scale / (iteration * iteration);
  112.       double    fractX = xo / zoom;
  113.       double    fractY = yo / zoom;
  114.       double    h1 = Noise2D ((int)fractX, (int)fractY);
  115.       double    h2 = Noise2D ((int)fractX + 1, (int)fractY);
  116.       double    h3 = Noise2D ((int)fractX, (int)fractY + 1);
  117.       double    h4 = Noise2D ((int)fractX + 1, (int)fractY + 1);
  118.  
  119.       double    xi = fractX - (int)fractX;
  120.       double    yi = fractY - (int)fractY;
  121.  
  122.       double    i1 = interpolate (h1, h2, xi);
  123.       double    i2 = interpolate (h3, h4, xi);
  124.       double    i3 = interpolate (i1, i2, yi);
  125.  
  126.       h += amplitude * i3;
  127.       maxH += amplitude;
  128.  
  129.       amplitude *= lambda;
  130.     }
  131.  
  132.   // Normalised
  133.   return (h / maxH);
  134. }
  135.  
  136. double perlin1DPoint (double amplitude, double scale, double xo,
  137.                       double lambda, int octaves)
  138. {
  139.   double    maxH = 0;
  140.   double    h = 0;
  141.   for (int iteration = 1; iteration <= octaves; iteration++)
  142.     {
  143.       double    zoom = scale / (iteration * iteration);
  144.       double    fractX = xo / zoom;
  145.       double    h1 = Noise ((int)fractX);
  146.       double    h2 = Noise ((int)fractX + 1);
  147.       double    i = fractX - (int)fractX;
  148.  
  149.       h += amplitude * interpolate (h1, h2, i);
  150.       maxH += amplitude;
  151.  
  152.       amplitude *= lambda;
  153.     }
  154.  
  155.   // Normalised
  156.   return (h / maxH);
  157. }
  158.  
  159.