Pers.narod.ru. Алгоритмы. Расстояние от точки до отрезка |
При работе с графикой часто нужно определить расстояние от заданной точки с координатами (Х0, Y0) до отрезка прямой, проходящей через две точки с координатами (Х1, Y1) и (X2, Y2). При этом мы должны рассмотреть уравнение прямой, проходящей через две точки, заданные координатами (Х1, Y1) и (X2, Y2), в общем виде:
А*х+В*у+С = 0
где A = Y2-Y1, B = Х1-Х2, С = -X1* (Y2 – Y1) + Y1*(X2 –X1).
Кратчайшее расстояние от точки, заданной координатами (Х0,Y0), до прямой, заданной уравнением А*х+В*у+С=0, может быть определено с использованием уравнения:
A*x/T + B*y/T + C/T = 0
в котором Т=корень(А2+В2), причём С<=0 (что достигается изменением знака выражения). При подстановке в уравнение координат произвольной точки получаем значение кратчайшего расстояния от рассматриваемой точки до прямой.
При определении расстояния от точки до отрезка нужно сначала проанализировать взаимное расположение точки и отрезка прямой, то есть, проверить, куда опустится перпендикуляр из точки (Х0, Y0): непосредственно на отрезок или на прямую, являющуюся продолжением рассматриваемого отрезка. Этот анализ может быть произведен путем построения треугольника, вершинами которого являются заданные точки (Х0, Y0), (Х1, Y1), (Х2, Y2), и сопоставления соотношения длин его сторон R1, R2, R12. Вариант программы представлен ниже, выводы о том, что точка находится "левее" или "правее" отрезка условны, они имеют смысл, только если задаётся X1<X2.

var x,y:array [0..2] of real;
r0,r1,r2,r12,a,b,c,t:real;
i:integer;
function dist (x1,y1,x2,y2:real):real; {Расстояние между точками}
begin
dist:=sqrt(sqr(x2-x1)+sqr(y2-y1));
end;
begin
{Ввод данных}
writeln;
for i:=0 to 2 do begin
repeat
write ('Введите R',i,' (координаты X и Y):');
{$I-}readln (x[i],y[i]);{$I+}
until IoResult=0;
end;
{Реализация алгоритма и вывод результатов}
r1:=dist(x[0],y[0],x[1],y[1]);
r2:=dist(x[0],y[0],x[2],y[2]);
r12:=dist(x[1],y[1],x[2],y[2]);
if r1>=dist(r2,r12,0,0) then
writeln ('Точка правее (x2,y2),r=',r2:6:2)
else if r2>=dist(r1,r12,0,0) then
writeln ('Точка левее (x1,y1),r=',r1:6:2)
else begin
a:=y[2]-y[1]; b:=x[1]-x[2]; c:=-x[1]*(y[2]-y[1])+y[1]*(x[2]-x[1]);
t:=dist (a,b,0,0);
if c>0 then begin a:=-a; b:=-b; c:=-c; end;
r0:=(a*x[0]+b*y[0]+c)/t;
write ('Расстояние от точки до отрезка=',r0:6:2);
if r0<0 then write (' (точка под отрезком)');
end;
reset (input); readln;
end.
|
|