Programmazione/Progetti/Architettura3D/Stesura II

Da WikiDsy.
  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();"
  		}"
  	}       "
  }