예제 #1
0
			Raggio CalcolaRaggio(Raggio rIn, CorpoOttico ambiente)
				{
				Raggio rout = null;
				if(ambiente==null)									// controlli iniziali
					return rout;
				if((!ambiente.Ambiente) || (!ambiente.IsValid))
					return rout;
				Intersection fint = TrovaPrimaIntersezione(rIn);	// Trova prima intersezione
				if(fint != null)
					{
					List<Contorno> lc = Belongs(fint.p);			// Trova i contorni cui appartiene la prima intersezione
					if(lc.Count > 2)								// Se piu` di due tratti: errore
						throw new Exception("Intersezione unica di un raggio con piu` di due tratti, in CalcolaRaggio()");
					if(lc.Count == 2)								// Se due tratti: su vertica
						{
						if(Tangenti(lc[0].Tratto, lc[1].Tratto))	// Se tangenti, considero intersezione su uno dei due, equivalente
							{
							if(lc[0].Stato != lc[1].Stato)			// Se hanno uno stato superficiale diverso, elimina il raggio
								{
								lc.Clear();
								}
							else									// altrimenti
								lc.Remove(lc[1]);					// elimino l'ultimo contorno
							}
						}
					if(lc.Count == 1)								// Se una sola intersezione
						{
						Point2D versoreIn = rIn.Vector();			// Versori entrante (Raggio gia` normalizzato) e normale.
						Point2D versoreNorm = Function2D.VersorOut(fint.p, lc[0].Tratto, rIn.Point(fint.t1 - dimcar*FrazioneEpsilon));
						switch(lc[0].Stato)
							{
							case StatoSuperficie.Opaca:
								{
								// Non fa nulla, raggio assorbito, nessun raggio in uscita
								break;
								}
							case StatoSuperficie.Riflettente:
								{
								rout = new Raggio(new Line2D(fint.p, Ottica.Riflesso(versoreIn, versoreNorm), true));
								rout.CorpoAttuale = rIn.CorpoAttuale;
								break;
								}
							case StatoSuperficie.Trasparente:
								{
								CorpoOttico co_in, co_out;			// Corpi ottici del raggio in ingresso ed uscita
								co_in = rIn.CorpoAttuale;
								if(co_in == this)					// Se il raggio entrante si trova nel corpo ottico
									{
									co_out = ambiente;				// quello uscente nell'ambiente
									}
								else								// se no, da ambiente...
									{
									co_out = this;					// a corpo attuale
									}
								Point2D vrifr = Ottica.Rifratto(versoreIn, versoreNorm, co_in.IndiceRifrazione,  co_out.IndiceRifrazione);
								if(vrifr != null)
									{
									rout = new Raggio(new Line2D(fint.p, vrifr, true));
									// throw new Exception("Manca determinazione se il raggio parte dall'esterno o dall'interno, per scegliere n1->n2 o n2->n1 ");
									rout.CorpoAttuale = co_out;
									}
								break;
								}
							}
						}
					}
				return rout;
				}
예제 #2
0
			/// <summary>
		/// Funzione principale di calcolo ottico
		/// </summary>
		/// <param name="rIncidente"></param>
		/// <param name="ambiente"></param>
		/// <returns></returns>
		public override List<Raggio> CalcolaRaggi(Raggio rIncidente, MaterialeOttico ambiente) 
			{
			List<Raggio> lR = new List<Raggio>();			// Lista di raggi
			if(ambiente !=null)								// Controllo iniziale
				{
				Raggio r1 = null;							// Raggio entrante
				Raggio r2 = null;							// Raggio uscente
				for(r1 = rIncidente; r1 != null; r1 = r2)	// Ciclo di calcolo
					{
					r2 = null;
					Intersection fint = TrovaIntersezione(r1);		// Trova prima intersezione di r1 con il corpo ottico
					if(fint != null)								// Se non la trova, r2 resta null	
						{
						List<Contorno> lc = Belongs(fint.p);		// Trova i contorni cui appartiene la prima intersezione
						if(lc.Count > 2)							// Se piu` di due tratti: errore
							throw new Exception("Intersezione unica di un raggio con piu` di due tratti, in CalcolaRaggio()");
						if(lc.Count == 2)								// Se due tratti: su vertice
					        {
					        if(Tangenti(lc[0].Tratto, lc[1].Tratto))	// Se tangenti, considero intersezione su uno dei due, equivalente
					            {
					            if(lc[0].Stato != lc[1].Stato)			// Se hanno uno stato superficiale diverso, elimina il raggio
					                {
					                lc.Clear();
					                }
					            else									// altrimenti
					                lc.Remove(lc[1]);					// elimino l'ultimo contorno...
					            }										// ...e proseguo al prossimo if
					        }
						if(lc.Count == 1)								// Se una sola intersezione
							{
							Point2D versoreIn = r1.Vector();			// Versori entrante (Raggio gia` normalizzato) e normale.
							Point2D versoreNorm = Function2D.VersorOut(fint.p, lc[0].Tratto, r1.Point(fint.t1 - dimcar*FrazioneEpsilon));
							switch(lc[0].Stato)
								{
								case StatoSuperficie.Opaca:
					                {
					                break;								// Non fa nulla, raggio assorbito, nessun raggio in uscita
					                }
								case StatoSuperficie.Riflettente:		// Calcola raggio riflesso
					                {									
					                r2 = new Raggio(new Line2D(fint.p, Ottica.Riflesso(versoreIn, versoreNorm), true),r1.Lambda);
					                r2.CorpoAttuale = r1.CorpoAttuale;
					                break;
					                }
					            case StatoSuperficie.Trasparente:
					                {
					                MaterialeOttico co1, co2;			// Corpi ottici del raggio in ingresso ed uscita
					                co1 = r1.CorpoAttuale;
					                if(co1 == this.Materiale)			// Se il raggio entrante si trova nel corpo ottico
					                    {
					                    co2 = ambiente;					// quello uscente nell'ambiente
					                    }
					                else								// se no, da ambiente...
					                    {
					                    co2 = this.Materiale;			// ...a corpo attuale
					                    }
					                Point2D vrifr = Ottica.Rifratto(versoreIn, versoreNorm, co1.nRifrazione,  co2.nRifrazione);
					                if(vrifr != null)
					                    {
					                    r2 = new Raggio(new Line2D(fint.p, vrifr, true),r1.Lambda);
										r2.CorpoAttuale = co2;
					                    #warning Manca determinazione se il raggio parte dall'esterno o dall'interno
					                    }
					                break;
					                }
								}
							
							}
						r1.T2r = fint.t1;
						}
					lR.Add(r1);
					}
				}
			return lR;
			}