package COM.furryandfrisky.fractal;

import java.applet.*;
import java.awt.*;
import java.awt.image.*;

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
class string_table
{
    // do not make these 'final'

    public static String title        = "f(x) = rx(1 - x)";
    public static String Ready        = "Ready";
    public static String Resolution   = "Resolution:";
    public static String Reset        = "Reset";
    public static String percent_sign = "%";
}


//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
class chaos_application extends Frame
{
    //------------------------------------------------------------------------
    public chaos_application()
    {
        super( string_table.title );

        the_applet.init();
        add( "Center", the_applet );
        pack();
        show();
        the_applet.start();
    }

    //------------------------------------------------------------------------
    public boolean handleEvent( Event evt )
    {
        return the_applet.handleEvent( evt );
    }

    //------------------------------------------------------------------------
    private ChaoticEquation  the_applet = new ChaoticEquation();
}


//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
public class ChaoticEquation extends Applet
{
    //------------------------------------------------------------------------
    public static void main( String[] args )
    {
        // if started from java, create frame for applet

        new chaos_application();
    }

    //------------------------------------------------------------------------
    public boolean handleEvent( Event evt )
    {
        if( evt.id == Event.WINDOW_DESTROY )
            System.exit( 0 );

        if( (evt.id == Event.ACTION_EVENT) && (evt.arg == string_table.Reset) )
        {
            the_graph.go( 1.0, 0.0, 3.01, 1.01 );
            return true;
        }

        return super.handleEvent( evt );
    }

    //------------------------------------------------------------------------
    private static boolean is102()
    {
        // is the java version 1.0.2?
        
        return "1.02".equals( System.getProperty( "java.version" ))
           || "1.0.2".equals( System.getProperty( "java.version" ));
    }

    //------------------------------------------------------------------------
    public void init()
    {
        Button    reset      = new Button( string_table.Reset );

        Label     status     = is102()
            ? new Label( "___________________", Label.LEFT )
            : new big_label();
        TextField resolution = new TextField( 4 );

        setLayout( new BorderLayout() );

        Panel control_panel = new Panel();
        control_panel.setLayout( new FlowLayout( FlowLayout.CENTER, 15, 15 ));

        control_panel.add( status );
        control_panel.add( new Label( string_table.Resolution ) );
        control_panel.add( resolution );
        control_panel.add( reset );
        add( "South", control_panel );

        the_graph = new screen_graph( status, resolution );
        add( "Center", the_graph );
    }

    //------------------------------------------------------------------------
    public void start()
    {
        the_graph.go( 1.0, 0.0, 3.01, 1.01 );
    }

    //------------------------------------------------------------------------
    private screen_graph  the_graph = null;
}


//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
class big_label extends Label
{
    //------------------------------------------------------------------------
    public Dimension getPreferredSize()
    {
        // set width to half the width of the container
        return new Dimension(
            getParent().getSize().width / 2,
            super.getPreferredSize().height );
    }
}

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
class screen_graph extends Canvas implements Runnable
{
    //------------------------------------------------------------------------
    public screen_graph( Label status_label, TextField resolution_edit )
    {
        position   = status_label;
        resolution = resolution_edit;
        resolution.setText( "100" );
    }

    //------------------------------------------------------------------------
    public void go( double leftmost, double bottommost, double wide,
        double high )
    {
        if( state == CALCULATING )
            calculating_thread.stop();

        left    = leftmost;
        bottom  = bottommost;
        width   = wide;
        height  = high;

        int res = 100;

        try
        {
            res = Integer.parseInt( resolution.getText() );
            if( res > 100 )
                res = 100;
            if( res < 1 )
                res = 1;
        }
        catch( NumberFormatException e ) {}

        resolution.setText( Integer.toString( res ) );
        width_in_pixels  = size().width  * res / 100; 
        height_in_pixels = size().height * res / 100;

        calculating_thread = new Thread( this );
        calculating_thread.start();
    }

    //------------------------------------------------------------------------
    public void run()
    {
        calculate_points();
        position.setText( string_table.Ready );
        repaint();
    }

    //------------------------------------------------------------------------
    public Dimension preferredSize()
    {
        return new Dimension( 600, 400 ); 
    }

    //------------------------------------------------------------------------
    public String toString()
    {
        String str = "screen_graph\n";
        str += "left:    " + left + "\n";
        str += "bottom:  " + bottom + "\n";
        str += "width:   " + width + "\n";
        str += "height:  " + height + "\n";
        str += "width_in_pixels:  " + width_in_pixels + "\n";
        str += "height_in_pixels: " + height_in_pixels + "\n";

        return str;
    }

    //------------------------------------------------------------------------
    public void update( Graphics g )
    {
        paint( g );
    }

    //------------------------------------------------------------------------
    public void paint( Graphics g )
    {
        if( state == READY )
            g.drawImage( image, 0, 0, size().width, size().height, this );
    }

    //------------------------------------------------------------------------
    public boolean mouseMove( Event evt, int x, int y )
    {
        if( state == READY )
            draw_point_as_string( new Point( x, y ) );

        return true;
    }

