Appendice B


Codice Java dell'applicazione Coulomb

/*
 * @(#)Coulomb.java     ver 1.0  20/12/95   Francesco Benvenuti
*/


import java.awt.*;
import java.applet.*;
import java.util.Date;

/**
 * Una applicazione didattica sulle linee di forza del campo 
elettrostatico
 * generato da tre cariche elettriche puntiformi.  Questa applicazione
 * puo' essere eseguita sia da sola (con l'interprete Java), sia come 
applet
 * sotto Netscape Navigator (versione 2.0 o successiva)
 */



class QFrame extends Frame {  /*QFrame sottoclasse di Frame con 
 						 gestione di WINDOWS_DESTROY */

     public QFrame(String titolo) {
     super(titolo);
     }

     public boolean handleEvent(Event e) {
        if (e.id == Event.WINDOW_DESTROY) {
        System.out.println("\n\n******************************"); 
        System.out.println("Grazie per l'uso del programma");
        System.out.println("******************************\n\n");
	System.exit(0);

          
	  }
     return true;
     }
}

class DFrame extends Frame { /* dFrame sottoclasse di Frame con 
						gestione di WINDOWS_DESTROY */
       Font font, font2;
       Date date = new Date();

       public DFrame(String titolo) {
       super(titolo);
       }
       
       public void paint(Graphics g) {
       
       Rectangle r = bounds(); 
       int i = (int)Math.round(r.width/15);
       int xc = (int)Math.round(r.width);
       int yc = (int)Math.round(r.height);
       g.setColor(Color.yellow); 
       g.fillRect(0, 0, r.width, r.height);
       g.setColor(Color.black);
       int diam = r.width/20;
       int dist = r.width/15; 
       g.fillOval(dist/2, dist/2, diam, diam);
       g.fillOval(dist/2, r.height - dist, diam, diam);
       g.fillOval(r.width - dist , r.height - dist, diam, diam);
       g.fillOval(r.width - dist, dist/2, diam, diam);
       font = new Font("Helvetica", Font.PLAIN, i);
       g.setColor(Color.red);   
       g.setFont(font);
       g.drawString("Autore: Francesco Benvenuti", xc/9, 2*yc/3);
       font2 = new Font("Arial", Font.ITALIC, i-3);
       g.setFont(font2);
       g.setColor(Color.blue);
       g.drawString("Oggi e' " + date, xc/20, yc/3);
       
       }
     
        public boolean handleEvent(Event e) {
          if(e.id == Event.WINDOW_DESTROY) {
          Coulomb.mostra(false); /* Coulomb.mostra e' metodo statico:
                                    non c'e' bisogna di istanziare
                                    Coulomb in un nuovo oggetto 
							con new */
          }
        return true;
        }  
}

public class Coulomb extends Applet {  /* Coulomb come Applet */

    CoulombControls1 controls;
    CoulombControls2 controls2;
    static Frame f;  

    public void init() {  /* metodo di inizio in ambiente Web */

      setLayout(new BorderLayout());
      CoulombCanvas c = new CoulombCanvas();
      add("North", controls2 = new CoulombControls2(c));
      add("Center", c);
      add("South", controls = new CoulombControls1(c, controls2));

      f = new DFrame("Informazioni");
        
    }

    public static void mostra(boolean a) {  /* il metodo mostra non
                                               necessita di essere
                                               istanziato: vedi DFrame 
*/
 
      if(a){
      f.resize(200, 100);
      f.show();
      } else {
      f.hide();
      }
    }


    public void start() {
	controls.enable();
        controls2.enable();
    }

    public void stop() {
	controls.disable();
        controls2.disable();
    }

    
    public static void main(String args[]) { /* main e' metodo di
                                                inizio quando
                                                l'applicazione non
                                                gira in ambiente Web 
*/

    Frame f = new QFrame("Linee di forza elettrostatiche");
    Coulomb coulomb = new Coulomb();

    coulomb.init();  /* si richiama init() */
    coulomb.start();

    f.add("Center", coulomb);
    f.resize(500, 400);
    f.show();
    }
}
    

class CoulombCanvas extends Canvas { /* genera la finestra con le
                                        linee di forza */

    double x, y, xp, yp, xi, yi, xd, yd, xr, yr, r1, r2, E, Ex, Ey,
       Ex1, Ey1, Ex2, Ey2, Ex3, Ey3, theta;
    double h;

    boolean     rossa = true;
    boolean     verde = false;
    boolean     gialla = false;
    boolean     no_auto = false;

    int         car1 = 3;
    int         car2 = 1;
    int         car3 = -10;

    int         x_car1 = -150;
    int         y_car1 = 20;
    int         x_car2 = 0;
    int         y_car2 = 0;
    int         x_car3 = 150;
    int         y_car3 = -30;
    
    int carex1, carex2, carey1, carey2;
    int max_x, max_y;
    int passo = 1000;

