Calcolo delle coordinate di un intersezione tra due segmenti
Salve a tutti i cervelloni matematici....
per esigenze di una programmazione che sto realizzando mi serve
ricavare le coordinate del punto di intersezione tra due segmenti di
cui conosco le coordinate.
Dunque la mia esigenza sarebbe che tramite le coordinate dei 4 punti
riesca a risalire alle coordinate del punto di intersezione senza
scomodare equazioni della retta che sulla carta so ben fare ma non
posso fargliele digerire alla mia programmazione...
mi sapreste aiutare??? Come posso fare???
Grazie in anticipo
Ciao
ZioAntonio
per esigenze di una programmazione che sto realizzando mi serve
ricavare le coordinate del punto di intersezione tra due segmenti di
cui conosco le coordinate.
Dunque la mia esigenza sarebbe che tramite le coordinate dei 4 punti
riesca a risalire alle coordinate del punto di intersezione senza
scomodare equazioni della retta che sulla carta so ben fare ma non
posso fargliele digerire alla mia programmazione...
mi sapreste aiutare??? Come posso fare???
Grazie in anticipo
Ciao
ZioAntonio
Risposte
E' facile, e non dovrebbe servirti neanche l'uso di cicli...
Prendiamo le rette, chiamandole R ed R', nella forma:
$y = mx + q $ (Retta R)
$y' = m'x + q' $ (Retta R')
Sapendo le coordinate di due punti di ciascuna retta, devi innanzitutto ricavarti, ponendoli in opportune variabili, i valori di m e q.
Lavoriamo sulla prima retta: per trovare m e q, chiamando $P_1(x_1, y_1)$ e $P_2(x_2, y_2)$ i due punti per cui passa la retta, e supponendo che tu abbia $x_1, x_2, y_1, y_2$ già memorizzate in variabili, usiamo la formula della retta passante per due punti:
$(y-y_1)/(y_2 - y_1) = (x - x_1)/(x_2 - x_1)$
Da cui si ricava (la formula di sopra l'ho presa da un libro, quelle di sotto le ho ricavate, dovrebbero essere corrette ma ricontrollale per sicurezza):
$m = (y_2-y_1)/(x_2 - x_1)$
$q = (x_2y_1 - x_1y_2)/(x_2 - x_1)$
Analogamente possiamo fare per la seconda retta. Avendo a questo punto ricavato i valori m, m', q, q', e salvati essi in quattro variabili mediante l'assegnamento delle espressioni di sopra, poniamo la condizione:
$mx + q = m'x + q'$
E quindi
$x = (q' - q)/(m - m')$
x è l'ascissa del punto di intersezione, e l'ordinata ce la ricaviamo sostituendo questo valore all'equazione di una delle due rette; non ci dovrebbero essere problemi a fare con qualsiasi linguaggio le operazioni che ti ho detto, tollerando quel minimo di imprecisione dei tipi "float" o "double" se si lavora sulla virgola mobile.
Prendiamo le rette, chiamandole R ed R', nella forma:
$y = mx + q $ (Retta R)
$y' = m'x + q' $ (Retta R')
Sapendo le coordinate di due punti di ciascuna retta, devi innanzitutto ricavarti, ponendoli in opportune variabili, i valori di m e q.
Lavoriamo sulla prima retta: per trovare m e q, chiamando $P_1(x_1, y_1)$ e $P_2(x_2, y_2)$ i due punti per cui passa la retta, e supponendo che tu abbia $x_1, x_2, y_1, y_2$ già memorizzate in variabili, usiamo la formula della retta passante per due punti:
$(y-y_1)/(y_2 - y_1) = (x - x_1)/(x_2 - x_1)$
Da cui si ricava (la formula di sopra l'ho presa da un libro, quelle di sotto le ho ricavate, dovrebbero essere corrette ma ricontrollale per sicurezza):
$m = (y_2-y_1)/(x_2 - x_1)$
$q = (x_2y_1 - x_1y_2)/(x_2 - x_1)$
Analogamente possiamo fare per la seconda retta. Avendo a questo punto ricavato i valori m, m', q, q', e salvati essi in quattro variabili mediante l'assegnamento delle espressioni di sopra, poniamo la condizione:
$mx + q = m'x + q'$
E quindi
$x = (q' - q)/(m - m')$
x è l'ascissa del punto di intersezione, e l'ordinata ce la ricaviamo sostituendo questo valore all'equazione di una delle due rette; non ci dovrebbero essere problemi a fare con qualsiasi linguaggio le operazioni che ti ho detto, tollerando quel minimo di imprecisione dei tipi "float" o "double" se si lavora sulla virgola mobile.

Grazie mille...provo a metterlo in pratica e ti faccio sapere!!!
grazie ancora!
Antonio
grazie ancora!
Antonio
Rieccomi....
Solo adesso sono riuscito a provare ma purtroppo temo di aver sbagliato qualcosa....
Le due rette sono descritte dai seguenti punti:
retta1: point_A al point_d
retta2: point_B al point_e
var m1:Number = Math.floor((point_A.y-point_d.y)/(point_A.x-point_d.x))
var m2:Number = Math.floor((point_B.y-point_e.y)/(point_B.x-point_e.x))
var q1:Number = Math.floor((point_A.x*point_d.y)-(point_d.x*point_A.y)/(point_A.x-point_d.x))
var q2:Number = Math.floor((point_B.x*point_e.y)-(point_e.x*point_B.y)/(point_B.x-point_e.x))
var myX:Number = Math.floor((q2-q1)/(m1-m2))
var myY:Number = Math.floor(m1*myX +q1)
Cosa ho sbagliato???
Solo adesso sono riuscito a provare ma purtroppo temo di aver sbagliato qualcosa....

Le due rette sono descritte dai seguenti punti:
retta1: point_A al point_d
retta2: point_B al point_e
var m1:Number = Math.floor((point_A.y-point_d.y)/(point_A.x-point_d.x))
var m2:Number = Math.floor((point_B.y-point_e.y)/(point_B.x-point_e.x))
var q1:Number = Math.floor((point_A.x*point_d.y)-(point_d.x*point_A.y)/(point_A.x-point_d.x))
var q2:Number = Math.floor((point_B.x*point_e.y)-(point_e.x*point_B.y)/(point_B.x-point_e.x))
var myX:Number = Math.floor((q2-q1)/(m1-m2))
var myY:Number = Math.floor(m1*myX +q1)
Cosa ho sbagliato???

Il procedimento di Iore è formalmente corretto ma non è per niente robusto!
La sua applicazione potrebbe dare spiacevoli sorprese, infatti molte variabili intermedie dell'algoritmo potrebbero risultare non definibili, in relazione alla posizione dei 4 pt (o alla scelta degli assi) anche se il problema è ben posto. Per esempio, se due punti sono sulla stessa ascissa, il coefficiente angolare della retta congiungente non è definito (il programma darebbe presumibilemente una divisione per 0).
Io ragionerei così:
1) verificherei l'esistenza della soluzione, ovvero che l'intersezione si possa fare (questo comporta che i quattro punti non siano allineati a due a due)
2) in caso favorevole, scriverei un algoritmo diretto che si ottiene dalla procedura di Iore però sviluppando completamente i calcoli 'a mano' fino al risultato finale (che poi scriverei nel linguaggio scelto)
Caro Antonio, ho l'impressione che se vuoi qualcosa di robusto un po' di algebra te la devi sobbarcare.
ciao
La sua applicazione potrebbe dare spiacevoli sorprese, infatti molte variabili intermedie dell'algoritmo potrebbero risultare non definibili, in relazione alla posizione dei 4 pt (o alla scelta degli assi) anche se il problema è ben posto. Per esempio, se due punti sono sulla stessa ascissa, il coefficiente angolare della retta congiungente non è definito (il programma darebbe presumibilemente una divisione per 0).
Io ragionerei così:
1) verificherei l'esistenza della soluzione, ovvero che l'intersezione si possa fare (questo comporta che i quattro punti non siano allineati a due a due)
2) in caso favorevole, scriverei un algoritmo diretto che si ottiene dalla procedura di Iore però sviluppando completamente i calcoli 'a mano' fino al risultato finale (che poi scriverei nel linguaggio scelto)
Caro Antonio, ho l'impressione che se vuoi qualcosa di robusto un po' di algebra te la devi sobbarcare.

