Newsgroup: it.comp.lang.visual-basic
Titolo: [?] Algoritmo per intersezione di due piani

ciao a tutti
in un programma VB che sto implementando devo ricavare la retta di
intersezione fra due piani nello spazio, avete suggerimenti in merito?!
ciao e grazie a chi vorrą aiutarmi

 nello spazio, avete suggerimenti in merito?!
Probabilmente dico cose che sai già, ma lo faccio lo stesso, per chiarezza:
L'equazione standard della retta è: aX+bY+c=0 (dove a,b e c sono valori
noti). Siccome l'equazione ha due variabili (x e y), per ottenere un punto
ti servono due rette.
L'equazione standard del piano è: aX+bY+cZ+d=0 (dove a,b,c e d sono valori
noti). Siccome l'equazione ha 3 variabili (x y z), per ottenere un punto ti
servono 3 piani, e per ottenere una retta 2.
A questo punto è facile capire che avendo 2 piani basta impostare un sistema
che risolva il valore di Z tramite X e Y per ottenere l'equazione della
retta di intersezione.
Il problema è come farlo da programma. Ti servirebbe un risolutore di
equazioni, che non è propriamente un programmino banale.
Ma quel'è la tua esigenza? Stai facendo un programma di ausilio allo studio
della geometria, oppure un videogame? Nel secondo caso, se spieghi bene la
tua esigenza, forse ci sono degli approcci più semplici alla soluzione del
problema.
Ciao
*Roby*

 problema.
sto facendo un programmino di architettura, in pratica un semplice CAD
tridimensionale, per cui mi serve una trattazione rigorosa del problema.

 in forma vettoriale più che algebrica
Scusa, così per capire, qual'è la rappresentazione vettoriale di un piano?
Prova a spiegare meglio, magari esemplificando, quali sono i tuoi dati di
partenza e come ti aspetti sia il risultato (questo forse l'ho capito, ma un
esempio non guasta mai).
Ciao
*Roby*

 per comodità preferisco una soluzione in forma vettoriale più che
algebrica
Più che da un vettore, penso che un piano sia caratterizzato da una matrice.
C'è bisogno di 3 punti, ciascuno caratterizzato da 3 coordinate.
Se fai qualche esempio, magari posso aiutarti.
Ignazio

 C'è bisogno di 3 punti, ciascuno caratterizzato da 3 coordinate.
