import java.awt.*; import java.awt.event.*; import java.applet.*; public class IFS extends Applet implements Runnable, MouseListener, MouseMotionListener { //private Vector points = new Vector(); private Image image = null; private Graphics g = null; private float x, y, w, h; private Point start = null; private Point end = null; public void init() { Dimension size = getSize(); image = createImage( size.width, size.height ); g = image.getGraphics(); addMouseListener( this ); addMouseMotionListener( this ); } public synchronized void mousePressed( MouseEvent me ) { start = new Point( me.getX(), me.getY() ); end = new Point( me.getX(), me.getY() ); } public synchronized void mouseReleased( MouseEvent me ) { end = new Point( me.getX(), me.getY() ); if ( start.equals( end ) ) initCoords(); else { Dimension size = getSize(); // on-screen rectangle int x = Math.min( start.x, end.x ); int y = Math.max( start.y, end.y ); int w = Math.abs( start.x - end.x ); int h = Math.abs( start.y - end.y ); // alter so y goes up screen y = size.height - y; float nx = this.x + (this.w*x)/size.width; float ny = this.y + (this.h*y)/size.height; float nw = (this.w*w)/size.width; float nh = (this.h*h)/size.height; changeCoords( nx, ny, nw, nh ); } start = end = null; } public void mouseClicked( MouseEvent me ) {} public synchronized void mouseExited( MouseEvent me ) { start = end = null; } public synchronized void mouseEntered( MouseEvent me ) { start = end = null; } public synchronized void mouseMoved( MouseEvent me ) { start = end = null; } public synchronized void mouseDragged( MouseEvent me ) { end = new Point( me.getX(), me.getY() ); } public synchronized void start() { (new Thread( this )).start(); } private void initCoords() { changeCoords( -5.5f, 0, 11, 11 ); } private synchronized void changeCoords( float x, float y, float w, float h ) { this.x = x; this.y = y; this.w = w; this.h = h; Dimension size = getSize(); g.setColor( Color.white ); g.fillRect( 0, 0, size.width, size.height ); } public void run() { Pt p = new Pt( 0.5f, 0.5f ); Dimension size = getSize(); //g.setColor( new Color( 0, 0, 0, 16 ) ); initCoords(); while ( true ) { synchronized( this ) { g.setColor( Color.black ); for ( int i = 0; i < 1000; i++ ) { int x = (int)(size.width*(p.x-this.x)/this.w); int y = (int)(size.height - size.height*(p.y-this.y)/this.h); g.drawLine( x, y, x, y ); p = apply( p ); } } //System.out.println( p.x + " " + p.y ); repaint(); try { Thread.sleep( 40 ); } catch( Exception e ) {} } } public Dimension getPreferredSize() { return new Dimension( 256, 256 ); } public Pt apply( Pt p, float a, float b, float c, float d, float e, float f ) { float x = p.x, y = p.y; p.x = a*x + b*y + e; p.y = c*x + d*y + f; return p; } public Pt apply( Pt p ) { double r = Math.random(); if ( r < 0.85 ) { return apply( p, 0.85f, 0.04f, -0.04f, 0.85f, 0, 1.6f ); } else if ( r < 0.92 ) { return apply( p, 0.2f, -0.26f, 0.23f, 0.22f, 0, 1.6f ); } else if ( r < 0.99 ) { return apply( p, -0.15f, 0.28f, 0.26f, 0.24f, 0, 0.44f ); } else { return apply( p, 0, 0, 0, 0.16f, 0, 0 ); } } public void update( Graphics g ) { paint( g ); } public synchronized void paint( Graphics g ) { if ( image != null ) { g.drawImage( image, 0, 0, this ); if ( start != null && end != null ) { int x = Math.min( start.x, end.x ); int y = Math.min( start.y, end.y ); int w = Math.abs( start.x - end.x ); int h = Math.abs( start.y - end.y ); g.setColor( Color.black ); g.setXORMode( Color.white ); g.drawRect( x, y, w, h ); } } } public static class Pt { public float x, y; public Pt( float x, float y ) { this.x = x; this.y = y; } } public static void main( String[] args ) { Frame f = new Frame( "IFS" ); f.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent we ) { we.getWindow().dispose(); } public void windowClosed( WindowEvent we ) { System.exit( 0 ); } } ); IFS ifs = new IFS(); f.add( ifs ); f.pack(); f.show(); ifs.init(); ifs.start(); } }