## 2005. augusztus 26., péntek

### Check if the mouse pointer is over or close to a line on a TCanvas

Problem/Question/Abstract:

I am painting a line on a canvas with LineTo. How can I determine if the mouse pointer is over that line or not.

This will give you the distance to the line and you can decide in your code how close (in pixels) you want the user to be to the line before selecting it. It takes into account the end points as well, so when the user is past the end points on the extension of the line it is not triggered.

MinDistPointLine calculates the minimum distance of a point to a line. P is the point, the line is between points A and B. It is based on the distance of P to the parametrised point Q = (1 - q) A + qB where 0 <= q <= 1. The distance PQ is sqrt(((1 - q) Ax + qBx - Px)^2 + (... Y term) ). Differentiating gives dPQ / dq = 2((Bx - Ax) q + (Ax - Px))(Bx - Ax) + (... Y term). dPQ / dq must be zero for minimum so q = (Px - Ax)(Bx - Ax) + (Py - Ay)(By - Ay) / ((Bx - Ax)^2 + (By - Ay)^2)

function MinDistPointLine(Px, Py, Ax, Ay, Bx, By: double): double;

implementation

function PointToPointDist(Ax, Ay, Bx, By: double): double;
begin
Result := sqrt(sqr(Bx - Ax) + sqr(By - Ay));
end;

function MinDistPointLine(Px, Py, Ax, Ay, Bx, By: double): double;
var
q: double;
begin
if (Ax = Bx) and (Ay = By) then
begin
{Point to point}
Result := PointToPointDist(Px, Py, Ax, Ay);
end
else
begin
{Minimum}
q := ((Px - Ax) * (Bx - Ax) + (Py - Ay) * (By - Ay)) / (sqr(Bx - Ax) + sqr(By - Ay));
{Limit q to 0 <= q <= 1}
if q < 0 then
q := 0;
if q > 1 then
q := 1;
{Distance}
Result := PointToPointDist(Px, Py, (1 - q) * Ax + q * Bx, (1 - q) * Ay + q * By);
end;
end;