invbuddha.java
By hansl - July 27th, 2008
/* * Invbuddha applet * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * * Hans Liss <Hans@Liss.pp.se> * http://hans.liss.pp.se * */ import java.awt.*; import java.awt.image.*; import java.awt.event.*; import java.applet.*; import java.io.*; public class invbuddha extends Applet implements Runnable,MouseListener,MouseMotionListener { private int tmpBuffer_r[]; private int tmpBuffer_g[]; private int tmpBuffer_b[]; private int hist_r[], hist_g[], hist_b[]; private int vmax_r, vmax_g, vmax_b; private Image ofsImage; private Graphics ofsG; private volatile Thread paintThread = null; private int width; private int height; private int wh; private final int MAXITER=5000; private double gc_x; private double gc_y; private double gd_x; private double gd_y; private double gv_x; private double gv_y; private int select_x0; private int select_y0; private int select_x1; private int select_y1; private int last_x1; private int last_y1; public static void main (String args[]) { System.out.println ("Run this program in a browser or in AppletViewer"); } public void init() { gc_x=-0.6134; gc_y=0; gd_x=4; gd_y=3; select_x0=0; select_y0=0; select_x1=0; select_y1=0; width = getSize().height; height = getSize().width; int tmpw=(int)((double)height * gd_x / gd_y); int tmph=(int)((double)width * gd_y / gd_x); if (tmpw < width) width=tmpw; else if (tmph < height) height=tmph; gv_x=gd_x/(double)width; gv_y=gd_y/(double)height; wh = width * height; tmpBuffer_r = new int[wh]; tmpBuffer_g = new int[wh]; tmpBuffer_b = new int[wh]; ofsImage = createImage (height, width); ofsG = ofsImage.getGraphics(); for (int y = 0 ; y < height; y++) { for (int x = 0 ; x < width; x++) { tmpBuffer_r[x + y*width] = 0; tmpBuffer_g[x + y*width] = 0; tmpBuffer_b[x + y*width] = 0; } } vmax_r=vmax_g=vmax_b = 0; hist_r=hist_g=hist_b=null; addMouseMotionListener( this ); addMouseListener( this ); } public void start() { if (paintThread == null) { paintThread = new Thread(this, "Paint"); paintThread.start(); } } public void mouseClicked(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mousePressed(MouseEvent e) { int x=e.getY(); int y=e.getX(); select_x0=x; select_y0=y; select_x1=x; select_y1=y; last_x1=x; last_y1=y; e.consume(); } public void mouseMoved(MouseEvent e) { } public void mouseDragged(MouseEvent e) { int x=e.getY(); int y=e.getX(); Graphics g = getGraphics(); if (x != select_x1 || y != select_y1) { int x0 = Math.min(select_x0, select_x1); int y0 = Math.min(select_y0, select_y1); int dx=Math.abs(select_x1 - select_x0); int dy=Math.abs(select_y1 - select_y0); g.setXORMode(getBackground()); if (dx>0 || dy>0) g.drawRect(y0, x0, dy, dx); select_x1=x; select_y1=y; dx=Math.abs(select_x1 - select_x0); dy=Math.abs(select_y1 - select_y0); if (dx < dy * width / height) { dx = dy * width/height; if (select_x1 < select_x0) select_x1 = select_x0 - dx; else select_x1=select_x0 + dx; } else if (dy < dx * height / width) { dy = dx * height/width; if (select_y1 < select_y0) select_y1 = select_y0 - dy; else select_y1=select_y0 + dy; } x0 = Math.min(select_x0, select_x1); y0 = Math.min(select_y0, select_y1); if (dx>0 || dy>0) g.drawRect(y0, x0, dy, dx); } e.consume(); } public void mouseReleased(MouseEvent e) { int x=e.getY(); int y=e.getX(); select_x1=x; select_y1=y; int dx=Math.abs(select_x1 - select_x0); int dy=Math.abs(select_y1 - select_y0); if (e.isMetaDown()) { gd_x *= 2; gd_y *= 2; } else if (dx == 0 && dy == 0) { gc_x += gd_x * ((double)(select_x0 - width/2) / (double)width); gc_y += gd_y * ((double)((height-1-select_y0) - height/2) / (double)height); gd_x /= 2; gd_y /= 2; } else { if (dx < (dy * width) / height) { dx = (dy * width) / height; if (select_x1 < select_x0) select_x1 = select_x0 - dx; else select_x1=select_x0 + dx; } else if (dy < (dx * height) / width) { dy = (dx * height) / width; if (select_y1 < select_y0) select_y1 = select_y0 - dy; else select_y1=select_y0 + dy; } double x0 = Math.min(select_x0, select_x1); double y0 = Math.max(select_y0, select_y1); gc_x += gd_x * ((double)(x0 + dx/2 - width/2) / (double)width); gc_y += gd_y * ((double)((height-1-y0) + dy/2 - height/2) / (double)height); gd_x *= (double)dx/(double)width; gd_y *= (double)dy/(double)height; } gv_x=gd_x/(double)width; gv_y=gd_y/(double)height; select_x0=0; select_y0=0; select_x1=0; select_y1=0; for (int i = 0 ; i < wh; i++) { tmpBuffer_r[i] = 0; tmpBuffer_g[i] = 0; tmpBuffer_b[i] = 0; } vmax_r=vmax_g=vmax_b = 0; hist_r=hist_g=hist_b=null; paintThread = new Thread(this, "Paint"); paintThread.start(); e.consume(); } public void paint(Graphics g) { super.paint(g); int hival_r; int hival_g; int hival_b; int i, j; // synchronized(this) { for (i=0; i<width*height; i++) { double col_r=0, col_g=0, col_b=0; for (hival_r = vmax_r; hival_r > 0 && hist_r[hival_r]<=1; hival_r--); for (hival_g = vmax_g; hival_g > 0 && hist_g[hival_g]<=1; hival_g--); for (hival_b = vmax_b; hival_b > 0 && hist_b[hival_b]<=1; hival_b--); if (hival_r > 0) col_r=(double)(tmpBuffer_r[i])/(double)hival_r; if (hival_g > 0) col_g=(double)(tmpBuffer_g[i])/(double)hival_g; if (hival_b > 0) col_b=(double)(tmpBuffer_b[i])/(double)hival_b; double v1 = Math.floor(col_r); col_r -= v1; v1 = Math.floor(col_g); col_g -= v1; v1 = Math.floor(col_b); col_b -= v1; ofsG.setColor(new Color((int)(255*col_r), (int)(255*col_g), (int)(255*col_b))); ofsG.drawLine((int)(i / width), i % width, (int)(i / width), i % width); } if (select_x1 != select_x0 && select_y1 != select_y0) { int x0 = Math.min(select_x0, select_x1); int x1 = Math.max(select_x0, select_x1); int y0 = Math.min(select_y0, select_y1); int y1 = Math.max(select_y0, select_y1); int dx=x1-x0; int dy=y1-y0; ofsG.drawRect(y0, x0, dy, dx); } // } g.drawImage( ofsImage, 0, 0, this); } boolean mandel(double cx, double cy) { int i=MAXITER, xpos, ypos; boolean didchange=false; double zx=cx, zy=cy, y, zx2=cx*cx, zy2=cy*cy; while((i > 0) && (zx2 + zy2 < 4.0)) { zy=2*zx*zy + cy; zx=zx2-zy2 + cx; zx2=zx*zx; zy2=zy*zy; i--; } int n=i; i=MAXITER; zx=cx; zy=cy; zx2=cx*cx; zy2=cy*cy; while((i > 0) && (zx2 + zy2 < 4.0)) { zy=2*zx*zy + cy; zx=zx2-zy2 + cx; zx2=zx*zx; zy2=zy*zy; i--; xpos=(int)((zx - (gc_x - gd_x/2))/gv_x); ypos=(int)((zy - (gc_y - gd_y/2))/gv_x); if (xpos >= 0 && xpos < width && ypos >= 1 && ypos < height) { didchange=true; int arpos=xpos + width * (height - 1 - ypos); if (n==0) { tmpBuffer_r[arpos]++; if (tmpBuffer_r[arpos] > vmax_r) { int hist2[]=new int[tmpBuffer_r[arpos]+1]; if (vmax_r > 0) System.arraycopy(hist_r, 0, hist2, 0, vmax_r+1); hist_r=hist2; for (int j=vmax_r+1; j<=tmpBuffer_r[arpos]; j++) hist_r[j]=0; vmax_r=tmpBuffer_r[arpos]; } hist_r[tmpBuffer_r[arpos]]++; } else { tmpBuffer_b[arpos]++; if (tmpBuffer_b[arpos] > vmax_b) { int hist2[]=new int[tmpBuffer_b[arpos]+1]; if (vmax_b > 0) System.arraycopy(hist_b, 0, hist2, 0, vmax_b+1); hist_b=hist2; for (int j=vmax_b+1; j<=tmpBuffer_b[arpos]; j++) hist_b[j]=0; vmax_b=tmpBuffer_b[arpos]; } hist_b[tmpBuffer_b[arpos]]++; } } } /* if (n==0) { xpos=(int)((cx - (gc_x - gd_x/2))/gv_x); ypos=(int)((cy - (gc_y - gd_y/2))/gv_x); if (xpos >= 0 && xpos < width && ypos >= 1 && ypos < height) { didchange=true; int arpos=xpos + width * (height - 1 - ypos); tmpBuffer_r[arpos]++; if (tmpBuffer_r[arpos] > vmax_r) vmax_r=tmpBuffer_r[arpos]; } }*/ return didchange; } public void run() { Thread myThread = Thread.currentThread(); int n=10; while (true) { if (paintThread != myThread) return; double cx=Math.random()*4-2; double cy=Math.random()*4-2; if (mandel(cx, cy)) { if (n-- == 0) { repaint(); n=10; } } } } public void stop() { paintThread = null; } public void update ( Graphics g ){ paint(g); } }


Recent comments
1 year 4 weeks ago
1 year 31 weeks ago
1 year 34 weeks ago
1 year 39 weeks ago
1 year 39 weeks ago
2 years 2 weeks ago
2 years 13 weeks ago
2 years 13 weeks ago
2 years 13 weeks ago
2 years 14 weeks ago