Index: trunk/src/search.c =================================================================== --- trunk/src/search.c (revision 28751) +++ trunk/src/search.c (revision 28752) @@ -611,7 +611,8 @@ * distance^2 = (X-QX)^2 + (Y-QY)^2 */ -double pcb_point_line_dist2(pcb_coord_t X, pcb_coord_t Y, pcb_line_t *Line) +/* also returns closest point-on-line in cpx;cpy if they are not NULL */ +PCB_INLINE double pcb_point_line_dist2_(pcb_coord_t X, pcb_coord_t Y, pcb_line_t *Line, pcb_coord_t *cpx, pcb_coord_t *cpy) { const double abx = Line->Point2.X - Line->Point1.X; const double aby = Line->Point2.Y - Line->Point1.Y; @@ -633,6 +634,9 @@ qx = Line->Point1.X + (t * abx); qy = Line->Point1.Y + (t * aby); + if (cpx != NULL) *cpx = qx; + if (cpy != NULL) *cpy = qy; + /* Return the distance from Q to (X,Y), squared */ dx = X - qx; dy = Y - qy; @@ -640,6 +644,16 @@ return (dx * dx) + (dy * dy); } +double pcb_point_line_dist2(pcb_coord_t X, pcb_coord_t Y, pcb_line_t *Line) +{ + return pcb_point_line_dist2_(X, Y, Line, NULL, NULL); +} + +double pcb_point_line_dist2_point(pcb_coord_t X, pcb_coord_t Y, pcb_line_t *Line, pcb_coord_t *cpx, pcb_coord_t *cpy) +{ + return pcb_point_line_dist2_(X, Y, Line, cpx, cpy); +} + pcb_bool pcb_is_point_on_line(pcb_coord_t X, pcb_coord_t Y, pcb_coord_t Radius, pcb_line_t *Line) { double max = Radius + Line->Thickness / 2; Index: trunk/src/search.h =================================================================== --- trunk/src/search.h (revision 28751) +++ trunk/src/search.h (revision 28752) @@ -171,9 +171,12 @@ pcb_bool pcb_is_point_in_line(pcb_coord_t X, pcb_coord_t Y, pcb_coord_t Radius, pcb_any_line_t *Pad); pcb_bool pcb_is_point_in_box(pcb_coord_t X, pcb_coord_t Y, pcb_box_t *box, pcb_coord_t Radius); -/* Return the distance^2 between a line-center and a point */ +/* Return the distance^2 between a line-center and a point, optionally + also returning the coordinates of the closest point */ double pcb_point_line_dist2(pcb_coord_t X, pcb_coord_t Y, pcb_line_t *Line); +double pcb_point_line_dist2_point(pcb_coord_t X, pcb_coord_t Y, pcb_line_t *Line, pcb_coord_t *cpx, pcb_coord_t *cpy); + /* Return the first line object that has its centerline crossing the point; if ang is not NULL, only return lines that are pointing in the right angle (also accept 180 degree rotation)