La classe con i Gestori degli eventi sulla finestra
1 import java.io.*;
2 import java.awt.*;
3 import java.awt.event.*;
4 class GestoreFinestra implements WindowListener {
5     public void windowIconified(WindowEvent e) {}
6     public void windowDeiconified(WindowEvent e){}
7     public void windowActivated(WindowEvent e){}
8     public void windowDeactivated(WindowEvent e){}
9     public void windowOpened(WindowEvent e){}
10     public void windowClosed(WindowEvent e){}
11    public void windowClosing(WindowEvent e){
12         System.exit(0);
13    }
14 }
La classe GestoreFinestra ridefinisce il gestore dell'evento chiudi Finestra

La classe Funzione.
Si dichiara una classe Funzione che descrive le caratteristiche del segnale applicato al circuito Resistenza Capacità
1 public class Funzione {
2   private double Periodo, Frequenza, Omega;
Le proprietà della classe comprendono i parametri che descrivono una sinusoide: Periodo, Frequenza e velocità angolare

Costruttore di oggetti di classe Funzione:
3   public Funzione(double T) {
4     Periodo = T;
5     Frequenza = 1/T;
6     Omega = 2*Math.PI/T;
7   }
Il costruttore riceve, come parametro, il valore del periodo e calcola la frequenza e la velocità angolare.

L'onda quadra è la funzione proposta in questo esempio. Il parametro ricevuto è il tempo e il parametro restituito è il valore della funzione al tempo t.
8   public double f(double t) {
9     int NrPer;
10     if (t > Periodo) {
11       NrPer = (int) (t/Periodo);
12       t = t - (double) (NrPer*Periodo);
13     }
Linea 9: si dichiara una variabile locale;

Linea 10: se il tempo è maggiore del periodo,

  Linea 11: dividi il tempo per il periodo e tronca la parte decimale. Il risultato rappresenta il numero di periodi trascorsi fino al tempo t,

  Linea 12: calcola il tempo trascorso dall'inizio del periodo.
14     if (t<=Periodo/2) return -10.0;
15     else return 10.0;
16   }
Linea 14: se il tempo trascorso dall'inizio del periodo è minore di un semiperiodo si restituisce il valore negativo (-10.0) dell'onda quadra,

Linea 15: altrimenti si restituisce il valore positivo (+10.0) dell'onda quadra.

Le proprietà della classe sono state dichiarate private quindi la classe deve possedere dei metodi pubblici di accesso alle proprietà:

Il primo di tali metodi è la funzione w(), che restituisce la velocità angolare della funzione periodica.
17   public double w(){
18     return Omega;
19   }


Poi si fornisce il metodo cambiaT per modificare il periodo della funzione:
20   public void cambiaT(double T){
21     Periodo = T;
23     Frequenza = 1/T;
23     Omega = 2*Math.PI/T;
24   }
Questo metodo riceve il nuovo valore del periodo e calcola i corrispondenti valori di frequenza e velocità angolare.

La classe fornisce anche il metodo per restituire il valore del periodo.
25   public double leggiT(){
26     return Periodo;
27   }
28 }

Parametri del circuito
Si dichiara una classe CircuitoRC le cui proprietà sono i parametri del circuito.
1 class circuitoRC {
2     private double R, C;
3     private double dt, tau, t;

Il costruttore della classe:
4     public circuitoRC(double Ohm, double Farad) {
5         R = Ohm;
6         C = Farad;
7         tau = R*C;
8         dt = tau/100;
9     }
I parametri del circuito sono la Resistenza e la Capacità.

Da questi si ottiene la costante di tempo τ e l'intervallo dt di osservazione tra due misure consecutive.

La classe fornisce due funzioni pubbliche per l'accesso ai campi privati:
10     public double leggiTau(){return tau;}
11     public double leggidt(){return dt;}
12 }