E' possibile che 3 punti non bastino, ad esempio nel caso particolare in cui
i 3 punti siano allineati su di una stessa retta (in questo caso
esisterebbero infiniti piani passanti, dati dalla rotazione del piano
sull'asse Z avente come fulcro la  retta stessa.
In realtà così come servono due punti per identificare univocamente una
retta, servono due rette per identificare univocamente un piano.
Credo che siano queste due rette la rappresentazione vettoriale del piano a
cui faceva riferimento Morpheus, ma preferisco aspettare i suoi esempi per
vedere se si trova una soluzione al quesito.
Ciao
*Roby*

> Scusa, cosě per capire, qual'č la rappresentazione vettoriale di un piano?
dati due versori (v1 e v2) indipendenti nel piano, un punto p generico che
gli appartiene ha le coordinate espresse dalla forma vettoriale
p = Po + alfa * v1 + beta * v2
con Po un punto appartenente al piano e alfa e beta coefficienti reali
In prativa vorrei esprimere la retta nella forma vettoriale
p = Po + gamma * V
con Po un punto della retta e V il suo versore

 E' possibile che 3 punti non bastino...
Vero, hai ragione.
Allora, una matrice non singolare.
Quella delle due rette è una soluzione ridondante, e non risolve il
problema: per identificare una retta servono due punti, per due rette 4
punti. E non è detto che non siano allineati.
Ignazio

 con Po un punto della retta e V il suo versore
Innanzitutto, V sarebbe UN suo versore e non IL suo versore.
Poi, i piani come li indichi?
Dovrebbe essere qualcosa tipo:
p = P0 + delta * V1 + epsilon * V2
A questo punto:
Sai a cosa vai incontro volendo usare una notazione di questo tipo?
Per esempio, per verificare se un punto appartiene ad un piano devi fare i
salti mortali! Se la forma ax+by+cz+d=0 sarebbe mooolto più semplice.
Oppure, per fare i calcoli con i vettori devi definire una serie di classi
ed operatori (che non puoi "overloadare", tra l'altro, quindi t'incasini la
vita con cose del tipo "set p = sommavettori (p0,
sommavettori(moltiplicascalarepervettore(delta,v1),moltiplicascalarepervetto
re(epsilon,v2))".
Nel caso tu voglia continuare per questa strada, fammi sapere così trovo la
formula per l'intersezione di due piani.
Ignazio

 formula per l'intersezione di due piani.
te ne sarei veramente grato, io intanto sto spulciando testi come Graphics
gems e sorgenti in C++ che ho trovato quà e la, ma ancora niente
ciao e grazie ancora

 Il mio problema è quello di determinare la retta di intersezione
Ah ok allora: innanzitutto passa per entrambi i piani alla notazione
algebrica, avrai 4 coefficienti per ciascun piano.
A questo punto risolvi rispetto a due delle tre variabili. Per esempio:
/ x + y + z - 1 = 0
\ x - y + z - 2 = 0
/ x + y = -z + 1
\ x - y = -z + 2
Da cui:
/ x = -z
\ y = 2
Che è una retta, e per cui non è difficile ritornare alla forma vettoriale
(basta prendere due x a caso, trovare i punti p0 e p1 corrispondenti: p = p0
+ alfa * ((p1 - p0) / |p1 - p0|).
Ora bisogna convincere il computer a risolvere il sistema... Ti serve una
mano a farlo?
Ignazio

 mano a farlo?
Supponendo che i due piani siano rappresentati dalle equazioni:
/ ax + by + cz + d = 0
\ ex + fy +gz + h = 0
Le soluzioni (ottenute con pochi semplici passaggi) sono:
/ x = (z*(b*g - c*f) + b*h - d*f)/(a*f - b*e)
\ y = (z*(a*g - c*e) + a*h - d*e)/(b*e - a*f)
Al variare di z tra -inf e +inf.
Oppure:
/ x = (y*(b*g - c*f) - c*h + d*g)/(c*e - a*g)
\ z = (y*(a*f - b*e) + a*h - d*e)/(c*e - a*g)
Al variare di y tra -inf e +inf.
Oppure:
/ y = (x*(a*g - c*e) - c*h + d*g)/(c*f - b*g)
\ z = (x*(a*f - b*e) - b*h + d*f)/(b*g - c*f)
Al variare di x tra -inf e +inf.
Quale delle tre usare? Quella che più ti piace, a patto che il denominatore
non sia 0.
Attento perché non è detto che se uno è 0, gli altri lo siano: provali tutti
e tre (dovrebbero bastarne due, ma non ci metterei la mano sul fuoco).
Ricorda che se a/e=b/f=c/g=d/h i piani che stai intersecando sono
coincidenti, se a/e=b/f=c/g<>d/h sono paralleli.
Per la rappresentazione vettoriale di queste rette in formato parametrico...
Facciamo un esempio. :-)
x(z) = k*z + p
y(z) = j*z + q
p0 = (x(0), y(0))
p1 = (x(1), y(1))
La retta è
p = p0 + gamma * (p1-p0)/|p1-p0|
Spero di essere stato chiaro...
Ignazio

 mano a farlo?
Supponendo che i due piani siano rappresentati dalle equazioni:


 Quella delle due rette è una soluzione ridondante [...]
Ho il sospetto che alla fine stiamo dicendo la stessa cosa.
Tu parli di 3 punti che non facciano parte della stessa retta, io di due
rette che non siano tra loro parallele (e quindi abbiano un punto in comune,
da cui si torna ai tuoi 3 punti).
Per il resto, tanto di cappello per la tua trattazione della risoluzione in
ambito algebrico. Mi consola solo pensare che almeno alla convenienza di
usare il metodo algebrico ci ero arrivato anche io. :-)
Ciao
*Roby*

 ambito algebrico.
Grazie.
Ignazio

ciao a tutti
ringrazio chi si è preso a cuore il mio problema e ha cercato di dare una
soluzione.
Per la cronaca la soluzione che cercavo è questa, la pubblico per dare un
aiuto a chi avesse il mio stesso problema:
dati due piani p e q, le equazioni vettoriali sono le seguenti
piano p:
P(u,w) = Pp + u* V1p + w * V2p   (1)
con Pp un punto qualsiasi nel piano p,  V1p e  V2p  due vettori linearmente
indipendenti nel piano p, u e w due numeri reali.
piano q
P(s,t) = Pq + s* V1q + t * V2q
con Pq un punto qualsiasi nel piano q,  V1q e  V2q  due vettori linearmente
indipendenti nel piano q, s e t due numeri reali.
La retta di intersezione la si ottiene con l'ugualianza fra i due piani.
Poichè la retta è uno spazio monodimensionale, i parametri in gioco sono in
eccesso, ma con delle semplificazioni riusciamo a limitarli.
Indichiamo con Vn la normale al piano q, ricavata come prodotto vettore di
V1q e  V2q.
Eseguendo il prodotto scalare su entrambe le espressioni
Vn*(Pp + u* V1p + w * V2p ) = Vn * (Pq + s* V1q + t * V2q)
per l'ortogonalità di Vn con V1q e  V2q otteniamo:
Vn*(Pp + u* V1p + w * V2p ) = Vn * Pq
se ad esempio fissiamo arbitrariamente u ad un valore ui otteniamo
Vn*(Pp + ui* V1p + w * V2p ) = Vn * Pq
ovvero
w  = (Vn * Pq - Vn*Pp - ui* Vn*V1p )/(Vn*V2p)
basta calcolare due valori di w e utilizzare la (1) per ricavare le
coordinate di due punti sulla retta e quindi della sua direzione.