Search code examples
javaperlin-noisesimplex-noise

Simplex Noise Adjustments only working in one direction


I am making a heightmap using simplex noise. I am running into problems adjusting it to give a slight tendency to form an island. I am just working on getting the values to be correct before actually rendering the biomes and other features. I have run into the problem that my code, which should work to create this tendency to make an island in the middle only seems to work in one direction.

If there a particular reason for this? My class that deals with the smoothing out of the terrain does the same thing in the x and y directions, but only one works.

public class MapGenerator{

public double[][] toRender;

int maxHeight = 300;

public MapGenerator() {

    int xResolution = 200;
    int yResolution = 200;

    double[][] result = new double[xResolution][yResolution];

    for (int x = 0; x < xResolution; x++){
        for (int y = 0; y < yResolution; y++){
            result[x][y] = transformPoint(x, y, xResolution, yResolution, SimplexNoise.noise(x, y));
        }
    }

    toRender = result;

}

private double transformPoint(int x, int y, int xSize, int ySize, double point){
    System.out.println();
    System.out.println(point);

    point += 20 * Math.sin(x * Math.PI / xSize);

    point += 20 * Math.sin(y * Math.PI / ySize);

    System.out.println(point);

    return point;
}

}

Images of the white noise:

With X and Y:

With only X (Y commented out):

[With only Y (X commented out):](Similar to X and Y, can't post link because of reputation.)

[Without X and Y:](Similar to only X, can't post link because of reputation.)


Solution

  • I'm not 100% where your error is. It could be in your noise routine. To debug this, I removed the call to noise and substituted a constant value of 0.5. Then I got the rest of it working so I saw a white halo in the center of the image. Then I added the noise call back. (Note I'm using my own SimplexNoise here.)

    So the problem is either in your bounds (Math.min( 1.0, point )) or in your graphics display (which you don't show) or in your SimplexNoise (which you also don't show).

    import SimpleUtils.noise.SimplexNoise;
    import java.awt.Image;
    import java.awt.image.BufferedImage;
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.SwingUtilities;
    
    /**
     *
     * @author Brenden Towey
     */
    public class MapGenerator
    {
    
       public static void main( String[] args )
       {
          SwingUtilities.invokeLater( new Runnable()
          {
             public void run()
             {
                JFrame frame = new JFrame();
    
                frame.add( new JLabel( new ImageIcon( new MapGenerator().toImage() )));
    
                frame.pack();
                frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
                frame.setLocationRelativeTo( null );
                frame.setVisible( true );
             }
          } );
    
       }
       public double[][] toRender;
    
       int maxHeight = 300;
       int xResolution = 200;
       int yResolution = 200;
    
       public MapGenerator()
       {
          double[][] result = new double[ xResolution ][ yResolution ];
          SimplexNoise noise = new SimplexNoise();
          for( int x = 0; x < xResolution; x++ )
             for( int y = 0; y < yResolution; y++ )
                result[x][y] = transformPoint( x, y, noise.noise(x, y) );
    
          toRender = result;
    
       }
    
       private double transformPoint( int x, int y, double point )
       {
          point += 2 * Math.sin( x * Math.PI / xResolution )/2.0;
          point += 2 * Math.sin( y * Math.PI / yResolution )/2.0;
          return Math.min( 1.0, point);
       }
    
       public Image toImage()
       {
          BufferedImage image = new BufferedImage( xResolution,
                  yResolution, BufferedImage.TYPE_INT_RGB );
          for( int x = 0; x < xResolution; x++ )
             for( int y = 0; y < yResolution; y++ )
                image.setRGB( x, y, greyScale( toRender[x][y] ) );
          return image;
       }
    
       private int greyScale( double toRender )
       {
          int scale = (int) ( 255 * toRender );
          return scale + (scale << 8) + (scale << 16);
       }
    }
    

    My output from this code