Newsgroup: it.comp.lang.visual-basic
Titolo: [?] Appartenenza di un punto ad una retta

Salve, ho il seguente problema:
cliccando con il mouse su un form vorrei sapere se il punto sul quale ho 
cliccato appartiene ad una retta le cui coordinate (in punti p1 e p2) 
conosco a priori.
ho guardato sui vecchi libri di matematica ed effettivamente ci sarebbe la 
formula aX + bY + c = 0 ma non saprei come tradure una formula matematica in 
codice... qualcuno ha già risolto o saprebbe risolvere il mio problema?
Grazie 

Gambero ha scritto:

Beh matematica alla mano.... per un punto passano infinite rette,
quindi come minimo
devi conoscere l'equazione esplicita della retta che è questa(quella
che hai menzionato non è sbagliata, ma solo la forma implicita):
y=mx+q
Ora se sostituendo al valore x quello che è il tuo P1(esempio) e ti
viene soddisfatto y=p2
il punto appartiene alla retta....!
Ora, magari sbaglio, ma tu non hai nemmeno l'equazione della retta....!
Per ottenere l'equazione della retta devi avere almeno 2 punti(non
quello di Test ovviamente)
ed in quel modo ricavi l'equazione di una retta passante per 2 punti
dati:
La formula da usare è questa:
(y-y1)/(y2-y1)=(x-x1)/(x2-x1)
Esempio:
P1(-1;+3) --- P2(+2;+1)
avrai:
(y-3)/(-2)=(x+1)/(3)
3y-9=-2x-2
y=-2/3x+7/3
Errori di calcolo a parte....
Se adesso gli passi le coordinate del tuo PuntoX verifichi che
appartenga......
@Alex

grazie mille!


> (y-y1)/(y2-y1)=(x-x1)/(x2-x1)
La formula è corretta, ma la divisione rende necessario usare numeri in 
virgola mobile, cosa che introduce problemi di approssimazione che 
rendono non corretto al 100% l'algoritmo.
Facendo due ulteriori passaggi "a mano" si arriva ad un'altra equazione 
nella quale ci sono solo moltiplicazioni e somme, permettendo l'uso di 
numeri interi:
(y-y1)/(y2-y1)=(x-x1)/(x2-x1)  -->  (y-y1)*(x2-x1) - (x-x1)*(y2-y1) = 0
Ciao.

Shinmen Takezo ha scritto:

Ineccepibile approccio informatico....!
@Alex

 codice...
Penso che la cosa migliore da fare (o almeno come
ho risolto io in casi simili) sia quella di calcolare
la distanza del punto dalla retta e decidere che il
punto appartiene alla retta se questa distanza e' minore
di un Eps piccolo a piacere (ma comunque entro la precisione
del tipo di variabili usate).  Usando la formula della retta,
con verifica di aX + bY + c = 0, difficilmente ti dara' un
risultato esatto, sempre per problemi relativi alla precisione
del sistema numerico impiegato.
Ti allego due routines per il calcolo della suddetta distanza.
Ciao, sperando di averti aiutato.
Franco
----------------------------------------------------------------
  Private Function DistanzaPuntoLinea(ByVal X0!, ByVal Y0! _
     , ByVal x1!, ByVal y1!, ByVal x2!, ByVal y2!) As Single
'
'   Calcola la distanza del punto (X0, Y0)
'   dalla retta passante per (X1, Y1)-(X2, Y2):
'
     Dim Dx!, Dy!, DxNum!, DyNum!, Den!, Dxx!, Dyy!
'
     On Error GoTo DistanzaPuntoLinea_ERR
'
     Dx = x2 - x1
     Dy = y2 - y1
'
     DxNum = Dy * (X0 * Dy - Y0 * Dx + x2 * y1 - x1 * y2)
     DyNum = Dx * (Y0 * Dx - X0 * Dy + x1 * y2 - x2 * y1)
     Den = Dx * Dx + Dy * Dy
'
     Dxx = DxNum / Den
     Dyy = DyNum / Den
     DistanzaPuntoLinea = Sqr(Dxx * Dxx + Dyy * Dyy)
'
'
DistanzaPuntoLinea_ERR:
     If Err <> 0 Then
         MsgBox "Punti coincidenti.", vbCritical, " Errore in 
DistanzaPuntoLinea"
     End If
'
'
'
End Function
Private Function Distanza2PuntoLinea(ByVal X0#, ByVal Y0# _
     , ByVal x1#, ByVal y1#, ByVal x2#, ByVal y2# _
     , Optional ByRef Xp#, Optional ByRef Yp# _
     , Optional ByRef bPrSuSeg As Boolean) As Double
'
'   Calcola la distanza del punto (X0, Y0) dalla retta passante
'   per (X1, Y1)-(X2, Y2). Se (X1, Y1) coincide con (X2, Y2)
'   ritorna la distanza di (X0, Y0) da (X1, Y1).
'   Ritorna anche le coordinate del punto (Xp, Yp), proiezione
'   di (X0, Y0) sulla retta e bPrSuSeg = True se la proiezione sta'
'   sul segmento (X1, Y1)-(X2, Y2).
'
     Dim Dx#, Dy#, DxNum#, DyNum#, Den#
'
     Dx = x2 - x1
     Dy = y2 - y1
'
     If (Dx <> 0) Or (Dy <> 0) Then
         DxNum = Dx * (X0 * Dx + Y0 * Dy) + Dy * (x1 * y2 - x2 * y1)
         DyNum = Dy * (X0 * Dx + Y0 * Dy) + Dx * (x2 * y1 - x1 * y2)
         Den = Dx * Dx + Dy * Dy
'
         Xp = DxNum / Den
         Yp = DyNum / Den
     Else
         Xp = x1
         Yp = y1
     End If
     Distanza2PuntoLinea = Sqr((X0 - Xp) * (X0 - Xp) + (Y0 - Yp) * (Y0 - 
Yp))
'
     bPrSuSeg = ((x1 - Xp) * (Xp - x2) >= 0) And ((y1 - Yp) * (Yp - y2) 
 >= 0)
'
'
'
End Function