private void calcolaRaggiToolStripMenuItem_Click(object sender, EventArgs e) { double xraggio, yraggio, alfraggio; FormTrasfo ft = new FormTrasfo(); ft.Text = "Inserimento del raggio, angolo in gradi"; ft.ShowDialog(); xraggio = ft.x; yraggio = ft.y; alfraggio = ft.r; Line2D lr; lr = new Line2D(new Point2D(xraggio,yraggio),new Point2D(10.0,alfraggio,true),true); Raggio r = new Raggio(lr,Ottica.LunghezzaOnda.linea_C); r.CorpoAttuale = completo.Matrice; List<Raggio> raggi; raggi = completo.CalcolaRaggio(r); MessageBox.Show(raggi.Count.ToString()); foreach(Raggio rr in raggi) rr.Display(displayList,1); Invalidate(); }
private void test6RaggiToolStripMenuItem_Click(object sender, EventArgs e) { List<Raggio> listaraggi = new List<Raggio>(); CorpoOttico lenteW = (CorpoOttico)singolo.GetOggetto(lente.GetNomeCorpoOttico()); double yraggio, i; for(i = -1.1; i <= 1.1; i+=0.05) { yraggio = lente.RL * i; Line2D lr = new Line2D(new Point2D(-10,yraggio),new Point2D(10.0,0,false),true); Raggio r = new Raggio(lr,Ottica.LunghezzaOnda.Verde); r.CorpoAttuale = singolo.Matrice; listaraggi.AddRange(lenteW.CalcolaRaggi(r,singolo.Matrice)); } MessageBox.Show(listaraggi.Count.ToString()); foreach(Raggio rr in listaraggi) rr.Display(displayList,1); Invalidate(); #pragma warning disable int tmp; tmp = 1; #pragma warning restore }
private void aggiungiRaggiECalcolaToolStripMenuItem_Click(object sender, EventArgs e) { List<Raggio> listaraggi = new List<Raggio>(); // Raggi complessivi List<Raggio>[] routs = new List<Raggio>[2]; // Raggi tratto superiore ed inferiore List<Raggio> rout = new List<Raggio>(); // I due raggi finali List<Point2D> fuoco = new List<Point2D>(); // I punti focali double ang = ((double)this.angolo) / 60.0; this.gradiprimi.Visible = false; this.percdiam.Visible = false; CorpoOttico lenteW = (CorpoOttico)singolo.GetOggetto(lente.GetNomeCorpoOttico()); if(lenteW != null) { double yraggio, i, xraggio, rmax; xraggio = Math.Max(lente.CT, lente.ET)*1.5; rmax = ((double)percentodiam)/100.0; for(i = 0.0; i <= rmax; i+=rmax/20.0) { yraggio = lente.RL * i; Line2D[] lr = new Line2D[2]; lr[0] = new Line2D(new Point2D(-xraggio,yraggio),new Point2D(10.0,ang,false),true); // raggio superiore lr[1] = new Line2D(new Point2D(-xraggio,-yraggio),new Point2D(10.0,ang,false),true); // raggio inferiore Raggio[] r = new Raggio[2]; r[0] = new Raggio(lr[0],Ottica.LunghezzaOnda.Rosso); r[1] = new Raggio(lr[1],Ottica.LunghezzaOnda.Rosso); r[0].CorpoAttuale = singolo.Matrice; r[1].CorpoAttuale = singolo.Matrice; routs[0] = lenteW.CalcolaRaggi(r[0],singolo.Matrice); // Raggi superiori routs[1] = lenteW.CalcolaRaggi(r[1],singolo.Matrice); // Raggi inferiori rout.Clear(); if(routs[0].Count > 1) rout.Add((routs[0])[routs[0].Count-1]); if(routs[1].Count > 1) rout.Add((routs[1])[routs[1].Count-1]); listaraggi.AddRange(routs[0]); if(yraggio!=0.0) listaraggi.AddRange(routs[1]); // Calcola intersezione if(rout.Count==2) { List<Intersection> pint; pint = Function2D.Intersect(rout[0],rout[1]); if(pint.Count>0) { Intersection intr = pint[0]; if((intr.t1>Raggio.CoincidenceDistance)&&(intr.t2>Raggio.CoincidenceDistance)) { rout[0].T2r=intr.t1; rout[1].T2r=intr.t2; fuoco.Add(intr.p); } } } } MessageBox.Show(listaraggi.Count.ToString()); foreach(Raggio rr in listaraggi) rr.Display(displayList,1); if(fuoco.Count > 0) { double xmin = Double.MaxValue; double xmax = -Double.MaxValue; double ymin = Double.MaxValue; double ymax = -Double.MaxValue; foreach(Point2D p in fuoco) { if(xmin > p.x) xmin = p.x; if(xmax < p.x) xmax = p.x; if(ymin > p.y) ymin = p.y; if(ymax < p.y) ymax = p.y; } MessageBox.Show(String.Format("Fuoco:\nX tra {0} e {1}\nY tra {2} e {3}",xmin,xmax,ymin,ymax)); } } Invalidate(); }
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; }
private void test5ToolStripMenuItem_Click(object sender,EventArgs e) { Line2D lin = new Line2D(0,0,1,1); Raggio ray0 = new Raggio(lin,700); Matrix mm = Matrix.Lower(4); Matrix mm1 = !mm; Point2D p1 = new Point2D(1, 0); Point2D p2 = new Point2D(0, 1); Point2D p3 = new Point2D (0,2); Point2D pc = new Point2D (0,0); Point2D p4 = new Point2D (2, 1); Point2D p1w = new Point2D(1, -0.01); Arc2D ar1 = new Arc2D(pc, p1, p2); Line2D ln1 = new Line2D(p2, p3); Line2D ln2 = new Line2D(p4, p3); Line2D ln3; ln3 = new Line2D(p4,p1); CorpoOttico cc = new CorpoOttico(new MaterialeOttico("vetro",1.4)); cc.Add(new Contorno(ln3)); cc.Add(new Contorno(ln2)); cc.Add(new Contorno(ln1)); cc.Add(new Contorno(ar1)); cc.Validate(); Point2D po = new Point2D(1.5, -1); Arc2D cerchio = new Arc2D(po, 4); Raggio ray; ray = new Raggio(new Line2D(po, p1 + new Point2D(0.05,0)),Ottica.LunghezzaOnda.Rosso); List<Intersection> intersezioni = cc.TrovaIntersezioniPositive(ray); Contorno xx = cc.Contorno(intersezioni[0].tr2); #pragma warning disable int tmp; tmp = 1; }
/// <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; }
/// <summary> /// Restituisce la lista di raggi (sempre nulla, non interagisce) /// </summary> /// <param name="rIncidente"></param> /// <param name="ambiente"></param> /// <returns></returns> public override List<Raggio> CalcolaRaggi(Raggio rIncidente, MaterialeOttico ambiente) { return new List<Raggio>(); }
public abstract List<Raggio> CalcolaRaggi(Raggio rIncidente, MaterialeOttico ambiente);
/// <summary> /// Calcola il percorso di un raggio /// </summary> /// <param name="rIncidente"></param> /// <returns></returns> public List<Raggio> CalcolaRaggio(Raggio rIncidente) { Raggio rIni; List<Raggio> lr = new List<Raggio>(); // Crea la lista complessiva, vuota if(rIncidente == null) // Se raggioIni e` nullo, esce dalla funzione return lr; if(!rIncidente.IsValid) return lr; rIni = rIncidente; // Imposta raggioIni pari a rIncidente. for(int countmax = 1000; (rIni != null) && (countmax>0); countmax--) // Ciclo di calcolo { OggettoOttico primoOgg = null; // Inizializza il riferimento double tmin = double.MaxValue; // e il parametro tmin Intersection inter; foreach(OggettoOttico ogg in oggetti) // Trova il primo oggetto intersecato dal raggioIni { // Percorre tutti gli elementi della lista ambient. inter = ogg.TrovaIntersezione(rIni); // Trova la prima intersezione positiva if(inter != null) { if(inter.t1 < tmin) // Se la t1 (relativa alla retta) e` minore di tmin { tmin = inter.t1; // Memorizza t1 e oggetto primoOgg = ogg; } } } if(primoOgg != null) // Se ha trovato il primo oggetto intersecato, prosegue. { // Trova i raggi del primo oggetto List<Raggio> lro = primoOgg.CalcolaRaggi(rIni,this.matrice); if(lro.Count > 0) // Se la lista non e` vuota { rIni = lro[lro.Count-1]; // Estrae l'ultimo elemento e lo mette nel raggioIni lro.RemoveAt(lro.Count-1); // Elimina l'ultimo elemento della lista lr.AddRange(lro); // Aggiunge la lista alla lista complessiva } } else // Se non ha trovato il primo oggetto intersecato { lr.Add(rIni); // Aggiunge rIni alla lista complessiva rIni = null; // poi lo azzera; } } return lr; #warning Funzione principale di calcolo ottico da verificare ! }
/// <summary> /// Crea la lista dei raggi generati dalla sorgente ottica /// </summary> /// <returns></returns> public List<Raggio> CreaRaggi() { List<Raggio> lr = new List<Raggio>(); int nr = (int)(((float)nraggi)/2.0 + float.Epsilon) + 1; Point2D vettore = lineaRaggio.Vector(); // Direzione double alfa = vettore.Alfa(); // Angolo Point2D normale = vettore.Normal(); // Normale Point2D vmeta = normale * diametro * 0.5; // Vettore di meta` lunghezza for(int i=0; i<nr; i++) { Point2D vp, vm, pp, pm; double ap, am, ang; double fraz = ((double)i)/((double)nr); // Frazione punti i-esimo vp = fraz * vmeta; // Offset dei due raggi vm = - vp; pp = lineaRaggio.P1 + vp; // Origini pm = lineaRaggio.P1 + vm; ang = divergenza * fraz; // Angoli dei due raggi ap = alfa + ang; am = alfa - ang; Line2D lp,lm; lp = new Line2D(pp.x,pp.y,ap,1.0,true,true); // Linee lm = new Line2D(pm.x,pm.y,am,1.0,true,true); Raggio rp, rm; rp = new Raggio(lp,this.lambda); // Raggi rm = new Raggio(lm,this.lambda); lr.Add(rp); // Li aggiunge alla lista lr.Add(rm); } return lr; }