Grafico della funzione
1 class Diagramma extends Canvas {
La classe Diagramma eredita le proprietà e i metodi della classe Canvas, che in java rappresenta la finestra grafica.

2   public void paint(Graphics g) {

Quando si crea un'istanza della classe viene chiamato automaticamente il metodo paint che riceve un oggetto g di classe Graphics con il quale può disegnare sulla finestra.
3     int YAscisse, XOrdinate, AsseOrdinate, X, Y, y;
4     double scalaX, scalaY, t, Vu, derivata, dVu, tMax;
Vengono dichiarate alcune variabili locali che servono per mantenere alcuni parametri, cioè la posizione degli assi cartesiani, i fattori di scala orizzontale e verticale, ecc...

5     circuitoRC C = new circuitoRC(10.0, 0.00002);
6     Funzione f = new Funzione(C.leggiTau()*5);
7     tMax = C.leggiTau()*20;
8     scalaX=300.0/(tMax);
9     scalaY=200.0/25.0;
Linea 5: Si crea un'istanza della classe CircuitoRC dove sono descritti i parametri del circuito,

Linea 6: Si crea un'istanza della classe Funzione nella quale è contenuta l'espressione della funzione,

Linea 7: Dall'istanza C della classe CircuitoRC si ottiene il valore della costante di tempo, e, moltiplicandola per 20, si stabilisce la durata dell'esperimento,

Linee 8÷9: si calcola il fattore di riduzione in scala, sulla base della larghezza e dell'altezza della finestra e dei valori massimi da rappresentare sui rispettivi assi.
10     Vu=0.0;
11     derivata=(f.f(0)-Vu)/C.leggiTau();
12     YAscisse=150;
13     AsseOrdinate=150;
14     XOrdinate=200;
15     g.setColor(Color.red);
16     g.drawLine(0,YAscisse,400,YAscisse);
17     g.drawLine(AsseOrdinate, 240,AsseOrdinate,0);
Linea 10: si assegna la condizione iniziale (Vu=0 quando t=0),

Linea 11: Si calcola la tangente nel punto (t=0, Vu=0),

Linea 12÷14: si assegnano i valori alle posizioni degli assi cartesiani,

Linea 15: Si assegna il colore per disegnare gli assi,

Linee 16÷17: si disegnano gli assi cartesiani.
18     for (t=0.0; t<=tMax; t+=C.leggidt()){
19       X = (int) (scalaX*t);
20       y = (int) (f.f(t)*scalaY)+YAscisse;
21       g.setColor(Color.green);
22       g.drawLine(X,y,X,y);
23       g.setColor(Color.blue);
24       y=(int)(scalaY*Vu+YAscisse);
25       g.drawLine(X,y,X,y);
26       dVu = derivata*C.leggidt();
27       Vu = Vu + dVu;
28       derivata=(f.f(t)-Vu)/C.leggiTau();
29     }
30   }
31 }
Linea 18: si inizia un ciclo in cui si fa variare il tempo t da 0 al valore massimo con incrementi dt

Linea 19: il valore del tempo, da rappresentare sull'easse delle ascisse viene moltiplicato per il fattore di scala orizzontale per ricavare la coordinata X del pixel da illuminare,

Linea 20: il valore della funzione di ingresso viene moltiplicato per il fattore di scala verticale per ottenere la coordinata Y del pixel da illuminare,

Linea 21: si imposta il colore con cui si disegna la funzione di ingresso,

Linea 22: il pixel viene disegnato,

Linea 23: si imposta il colore con cui si disegna la funzione di uscita (Vu),

Linea 24: si calcola la coordinata verticale in cui illuminare il pixel relativo al valore della funzione di uscita (la coordinata orizzontale è la stessa del pixel già illuminato),

Linea 25: si disegna il punto,

Linea 26: conoscendo la derivata della funzione nel punto t si calcola l'incremento della funzione nell'intervallo dt,

Linea 27: l'incremento della funzione nell'intervallo dt viene aggiunto al valore della funzione all'istante t e si ottiene il valore della funzione all'istante t + dt.

Linea 28: Prima di ripetere un altro passo del ciclo si calcola il valore della derivata

La classe principale
1 public class RispostaRC {
2     public static void main(String argv[]) {
3         Frame Finestra = new Frame("Risposta all'onda quadra");
4         Diagramma Grafico = new Diagramma();
5         Finestra.addWindowListener(new GestoreFinestra());
6         Finestra.setSize(500,400);
7         Finestra.setLocation(100,100);
8         Finestra.setResizable(false);
9         Finestra.add(Grafico);
10         Finestra.setVisible(true);
11   }
12 }

Problemi
Tracciare una griglia di linee orizzontali a intervalli di 1/5 dell'escursione massima della funzione di ingresso. Questa griglia servirà per rilevare, approssimativamente, il valore massimo della funzione di uscita.

Variare il periodo della funzione e rilevare, per ciascun valore di Periodo, l'ampiezza massima della funzione di uscita. Verificare se la frequenza di taglio è 1/τ.

Modificare la funzione di ingresso in dente di sega e poi in sinusoide. Osservare i grafici ottenuti. Si deve notare che la funzione di uscita assomiglia alla funzione di ingresso.

modificare la frequenza della sinusoide e rilevare diverse misure dell'ampiezza del segnale di uscita. Con tali valori determinare la frequenza di taglio.