title: Java 2D Array Bicubic Interpolation
body: <p>I have recently been playing around with Bicubic Interpolation, as I am wanting to generate the earth, based on real heightmaps inside Minecraft. The reason I am using the interpolation, is because I would like to make the world have more detail. After a lot of research, and a lot of trial and error, I decided to come ask here. :)</p>
  
  <p>Because of limited memory, I can't scale the image on startup, and keep that loaded, I have to do the interpolation on the fly. </p>
  
  <p>I seem to have gotten Cubic Interpolation to work, as seen here: 
  <a href="http://i.stack.imgur.com/tgyyE.png" rel="nofollow">Visualisation of the interpolation</a>
  However, I can not get Bicubic Interpolation to work. For testing purposes, I am using a small image, and scaling it by 4. This is what the code does: <a href="http://i.stack.imgur.com/aprgs.png" rel="nofollow">Input -> Output</a></p>
  
  <p>This is my current code:</p>
  
  <pre><code> public static double cubicInterpolate(double[] points, double x, double scale)
  {
      x /= scale;
  
      double inBetweenPoint = x;
      int xInHeightmap = (int) x;
      inBetweenPoint -= xInHeightmap;
  
      double beforePoint1 = safe(points, xInHeightmap - 1);
      double point1 = safe(points, xInHeightmap);
      double point2 = safe(points, xInHeightmap + 1);
      double afterPoint2 = safe(points, xInHeightmap + 2);
  
      double p = (afterPoint2 - point2) - (beforePoint1 - point1);
      double q = (beforePoint1 - point1) - p;
      double r = point2 - beforePoint1;
      double s = point1;
  
      return (p * Math.pow(inBetweenPoint, 3)) + (q * Math.pow(inBetweenPoint, 2)) + (r * inBetweenPoint) + s;
  }
  
  public static double bicubicInterpolate(double[][] points, double x, double y, double scale)
  {
      x /= scale;
  
      double inBetweenPoint = x;
      int xInHeightmap = (int) x;
      inBetweenPoint -= xInHeightmap;
  
      double beforePoint1 = cubicInterpolate(safe(points, xInHeightmap - 1), y, scale);
      double point1 = cubicInterpolate(safe(points, xInHeightmap), y, scale);
      double point2 = cubicInterpolate(safe(points, xInHeightmap + 1), y, scale);
      double afterPoint2 = cubicInterpolate(safe(points, xInHeightmap + 2), y, scale);
  
      return cubicInterpolate(new double[]{beforePoint1, point1, point2, afterPoint2}, inBetweenPoint + 1, scale);
  }
  
  public static double[] safe(double[][] p, int i)
  {
      return p[Math.max(0, Math.min(i, p.length - 1))];
  }
  
  public static double safe(double[] p, int i)
  {
      return p[Math.max(0, Math.min(i, p.length - 1))];
  }
  </code></pre>
  
  <p>Thank you for your help :)</p>