ciao
var q1:Number = Math.floor((point_A.x*point_d.y)-(point_d.x*point_A.y)/(point_A.x-point_d.x)) var q2:Number = Math.floor((point_B.x*point_e.y)-(point_e.x*point_B.y)/(point_B.x-point_e.x))
Devi racchiudere tra parentesi il numeratore, sennò ne divide solo metà....
Tieni pure conto che almeno non ci siano tutte divisioni esatte, senza resto, la funzione floor può portare una certa perdita di precisione

P.S.: Che linguaggio stai usando?
Lore hai ragione....rivedendola adesso a mente non fusa ho visto l'errore del numeratore....
Grazie ancora
Uso ActionScript 2 per un progetto fatto in flash.
Ciao
Grazie ancora
Uso ActionScript 2 per un progetto fatto in flash.
Ciao
"ZioAntonio":
Lore hai ragione....rivedendola adesso a mente non fusa ho visto l'errore del numeratore....
Grazie ancora
Uso ActionScript 2 per un progetto fatto in flash.
Ciao
Segui anche il consiglio di Mirko, e controlla i denominatori con degli if per prevenire divisioni per zero

Se vuoi seguire il mio consiglio.... non mettere IF ai denominatori! Metti gli IF all'inizio per verificare che la coppia di segmenti non sia allineata e poi scrivi l'espressione completa delle coordinate di intersezione senza passaggi intermedi.
Altrimenti devi prevedere una procedura di soluzione quando gli IF non sono rispettati e questo complica non poco l'algoritmo per quei pochi casi patologici.
ciao
Altrimenti devi prevedere una procedura di soluzione quando gli IF non sono rispettati e questo complica non poco l'algoritmo per quei pochi casi patologici.
ciao
Grazie Lore e Grazie Mirko...
superata fase di cottura e rianalizzando il tutto per bene sono giunto a soluzione...
Per la cronaca avevo interpretato male anche funzionalità di Math.Floor che pensavo mi trattasse le virgole mobili...invece mi arrotondava...lascio immaginare il centro dove lo calcolasse!!!!!
Fatte le correzioni del caso, ora il centro è perfetto e al deformare la figura si adatta perfettamente il puntatore!
GRAZIE ANCORA...
Alla prossima...domanda!!!
( devo ancora terminare questo progettino e ho da fare ancora altri calcoli....es. bisettrice)
Ciao
Antonio
superata fase di cottura e rianalizzando il tutto per bene sono giunto a soluzione...
Per la cronaca avevo interpretato male anche funzionalità di Math.Floor che pensavo mi trattasse le virgole mobili...invece mi arrotondava...lascio immaginare il centro dove lo calcolasse!!!!!

Fatte le correzioni del caso, ora il centro è perfetto e al deformare la figura si adatta perfettamente il puntatore!
GRAZIE ANCORA...
Alla prossima...domanda!!!

( devo ancora terminare questo progettino e ho da fare ancora altri calcoli....es. bisettrice)
Ciao
Antonio
"mirco59":
Se vuoi seguire il mio consiglio.... non mettere IF ai denominatori! Metti gli IF all'inizio per verificare che la coppia di segmenti non sia allineata e poi scrivi l'espressione completa delle coordinate di intersezione senza passaggi intermedi.
Altrimenti devi prevedere una procedura di soluzione quando gli IF non sono rispettati e questo complica non poco l'algoritmo per quei pochi casi patologici.
ciao
Confermo: così ci guadagni anche in chiarezza.