Пример #1
0
		/// <summary>
		/// Proiezione di un punto su un arco
		/// </summary>
		/// <param name="p">Punto</param>
		/// <param name="a">Arco</param>
		/// <param name="projection">Proiezione (parametro out)</param>
		/// <param name="bInside">true se richiesta appartenenza proiezione all'interno dell'arco</param>
		/// <returns>true se trovata</returns>
		public static bool		Projection( Point2D p, Arc2D a, out Point2D projection, bool bInside = false) 
			{
			Point2D proj = null;										// La proiezione, se trovata
			Point2D dir = p - a.Center;									// Calcola il vettore dal centro al punto
			if(dir.Normalize())											// Lo normalizza. Se nessun errore...
				{
				Point2D proj1 = a.Center + a.Radius * dir;				// Calcola le due proiezioni sul cerchio.
				Point2D proj2 = a.Center - a.Radius * dir;				
				double d1 = Function2D.Distance(proj1, p);				// e le distanze tra punto e proiezione
				double d2 = Function2D.Distance(proj2, p);
				bool app1, app2;										// Appartenenza all'arco delle due proiezione
				app1 = app2 = true;
				if( bInside == true)									// Verifica le appartenenze all'arco
					{
					double alfa;
					if(a.Alfa(proj1, out alfa))							// calcola l'angolo del primo e del secondo punto proiettato
						{												// scarta, se non appartiene all'arco
						if(!a.Belongs(alfa))		app1 = false;
						}
					if(a.Alfa(proj2, out alfa))
						{
						if(!a.Belongs(alfa))		app2 = false;
						}
					}													
				if( (app1==true) && (app2==true) )						// Se entrambi appartengono all'arco
					{													// scarta quello con distanza maggiore
					if(d1 >= d2)
						app1 = false;
					else
						app2 = false;
					}
				if(app1)												// Imposta proj con la proiezione valida...
					proj = proj1;										// ...se c'e`
				else if(app2)
					proj = proj2;
				}
			if(proj != null)											// Se trovata proiezione, esce con true...
				{
				projection = proj;
				return true;
				}
			projection = new Point2D();									
			return false;												// ...se non trovata, esce con false + punto vuoto.
			}
Пример #2
0
		/// <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
			}