Mandel
Java Source:
import java.applet.*;
import java.awt.*;
import java.awt.image.*;
public class Mandel extends Applet implements Runnable{
int[] pixel;
int[] color;
Thread mainthread;
Graphics bbg;
Image bb;
Image fractimg;
// Configuration:
// ----------------------------------------
int nw = 400; // Image width
int nh = nw; // Image height
// !! Image should be quadratic!
int max_i = 300; // max iteration count
int n_bailout = 4; // bailout value
int colMult = 5; // palette index multiplication factor
double sx = -2; // start X
double sy = -2; // start Y
double ex = 2; // end X
double ey = 2; // end Y
int pal_len = 2000; // palette size
int col_period = 15; // palette color fade 'period'
// Other vars:
int zoom_sx = 0;
int zoom_sy = 0;
int zoom_ex = 0;
int zoom_ey = 0;
boolean mdown = false;
public void init(){
// Init stuff:
pixel = new int[nw*nh];
bb = createImage(nw,nh);
fractimg = createImage(nw,nh);
bbg = bb.getGraphics();
initPal(); // initialize palette
calcMandel();
setBackground(Color.black);
if(mainthread!=null){
mainthread = new Thread(this);
mainthread.start();
}
}
public void stop(){
if(mainthread!=null){
mainthread.stop();
mainthread = null;
}
}
public void destroy(){
bb = null;
bbg = null;
fractimg = null;
}
public void run(){
while(true){
repaint();
try{
mainthread.sleep(30);
}catch(InterruptedException e){}
}
}
public boolean mouseDown(Event e, int x, int y){
zoom_sx = x;
zoom_sy = y;
mdown = true;
return true;
}
public boolean mouseUp(Event e, int x, int y){
int tmp = 0;
double midx = 0;
double midy = 0;
double dx = 0;
if (mdown){
// Zoom in!
mdown = false;
zoom_ex = x;
zoom_ey = y;
if((zoom_sx != zoom_ex)&&(zoom_sy != zoom_ey)){
if(zoom_sx > zoom_ex){
tmp = zoom_sx;
zoom_sx = zoom_ex;
zoom_ex = tmp;
}
if(zoom_sy > zoom_ey){
tmp = zoom_sy;
zoom_sy = zoom_ey;
zoom_ey = tmp;
}
midx = sx+((((zoom_sx+zoom_ex)/2)*(ex-sx))/(double)nw);
midy = sy+((((zoom_sy+zoom_ey)/2)*(ey-sy))/(double)nh);
if ((zoom_ex-zoom_sx)>(zoom_ey-zoom_sy)){
dx = ((zoom_ex-zoom_sx)*(ex-sx))/(double)nw;
}
else{
dx = ((zoom_ey-zoom_sy)*(ey-sy))/(double)nh;
}
sx = midx-(dx/2);
sy = midy-(dx/2);
ex = midx+(dx/2);
ey = midy+(dx/2);
// Recalculate & show:
calcMandel();
repaint();
}
}
return true;
}
public boolean mouseDrag(Event e, int x, int y){
if(mdown){
zoom_ex = x;
zoom_ey = y;
repaint();
}
return true;
}
public void update(Graphics g){
paint(g);
}
public void paint(Graphics g){
int rect_sx, rect_ex, rect_sy, rect_ey;
bbg.drawImage(fractimg,0,0,null);
// Show zoom rectangle:
if(mdown){
if(zoom_sx < zoom_ex){
rect_sx = zoom_sx;
rect_ex = zoom_ex;
}
else{
rect_sx = zoom_ex;
rect_ex = zoom_sx;
}
if(zoom_sy < zoom_ey){
rect_sy = zoom_sy;
rect_ey = zoom_ey;
}
else{
rect_sy = zoom_ey;
rect_ey = zoom_sy;
}
bbg.setColor(Color.black);
bbg.drawRect(rect_sx,rect_sy,rect_ex-rect_sx,rect_ey-rect_sy);
}
g.drawImage(bb,0,0,null);
}
public void calcMandel(){
double nx=0;
double ny=0;
double x0=0;
double x1=0;
double y0=0;
double y1=0;
double lower=0;
double upper=0;
double middle=0;
double fade_factor=0;
int pixx, pixy, i, ncol;
boolean bailout = false;
double col1[] = new double[3];
double col2[] = new double[3];
int r, g, b;
// Loop through entire pixel int array:
for(pixy=0;pixy<nh;pixy++){
for(pixx=0;pixx<nw;pixx++){
nx = sx + (((ex-sx)*(double)pixx)/(double)nw);
ny = sy + (((ey-sy)*(double)pixy)/(double)nh);
i = 0;
x0 = 0;
y0 = 0;
bailout = false;
// Loop until bailout value is reached or the iteration count exceeds
// the maximum iteration count specified:
while(i < max_i){
x1 = x0*x0 - y0*y0 + nx;
y1 = 2*x0*y0 + ny;
if((x1*x1+y1*y1)>n_bailout){
// Bailout.
bailout = true;
lower = x0*x0+y0*y0;
middle = n_bailout-lower;
upper = x1*x1+y1*y1;
break;
}
x0 = x1;
y0 = y1;
i++;
}
if (bailout){
// Compute color:
ncol = (i*colMult) % pal_len;
col1[0] = (double)(color[ncol]>>16 & 255);
col1[1] = (double)(color[ncol]>>8 & 255);
col1[2] = (double)(color[ncol] & 255);
col2[0] = (double)(color[ncol+colMult]>>16 & 255);
col2[1] = (double)(color[ncol+colMult]>>8 & 255);
col2[2] = (double)(color[ncol+colMult] & 255);
fade_factor = upper-lower;
r = (int)(col1[0] + (((col2[0]-col1[0])*middle)/fade_factor));
g = (int)(col1[1] + (((col2[1]-col1[1])*middle)/fade_factor));
b = (int)(col1[2] + (((col2[2]-col1[2])*middle)/fade_factor));
pixel[(pixy*nw)+pixx] = (255<<24)|(r<<16)|(g<<8)|(b);
}
else{
// Use white color:
pixel[(pixy*nw)+pixx] = (255<<24)|(16777215);
}
}
}
fractimg = createImage(new MemoryImageSource(nw,nh,pixel,0,nw));
}
public void initPal(){
int b1, b2, b3;
int ppos = 0; // The color fade 'period position'
int col1[] = new int[3];
int col2[] = new int[3];
color = new int[pal_len];
col1[0] = (int)(Math.random()*256);
col1[1] = (int)(Math.random()*256);
col1[2] = (int)(Math.random()*256);
col2[0] = (int)(Math.random()*256);
col2[1] = (int)(Math.random()*256);
col2[2] = (int)(Math.random()*256);
for(int i=0;i<pal_len;i++){
b1 = col1[0] + (((col2[0]-col1[0])*ppos)/col_period);
b2 = col1[1] + (((col2[1]-col1[1])*ppos)/col_period);
b3 = col1[2] + (((col2[2]-col1[2])*ppos)/col_period);
color[i] = (255<<24)|(b1<<16)|(b2<<8)|(b3);
if(ppos==col_period){
ppos=0;
col1[0] = col2[0];
col1[1] = col2[1];
col1[2] = col2[2];
col2[0] = (int)(Math.random()*256);
col2[1] = (int)(Math.random()*256);
col2[2] = (int)(Math.random()*256);
}
ppos++;
}
}
}
New on the Java Boutique:
New Review:
Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling
API boasts simplicity, ease-of-integration, a well-rounded feature
set, and it's free!
New Applet:
Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA
sequences into three useful formats.
Elsewhere on internet.com:
WebDeveloper Java
Lots of Java information on webdeveloper.com
WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.
ScriptSearch Java
Hundreds of free Java code files to download.
jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.
|