Blog del corso di Programmazione (9 CFU) tenuto da Marco La Cascia presso l'Universita' di Palermo per il corso di laurea in Ingegneria Informatica e delle Telecomunicazioni. Tratta la programmazione a oggetti in Java.
lunedì 7 febbraio 2011
Soluzione altri esercizi dell'esercitazione 10
Eccovi le implementazioni degli altri esercizi dell'esercitazione 10. Il codice dovrebbe essere abbastanza commentato ma se avete dubbi chiedete liberamente.
Salve prof, ho dato uno sguardo all'esercizio sulla simulazione del tavolo da biliardo. Dopo aver compreso la sua implementazione(non mi era chiaro come svolgere l'esercizio e quali metodi implementare), ho pensato di estendere il programma prevedendo anche l'urto tra biglie. Ho pensato di fare un controllo sulle posizioni delle biglie prima di procedere con il successivo spostamento, cioè se la biglia si trova sulla stessa posizione di un'altra non procedo subito con lo spostamento ma prima dovrei fare eseguire un metodo della classe Palla che mi aggiorna le velocità delle due palle che intervengono nell'urto. Mentre se la palla è libera da impatto con altre palle procedo normalmente con l'avanzamento unitario. Ho aggiunto alla classe Palla 4 metodi: Palla& collide(Tavolo&); bool libera(Tavolo&); void urto(Tavolo&, Palla&); int getNum() const {return n;}
collide: verifica se ci sono collisioni tra la palla che richiama il metodo e un altra palla sul tavolo: bool Palla::libera(Tavolo & t){ collide(t); if(!coll){ return true; //se nn ci sono //collisioni la palla è libera di avanzare } else return false; }
Ecco anche il metodo urto(Tavolo&, Palla&) a cui passo per riferimento il tavolo e la palla urtata nella collisione:
void Palla::urto(Tavolo &t, Palla &p){ num_urti++; //urto tra biglie, urto elastico //avendo supposto le biglie puntiformi e //quindi di massa uguale, nell'urto le biglie si //scambiano le velocità double tmpx, tmpy; tmpx = vx; tmpy = vy; vx = p.vx; vy = p.vy; p.vx = tmpx; p.vy = tmpy;
coll = false; //collisione risolta
}
e questa è il metodo simula: void Tavolo::simula(int t) { for(int s=0; s<t; s++) { // Per ogni passo di simulazione for(int i=0; i<9; i++) { // per ogni palla if(p[i].inGioco()) { // se la palla e' in gioco if(p[i].libera(*this)){ p[i].avanza(*this); // fa avanzare la //palla,passa il tavolo altrimenti la palla // non sa le dimensioni e non puo' verificare //urti coi bordi } else{ //collide ritorna il riferimento alla palla //colpita da p[i]; p[i].urto(*this, p[i].collide(*this));//urto aggiorna velocità delle palle che intervengono nell'urto p[i].avanza(*this); }
for(int j=0; j<6; j++) // se e' andata in buca la elimina if(b[j].inBuca(p[i])){ p[i].stampa(); cout << "in buca!!!" << endl; p[i].disattiva(); break; // esce dal for(j...) } } } } }
---In conclusione: il programma compila, sempre che io abbia scritto correttamente il codice, viene effettuata la simulazione, però di fatto come è normale che sia non si verificano urti perchè il controllo sull'urto viene fatto confrontando double, DOMANDA:
non sarebbe quindi opportuno cambiare la struttura della classe e rappresentare le posizioni delle palle con variabili di tipo intero?
Non sono entrato nel dettaglio del codice riga per riga ma come impostazione e' certamente corretto. RISPOSTA:
piuttosto che snaturare il problema passando a int e quindi effettuando una quantizzazione dello spazio penso sarebbe piu' semplice sostituire la verifica di uguaglianza della posizione delle due palle con la verifica che la loro distanza sia minore di una certa costante (che poi sarebbe il raggio della palla reale).
Si in effetti la soluzione di effettuare la quantizzazione risulata più complicata, inoltre richiederebbe la modifica di gran parte del codice dell'esercizio, mentre questa che mi ha proposto è anche più attinente al problema in questione. Grazie per la dritta
Ho sostituito il file zip contenente le implementazioni perche' in quello pubblicato in precedenza mancava l'esercizio 8. Adesso e' tutto completo.
RispondiEliminaSalve prof, ho dato uno sguardo all'esercizio sulla simulazione del tavolo da biliardo.
RispondiEliminaDopo aver compreso la sua implementazione(non mi era chiaro come svolgere l'esercizio e quali metodi implementare), ho pensato di estendere il programma prevedendo anche l'urto tra biglie.
Ho pensato di fare un controllo sulle posizioni delle biglie prima di procedere con il successivo spostamento, cioè se la biglia si trova sulla stessa posizione di un'altra non procedo subito con lo spostamento ma prima dovrei fare eseguire un metodo della classe Palla che mi aggiorna le velocità delle due palle che intervengono nell'urto.
Mentre se la palla è libera da impatto con altre palle procedo normalmente con l'avanzamento unitario.
Ho aggiunto alla classe Palla 4 metodi:
Palla& collide(Tavolo&);
bool libera(Tavolo&);
void urto(Tavolo&, Palla&);
int getNum() const {return n;}
collide: verifica se ci sono collisioni tra la palla che richiama il metodo e un altra palla sul tavolo:
bool Palla::libera(Tavolo & t){
collide(t);
if(!coll){
return true; //se nn ci sono //collisioni la palla è libera di avanzare
}
else
return false;
}
Palla& Palla::collide(Tavolo& t){
for(int i = 0; i < 9; i++){
if((this->n)!=(t.getPalla(i).getNum())){
if( (this->xPos==(t.getPalla(i).getX())) &&
(this->yPos==(t.getPalla(i).getY())) ){
coll = true;
return (t.getPalla(i));
}
}
}
return *this;
}
Ecco anche il metodo urto(Tavolo&, Palla&) a cui passo per riferimento il tavolo e la palla urtata nella collisione:
void Palla::urto(Tavolo &t, Palla &p){
num_urti++;
//urto tra biglie, urto elastico
//avendo supposto le biglie puntiformi e //quindi di massa uguale, nell'urto le biglie si //scambiano le velocità
double tmpx, tmpy;
tmpx = vx; tmpy = vy;
vx = p.vx; vy = p.vy;
p.vx = tmpx; p.vy = tmpy;
coll = false; //collisione risolta
}
e questa è il metodo simula:
void Tavolo::simula(int t) {
for(int s=0; s<t; s++) { // Per ogni passo di simulazione
for(int i=0; i<9; i++) { // per ogni palla
if(p[i].inGioco()) { // se la palla e' in gioco
if(p[i].libera(*this)){
p[i].avanza(*this); // fa avanzare la //palla,passa il tavolo altrimenti la palla
// non sa le dimensioni e non puo' verificare //urti coi bordi
}
else{
//collide ritorna il riferimento alla palla //colpita da p[i];
p[i].urto(*this, p[i].collide(*this));//urto aggiorna velocità delle palle che intervengono nell'urto
p[i].avanza(*this);
}
for(int j=0; j<6; j++) // se e' andata in buca la elimina
if(b[j].inBuca(p[i])){
p[i].stampa();
cout << "in buca!!!" << endl;
p[i].disattiva();
break; // esce dal for(j...)
}
}
}
}
}
---In conclusione: il programma compila, sempre che io abbia scritto correttamente il codice, viene effettuata la simulazione, però di fatto come è normale che sia non si verificano urti perchè il controllo sull'urto viene fatto confrontando double, DOMANDA:
non sarebbe quindi opportuno cambiare la struttura della classe e rappresentare le posizioni delle palle con variabili di tipo intero?
Non sono entrato nel dettaglio del codice riga per riga ma come impostazione e' certamente corretto.
RispondiEliminaRISPOSTA:
piuttosto che snaturare il problema passando a int e quindi effettuando una quantizzazione dello spazio penso sarebbe piu' semplice sostituire la verifica di uguaglianza della posizione delle due palle con la verifica che la loro distanza sia minore di una certa costante (che poi sarebbe il raggio della palla reale).
Si in effetti la soluzione di effettuare la quantizzazione risulata più complicata, inoltre richiederebbe la modifica di gran parte del codice dell'esercizio, mentre questa che mi ha proposto è anche più attinente al problema in questione.
RispondiEliminaGrazie per la dritta