import java.applet.*;
import java.util.*;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.image.ColorModel;
import java.awt.image.MemoryImageSource;
/* portions of this code were adapted from the DitherTest applet */
/* fractal faulting codes adapted from Usenet and published references
* - Basic faulting on a plane adapted from 'faultmap' by Aurel Balmosan
* (aurel@xylo.owl.de) -- some significant changes made
*/
public class FaultingApplet extends Applet implements Runnable
{
/************************************************************
* Boilerplate methods to handle painting and initialization
************************************************************/
private int width = 256;
private int height = 256;
private double scalefactor = 1.0;
private int[][] heightfield;
private Random rgen;
private Image img;
private boolean started;
public boolean handleEvent(Event evt)
{
if (evt.id == Event.WINDOW_DESTROY) System.exit(0);
return super.handleEvent(evt);
}
public boolean action( Event evt, Object arg)
{
return true;
}
String calcString = "Calculating...";
public void paint(Graphics g)
{
int w = size().width;
int h = size().height;
if (img == null) {
super.paint(g);
g.setColor(Color.black);
FontMetrics fm = g.getFontMetrics();
int x = (w - fm.stringWidth(calcString))/2;
int y = h/2;
g.drawString(calcString, x, y);
} else {
g.drawImage(img, 0, 0, w, h, this);
}
}
public void init()
{
int w = Integer.parseInt(getParameter("width"));
if (w<=0 || w>256) w=width;
width=w;
height=w;
scalefactor = 256/width;
rgen = new Random();
started = false;
start();
}
synchronized void BuildImage()
{
/* build the image for display -- greyscale */
int pixels[];
int i, j, a, index = 0, min, max;
// calculate range of values in heightfield
min = heightfield[0][0];
max = heightfield[0][0];
for (i=0;i max) max = heightfield[i][j];
}
}
scalefactor = 255.0 / (max-min);
pixels = new int[width * height];
for (i=0;i255) a=255;
/*if (a>255) a=255;*/
pixels[index++] = (255 << 24) | (a << 16) | (a << 8) | a;
}
}
img = createImage(new MemoryImageSource(width, height,
ColorModel.getRGBdefault(),
pixels, 0, width));
repaint();
}
/************************************************************
* Thread methods to handle processing in the background
************************************************************/
Thread kicker;
public /*synchronized*/ void start() {
if (!started) {
started = true;
kicker = new Thread(this);
kicker.start();
} else if ((kicker != null) && (kicker.isAlive()))
kicker.resume();
}
public /*synchronized*/ void stop() {
try {
if ((kicker != null) && (kicker.isAlive())) {
kicker.suspend();
}
} catch (Exception e) {
}
}
public void restart() {
try {
if (kicker != null) {
kicker.stop();
}
} catch (Exception e) {
}
kicker = null;
img = null;
started = false;
start();
}
public void run()
{
Thread me = Thread.currentThread();
me.setPriority(4);
DoFaulting(10000);
}
/************************************************************
* 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, tx, ty, wmod=width, hmod=width;
/* Get the memory (widthxwidth bytes) */
heightfield = new int[width][width];
/* base value = 0 */
for (i=0;i0)
{
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=0 && x=0 && x>=0 && x=0))
for (;y>=0;y--)
{
heightfield[0][y]+=h;
}
}
}
for (y=0; y