Corso di Interfacce Utente - A.A. 2002-2003
PROGETTO DI LABORATORIO - DOCUMENTO 2
(Versione semplificata 29/5/03)
Descrizione del programma che implementa l'applicazione
Introduzione
Il programma e' composto da 5 classi java (contenute in 5 file):
-
PairOfDouble implementa una coppia di coordinate double,
serve per rappresentare punti e vettori
-
ParticleType implementa un tipo di particelle
-
Outcome ha due scopi:
implementa l'esito dello scontro fra un
tipo di particelle e un altro e pure la storia di una particella
(cioe' la descrizione di che cosa le e' successo al precedente passo
della simulazione)
-
Particle implementa una particella
-
WorkEnv implementa l'ambiente di lavoro con i tipi di particelle
conosciuti, le regole che stabiliscono gli esiti degli urti,
l'insieme di particelle correnti ecc.
Nel seguito sono
documentate le variabili e funzioni pubbliche di queste 5 classi.
Nota:
non tutte le funzioni vi saranno utili per sviluppare l'interfaccia,
comunque qui per completezza sono state documentate tutte.
classe PairOfDouble
Le istanze di questa classe sono coppie di coordinate che rappresentano
a seconda del contesto punti oppure vettori nel piano.
I punti servono per le posizioni delle particelle,
i vettori servono per le velocita' delle particelle.
Elementi appartenenti alla classe (static)
Costanti che definiscono l'orientamento di una terna di punti:
- int LEFT; svolta a sinistra ovvero in senso antiorario
- int ALIGN; nessuna svolta ovvero i tre punti sono allineati
- int RIGHT; svolta a destra ovvero in senso orario
Funzioni relative agli orientamenti di terne di punti
(il risultato e' uno fra LEFT, ALIGN, RIGHT):
-
int orientation(PairOfDouble p1, PairOfDouble p2)
Restituisce l'orientamento della terna di punti p1-origine-p2.
-
int orientation(PairOfDouble p1, PairOfDouble p2, PairOfDouble p3)
Restituisce l'orientamento della terna di punti p1-p2-p3.
Funzione che restituisce il punto medio del segmento che unisce
i punti p1 e p2:
-
PairOfDouble midPoint(PairOfDouble p1, PairOfDouble p2)
Elementi appartenenti ad ogni oggetto istanza della classe
Variabili che descrivono lo stato interno:
-
double x, y;
Coordinate del punto oppure componenti del vettore.
Costruttori:
-
PairOfDouble(double x0, double y0)
Crea un punto o un segmento con coordinate o componenti x0, y0.
-
PairOfDouble(PairOfDouble p)
Crea un punto o un segmento come copia di un dato punto o segmento p.
Funzioni che agiscono sul punto o vettore:
-
double length()
Restituisce la lunghezza di questo vettore,
ovvero la distanza di questo punto dall'origine.
-
void normalize()
Normalizza il vettore per renderlo un versore.
-
void scale(double f)
Scala questo punto o vettore secondo il fattore di scala f.
-
void translate(PairOfDouble p)
Trasla questo punto o vettore secondo il vettore di traslazione p.
-
void counterclockRotate(double cosA, double sinA)
Ruota questo punto o vettore in senso antiorario
secondo un angolo A (gli argomenti sono il coseno e il seno dell'angolo).
classe ParticleType
Le istanze di questa classe sono tipi di particelle.
Un tipo di particelle e' caratterizzato da:
- nome
- raggio delle particelle di questo tipo
- flag booleano che indica se questo tipo di particelle e' un
composto
- se e' un composto, i due tipi di particelle componenti
- velocita' delle particelle di questo tipo alla temperatura
di zero gradi
- incremento di velocita' che interviene per ogni grado in piu'
di temperatura
Elementi appartenenti alla classe (static)
Costanti che definiscono il minimo e massimo raggio che un tipo
di particella puo' avere:
- double MIN_RADIUS = 5.0;
- double MAX_RADIUS = 20.0;
Costanti che definiscono il massimo valore della velocita' a zero
gradi e dell'incremento di velocita come fattore
moltiplicativo rispetto al raggio della particella:
- double MAX_ZEROSPEED = 0.5;
- double MAX_INCRSPEED = 0.005;
VARIAZIONE rispetto al
documento della tappa 0:
l'incremento di velocita' per ogni grado in piu' non puo' superare
0.005 del raggio (si era detto 0.1, ma in realta' ho visto che la
velocita' tendeva a diventare troppo grande...)
Elementi appartenenti ad ogni oggetto istanza della classe
Variabili che descrivono lo stato interno
sono private, accessibili in lettura e scrittura solo mediante funzioni.
Costruttore:
- ParticleType(String n, double r)
Crea un tipo di particelle dato il nome del tipo e
il raggio delle sue particelle.
Per difetto il tipo non e' un composto e
tutte le altre quantita' (velocita' a zero gradi e incremento)
sono poste a zero.
Funzioni relative al nome di questo tipo di particelle:
- void setName(String n)
- String getName()
Funzioni relative al raggio delle particelle di questo
tipo:
- boolean setRadius(double r)
Se il r e' nell'intervallo dei raggi ammissibili, lo assegna
e restituisce true.
Altrimenti lo tronca al minimo (se minore) o al massimo (se maggiore)
raggio ammissibile, lo assegna e restituisce false.
- double getRadius()
Restituisce il raggio.
Funzioni relative al fatto
che questo tipo di particelle sia un composto oppure no:
- boolean isCompound()
Controlla se questo tipo e' un composto.
- void setCompound(ParticleType c1, ParticleType c2)
Assegna che questo tipo e' un composto e c1, c2 sono i due tipi
che lo compongono.
- void setNoCompound()
Assegna che questo tipo non e' un composto.
- boolean hasComponents(ParticleType c1, ParticleType c2)
Controlla se questo tipo e' composto dai tipi c1 e c2.
- boolean hasComponent(ParticleType c)
Controlla se questo tipo e' composto e uno dei suoi tipi
componenti e' c.
- ParticleType getCompType1()
ParticleType getCompType2()
Restituiscono i due tipi componenti questo tipo di particelle,
che deve essere un composto.
Funzioni relative alla velocita' delle particelle di questo tipo:
- boolean setZeroSpeed(double zs)
Assegna la velocita' alla temperatura di zero gradi.
Se zs e' nell'intervallo di temperature ammissibili, la assegna e
restituisce true.
Altrimenti la tronca alla minima (se minore) o alla massima (se maggiore)
velocita' ammissibile, la assegna e restituisce false.
- double getZeroSpeed()
Restituisce la velocita' alla temperatura di zero gradi.
- boolean setIncrSpeed(double is)
Assegna l'incremento di velocita' per ogni grado in piu' di temperatura.
Se is e' nell'intervallo di velocita' ammissibili, lo assegna e
restituisce true.
Altrimenti lo tronca al minimo (se minore) o al massimo (se maggiore)
incremento ammissibile, lo assegna e restituisce false.
- double getIncrSpeed()
Restituisce l'incremento di velocita' per ogni grado in piu' di temperatura.
classe Outcome
Questa classe definisce una serie di costanti
che sono usate in due situazioni:
- Esito d'urto:
per descrivere l'esito dell'urto fra due tipi di particelle.
Il valore della costante indica che cosa accadra' a una particella
di tipo 1 quando dopo che ha urtato una particella ti tipo 2
- Storia:
per descrivere la storia di una certa particella.
Il valore della costante indica che cosa e' accaduto a
questa particella nell'ultimo passo della simulazione.
La classe e' intesa solo come portatrice di queste costanti.
Non e' previsto abbia istanze.
Elementi appartenenti alla classe (static)
Costanti che descrivono sia gli esiti d'urto che le storie.
Come esito d'urto si applicano solo le prime tre costanti.
Come storia si applicano tutte.
Sono:
- int REFLECT;
Come esito d'urto: la particella sara' riflessa.
Come storia: la particella ha subito un urto in cui e' stata riflessa.
- int SPLIT;
Come esito d'urto: la particella, che e' di un tipo composto,
si scindera' nelle sue due componenti.
Come storia:
la particella e' stata creata per scissione di un'altra
particella, che era di un tipo composto, in un urto.
- int MERGE;
Come esito d'urto: la particella si fondera' con l'altra
particella urtante creando una particella di tipo composto.
Come storia: la particella, che e' ti un tipo composto, e' stata
creata dalla fusione di due particelle che si sono urtate.
- int BORDER;
Solo come storia: la particella ha urtato una parete
dell'ambiente di lavoro ed e' stata riflessa.
- int PLAIN;
Solo come storia: la particella non e' stata coinvolta in alcun urto.
Elementi appartenenti ad ogni oggetto istanza della classe
Variabili che descrivono lo stato interno:
- ParticleType pt1; il tipo di particella di cui
descriviamo il comportamento
- ParticleType pt2; l'altro tipo di particella urtante
- int outcome; l'esito dell'urto cioe' che
cosa succede al tipo pt1 quando urta pt2
Questa regola d'urto descrive che cosa accade a una particella di
tipo pt1 quando urta una particella di tipo pt2.
Ci sara' poi un'altra regola per descrivere
che cosa succede a una particella di
tipo pt2 quando urta una particella di tipo pt1.
Nota: gli esiti d'urto non sono necessariamente simmetrici.
Per esempio, quando il tipo 1 e 2 si urtano, e' possibile che il tipo 1
sia riflesso (esito REFLECT) e il tipo 2 sia scisso (esito SPLIT).
Solo l'esito della fusione (esito MERGE) e' simmetrico.
Il costruttore e' quello di default (senza argomenti).
Poi bisogna inizializzare esplicitamente le variabili
(che sono pubbliche!).
Sulla regola non viene fatto alcun controllo di consistenza
fino al momento in cui viene inserita nell'ambiente di lavoro.
classe Particle
Le istanze di questa classe sono singole particelle.
Ogni particella e' caratterizzata da:
- tipo, da cui riceve una serie di proprieta' (raggio ecc.)
- posizione (quella del suo centro)
- direzione della velocita'
(mentre l'intensita' della velocita' dipendera' dalla temperatura
dell'ambiente di lavoro)
- una storia che
descrive che cosa e' successo alla particella nel precedente passo di
simulazione
Elementi appartenenti alla classe (static)
Funzioni relative al calcolo di distanze:
- double squaredDistance(Particle b1, Particle b2)
Restituisce il quadrato della distanza fra i centri delle due particelle
- double distance(Particle b1, Particle b2)
Restituisce la distanza fra i centri delle due particelle
Controlla se due particelle si urtano:
- boolean isHit(Particle b1, Particle b2)
Elementi appartenenti ad ogni oggetto istanza della classe
Variabili che descrivono lo stato interno sono private, accessibili
in lettura e scrittura solo tramite funzioni.
Costruttori:
- Particle(ParticleType t, double x0, double y0,
double svx0, double svy0)
Crea una particella di tipo t collocandola nella posizione
(x0,y0) e con velocita' diretta secondo il versore di
(svx0, svy0).
- Particle(Particle b)
Crea una particella come copia di una data particella b.
- Particle(Particle b1, Particle b2, ParticleType t)
Crea una particella di tipo composto t dandole posizione e
direzione della velocita' ricavate in base a quelle delle
particelle b1 e b2, che devono essere dei due tipi
componenti del tipo t.
La posizione sara' il punto medio e la direzione della
velocita' sara' la media rispetto alle due particelle date.
Funzioni relative al tipo di questa particella:
- void setType(ParticleType t) assegna il tipo
- ParticleType getType() restituisce il tipo
Funzioni relative alla posizione (del centro della particella):
- void setCenter(double x1, double y1)
void setCenter(PairOfDouble c1)
Assegnano la posizione del centro.
- PairOfDouble getCenter()
Restituisce la posizione del centro.
Funzioni relative alla direzione della velocita' di questa particella:
- void setDirection(double vx1, double vy1)
void setDirection(PairOfDouble sv1)
Assegnano la direzione della velocita'.
Il vettore puo' avere lunghezza non unitaria,
viene automaticamente normalizzato per renderlo un versore.
- PairOfDouble getDirection()
Restituisce la direzione della velocita', che e' un versore
cioe' un vettore di lunghezza unitaria.
Funzioni relative alla storia di questa particella (che cosa le
e' accaduto nell'ultimo passo di simulazione.
I valori ammissibili della storia sono
Outcome.REFLECT, Outcome.MERGE, Outcome.BORDER,
Outcome.PLAIN:
- void setHistory(int h) assegna la storia.
- int getHistory() restituisce la storia.
Funzioni ausiliarie usate per simulazione (in particolare
per la gestione degli urti):
- PairOfDouble axis(Particle b1)
Restituisce l'asse del segmento che unisce la particella b1
con questa particella, diretto da b1 a questa particella.
- PairOfDouble reflectDirection(double nx, double ny)
PairOfDouble reflectDirection(PairOfDouble normal)
Restituiscono la direzione della velocita' riflessa
quando questa particella urta.
L'argomento e' la normale (o le sue due componenti)
al "muro" che questa particella urta
e rispetto a cui va eseguita la riflessione.
classe WorkEnv
Un'istanza di questa classe e' un ambiente di lavoro.
Un ambiente di lavoro e' caratterizzato da:
- Un'area rettangolare nel piano.
- Una certa temperatura.
- Un certo numero di tipi di particelle che
questo ambiente conosce.
L'insieme dei tipi conosciuti e' chiuso nel senso che, se
e' conosciuto un tipo composto, allora sono conosciuti anche i
due tipi che lo compongono.
- Un certo numero di particelle contenute nell'area di
lavoro, che devono essere di tipi conosciuti
La classe estende (e' sottoclasse) della classe java Vector.
La classe Vector e' una implementazione delle liste.
WorkEnv usa se stesso come lista per memorizzare le particelle
contenute nell'area di lavoro.
Costruttore:
- WorkEnv(double x0, double y0, double x1, double y1, double t)
Crea un ambiente di lavoro dato il suo contorno e
la temperatura.
Per difetto l'ambiente creato non conosce nessun tipo di particella
ed e' vuoto (cioe' non contiene particelle).
Elementi appartenenti alla classe (static)
Costanti che denotano le quattro pareti dell'ambiente di lavoro
(indicate coi nomi dei quattro punti cardinali):
- int TOP;
- int BOTTOM;
- int LEFT;
- int RIGHT;
Costanti che denotano la temperatura minima e massima ammesse
in un ambiente di lavoro:
- double MIN_TEMPERATURE = -50.0;
- double MAX_TEMPERATURE = 50.0;
Costante che stabilisce il massimo numero di tipi di particelle che
un ambiente di lavoro puo' conoscere:
- static final int CAPACITY = 10;
Elementi appartenenti ad ogni oggetto istanza della classe
Variabili che rappresentano il contorno dell'ambiente di lavoro
sono private, accessibili solo attraverso le funzioni.
Costruttore:
- WorkEnv(double x0, double y0, double x1, double y1, double t)
Crea un ambiente di lavoro dato il suo contorno e
la temperatura.
Per difetto l'ambiente creato non conosce nessun tipo di particella
ed e' vuoto (cioe' non contiene particelle).
Funzioni relative alla temperatura:
- boolean setTemperature(double t)
Assegna la temperatura dell'ambiente.
Se t rientra nell'intervallo di temperature
ammissibili, la assegna e restituisce true.
Altrimenti la tronca alla temperatura minima (se minore) o
massima (se maggiore) ammissibile, la assegna e restituisce false.
- double getTemperature()
Restiuisce la temperatura corrente.
Funzioni per gestire i tipi di particelle conosciuti:
- boolean addParticleType(ParticleType pt)
Aggiunge un tipo di particella a quelli conosciuti.
Requisiti:
- non deve essere gia' conosciuto un tipo di particella con lo stesso
nome
- se si tratta di un tipo composto, entrambi i tipi che lo compongono
devono essere conosciuti
-
non bisogna superare il numero massimo di tipi conoscibili.
Se i requisiti sono soddisfatti, aggiunge e restituisce true.
Altrimenti non aggiunge e restituisce false.
- boolean removeParticleType(ParticleType pt)
Rimuove un tipo di particella da quelli conosciuti.
Requisiti:
- deve essere conosciuto un tipo di particella con quel nome
- il tipo non deve apparire come componente di un tipo composto
conosciuto
Se i requisiti sono soddisfatti, rimuove e restituisce true.
Altrimenti non rimuove e restituisce false.
- int numTypes()
Restituisce il numero di tipi di particelle conosciuti in questo
ambiente di lavoro.
- ParticleType getType(int i)
Restituisce l'i-esimo tipo di particella conosciuto.
Funzioni per gestire gli esiti degli urti:
- getHitRule(ParticleType pt1, ParticleType pt2)
Restituisce l'esito dell'urto fra due particelle di tipi pt1 e pt2.
L'esito e' Outcome.MERGE se e' conosciuto il tipo
composto di pt1 e pt2, ed e' Outcome.REFLECT altrimenti.
Funzioni relative al rettangolo che definisce l'area
di lavoro e a sue sotto-aree:
- boolean outsideArea(Particle b)
Controlla se la particella b e' fuori dall'area di lavoro.
- double getMinX(), double getMinY(), double getMaxX(),
double getMaxY()
Restituiscono i limiti dell'area di lavoro.
- boolean setBoundary(double x0, double y0, double x1, double y1)
Riassegna i limiti dell'area di lavoro, che diventa il rettangolo di
diagonale (x0,y0)-(x1,y1).
Requisiti:
- ciascuna coordinata minima non deve essere maggiore della
corrispondente coordinata massima
-
l'ambiente non deve contenere nessuna particella
Restituisce true se ha successo, false se fallisce.
- PairOfDouble wallNormal(int wall)
Restituisce il vettore normale a una parete dell'ambiente di lavoro,
che deve essere una tra WorkEnv.TOP, WorkEnv.BOTTOM, WorkEnv.LEFT,
WorkEnv.RIGHT.
Funzioni relative alle particelle presenti nell'area di lavoro:
- boolean addParticle(Particle b)
Aggiunge una particella, che deve essere di tipo noto ed essere
situata dentro l'area di lavoro.
Restituisce true se ha successo, false se fallisce.
- size()
Funzione ereditata dalla super-classe
Vector, restituisce il numero di particelle presenti.
- Particle getParticle(int i)
Restituisce l'i-esima particella presente.
- boolean removeParticle(Particle b)
Rimuove una particella dall'ambiente di lavoro, la particella deve
essere presente.
La funzione restituisce true se ha successo, false se fallisce.
- void emptyArea(double x0, double y0, double x1, double y1)
Svuota la sotto-area di diagonale (x0,y0)-(x1,y1)
cancellando tutte le particelle contenute.
- boolean fillArea(double x0, double y0, double x1, double y1,
ParticleType t1, int percent1,
ParticleType t2, int percent2,
ParticleType t3, int percent3)
Riempie la sotto-area di diagonale (x0,y0)-(x1,y1) con una miscela di
particelle dei tipi t1, t2, t3, dove ciascun tipo e' presente in
percentuale assegnata.
Qualcuno degli argomenti t1, t2, t3 puo' essere null,
e la corrispondente percentuale zero: in tal caso non viene usato.
La sotto-area deve essere vuota e la somma delle percentuali corrispondenti
ai tipi non nulli deve valere 100.
La funzione restituisce true se ha successo, false se fallisce.
Funzioni relative alle velocita' delle particelle:
- double getSpeed(ParticleType t)
Restituisce l'intensita' della velocita' delle particelle di tipo
t in questo ambiente di lavoro (tale intensita' dipende
dalla temperatura corrente).
- PairOfDouble getSpeed(Particle b)
Restituisce il vettore velocita'
della particella b in questo ambiente di lavoro.
Funzioni relative alla simulazione:
- PairOfDouble nextCenter(Particle b)
Restituisce la posizione della particella b
nella prossima unita' di tempo, cioe' dopo un passo di simulazione.
- boolean hitWall(Particle b, int wall)
Controlla se la particella b urta un muro wall dell'ambiente di lavoro,
che deve essere uno tra WorkEnv.TOP, WorkEnv.BOTTOM, WorkEnv.LEFT,
WorkEnv.RIGHT.
- void moveOneStep()
Avanza di un'unita' di tempo, cioe' di un passo, nella simulazione.
Gestisce automaticamente gli urti in base agli esiti specificati nella
tabella.
Funzioni relative agli attrattori:
- void attract(PairOfDouble a, int percent)
Attrae le direzioni delle velocita' di tutte le particelle
verso il punto a con percentuale di attrazione assegnata (tra 0 e 100).
Con percentuale 0 le velocita' resteranno invariate,
con percentuale 100 le velocita' andranno a dirigersi esattamente
verso il punto.
- void attract(int w, int percent)
Attrae le direzioni delle velocita' di tutte le particelle
verso la parete w dell'ambiente di lavoro, che
deve essere una tra WorkEnv.TOP, WorkEnv.BOTTOM, WorkEnv.LEFT,
WorkEnv.RIGHT) con percentuale di attrazione assegnata (tra 0 e 100).
Con percentuale 0 le velocita' resteranno invariate,
con percentuale 100 le velocita' andranno a dirigersi esattamente
verso il muro.
Altre funzioni di utilita':
- boolean
isEmptyArea(double x0, double y0, double x1, double y1)
Controlla se la sotto-area di diagonale (x0,y0)-(x1,y1)
e' vuota da particelle.
- ParticleType searchByName(String name)
Cerca fra i tipi di particelle conosciuti un tipo che
abbia il nome assegnato e lo restituisce,
se non lo trova restituisce null.
- int locateByName(String name)
Cerca fra i tipi di particelle conosciuti un tipo che
abbia il nome assegnato e restituisce la sua posizione nell'array
dei tipi conosciuti, se non lo trova restituisce -1.
- ParticleType
searchCompound(ParticleType pt1, ParticleType pt2)
Cerca fra i tipi di particelle conosciuti un tipo che
sia il composto dei due tipi assegnati e lo restituisce,
se non lo trova restituisce null.
Funzioni di lettura:
- ParticleType loadParticleType(FileInputStream in)
Legge da file un tipo di particella, senza ancora aggiungerlo
all'ambiente di lavoro.
Non controlla se sia un tipo di particella corretto
(questo controllo e' fatto dalla funzione che aggiunge poi il tipo
tipo di particella all'ambiente di lavoro).
Restituisce la particella se tutto ok, oppure null se errore.
Funzioni di scrittura:
- boolean writeParticleType(OutputStream out, ParticleType pt)
Scrive su file un tipo di particella
- boolean writeWorkEnv(OutputStream out)
Funzione di test che scrive l'ambiente (solo i tipi di
particelle noti, non le particelle).