      public void paint(Graphics g) {

	 Rectangle r = bounds();
      max_x = r.width / 2;
      max_y = r.height / 2;

	int hlines = r.height / 10;
	int vlines = r.width / 10;

	g.setColor(Color.pink);
        for (int i = 1; i <= hlines; i++) {
	    g.drawLine(0, i * 10, r.width, i * 10);
	}
        for (int i = 1; i <= vlines; i++) {
	    g.drawLine(i * 10, 0, i * 10, r.height);
	}

        g.setColor(Color.red);
        g.fillOval(max_x + x_car1, max_y - y_car1, 4, 4);

        g.setColor(Color.green);
        g.fillOval(max_x + x_car2, max_y - y_car2, 4, 4);

        g.setColor(Color.yellow);
        g.fillOval(max_x + x_car3, max_y -  y_car3, 4 ,4);

        if(rossa) {
           xi = x_car1; yi = y_car1; 
           carex1 = x_car2; carex2 = x_car3;
           carey1 = y_car2; carey2 = y_car3;
           if(car1<0) {car1=-car1; car2=-car2; car3=-car3;}
        }

        if(verde) {
           xi = x_car2; yi = y_car2;
           carex1 = x_car1; carex2 = x_car3;
           carey1 = y_car1; carey2 = y_car3;
           if(car2<0) {car1=-car1; car2=-car2; car3=-car3;}
        }

        if(gialla) {
           xi = x_car3; yi = y_car3;
           carex1 = x_car1; carex2 = x_car2;
           carey1 = y_car1; carey2 = y_car2;
           if(car3<0) {car1=-car1; car2=-car2; car3=-car3;}
        } 



   g.setColor(Color.black);

   if(!no_auto) { 

        for(theta = 0.523; theta < 6.28; theta=theta+0.523) {

        /* 12 condizioni iniziali coordinate x e y pb di Cauchy a
        2 eqq. (angolo di 30 gradi) */
   
        h = 100;
 
        x = Math.cos(theta) * 5 + xi;
        y = Math.sin(theta) * 5 + yi;

           do {

                xd = x - x_car1;
           	yd = y - y_car1;
			r2 = xd*xd + yd*yd;
			r1 = Math.sqrt(r2);
			E = car1/r2;
			Ex1 = E * xd/r1;
			Ey1 = E * yd/r1;

			xd = x - x_car2;
			yd = y - y_car2;
			r2 = xd*xd + yd*yd;
			r1 = Math.sqrt(r2);
			E = car2/r2;
			Ex2 = E * xd/r1;
			Ey2 = E * yd/r1;

			xd = x - x_car3;
			yd = y - y_car3;
			r2 = xd*xd + yd*yd;
			r1 = Math.sqrt(r2);
			E = car3/r2;
			Ex3 = E * xd/r1;
			Ey3 = E * yd/r1;

      	/* si memorizzano i vecchi valori di coordinate prima di 	
		assegnare	quelli nuovi */

                xp= x;
                yp= y;
        
                Ex = Ex1 + Ex2 + Ex3;
                Ey = Ey1 + Ey2 + Ey3;
         
                xd = Ex * h;
                yd = Ey * h;
 
                if(Math.abs(xd) > 2 || Math.abs(yd) > 2) {
                   h = h/10;
                   xd = Ex * h;
                   yd = Ey * h;

                   } else
       
                   if(Math.abs(xd) < 0.5 || Math.abs(yd) < 0.5) {

                   h = h * 10;
                   xd = Ex * h;
                   yd = Ey * h;
                }

                x = x + xd;
			y = y + yd;

                xr = x - xp;
                yr = y - yp;

                if(Math.abs((carex1 - xp)/xr - (carey1 - yp)/yr) <
0.01) break;
                if(Math.abs((carex2 - xp)/xr - (carey2 - yp)/yr) <
0.01) break;
 

	        g.drawLine( (int)Math.round(xp) + max_x , max_y - 
(int)Math.round(yp),
      	              (int)Math.round(x) + max_x, max_y - 
(int)Math.round(y));


                } while(Math.abs(x) < max_x && Math.abs(y) < max_y);
           }

	} else {

        h = passo;
        for(theta = 0.523; theta < 6.28; theta=theta+0.523) {

        /* 12 condizioni iniziali coordinate x e y pb di Cauchy a
        2 eqq. (angolo di 30 gradi) */
   
          
        x = Math.cos(theta) * 5 + xi;
        y = Math.sin(theta) * 5 + yi;

           do {

                xd = x - x_car1;
           	yd = y - y_car1;
			r2 = xd*xd + yd*yd;
			r1 = Math.sqrt(r2);
			E = car1/r2;
			Ex1 = E * xd/r1;
			Ey1 = E * yd/r1;

			xd = x - x_car2;
			yd = y - y_car2;
			r2 = xd*xd + yd*yd;
			r1 = Math.sqrt(r2);
			E = car2/r2;
			Ex2 = E * xd/r1;
			Ey2 = E * yd/r1;

			xd = x - x_car3;	
			yd = y - y_car3;
			r2 = xd*xd + yd*yd;
			r1 = Math.sqrt(r2);	
			E = car3/r2;
			Ex3 = E * xd/r1;
			Ey3 = E * yd/r1;

      	/* si memorizzano i vecchi valori di coordinate prima di 	
		assegnare quelli nuovi */

                xp = x;
                yp = y;
        
     			x = x + (Ex1 + Ex2 + Ex3) * h;
			y = y + (Ey1 + Ey2 + Ey3) * h;

                xr = x - xp;
                yr = y - yp;

                if(Math.abs((carex1 - xp)/xr - (carey1 - yp)/yr) <
0.01) break;
                if(Math.abs((carex2 - xp)/xr - (carey2 - yp)/yr) <
0.01) break;
 

	        g.drawLine( (int)Math.round(xp) + max_x , max_y - 
(int)Math.round(yp),
      	              (int)Math.round(x) + max_x, max_y - 
(int)Math.round(y));


                } while(Math.abs(x) < max_x && Math.abs(y) < max_y);
          }
      }

 }