    //------------------------------------------------------------------------
    public boolean mouseDown( Event evt, int x, int y )
    {
        if( state == READY )
        {
            selected_point = clip_point( x, y );
            previous_point = selected_point;
            dragging = true;
        }
        return true;
    }

    //------------------------------------------------------------------------
    public boolean mouseUp( Event evt, int x, int y )
    {
        if( dragging )
        {
            dragging = false;
            Point point = clip_point( x, y );

            if( (point.x > selected_point.x) && (point.y > selected_point.y) )
                set_new_bounds( selected_point, point );
        }
        return true;
    }

    //------------------------------------------------------------------------
    public boolean mouseDrag( Event evt, int x, int y )
    {
        if( dragging )
        {
            Point point = clip_point( x, y );

            draw_point_as_string( point );
            Graphics g = getGraphics();
            g.setXORMode( Color.white );
            g.setColor( Color.black );

            if( selected_point != previous_point )
                g.drawRect( selected_point.x, selected_point.y,
                    previous_point.x - selected_point.x,
                    previous_point.y - selected_point.y );

            if( (point.x > selected_point.x) && (point.y > selected_point.y) )
            {
                g.drawRect( selected_point.x, selected_point.y,
                    point.x - selected_point.x, point.y - selected_point.y );
                previous_point = point;
            }
            else
                previous_point = selected_point;

            g.dispose();
        }
        return true;
    }

    //------------------------------------------------------------------------
    protected Point clip_point( int x, int y )
    {
        if( x > size().width )
            x = size().width;

        if( y > size().height )
            y = size().height;

        return new Point( x, y );
    }

    //------------------------------------------------------------------------
    protected void draw_point_as_string( Point point )
    {
        double delta_x    = width  / size().width;
        double delta_y    = height / size().height;
        double leftmost   = point.x * delta_x + left;
        double bottommost = (size().height - point.y) * delta_y + bottom;
        String str = "(" + leftmost + ", " + bottommost + ")";
        position.setText( str );
    }

    //------------------------------------------------------------------------
    protected synchronized void calculate_points()
    {
        state = CALCULATING;
        int     start_at_run    = 1000;
        int     scatter_amount  = height_in_pixels;
        double  init_y          = 0.1;
        int     max_trys        = 500;

        double  delta_x         = width  / width_in_pixels;
        double  delta_y         = height / height_in_pixels;

        int[]   graph           = new int[width_in_pixels * height_in_pixels];

        for( int i = 0; i < graph.length; i++ )
            graph[i] = 0xFFFFFFFF;

        for( double x = left; x < left + width; x += delta_x )
        {
            int discrete_x = (int) ((x - left) / delta_x);

            int percent_complete = (int) (discrete_x * 100 / width_in_pixels);
            position.setText( percent_complete + string_table.percent_sign );

            if( discrete_x < 0 )
                discrete_x = 0;
            if( discrete_x >= width_in_pixels )
                discrete_x = width_in_pixels - 1;

            double y = init_y;

            int i;
            for( i = 0; i < start_at_run; i++ )
                y = function( x, y );

            if( y < 0 )
                continue;

           scatter_chart:
            for( i = 0; i < scatter_amount; i++ )
            {
                int trys = 0;
                y = function( x, y );

                while( true )
                {
                    int discrete_y = (int) ((y - bottom) / delta_y);
                    discrete_y = height_in_pixels - 1 - discrete_y;

                    if( discrete_y < height_in_pixels && discrete_y >= 0 )
                    {
                        if( graph[discrete_x + discrete_y * width_in_pixels]
                            != 0xFF000000 )
                            graph[discrete_x + discrete_y * width_in_pixels]
                                -= 0x00111111;
                        break;
                    }
                    y = function( x, y );

                    if( ++trys == max_trys )
                        break scatter_chart;
                }
            }
        }
        image = createImage( new MemoryImageSource(width_in_pixels,
            height_in_pixels, graph, 0, width_in_pixels) );
        state = READY;
    }

    //------------------------------------------------------------------------
    protected void set_new_bounds( Point upper_left, Point lower_right )
    {
        double delta_x = width  / size().width;
        double delta_y = height / size().height;

        double l = upper_left.x * delta_x + left;
        double b = (size().height - lower_right.y) * delta_y + bottom;
        double w = (lower_right.x - upper_left.x) * delta_x;
        double h = (lower_right.y - upper_left.y) * delta_y;

        go( l, b, w, h );
    }

    //------------------------------------------------------------------------
    protected static final double function( double x, double y )
    {
        return ( x * y * (1 - y) );
    }

    //------------------------------------------------------------------------
    private static final byte NEW           = 1;
    private static final byte CALCULATING   = 2;
    private static final byte READY         = 3;

    private byte       state           = NEW;
    private Point      selected_point  = null;
    private Point      previous_point  = null;
    private boolean    dragging        = false;
    private Image      image           = null;

    private double     left, bottom, width, height;
    private int        width_in_pixels;
    private int        height_in_pixels;

    private Thread     calculating_thread = null;
    private Label      position           = null;
    private TextField  resolution         = null;
}
1
Hosted by www.Geocities.ws