How to calculate the closest point on a segment to a point

Hi, below there is a little snippet that calculates the closest point on a segment to a determined point.

It is written in C++ but can be easily translated to any other language.

Disclaimer: given its age, it uses hungarian notation, and some names are in Spanish, but it was thoroughly tested and works as expected.

 1//--------------------------------------------------------------------------------------------------------
 2//author: Adrián Deccico - http://adrian.org.ar
 3/*
 4Description: calculate the closest point on a segment to a point.
 5Parameters:
 6nSx1, nSy1 =  First point of the segment
 7nSx2, int nSy2 = Second point of the segment
 8nPx, int nPy = The point to analize
 9*nCercaX,  *nCercaY = The closest point to the given point (nPx,nPy) that belongs to the segment
10Returns: The distance between the given point and the point found of the segment
11*/
12double ElPuntoMasCercanoAUnSegmento(double nSx1, double nSy1, double nSx2,
13double nSy2, double nPx, double nPy,
14double *nCercaX,  double *nCercaY)
15{
16 
17//caracterizo la recta del segmento dado Y=m*X + b
18double m, b;
19 
20bool bEsHorizontalOVertical = false;
21 
22//el segmento es vertical
23if (nSx2 == nSx1){
24    *nCercaX = nSx1;
25    *nCercaY = nPy;
26    bEsHorizontalOVertical = true;
27}
28 
29//el segmento es horizontal
30if (nSy2 == nSy1){
31    *nCercaY = nSy1;
32    *nCercaX = nPx;
33    bEsHorizontalOVertical = true;
34}
35 
36//el segmento está caracterizado por una recta "AX + BY + C = 0" con
37// A y B distintos de cero
38if (!bEsHorizontalOVertical)
39{
40    m= (nSy2 - nSy1) / (nSx2 - nSx1);
41    b = nSy1 - (nSx1 * m);
42 
43    //caracterizo la recta que une al punto dado con el punto más
44    // cercano dentro del segmento Y=m1*X + b1
45    double m1, b1;
46 
47    m1 = -1 / m;
48    b1 = -m1 * nPx + nPy;
49 
50    //encuentro el punto de intersección
51    *nCercaX =  (b1 - b) / (m - m1);
52    *nCercaY =  m * *nCercaX + b;
53}
54 
55//verificar que el punto encontrado está dentro del segmento
56if (*nCercaX < min(nSx1,nSx2)
57||  *nCercaX > max(nSx1,nSx2)
58||  *nCercaY < min(nSy1,nSy2)
59||  *nCercaY > max(nSy1,nSy2) )
60{
61    //el punto más cercano será uno de los dos extremos (el más cercano al punto)
62    if (dDistanciaEntrePuntos(nSx1, nSy1, nPx, nPy) <= dDistanciaEntrePuntos(nSx2, nSy2, nPx, nPy))
63    {
64        *nCercaX = nSx1;
65        *nCercaY = nSy1;
66    }
67    else
68    {
69        *nCercaX = nSx2;
70        *nCercaY = nSy2;
71    }
72}
73 
74return dDistanciaEntrePuntos(nPx, nPy, *nCercaX , *nCercaY);
75 
76}
77//--------------------------------------------------------------------------------------------
78 
79//------------------------------------------------------------------------
80//return the distance between two points in a x,y plane.
81double dDistanciaEntrePuntos(double lOldX, double lOldY,
82double lNewX, double lNewY)
83{
84    double x = lNewX - lOldX;
85    double y = lNewY - lOldY;
86 
87    return sqrt(pow(x,2) + pow(y,2));
88}
89//------------------------------------------------------------------------