    public void redraw(int x_car1, int y_car1,
                                       int x_car2, int y_car2,
                                       int x_car3, int y_car3 ) {

        this.x_car1 = x_car1;
        this.y_car1 = y_car1;
        this.x_car2 = x_car2;
        this.y_car2 = y_car2;
        this.x_car3 = x_car3;
        this.y_car3 = y_car3;

	repaint();
    }

    public void redraw2(int car1, int car2, int car3) {
        this.car1 = car1;
        this.car2 = car2;
        this.car3 = car3;
     
    }

    public void redraw3(boolean rossa, boolean verde, boolean gialla,
                        boolean no_auto, int passo) {

        this.rossa = rossa;
        this.verde = verde;
        this.gialla = gialla;
        this.no_auto = no_auto;
        this.passo = passo;
    }

}

class CoulombControls1 extends Panel { /* Controlli inferiori */

    TextField x_car1;
    TextField y_car1;
    TextField x_car2;
    TextField y_car2;
    TextField x_car3;
    TextField y_car3;
    CoulombCanvas canvas;
    CoulombControls2 cont;

    public CoulombControls1(CoulombCanvas canvas, CoulombControls2 
cont) {
	this.canvas = canvas;
        this.cont = cont;
        add(x_car1 = new TextField("-150", 4));
        add(y_car1 = new TextField("20", 4));
        add(x_car2 = new TextField("0", 4));
        add(y_car2 = new TextField("0", 4));
        add(x_car3 = new TextField("150", 4));
        add(y_car3 = new TextField("-30", 4));

        add(new Button("Disegna..."));

    }


    public boolean action(Event ev, Object arg) {
	if (ev.target instanceof Button) {
	  
           canvas.redraw(
                          Integer.parseInt(x_car1.getText().trim()),
                          Integer.parseInt(y_car1.getText().trim()),
                          Integer.parseInt(x_car2.getText().trim()),
                          Integer.parseInt(y_car2.getText().trim()),
                          Integer.parseInt(x_car3.getText().trim()),
                          Integer.parseInt(y_car3.getText().trim()));
            cont.tValori();

            return true;
        }

	return false;
    }
}


class CoulombControls2 extends Panel { /* Controlli superiori */

    TextField car1;
    TextField car2;
    TextField car3;
    TextField passo;
    Checkbox ck1;
    Checkbox ck2;
    Checkbox ck3;
    Checkbox no_auto;
    CoulombCanvas canvas;

    public CoulombControls2(CoulombCanvas canvas) {
        
        this.canvas = canvas;
        add(car1 = new TextField("3", 2));
        add(car2 = new TextField("1", 2));
        add(car3 = new TextField("-10", 2));
        CheckboxGroup ckg = new CheckboxGroup();
        ck1 = new Checkbox("Rossa", ckg, true);
        ck2 = new Checkbox("Verde", ckg, false);
        ck3 = new Checkbox("Gialla", ckg, false);
        add(ck1);
        add(ck2);   
        add(ck3);
        no_auto = new Checkbox("passo");
        add(no_auto);
        add(passo = new TextField("1000", 5));
        add(new Button("Info")); 
        }

        public boolean action(Event ev, Object arg) {
	      if (ev.target instanceof Button) {
                Coulomb.mostra(true);   
                return true;
            }     
            return false;
        }  

    


        public void tValori() {
        canvas.redraw2(Integer.parseInt(car1.getText().trim()),
                       Integer.parseInt(car2.getText().trim()),
                       Integer.parseInt(car3.getText().trim()));
        canvas.redraw3(ck1.getState(), ck2.getState(), ck3.getState(),
                       no_auto.getState(), 			 		 
Integer.parseInt(passo.getText().trim()));
     

        }

}