Programmazione/Progetti/Architettura3D/Stesura II
Versione del 3 feb 2006 alle 09:14 di Yoruno (discussione | contributi)
import prog.io.*; import java.lang.Math; import java.util.List; import java.util.LinkedList; import java.util.Set; import java.util.HashSet; import java.util.Iterator; class Figura3DException extends RuntimeException { public Figura3DException(String message) {" super(message);" }" } /** Questa classe e' stata creata per poter derivare piu' facilmente le sottoclassi" relative alle varie figure senza apportare modifiche ai metodi fissati di Figura3D." */ abstract class Figura3DAutomatica extends Figura3D { protected double[] prms;" /**" Crea una nuova Figura3DAutomatica contenente un numero specificato di parametri." @param numprms il numero dei parametri della figura" */" public Figura3DAutomatica(int numprms) {" prms=new double[numprms];" }" /**" Controlla che il parametro fornito sia valido; se non lo e', solleva un'eccezione." @param parametro il parametro da controllare" @return il parametro stesso" */" protected double check(double parameter) {" if(parameter<=0) throw new Figura3DException(this.getClass().getName()+"": Parametro errato!"");" return parameter;" }" /**" Imposta i parametri relativi ad una figura, effettuando i test di correttezza." @param param l'array di double contenente i parametri" */" public void setParametri(double[] param) {" if(param.length==prms.length) {" for(int i=0; i<param.length; i++) {" check(param[i]);" }" } else throw new Figura3DException(this.getClass().getName()+"": Numero di parametri errato!"");" prms=(double[])param.clone();" }" /**" Restituisce un'array contenente i parametri della figura." @return i parametri della figura sotto forma di array di double" */" public double[] getParametri() {" return (double[])prms.clone();" }" /**" Restituisce una rappresentazione testuale della figura, nel formato:" NomeFigura: parametro0 = n0, parametro1 = n1, ... parametrom = nm" @return una rappresentazione testuale della figura" */" public String toString() {" String stringRepresentation=""Figura3DAutomatica:"";" for(int i=0; i<prms.length; i++) {" stringRepresentation+="" parametro""+i+"" = ""+prms[i];" }" return stringRepresentation;" }" /* Questo metodo e' stato abbandonato a favore di quello che segue poiche'" forniva a volte risultati errati, e non avevo voglia di trovare il motivo." public boolean equals(Object shape) {" if(!(shape instanceof Figura3DAutomatica)) return false; else {" double[] shapePrms=((Figura3D)shape).getParametri();" if(shapePrms.length!=prms.length) return false; else {" for(int i=0; i<prms.length; i++) {" if(shapePrms[i]!=prms[i]) return false;" }" return true;" }" }" }" */ /**" Confronta la figura con un'altra figura per congruenza." @param shape la figura da confrontare" @return true se le due figure sono congruenti, altrimenti false" */" public boolean equals(Object shape) {" if(!(shape instanceof Figura3DAutomatica)) return false; else {" if(shape.toString().equals(this.toString())) return true;" else return false;" }" }" } class Sfera extends Figura3DAutomatica { protected final short R=0;" public Sfera(double r) {" super(1);" prms[R]=check(r);" }" public double getVolume() {" return (4.0/3.0)*Math.PI*Math.pow(prms[R], 3);" }" public double getSuperficie() {" return 4.0*Math.PI*Math.pow(prms[R], 2);" }" public String toString() {" return ""Sfera: raggio = ""+prms[R];" }" } class Parallelepipedo extends Figura3DAutomatica { protected final short A=0;" protected final short B=1;" protected final short H=2;" public Parallelepipedo(double a, double b, double h) {" super(3);" prms[A]=check(a);" prms[B]=check(b);" prms[H]=check(h);" }" public double getVolume() {" return prms[A]*prms[B]*prms[H];" }" public double getSuperficie() {" return 2*(prms[H]*(prms[A]+prms[B])+prms[A]*prms[B]);" }" public String toString() {" return ""Parallelepipedo: latoA = ""+prms[A]+"", latoB = ""+prms[B]+"", altezza = ""+prms[H];" }" } class Cubo extends Parallelepipedo { protected final short SIDE=0;" public Cubo(double side) {" super(side, side, side);" }" public void setParametri(double[] prms) {" double[] prmsSuper={prms[SIDE], prms[SIDE], prms[SIDE]};" super.setParametri(prmsSuper);" }" public double[] getParametri() {" double[] prms={super.prms[super.H]};" return prms;" }" public String toString() {" // Stampo 'raggio' perche' cosi' e' nei risultati di esempio" return ""Cubo: raggio = ""+prms[SIDE];" }" } class TroncoDiCono extends Figura3DAutomatica { protected final short R1=0;" protected final short R2=1;" protected final short H=2;" public TroncoDiCono(double r1, double r2, double h) {" super(3);" prms[R1]=check(r1);" prms[R2]=check(r2);" prms[H]=check(h);" }" /**" Crea un tronco di cono col raggio minore nullo, ad uso esclusivo" delle sottoclassi." @param r1 il raggio maggiore" @param h l'altezza" */" protected TroncoDiCono(double r1, double h) {" super(3);" prms[R1]=check(r1);" prms[R2]=0;" prms[H]=check(h);" }" public double getVolume() {" return (Math.PI/3.0)*(prms[R1]*prms[R2]+Math.pow(prms[R1], 2)+Math.pow(prms[R2], 2))*prms[H];" }" public double getSuperficie() {" return Math.PI*(prms[R1]+prms[R2])*Math.sqrt(Math.pow(prms[R1]-prms[R2], 2)+Math.pow(prms[H], 2));" }" public String toString() {" return ""Tronco di cono: raggio grande = ""+prms[R1]+"", raggio piccolo = ""+prms[R2]+"", altezza = ""+prms[H];" }" } class Cilindro extends TroncoDiCono { protected final short R=0;" protected final short H=1;" public Cilindro(double r, double h) {" super(r, r, h);" }" public void setParametri(double[] prms) {" double[] prmsSuper={prms[R], prms[R], prms[H]};" super.setParametri(prmsSuper);" }" public double[] getParametri() {" double[] prmsSub={prms[super.R1], prms[super.H]};" return prmsSub;" }" public String toString() {" return ""Cilindro: raggio = ""+prms[super.R1]+"", altezza = ""+prms[super.H];" }" } class Cono extends TroncoDiCono { protected final short R=0;" protected final short H=1;" public Cono(double r, double h) {" super(r, h);" }" public void setParametri(double[] prms) {" // TroncoDiCono non accetta, da specifiche, 0 come raggio minore" double[] prmsSuper={prms[R], 1, prms[H]};" super.setParametri(prmsSuper);" super.prms[super.R2]=0;" }" public double[] getParametri() {" double[] prmsSub={prms[super.R1], prms[super.H]};" return prmsSub;" }" public String toString() {" return ""Cono: raggio = ""+prms[super.R1]+"", altezza = ""+prms[super.H];" }" } class TipoNonPrevistoException extends Exception { public TipoNonPrevistoException(String msg) {" super(msg);" }" } class Architettura3D { private List shapes;" boolean modified=false;" Set cachedAccountables;" private double volume;" private double area;" private double meanVolume;" private double meanArea;" /**" Crea un nuovo insieme di Figura3D." */" public Architettura3D() {" shapes=new LinkedList();" }" /**" Aggiunge una figura all'insieme." @param figura la figura da aggiungere" */" public void addFigura3D(Figura3D figura) {" shapes.add(figura);" modified=true;" }" /**" Restituisce un'array contenente le figure appartenenti all'insieme." @return le figure appartenenti all'insieme" */" public Figura3D[] getFigure3D() {" Object[] tempArray=shapes.toArray();" Figura3D[] finalArray=new Figura3D[tempArray.length];" for(int i=0; i<tempArray.length; i++) {" finalArray[i]=(Figura3D)tempArray[i];" }" return finalArray;" }" /**" Calcola volume totale, area totale, volume medio e area media di quelle figure" il cui nome di classe e' contenuto nell'insieme accountables sotto forma di stringa," o di tutte le figure dell'architettura se accountables e' l'insieme vuoto." @param accountables i nomi delle classi delle figure da considerare" */" private void calculateOverviewData(Set accountables) {" int count=0;" if(modified || !accountables.equals(cachedAccountables)) {" volume=area=0;" Iterator i=shapes.iterator();" while(i.hasNext()) {" Figura3D shape=(Figura3D)i.next();" if(accountables.isEmpty() || accountables.contains(shape.getClass().getName())) {" volume+=shape.getVolume();" area+=shape.getSuperficie();" count++;" }" }" // Anche se dovrebbe essere count!=0 sempre, controlliamo ugualmente" if(count!=0) {" meanVolume=volume/count;" meanArea=area/count;" } else meanVolume=meanArea=0;" modified=false;" cachedAccountables=accountables;" }" }" /**" Crea un insieme di nomi di classi di figure basandosi su una stringa che rappresenta" un tipo di figure; tale stringa puo' essere: ""SC"", per Sfera e Cilindro; ""PC"", per" Parallelepipedo e Cubo; ""TC"" per TroncoDiCono e Cono. La stringa ""TUTTE"" fa restituire" l'insieme vuoto, mentre qualunque altra stringa solleva un'eccezione." @param tipoFigura la stringa che rappresenta il tipo di figure" @return l'insieme dei nomi delle classi delle figure rappresentate" */" private Set resolveType(String tipoFigura) throws TipoNonPrevistoException {" Set accountables=new HashSet();" if(tipoFigura.equals(""SC"")) {" accountables.add(""Sfera"");" accountables.add(""Cilindro"");" } else if(tipoFigura.equals(""PC"")) {" accountables.add(""Parallelepipedo"");" accountables.add(""Cubo"");" } else if(tipoFigura.equals(""TC"")) {" accountables.add(""TroncoDiCono"");" accountables.add(""Cono"");" } else if(!tipoFigura.equals(""TUTTE"")) {" throw new TipoNonPrevistoException(""Il tipo ""+tipoFigura+"" non e' previsto!"");" }" return accountables;" }" /**" Restituisce il volume totale che raggiungono le figure di tipo tipoFigura." @param tipoFigura la stringa che rappresenta il tipo di figure" @return il volume totale" */" public double getVolume(String tipoFigura) throws TipoNonPrevistoException {" Set accountables=resolveType(tipoFigura);" calculateOverviewData(accountables);" return volume;" }" /**" Restituisce la superficie totale che raggiungono le figure di tipo tipoFigura." @param tipoFigura la stringa che rappresenta il tipo di figure" @return la superficie totale" */" public double getSuperficie(String tipoFigura) throws TipoNonPrevistoException {" Set accountables=resolveType(tipoFigura);" calculateOverviewData(accountables);" return area;" }" /**" Restituisce il volume medio delle figure presenti nell'architettura." @return il volume medio" */" public double getVolumeMedio() throws TipoNonPrevistoException {" Set accountables=resolveType(""TUTTE"");" calculateOverviewData(accountables);" return meanVolume;" }" /**" Restituisce il volume medio delle figure presenti nell'architettura." @return la superficie media" */" public double getSuperficieMedia() throws TipoNonPrevistoException {" Set accountables=resolveType(""TUTTE"");" calculateOverviewData(accountables);" return meanArea;" }" /**" Restituisce un riferimento ad una figura dell'architettura congruente" a fig, se esiste; altrimenti restituisce il riferimento nullo." @param fig la figura da cercare nell'architettura" @return una figura dell'architettura congruente a fig, o null" */" public Figura3D trova(Figura3D fig) {" int index=shapes.indexOf(fig);" if(index==-1) return null; else {" return (Figura3D)shapes.listIterator(index).next();" }" } " }