home *** CD-ROM | disk | FTP | other *** search
/ The Best of Windows 95.com 1996 September / WIN95_09962.iso / vrml / glview.zip / Landscape.java < prev    next >
Text File  |  1996-06-12  |  11KB  |  364 lines

  1.  /*
  2.  
  3. Standalone Java program to create a VRML 2.0 fractal height field surface
  4. You need that Java Dev. Kit to compile and run this program.
  5. // 10.06. changed tom VRML 2.0 draft 2 syntax
  6.  
  7.  
  8.  
  9.  Basic algorithm from 
  10.  
  11.     H. Peitgen, D. Saupe 
  12.     "The Science of Fractal Images"
  13.     Springer Verlag,
  14.     Page 100
  15.  
  16.  
  17.  
  18.  Steps to exectue:
  19.      javac Landscape.java
  20.      set CLASSPATH = .;%CLASSPATH%
  21.      java Landscape
  22.      glview Landscape.wrl
  23.  
  24.  
  25. Startet from an applet from 
  26. C. Thornborrow (Silicon Graphics (UK) )
  27. http://www.sgi.com/Fun/free/java/chris-thornborrow/index.html
  28.  
  29.  
  30. hg@berlin.snafu.de
  31. http://www.snafu.de/~hg
  32.  
  33.  
  34. */
  35.  
  36. import java.applet.Applet;
  37. import java.awt.Color;
  38. import java.lang.Math;
  39. import java.util.Random;
  40. import java.io.*;
  41. import java.lang.Integer;
  42.  
  43.  
  44. public class Landscape extends java.applet.Applet implements Runnable 
  45.  
  46. {
  47.     
  48.     int      scape[][];     // height field
  49.     Color    colors[][];    // height field colors
  50.  
  51.     
  52.     // actual amplitude  for level
  53.     double   delta;
  54.     
  55.     // options 
  56.     int      size; // size of landscape = 2^power
  57.     int      power; // size of landscape as 2 power
  58.     boolean  zeroBorder; // start with 0 at outer first level
  59.                          // to have a landscape embedded in water 
  60.     long     seed;      // random seed
  61.     boolean  outputColor; // output a VRML file with colors (makes file much larger)
  62.     
  63.     
  64.     int      red,green;
  65.  
  66.     Color    c;
  67.     Random   rng;
  68.  
  69.     double   sigma,fracdim;
  70.     boolean addition;
  71.  
  72.     
  73.     public void init(){
  74.         //size = 512;   power = 9;      sigma = 90.0;
  75.         //size = 256;   power = 8;        sigma = 64.0;  // will be 1.3 Meg 
  76.         size = 128;   power = 7; sigma = 64.0; // 
  77.         fracdim = 0.85-0.1;
  78.         zeroBorder = true;
  79.         outputColor = true;
  80.         addition = true;
  81.         
  82.         if (zeroBorder) sigma*=2;
  83.  
  84.         seed = 1;
  85.  
  86.         if (seed != 0) rng = new Random(seed);
  87.         else rng = new Random(); // seed based on time
  88.  
  89.         scape = new int[size+1][size+1];
  90.         
  91.         colors = new Color[size+1][size+1];
  92.  
  93.         int i,j;
  94.  
  95.         for (i=0; i<size; i++)
  96.             for (j=0; j<size; j++) 
  97.                 scape[i][j] = 0;        
  98.         
  99.     
  100.     }
  101.     
  102.     
  103.     
  104.  
  105.     
  106.     
  107.     // application entry point
  108.     public static void main(String argv[]){
  109.  
  110.  
  111.         Landscape l;
  112.         l = new Landscape();
  113.  
  114.         l.init();
  115.         l.compute();
  116.         try {
  117.             l.save();
  118.         } catch (java.io.IOException e) { }
  119.  
  120.     }
  121.  
  122.  
  123.     public void run(){
  124.         compute();
  125.     }
  126.       
  127.     // MIdPointFM2D
  128.     // H. Peitgen, D. Saupe The Science of Fractal Images
  129.     // Springer Verlag Page 100
  130.  
  131.     public void compute(){
  132.       
  133.       int i,j,scale;
  134.       int step,hstep;
  135.       delta = sigma;
  136.  
  137.       step = size;
  138.       hstep = step/2;
  139.  
  140.       if (!zeroBorder) {
  141.         // set the four corner points
  142.         scape[0][0]      = (int) ((rng.nextGaussian())*delta);
  143.         scape[0][size]   =(int) ((rng.nextGaussian())*delta);
  144.         scape[size][0]   =(int) ((rng.nextGaussian())*delta);
  145.         scape[size][size] =(int) ((rng.nextGaussian())*delta);
  146.       }
  147.  
  148.        System.out.print("##computing Size = ");
  149.        System.out.print(size); 
  150.        System.out.print(" Fracdim= ");
  151.        System.out.print(fracdim); 
  152.        System.out.println(" ...");
  153.  
  154.         
  155.         // create the landscape
  156.         for (scale=1; scale<=power; scale++) {
  157.         
  158.             delta *= Math.pow (0.5, 0.5*fracdim);
  159.         
  160.             // set the internal point in square
  161.             for (i=hstep; i<=size-hstep; i+=step)
  162.                 for (j=hstep; j<=size-hstep; j+=step)
  163.                     this.set4point (i,j, scale, 
  164.                                     scape[i+hstep][j+hstep],
  165.                                     scape[i+hstep][j-hstep],
  166.                                     scape[i-hstep][j+hstep],
  167.                                     scape[i-hstep][j-hstep]);
  168.             
  169.             // displace other points
  170.             if (addition)
  171.                 for (i=0; i<=size; i+=step)
  172.                     for (j=0; j<=size; j+=step)
  173.                         scape[i][j] +=(int) ((rng.nextGaussian())*delta);
  174.  
  175.  
  176.                                     
  177.             delta *= Math.pow (0.5, 0.5*fracdim);
  178.                                     
  179.             // set boundary points
  180.             for (i=hstep; i<=size-hstep; i+=step) {
  181.                 this.set3point (i, 0, scale-1,scape[i+hstep][0],
  182.                                 scape[i-hstep][0], scape[i][hstep]);
  183.                 this.set3point (i,size,scale -1, scape[i+hstep][size],
  184.                                 scape[i-hstep][size], scape[i][size-hstep]);
  185.                 this.set3point (0,i, scale -1, scape[0][i+hstep],
  186.                                 scape[0][i-hstep],scape[hstep][i]);
  187.                 this.set3point (size,i, scale-1, scape[size][i+hstep],
  188.                                 scape[size][i-hstep],scape[size-hstep][i]);
  189.             }
  190.             
  191.             // set interior grid points
  192.             for (i=hstep; i<=size-hstep; i+=step)
  193.                 for (j=step; j<=size-hstep; j+=step)
  194.                     this.set4point (i,j,scale-1, 
  195.                                     scape[i][j+hstep], scape[i][j-hstep],
  196.                                     scape[i+hstep][j], scape[i-hstep][j]);
  197.                                     
  198.             for (i=step; i<=size-hstep; i+=step)
  199.                 for (j=hstep; j<=size-hstep; j+=step)
  200.                    this.set4point (i,j, scale-1,
  201.                                    scape[i][j+hstep], scape[i][j-hstep],
  202.                                    scape[i+hstep][j],scape[i-hstep][j] ); 
  203.  
  204.             // displace other points
  205.             if (addition) {
  206.                 for (i=0; i<=size; i+=step)
  207.                     for (j=0; j<=size; j+=step)
  208.                         scape[i][j] +=(int) ((rng.nextGaussian())*delta);
  209.  
  210.                 for (i=hstep; i<=size-hstep; i+=step)
  211.                     for (j=hstep; j<=size-hstep; j+=step)
  212.                         scape[i][j] +=(int) ((rng.nextGaussian())*delta);
  213.  
  214.             }
  215.  
  216.             if (zeroBorder) 
  217.                 for (i=0; i<=size; i+=step)
  218.                 {
  219.                     scape[i][0]=0;
  220.                     scape[i][size]=0;
  221.                     scape[0][i]=0;
  222.                     scape[size][i]=0;
  223.                 }
  224.  
  225.                             
  226.             // change the size of the grid we are working on
  227.             step /=2;
  228.             hstep /=2;
  229.         }
  230.  
  231.  
  232.         System.out.println("computing colors ..");
  233.         
  234.          for (i=0; i<=size; i++) 
  235.               for (j=size; j>=0; j--) {
  236.                 
  237.  
  238.                     computeColor(i,j,scape[i][j]);
  239.  
  240.                     if (scape[i][j] < 0) scape[i][j] = (int) (scape[i][j]*0.1);
  241.  
  242.                }
  243.         
  244.         System.out.println("computing done ..");
  245.  
  246.  
  247.  
  248.                     
  249.     }
  250.  
  251.     private void set4point (int i, int j, int s, int a, int b, int c, int d) {
  252.         
  253.         scape[i][j] =   (a + b +c +d )/4;
  254.         scape[i][j] +=  (int)(rng.nextGaussian() * delta);
  255.     }
  256.     
  257.     private void set3point (int i, int j, int s, int a, int b, int c) {
  258.     
  259.         scape[i][j] = (a + b + c )/3;
  260.         scape[i][j] +=  (int)(rng.nextGaussian() * delta);
  261.     }
  262.  
  263.  
  264.     // save Heighfield as VRML file 
  265.     public void save()
  266.             throws  java.io.IOException
  267.     {
  268.             FileOutputStream outFile;
  269.             PrintStream data;
  270.             int i,j;
  271.  
  272.             System.out.println("saving ...");
  273.             
  274.             // first open the file
  275.             
  276.             outFile = new FileOutputStream("Landscape.wrl");
  277.             // create a data stream
  278.             data   = new PrintStream( outFile );
  279.  
  280.             data.println("#VRML V1.0 ascii");
  281.             data.println("#GLView heightfield demo created by Landscape.java V 0");
  282.             data.println("Separator {");
  283.  
  284.             double f = 1.0/ 255.0;
  285.             
  286.             // ********* write per vertex color 
  287.             if (outputColor) {
  288.  
  289.             data.println("Material {");
  290.             data.println("diffuseColor [ "); 
  291.             
  292.  
  293.             for (i=0; i<=size; i++) {
  294.                 for (j=size; j>=0; j--) {
  295.                     Color c= colors[i][j];
  296.                     data.print(c.getRed() *f); data.print(" ");
  297.                     data.print(c.getGreen() *f); data.print(" ");
  298.                     data.print(c.getBlue() *f); data.print(" ");
  299.                     data.print(",");
  300.                 }
  301.                 data.println();
  302.             }
  303.             
  304.             data.println("]"); 
  305.             data.println("}");
  306.  
  307.             data.println("MaterialBinding {value PER_VERTEX }");
  308.             }
  309.  
  310.             // VRML convention Y is Z
  311.             f = 0.15;
  312.             //data.println("Scale { scaleFactor 1.0 "); data.print(f); data.println(" 1.0}"); 
  313.  
  314.  
  315.             // ********** output the grid
  316.             data.println("ElevationGrid {");
  317.                 data.print("xDimension "); data.print(size+1); data.println();
  318.                 data.print("zDimension "); data.print(size+1); data.println();
  319.                 data.print("#fracdim "); data.print(fracdim); data.println();
  320.                 data.println("height [ "); 
  321.             
  322.             for (i=0; i<=size; i++) {
  323.                 for (j=size; j>=0; j--) {
  324.                     data.print(scape[i][j]*f);
  325.                     data.print(",");
  326.                 }
  327.                 data.println();
  328.             }
  329.             data.println("]"); 
  330.             data.println("}");
  331.             
  332.             data.println("}");
  333.  
  334.             outFile.close();
  335.     }
  336.     
  337.     
  338.     // compute a color for grid point i,j based on h
  339.     private void computeColor (int i, int j, int h) {
  340.     
  341.         if (j==0) 
  342.             c = (Color.black);
  343.         else if (h<=0) 
  344.             c = (new Color (0,0,200+h));
  345.         else if (h<5)
  346.             c = (new Color (218,195,112));
  347.         else if (h<110) {
  348.             red = 0;
  349.             green = 50+h/2;
  350.             if (h>30) red = h-10;
  351.             c = (new Color(red,green,0));
  352.         }
  353.         else if (h>=110) {
  354.             red = h+100;
  355.             if (red>255) red = 255;
  356.             c = (new Color(red-10,red-10,red));
  357.         }
  358.             
  359.         colors[i][j]= c;
  360.  
  361.     }
  362.          
  363. }
  364.