 whats new ¦  programming tips ¦  indy articles ¦  intraweb articles ¦  informations ¦  links ¦  interviews
misc ¦  tutorials ¦  Add&Win Game

 16 Visitors Online

 ...get the perpendicular point on segment from external point? Autor: Arash Partow Homepage: http://www.partow.net [ Print tip ]

 Tip Rating (12):     {---------------------------------------------------------------------
Two routines are made available, the first takes into account a segment
and will produce point on the given segment that is of least distance
to an external point.

The second routine is similar to the first other than the fact that it
will extended the given segment into a ray and hence also produce a point
on the ray which will produce a segment of least distance between that
point and an external point, the segment produced between the point on
the ray and the external point is guaranteed to be perpendicular to the
ray in all cases except for the instance where the external point is
collinear to ray.

Both routines come from the computational geometry library
FastGEO (url: http://fastgeo.partow.net)
---------------------------------------------------------------------}

procedure PerpendicularPntToSegment(const x1, y1, x2, y2, Px, Py: Double;
out Nx, Ny: Double);
var

Ratio: Double;
Dx: Double;
Dy: Double;
begin

Dx    := x2 - x1;
Dy    := y2 - y1;
Ratio := ((Px - x1) * Dx + (Py - y1) * Dy) / (Dx * Dx + Dy * Dy);
if Ratio < 0 then
begin

Nx := x1;
Ny := y1;
end
else if
Ratio > 1 then
begin

Nx := x2;
Ny := y2;
end
else
begin

Nx := x1 + (Ratio * Dx);
Ny := y1 + (Ratio * Dy);
end;
end;
(* End PerpendicularPntSegment *)

procedure PerpendicularPntToLine(const Rx1, Ry1, Rx2, Ry2, Px, Py: Double;
out Nx, Ny: Double);
var

Ratio: Double;
Gr1, Gr2: Double;
Gr3, Gr4: Double;
begin

(*  The ray is defined by the coordinate pairs (Rx1,Ry1) and (Rx2,Ry2) *)

if NotEqual(Rx1, Rx2) then

Gr1 := (Ry2 - Ry1) / (Rx2 - Rx1)
else

Gr1 := 1e300;
Gr3 := Ry1 - Gr1 * Rx1;
if NotEqual(Gr1, 0) then
begin

Gr2   := -1 / Gr1;
Gr4   := Py - (Gr2 * Px);
Ratio := (Gr4 - Gr3) / (Gr1 - Gr2);
Nx    := Ratio;
Ny    := (Gr2 * Ratio) + Gr4;
end
else
begin

Nx := Px;
Ny := Ry2;
end;
end;
(* End PerpendicularPntToLine *)

Rate this tip:

 poor very good 