/** * Copyright (c) 2003-2009, Xith3D Project Group all rights reserved. * * Portions based on the Java3D interface, Copyright by Sun Microsystems. * Many thanks to the developers of Java3D and Sun Microsystems for their * innovation and design. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the 'Xith3D Project Group' nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) A * RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE */ package org.xith3d.terrain.legacy.heightmap; import java.util.Random; import org.xith3d.scenegraph.Geometry; /** * Generates a heightmap using fractal faulting. The Algorithm was adapted from Aurel Balmosan's * 'faultmap' program posted to Usenet by Carl Burke. Carl has an example and explanation here: * <a href="http://www.geocities.com/Area51/6902/t_fl_app.html"> * http://www.geocities.com/Area51/6902/t_fl_app.html</a>. Converson to the HeightMap class * by William Denniss. * * @author William Denniss * @version 1.0 - 17 March 2004 */ public class Faulting extends HeightMap implements Terrain { private static final long serialVersionUID = -4450585657315846596L; private int width = 256; private int height = 256; private Random rgen; /** * Initialises the miller fractal generator. * * @param width * @param height * @param scalefactor * @param rgen Random number generator to use */ public Faulting( int width, int height, double scalefactor, Random rgen ) { this.width = width; this.height = height; //this.scalefactor = scalefactor; this.rgen = rgen; // generates the terrain generateTerrain(); } /************************************************************ * Faulting implementations ************************************************************/ private int rand0( int range ) { double d = rgen.nextDouble(); int i = (int)( d * range ); if ( i < 0 ) i = -i; return ( i ); } synchronized void doFaulting( int iterations ) { double pfi, cp, sp; int i, h, j, x, y; int px, py, wmod = width, hmod = width; /* Get the memory (widthxwidth bytes) */ heightmap = new float[ width ][ width ]; /* base value = 0 */ for ( i = 0; i < width; i++ ) for ( j = 0; j < width; j++ ) heightmap[ i ][ j ] = 0; while ( iterations-- > 0 ) { px = rand0( wmod ); py = rand0( hmod ); pfi = rgen.nextDouble() * 2.0 * Math.PI; cp = Math.cos( pfi ); sp = Math.sin( pfi ); h = ( ( pfi > Math.PI / 2 ) && ( pfi <= Math.PI + Math.PI / 2 ) ) ? -1 : 1; // I'll ignore any horizontal or vertical cuts -- CDB if ( ( sp > -0.01 ) && ( sp < 0.01 ) ) // line essentially horizontal { iterations++; } else if ( ( cp > -0.01 ) && ( cp < 0.01 ) ) // line essentially vertical { iterations++; } else // walk from selected point, setting faultline { double dx; double mx = cp / sp; // dx for unit y for ( y = py + 1, dx = px + mx, x = (int)dx; ( ( y < height ) && ( x >= 0 ) && ( x < width ) ); y++, dx += mx, x = (int)( dx + 0.5 ) ) { heightmap[ x ][ y ] += h; } if ( ( x < 0 ) && ( y < height ) ) for ( ; y < height; y++ ) { heightmap[ 0 ][ y ] += h; } for ( y = py, dx = px, x = px; ( ( y >= 0 ) && ( x >= 0 ) && ( x < width ) ); y--, dx -= mx, x = (int)( dx + 0.5 ) ) { heightmap[ x ][ y ] += h; } if ( ( x < 0 ) && ( y >= 0 ) ) for ( ; y >= 0; y-- ) { heightmap[ 0 ][ y ] += h; } } } for ( y = 0; y < height; y++ ) { h = 0; for ( x = 0; x < width; x++ ) { h += heightmap[ x ][ y ]; heightmap[ x ][ y ] = h; } } //BuildImage(); } public void generateTerrain() { doFaulting( 10000 ); } public Geometry generateGeometry( float startX, float startY, float stepX, float stepY ) { return ( generate3D( startX, startY, stepX, stepY, 0 ) ); } /* public static final void main( String[] args ) throws IOException { Faulting m = new Faulting( 256, 256, 1.0, new Random() ); //System.out.println( m.generateUTF() ); //m.outputAscii(); System.out.println( "done1" ); ImageIO.write( m.generate2D(), "png", new File( "output.png" ) ); } */ }