/* Classe MANDEL 20000409 © alain.marty@wanadoo.fr */ import java.applet.*; import java.awt.*; import java.awt.image.*; import java.util.*; import DESSIN; public class MANDEL implements DESSIN { int nb_iter; double kx, ky, k, norme; boolean julia; int coul; final int COUL1 = 1, COUL2 = 2, COUL3 = 3, COUL4 = 4, COUL5 = 5; TextField s_iteration = new TextField(), s_kx = new TextField(), s_ky = new TextField(); public MANDEL() { init(); } public final Panel controles() { Panel cont = new Panel(); cont.setLayout( new GridLayout( 0, 2, 1, 1 ) ); cont.add( new Label( "Iter:", Label.RIGHT )); cont.add( s_iteration ); cont.add( new Label( "Kx:", Label.RIGHT )); cont.add( s_kx ); cont.add( new Label( "Ky:", Label.RIGHT )); cont.add( s_ky ); Choice type = new Choice(); type.addItem( "Mandel" ); type.addItem( "Julia" ); cont.add( type ); Choice couleur = new Choice(); couleur.addItem( "Coul 1" ); couleur.addItem( "Coul 2" ); couleur.addItem( "Coul 3" ); couleur.addItem( "Coul 4" ); couleur.addItem( "Coul 5" ); cont.add( couleur ); return cont; } public final void init() { nb_iter = 1; kx = 0.025; ky = -0.65; k = 0.1; julia = false; coul = COUL1; } public final void infos() { s_iteration.setText( new Integer( nb_iter).toString() ); double d, decim = 10000.0; d = Math.round( kx*decim ) / decim; s_kx.setText( new Double( d ).toString() ); d = Math.round( ky*decim ) / decim; s_ky.setText( new Double( d ).toString() ); } public final boolean mouseUp( Event e, double x, double y ) { boolean bof = false; if ( e.metaDown() ) { nb_iter += 10; bof = true; } return bof; } public final boolean keyDown( Event e, int key ) { boolean bof = false; switch (key) { case Event.RIGHT: // augmente la profondeur de recursion if (nb_iter >= 10) nb_iter += 10; else nb_iter += 1; bof = true; break; case Event.LEFT: // diminue la profondeur de recursion if (nb_iter > 10) nb_iter -= 10; else nb_iter -= 1; if (nb_iter <= 0) nb_iter = 0; bof = true; break; case ' ': init(); bof = true; break; case 'j': case 'J': julia = true; bof = true; break; case 'm': case 'M': julia = false; bof = true; break; case 'x': kx -= k; bof = true; break; case 'X': kx += k; bof = true; break; case 'y': ky -= k; bof = true; break; case 'Y': ky += k; bof = true; break; case 'z': k *= 10.0; bof = true; break; case 'Z': k /= 10.0; bof = true; break; case '1': coul = COUL1; bof = true; break; case '2': coul = COUL2; bof = true; break; case '3': coul = COUL3; bof = true; break; case '4': coul = COUL4; bof = true; break; } return bof; } public boolean action( Event e, Object o ) { if ( e.target instanceof Choice ) { if ( o.equals( "Mandel" ) ) { julia = false; return true; } else if ( o.equals( "Julia" ) ) { julia = true; return true; } else if ( o.equals( "Coul 1" ) ) { coul = COUL1; return true; } else if ( o.equals( "Coul 2" ) ) { coul = COUL2; return true; } else if ( o.equals( "Coul 3" ) ) { coul = COUL3; return true; } else if ( o.equals( "Coul 4" ) ) { coul = COUL4; return true; } else if ( o.equals( "Coul 5" ) ) { coul = COUL5; return true; } } return false; } public final int couleur( double x, double y ) { int k; if (julia) k = test_julia(x, y); else k = test_mandel(x, y); int c; switch (coul) { case COUL1: c = test_couleur1( k ); break; case COUL2: c = test_couleur2( k ); break; case COUL3: c = test_couleur3( k ); break; case COUL4: c = test_couleur4( k ); break; case COUL5: c = test_couleur5( k ); break; default: c = test_couleur1( k ); break; } return c; } private final int test_mandel( double cx, double cy ) // laboratoire geometrique { double x = 0.0, y = 0.0; // initialise z = x +iy = 0 int k; for (k = 0; k < nb_iter; k++) { double X = x*x - y*y + cx; // calcule z =z^2 + c double Y = 2*x*y + cy; norme = X*X + Y*Y; if ( norme > 4.0 ) break; // sort de la boucle si norme > 2 x = X; // memorise x et y y = Y; } return k; } private final int test_julia( double cx, double cy ) // laboratoire geometrique { double x = cx, y = cy; // initialise z = x +iy = c int k; for (k = 0; k < nb_iter; k++) { double X = x*x - y*y + kx; // calcule z =z^2 + k double Y = 2*x*y + ky; norme = X*X + Y*Y; if ( norme > 4.0 ) break; // sort de la boucle si norme > 2 x = X; // memorise x et y y = Y; } return k; // si k == nb_iter on est dans l'ensemble } private final int test_couleur1( int k ) // laboratoire des couleurs { int r, g, b; if ( k < nb_iter ) // on est hors de l'ensemble : { r = ( k%2 == 0 )? 255 : 0; g = ( k%2 == 0 )? 0 : 255; b = 0; } else // on est dans l'ensemble : couleur bleue { r = 0; g = 0; b = 255; } return 0xff000000 | (r<<16) | (g<<8) | b; // combinaison argb } private final int test_couleur2( int k ) { int r, g, b; if ( k < nb_iter ) // on est hors de l'ensemble : { r = g = (255 * k)/nb_iter; b = 0; } else // on est dans l'ensemble : { int u = (int) (4.0 / norme); // u = [1, infini] r = g = 0; b = u%255 ; } return 0xff000000 | (r<<16) | (g<<8) | b; } private final int test_couleur3( int k ) { int r, g, b; if ( k < nb_iter ) // on est hors de l'ensemble : k < nb_iter, norme == 4 { double u = Math.abs( Math.sin( (2*Math.PI* k)/ (double) nb_iter ) ); r = g = (int) ( 255 * u); b = 0; } else // on est dans l'ensemble : k == nb_iter, norme < 4 { r = (int) ( 255 * (1 - norme/4) ); g = 0; b = 0; } return 0xff000000 | (r<<16) | (g<<8) | b; } private final int test_couleur4( int k ) { int r, g, b; if ( k < nb_iter ) // on est hors de l'ensemble : k < nb_iter, norme == 4 { r = g = b = (255 * k) / nb_iter; } else // on est dans l'ensemble : k == nb_iter, norme < 4 { r = g = b = (int) ((255 * norme) / 4); } return 0xff000000 | (r<<16) | (g<<8) | b; } private final int test_couleur5( int k ) { int r, g, b; if ( k < nb_iter ) // on est hors de l'ensemble : k < nb_iter, norme == 4 { double u = (double) k / (double) nb_iter; r = g = b = (int) (255*Math.abs(Math.sin(2*Math.PI*( u )))); } else // on est dans l'ensemble : k == nb_iter, norme < 4 { double u = norme * 0.25; r = g = b = (int) (255*Math.abs(Math.sin(2*Math.PI*( u )))); } return 0xff000000 | (r<<16) | (g<<8) | b; } }