/// <summary> /// Costruttore da linea e lunghezza d'onda /// </summary> /// <param name="l">Linea</param> /// <param name="lambda">Lunghezza d'onda in nm (1e-9 m)</param> public Raggio(Line2D l, double lambda) : base(l) { // Chiama il costruttore della classe base (che comprende Line2D.Validate() t1r = 0.0; t2r = 1.0; this.lambda = lambda; this.Validate(); // poi chiama Raggio.Validate() }
/// <summary> /// Intersezione tra linea e tratto generico /// </summary> /// <param name="l1">Linea</param> /// <param name="te">Tratto</param> /// <param name="bCheckInside1">Richiesta intersezione interna alla linea</param> /// <param name="bCheckInside2">Richiesta intersezione interna al tratto</param> /// <returns></returns> public static List<Intersection> Intersect( Line2D l1, Tratto te, bool bCheckInside1 = false, bool bCheckInside2 = false) { Type tp; tp = te.GetType(); if(tp == typeof(Line2D)) { return Intersect( l1, (Line2D)te, bCheckInside1 , bCheckInside2 ); } if(tp == typeof(Arc2D)) { return Intersect( l1, (Arc2D)te, bCheckInside1 , bCheckInside2 ); } throw new Exception("Tipo non implementato"); }
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(); }
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; }
private void test3ToolStripMenuItem_Click(object sender,EventArgs e) { Point2D p1 = new Point2D(1, 0); Point2D p2 = new Point2D(0, 1); Point2D p3 = new Point2D (1,1); Point2D pc = new Point2D (0,0); Arc2D ar1 = new Arc2D(pc, p1, p2); Arc2D ar2 = new Arc2D(pc, p2, p1); Arc2D ar3 = new Arc2D(p3, p2); Line2D ln1 = new Line2D(p1, p2); Line2D ln2 = new Line2D(pc, p3); Line2D ln3 = new Line2D(0,0,30,3,false,true); List<Contorno> profilo = new List<Contorno>(); profilo.Add(new Contorno(ln1)); profilo.Add(new Contorno(ln2)); profilo.Add(new Contorno(ar1)); List<Intersection> li1 = Function2D.Intersect(ln1, profilo[1].Tratto); CorpoOttico blocco = new CorpoOttico(new MaterialeOttico("vetro",1.4)); #pragma warning disable int tmp; tmp = 1; #pragma warning restore }
/// <summary> /// Trova la prima intersezione della linea con il corspo ottico, da P1 in poi, oppure null. /// </summary> /// <param name="lin">La linea</param> /// <returns></returns> public Intersection TrovaPrimaIntersezione(Line2D lin) { List<Intersection> li = this.TrovaIntersezioniPositive(lin); if(li.Count > 0) return li[0]; else return new Intersection(null, 0, 0, null, null); }
/// <summary> /// Costruttore di copia /// </summary> /// <param name="l">Linea</param> public Line2D(Line2D l) : base(typeof(Line2D)) { this.p1 = l.p1; this.p2 = l.p2; Validate(); }
public abstract Intersection TrovaIntersezione(Line2D lin);
/// <summary> /// Linea (modulo unitario) per il punto p normale ad l /// </summary> /// <param name="p">Punto p</param> /// <param name="l">Linea l</param> /// <param name="ext">Punto esterno opzionale per definire il verso</param> /// <returns>La linea normale o null se non trovata </returns> public static Line2D LineOut( Point2D p, Line2D l, Point2D ext = null) { Line2D vOut; if( ! LineOut( p, l, out vOut, ext)) vOut = null; return vOut; }
/// <summary> /// Versore (modulo unitario) per il punto p normale ad l /// </summary> /// <param name="p">Punto p</param> /// <param name="l">Linea l</param> /// <param name="vOut">Versore (parametro out)</param> /// <param name="ext">Punto esterno opzionale per definire il verso</param> /// <returns>true se trovato</returns> public static bool VersorOut( Point2D p, Line2D l, out Point2D vOut, Point2D ext = null) { bool prf; Point2D pr; vOut = null; prf = Projection(p, l, out pr, true); // Proiezione su curva (appartenente) if(prf) // Se trovata... { Point2D normale = l.Vector().Normal(); // Normale per il punto di proiezione if(ext != null) { double scalare = (ext-pr) ^ normale; // Scalare tra vettore uscente e normale calcolata if(scalare < 0) normale = -normale; // Inverte } vOut = normale; // Versore da pr, lunghezza unitaria } return prf; // restituisce false se errore }
/// <summary> /// Distanza punto - retta /// </summary> /// <param name="p">Punto</param> /// <param name="l">Linea</param> /// <returns></returns> public static double Distance(Point2D p, Line2D l) { // Scalare tra versore normale return (p - l.P2) ^ ((l.Vector()).Normal()); // e segmento Po - P1 o Po - P2 }
/// <summary> /// Proiezione di un punto su una linea /// </summary> /// <param name="p">Punto</param> /// <param name="l">Linea</param> /// <param name="bInside">true se richiesta appartenenza proiezione all'interno della linea</param> /// <returns>La proiezione</returns> public static Point2D Projection( Point2D p, Line2D l, bool bInside = false) { Point2D proj; if( ! Projection( p, l, out proj, bInside)) // Cerca il punto proj = null; // Se non trova: imposta a null return proj; }
/// <summary> /// Proiezione di un punto su una linea /// </summary> /// <param name="p">Punto</param> /// <param name="l">Linea</param> /// <param name="projection">Proiezione (parametro out)</param> /// <param name="bInside">true se richiesta appartenenza proiezione all'interno della linea</param> /// <returns>true se trovata</returns> public static bool Projection( Point2D p, Line2D l, out Point2D projection, bool bInside = false) { Point2D tmp = l.Vector().Normal(); Line2D prLine = new Line2D(p, l.Vector().Normal(), true); // Calcola normale al segmento passante per p List<Intersection> lint = Function2D.Intersect(l, prLine, bInside, false); // Interseca linea e normale, chiede eventuale appartenenza a linea if(lint.Count > 0) // Se trovata almeno una intersezione { projection = (lint[0]).p; // Estrae il punto di intersezione dal primo elemento della lista return true; } projection = new Point2D(); // Se non trova intersezione o se bInside e fuori dal segmento return false; // restituisce false + punto vuoto }
/// <summary> /// Punto piu` vicino a p, su una linea /// </summary> /// <param name="p">Punto p</param> /// <param name="l">Linea</param> /// <param name="bInside">true se richiesta intersezione interna alla linea</param> /// <returns>Il punto trovato, se no null</returns> public static Point2D Nearest( Point2D p, Line2D l, bool bInside = false) { Point2D nearest; double distance; if( ! Nearest(p, l, out nearest, out distance, bInside)) // Cerca il punto. nearest = null; // Se non trova: imposta a null return nearest; }
/// <summary> /// Punto piu` vicino a p, su una linea /// </summary> /// <param name="p">Punto p</param> /// <param name="l">Linea</param> /// <param name="nearest">Punto trovato (parametro out)</param> /// <param name="distance">Distanza (parametro out)</param> /// <param name="bInside">true se richiesta intersezione interna alla linea</param> /// <returns>true se trovato</returns> public static bool Nearest( Point2D p, Line2D l, out Point2D nearest, out double distance, bool bInside = false) { bool bFound = false; nearest = new Point2D(); distance = double.MaxValue; Point2D projection = new Point2D(); List<Point2D> plist = new List<Point2D>(); if(Function2D.Projection(p, l, out projection, bInside)) // Calcola la proiezione di p su l usando bInside { // Se la trova, la aggiunge alla lista plist.Add(projection); } if (bInside) // Se richiesto bInside, cioe` solo punti interni... { // al segmento, ne aggiunge anche gli estremi alla lista plist.Add(l.P1); // (se bInside e` false, la prioezione e` comunque plist.Add(l.P2); // il piu` vicino } bFound = Function2D.Nearest(p, plist, out nearest, out distance); // Cerca il punto piu` vicino nella lista return bFound; }
/// <summary> /// Costruttore per sorgente collimata /// </summary> /// <param name="nome">Nome oggetto</param> /// <param name="origine">Punto di origine</param> /// <param name="angolo">Angolo dell'asse del raggio</param> /// <param name="radianti">true se in radianti</param> /// <param name="diametro">Diametro del fascio</param> /// <param name="divergenza">Divergenza in radianti (tra raggio estremo ed asse)</param> /// <param name="lambda">Lunghezza d'onda</param> /// <param name="nraggi">Numero di raggi </param> public SorgenteOttica(string nome, Point2D origine, double angolo, bool radianti, double diametro, double divergenza, double lambda, int nraggi) : base(nome) { tipoSorgente = TipoSorgente.collimata; lineaRaggio = new Line2D(origine.x,origine.y,angolo,1.0,true,true); this.diametro = diametro; this.divergenza = divergenza; this.lambda = lambda; this.nraggi = nraggi; Validate(); }
/// <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; }
/// <summary> /// Versore (modulo unitario) per il punto p normale ad l /// </summary> /// <param name="p">Punto p</param> /// <param name="l">Linea l</param> /// <param name="ext">Punto esterno opzionale per definire il verso</param> /// <returns>Il versore normale o null se non trovato</returns> public static Point2D VersorOut( Point2D p, Line2D l, Point2D ext = null) { Point2D vOut; if( ! VersorOut( p, l, out vOut, ext)) vOut = null; return vOut; }
{} // Non fa nulla /// <summary> /// Restituisce prima intersezione positiva con una linea (sempre null) /// </summary> /// <param name="lin"></param> /// <returns></returns> public override Intersection TrovaIntersezione(Line2D lin) { return null; }
/// <summary> /// Linea (modulo unitario) per il punto p normale ad un arco /// </summary> /// <param name="p">Punto p</param> /// <param name="a">Arco</param> /// <param name="vOut">Linea normale (parametro out)</param> /// <param name="ext">Punto esterno opzionale per definire il verso</param> /// <returns>true se trovato</returns> public static bool LineOut( Point2D p, Arc2D a, out Line2D vOut, Point2D ext = null) { bool prf; Point2D pr; vOut = null; prf = Projection(p, a, out pr, true); // Proiezione su curva (appartenente) if(prf) // Se trovata... { Point2D normale = (pr - a.Center); // Normale per il punto di proiezione bool test = normale.Normalize(); // Normalizza modulo (false se fallisce) if(ext != null) { double scalare = (ext-pr) ^ normale; // Scalare tra vettore uscente e normale calcolata if(scalare < 0) normale = -normale; // Inverte } if(test) // controllo extra vOut = new Line2D(pr, normale, true); // Linea uscente da pr, lunghezza unitaria } return prf; // restituisce false se errore }
/// <summary> /// Trova intersezioni con la linea, solo se dopo P1, e le ordina /// </summary> /// <param name="lin">Linea</param> /// <returns></returns> public List<Intersection> TrovaIntersezioniPositive(Line2D lin) { List<Intersection> li = new List<Intersection>(); // Nuova lista vuota foreach(Contorno c in contorni) // Percorre i tratti di contorno { List<Intersection> lc; lc = Function2D.Intersect(lin, c.Tratto, false, true); // Cerca le intersezioni lc.ForEach(delegate(Intersection x) // Le aggiunge solo se strettamente positive (oltre P1 verso P2) { // Esclude la prima, se il punto iniziale della linea if( x.t1 > Double.Epsilon) // e` gia` sul contorno { li.Add(x); } } ); } li.Sort(CfrT1); // Ordina per distanza crescente li = EliminaIntersezioniDoppie(li); // Elimina punti coincidenti li.Sort(CfrT1); // Ordina di nuovo return li; }
/// <summary> /// Linea uscente /// </summary> /// <param name="p">Punto sul tratto</param> /// <param name="te">Tratto</param> /// <param name="vOut">Versore uscente (parametro out)</param> /// <param name="ext">Punto esterno opzionale</param> /// <returns>bool</returns> public static bool LineOut( Point2D p, Tratto te, out Line2D vOut, Point2D ext = null) { Type tp; tp = te.GetType(); if(tp == typeof(Line2D)) { return LineOut( p, (Line2D) te, out vOut, ext); } if(tp == typeof(Arc2D)) { return LineOut( p, (Arc2D) te, out vOut, ext); } throw new Exception("Tipo non implementato"); }
private void test1ToolStripMenuItem_Click(object sender, EventArgs e) { Point2D p1 = new Point2D(1, 0); Point2D p2 = new Point2D(0, 1); Point2D p3 = new Point2D (1,1); Point2D pc = new Point2D (0,0); Point2D p4 = new Point2D (0, -1); Point2D p5 = new Point2D (1, 2); Point2D p6 = new Point2D (1, -1); Arc2D ar1 = new Arc2D(pc, p1, p2); Arc2D ar1x = new Arc2D(p1, p2, pc, Arc2D.TrePunti.Estremi_e_Centro); Arc2D ar2 = new Arc2D(pc, p2, p1); Arc2D ar2x = new Arc2D(p2, p1, pc, Arc2D.TrePunti.Estremi_e_Centro); Arc2D ar3 = new Arc2D(p3, p2); Line2D ln1 = new Line2D(p1, p2); Line2D ln2 = new Line2D(pc, p3); Line2D ln3 = new Line2D(0,0,30,3,false,true); Line2D ln4 = new Line2D(pc, p2, true); Line2D ln5 = new Line2D(p2, p3); bool b1 = ar1.Belongs(0); bool b2 = ar1.Belongs(Math.PI/4); bool b3 = ar1.Belongs(Math.PI / 8); bool b4 = ln1.Belongs(p1); bool c1 = ar1.Belongs(new Point2D(0,1)); bool c2 = ar1.Belongs(new Point2D(1,0)); bool c3 = ar1.Belongs(new Point2D(Math.Sqrt(2)/2,Math.Sqrt(2)/2)); List<Intersection> li1 = Function2D.Intersect(ln1, ln2); List<Intersection> li2 = Function2D.Intersect(ln2, ar1); List<Intersection> li3 = Function2D.Intersect(ln2, ar1, true, true); List<Intersection> li4 = Function2D.Intersect(ln3, ar1); List<Intersection> li5 = Function2D.Intersect(ln2, ar2, false, true); List<Intersection> li6 = Function2D.Intersect(ln4, ar3, false, false); List<Intersection> li7 = Function2D.Intersect(ln5, ln3); Point2D[] nr = new Point2D[3]; double[] nrd = new double[3]; Function2D.Nearest(p2, ln2, out nr[0], out nrd[0]); Function2D.Nearest(p4, ln3, out nr[1], out nrd[1], true); Function2D.Nearest(p6, ln3, out nr[2], out nrd[2]); Point2D[] nrx = new Point2D[3]; nrx[0] = Function2D.Nearest(p2, ln2); nrx[1] = Function2D.Nearest(p4, ln3, true); nrx[2] = Function2D.Nearest(p6, ln3); Point2D[] pr = new Point2D[4]; bool[] prb = new bool[4]; prb[0] = Function2D.Projection(p3, ln2, out pr[0]); prb[1] = Function2D.Projection(p4, ln2, out pr[1]); prb[2] = Function2D.Projection(p6, ln2, out pr[2]); prb[3] = Function2D.Projection(p2, ln3, out pr[3]); Point2D[] prx = new Point2D[4]; prx[0] = Function2D.Projection(p3, ln2); prx[1] = Function2D.Projection(p4, ln2); prx[2] = Function2D.Projection(p6, ln2); prx[3] = Function2D.Projection(p2, ln3); Point2D[] pra = new Point2D[5]; bool[] prab = new bool[5]; prab[0] = Function2D.Projection(p6, ar2, out pra[0], true); prab[1] = Function2D.Projection(p5, ar1, out pra[1], true); prab[2] = Function2D.Projection(p5, ar2, out pra[2], true); prab[3] = Function2D.Projection(p5, ar2, out pra[3], false); prab[4] = Function2D.Projection(p4, ar3, out pra[4], true); Point2D[] prax = new Point2D[5]; prax[0] = Function2D.Projection(p6, ar2, true); prax[1] = Function2D.Projection(p5, ar1, true); prax[2] = Function2D.Projection(p5, ar2, true); prax[3] = Function2D.Projection(p5, ar2); prax[4] = Function2D.Projection(p4, ar3, true); Point2D x = new Point2D(10,-1); x = -x; Line2D[] vout = new Line2D[3]; bool[] bv = new bool[3]; bv[0] = Function2D.LineOut(pra[0], ar2, out vout[0], p6); bv[1] = Function2D.LineOut(pr[3], ln3, out vout[1], p3); bv[2] = Function2D.LineOut(pra[0], ar2, out vout[2], p2); Line2D[] voux = new Line2D[3]; voux[0] = Function2D.LineOut(pra[0], ar2, p6); voux[1] = Function2D.LineOut(pr[3], ln3, p3); voux[2] = Function2D.LineOut(pra[0], ar2, p2); Point2D[] vettori = new Point2D[3]; vettori[0] = voux[0].Vector(); vettori[1] = voux[1].Vector(); vettori[2] = voux[2].Vector(); Point2D[] vvout = new Point2D[3]; bool[] bvv = new bool[3]; bvv[0] = Function2D.VersorOut(pra[0], ar2, out vvout[0], p6); bvv[1] = Function2D.VersorOut(pr[3], ln3, out vvout[1], p3); bvv[2] = Function2D.VersorOut(pra[0], ar2, out vvout[2], p2); Point2D[] vvoux = new Point2D[3]; vvoux[0] = Function2D.VersorOut(pra[0], ar2, p6); vvoux[1] = Function2D.VersorOut(pr[3], ln3, p3); vvoux[2] = Function2D.VersorOut(pra[0], ar2, p2); double[] scalari = new double[3]; scalari[0] = vvoux[0]^vettori[0]; scalari[1] = vvoux[1]^vettori[1]; scalari[2] = vvoux[2]^vettori[2]; Point2D Punto2 = new Point2D(-5.17,9.91); Point2D Punto3 = new Point2D(-4.82,-10.08); Point2D centroX = new Point2D(94.48,1.64); Arc2D Arco = new Arc2D(Punto2,Punto3,centroX,Arc2D.TrePunti.Estremi_e_Centro); #pragma warning disable int tmp; tmp = 1; #pragma warning restore }
/// <summary> /// Interpolazione lineare /// Se la lista contiene un solo valore, lo restituisce comunque /// Se no interpola solo tra il primo e l'ultimo punto. /// </summary> /// <param name="punti">Lista punti ordinata secondo x</param> /// <param name="x">Valore x da interpolare</param> /// <returns>Valore interpolato linearmente oppure NaN se fuori limiti</returns> public static double InterpolazioneLineare(List<Point2D> punti, double x) { if(punti.Count == 1) // Se un solo valore, restiruisce la y ed esce return punti[0].y; if(punti.Count == 0) // Se nessuno, restiruisce NaN return Double.NaN; int imin, imax; // Percorre la lista e cerca i valori x precedente e successivo imin = imax = -1; double xmin, xmax; xmin = Double.MinValue; xmax = Double.MaxValue; for(int i=0; i<punti.Count; i++) { double px = punti[i].x; if( (px >= x) && (px < xmax) ) { imax = i; xmax = px; } if( (px <= x) && (px > xmin) ) { imin = i; xmin = px; } } if( (imin==-1) || (imax==-1)) // Punto esterno all'intervallo return Double.NaN; double t; // Calcola la posizione di x if(xmax-xmin <= Double.Epsilon) t = 0.5; else t = (x-xmin)/(xmax-xmin); Line2D l = new Line2D(punti[imin],punti[imax]); return l.Point(t).y; }
private void test4ToolStripMenuItem_Click(object sender,EventArgs e) { 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); // ln3 = new Line2D(p4,p1w); 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); Line2D ray; ray = new Line2D(po, p1 + new Point2D(0.05,0)); ray.Normalize(); List<Intersection> intersezioni = cc.TrovaIntersezioniPositive(ray); #pragma warning disable int tmp; tmp = 1; #pragma warning restore }
/// <summary>Costruttore vuoto</summary> public SorgenteOttica() : base() { tipoSorgente = TipoSorgente.collimata; lineaRaggio = new Line2D(); divergenza = new Angolo(0.0); Validate(); }
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 }
/// <summary>Costruttore di copia</summary> /// <param name="sorgente"></param> public SorgenteOttica(SorgenteOttica sorgente) : base(sorgente.Nome) { this.tipoSorgente = sorgente.tipoSorgente; this.arco = sorgente.arco; this.diametro = sorgente.diametro; this.divergenza = sorgente.divergenza; this.lambda = sorgente.lambda; this.nraggi = sorgente.nraggi; this.lineaRaggio = sorgente.lineaRaggio; Validate(); }
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(); }
/// <summary> /// Intersezioni tra linea ed arco /// </summary> /// <param name="l1">Linea</param> /// <param name="a2">Arco</param> /// <param name="bCheckInside1">Richiesta intersezione interna alla linea</param> /// <param name="bCheckInside2">Richiesta intersezione interna all'arco</param> /// <returns></returns> public static List<Intersection> Intersect( Line2D l1, Arc2D a2, bool bCheckInside1 = false, bool bCheckInside2 = false) { double[] t = new double[2]; double[] a = new double[2]; Point2D[] p = new Point2D[2]; bool[] ok = new bool[2]; // soluzione trovata e valida bool[] tg = new bool[2]; // intersezione doppia List<Intersection> intersezioni = new List<Intersection>(); // P = P1 + t (P2 - P1) equazione della retta del segmento // P = C + r (cos a, sin a) oppure equazione della circonferenza // || P - C ||^2 = r^2 altra equazione della circonferenza // || P1 - C + t (P2 - P1) ||^2 = r^2 Intersezione: punto su entrambi // A = P1 - C; B = P2 - P1 Sostituzioni // || V || = V.x^2 + V.y^2 = V ^ V (scalare) Definizione di modulo // || A + t B ||^2 = r^2 Intersezione, sostituendo... // (A.x + t B.x)^2 + (A.y + t B.y)^2 - r^2 = 0 ... // A.x^2 + t^2 B.x^2 + 2 t A.x B.x + A.y^2 + t^2 B.y^2 + 2 t A.y B.y - r^2 = 0 ... // A.x^2 + A.y^2 + t^2 ( B.x^2 + B.y^2) + 2 t ( A.y B.y + A.x B.x) - r^2 = 0 ... // t^2(B^B) + 2 t (A^B) + A^A - r^2 = 0 Equazione di secondo grado da risolvere // a=B^B 2b=2*A^B c=A^A-r^2 in a*t^2 + 2*b*t + c = 0 Coefficienti // t12 = [-2b +- sqr( (2b)^2 - 4ac) ] / 2a = [-2b +- 2sqr( b^2 - ac) ] / 2a Formula completa... // t1 = [-b +- sqr(b^2-ac)]/a ...e ridotta Point2D A = l1.P1 - a2.Center; Point2D B = l1.P2 - l1.P1; double r = a2.Radius; ok[0] = ok[1] = false; // Imposta i flag tg[0] = tg[1] = false; double aEq, bEq, cEq, dEq24, dEq2; // Calcola con formula ridotta ERRORE NELLA FORMULA ??? aEq = B^B; bEq = A^B; cEq = (A^A) - r*r; dEq24 = bEq*bEq - aEq*cEq; if(dEq24 >= 0.0) // Cerca le soluzioni, memorizza valori ed imposta i flag { // Se ci sono soluzioni if(Math.Abs(dEq24) < Function2D.epsilon) // Delta = 0, una soluzione { t[0] = -bEq / aEq; p[0] = l1.P1 + t[0] * (l1.P2 - l1.P1); if(a2.Alfa(p[0], out a[0])) // Calcola alfa dell'arco e imposta flag della soluzione { ok[0] = true; tg[0] = true; // tangente, soluzione doppia } } else // Delta > 0, due soluzioni { dEq2 = Math.Sqrt(dEq24); // Radice di delta t[0] = (-bEq - dEq2) / aEq; t[1] = (-bEq + dEq2) / aEq; p[0] = l1.P1 + t[0] * (l1.P2 - l1.P1); p[1] = l1.P1 + t[1] * (l1.P2 - l1.P1); if(a2.Alfa(p[0], out a[0])) // Calcola alfa e flag delle due soluzioni ok[0] = true; if(a2.Alfa(p[1], out a[1])) ok[1] = true; } } for(int i=0; i<2; i++) // Verifica, se richieste, le appartenenze a segmento e arco { if(ok[i]) // Esamina, se c'e', la soluzione { if(bCheckInside1) // Se richiesto punto interno verifica... { if( (t[i] < 0.0) || (t[i] > 1.0) ) // Se t trovato indica che e` esterno, imposta a false ok[i] = false; } if(bCheckInside2) // Idem per l'arco... { if(!a2.Belongs(a[i])) ok[i] = false; } } } for(int i=0; i<2; i++) // Riesamina le soluzione { if(ok[i]) // Se trovata, aggiunge intersezione alla lista { intersezioni.Add(new Intersection(p[i], t[i], a[i], l1, a2, false, tg[i])); } } return intersezioni; // Restituisce il rif. alla lista }