Принадлежность точки области
Имея координаты области можно утверждать, что точка принадлежит области, если ее координаты больше X1,Y1 и меньше X2,Y2.
Procedure Tch_Obl(X,Y,X1,Y1,X2,Y2,P);
begin
if X>=X1 and X<=X2 and Y>=Y1 and Y<=Y2 then P=1
else P=0;
{Р=1 - точка принадлежит области}
end;
Задача 1. Записать в файл участки дуги, расположенные в прямоугольной области(рис. 128).
Дуга NK пересекается с линиями границы области. В этом случае следует в любой последовательности определить точки S1, S2, S3, S4, S5 и записать в файл с сортировкой строк по возрастанию LD, где LD - длина дуги от начальной точки N до точки пересечения S. Одновременно записать отрезок границы области, на котором расположена точка.
Рис. 128
begin
Ps:=0; {счетчик записей точек пересечения}
Repeat
Читаем файл линий границы выделенной области с 1-ой строки:
SledLine( g, 1, Nag, Xg1, Yg1, Xg2, Yg2, XCg, YCg ),
Определяем текущий угол:
TekUgol(Xg1, Yg1, Xg2, Yg2,Ug);
Определяем точку пересечения дуги (XCm,YCm,Xm1,Ym1,Xm2,Ym2) с линией области:
OtrDug(Xg1,Yg1,Ug,XCm,YCm,R,XP1,YP1,XP2,YP2,Pt);
Проверка на принадлежность точки пересечения (XP1,YP1) отрезку линии выделенной области:
if Pt=1 then
PikOtr(XP1,YP1,Xg1,Yg1,Xg2,Yg2,P);
Проверка на принадлежность точки пересечения (XP1,YP1) дуге:
if P=1 then
. PikDug(XP1,YP1,XCm,YCm,Xm1,Ym1,Xm2,Ym2,Nam,P);
if P=1 then begin
Ps:=Ps+1; {наличие точки пересечения}
Xs:=XP1; Ys:=YP1; {координаты точки пересечения}
Определяем длину дуги от начала до точки пересечения S:
DlinaD(XСm,YСm,Xm1,Ym1,Xs,Ys,nam,LD);
Запись в текущий файл с сортировкой строк по возрастанию LD:
if LD>0 then
StrokBox( e, Ps, LD>, Xg1, Yg1, Xg2, Yg2, Xs, Ys );
end;
Проверка на принадлежность 2-ой точки пересечения (XP2,YP2) отрезку линии выделенной области:
if Pt=1 then
PikOtr(XP2,YP2,Xg1,Yg1,Xg2,Yg2,P);
Проверка на принадлежность точки пересечения (XP2,YP2) дуге:
if P=1 then
. PikDug(XP2,YP2,XCm,YCm,Xm1,Ym1,Xm2,Ym2,Nam,P);
if P=1 then begin
Ps:=Ps+1; {наличие точки пересечения}
Xs:=XP2; Ys:=YP2; {координаты точки пересечения}
Определяем длину дуги чертежа от начала до точки пересечения S:
DlinaD(XCm,YCm,Xm1,Ym1,Xs,Ys,nam,LD);
Запись в текущий файл с сортировкой строк по возрастанию LD:
if LD>0 then
StrokBox( e, Ps, LD>, Xg1, Yg1, Xg2, Yg2, Xs, Ys );
end;
Until E=Nkg; {номер последней строки в файле}
if Ps=0 then begin
Проверка на принадлежность начальной точки дуги (Xm1,Ym1) выделенной области
Tch_Obl(Xm1,Ym1,X1,Y1,X2,Y2,P);
if P=1 then {дуга расположена внутри области}
Записать дугу в файл области
RisLineBox( o, 2, Nam, Xm1, Ym1, Xm2, Ym2, XCm, YCm );
end;
Until E=Nkm;
Если есть точки пересечения, то необходимо выделить те участки дуги, которые расположены внутри области (Procedure Filtr):
if Ps>0 then Filtr;
end;
Procedure FiltrDug; {определение принадлежности дуг области,
прорисовка их и запись в текущий файл}
var Xm1s, Ym1s :Float;
begin
Xm1s:=Xm1; Ym1s:=Ym1;
Направление измерений дуги:
if обход=1 then Hod:=2 else Hod:=1;
Repeat
Читаем с 1-й строки файл е, в котором записаны точки пересечения:
SledStrok(e, Ps, LD>, Xg1, Yg1, Xg2, Yg2,Xs, Ys);
Длина дуги от начальной точки до точки пересечения:
DlinaD(XCm,YCm,Xm1,Ym1,Xs,Ys,Nam,LD1);
if LD1>0 then begin
Определяем точку (XTn,YTn) начала измерений дуг и максимальную длину дуги LDk:
Tch_NiK(XCg,YCg,Xg1,Yg1,Ug,Xs,Ys,XTn,YTn,LDk);
Определяем конечную точку для измерения длины дуги:
DugDug(XCm,YCm,R,Xs,Ys,Ri,XP1,YP1,XP2,YP2,P);
{Ri - радиус дуги измерений}
Измеряем длины дуг до точек пересечения:
DlinaD(Xs,Ys,XTn,YTn,XP1,YP1,Hod,LD1);
DlinaD(Xs,Ys,XTn,YTn,XP2,YP2,Hod,LD2);
Конечной точке соответствует меньшая длина дуги:
if LD1<LD2 then LD:=LD1 else LD:=LD2;
if LD<LDk then {записать в файл o}
RisLineBox(о, 2, Nam, Xm1, Ym1, Xs, Ys, XCm, YCm );
end;
Xm1:=Xs; Ym1:=Ys;
Until E=Nke;
Проверка на принадлежность области конечной точки дуги:
Tch_Obl(Xm2,Ym2,X1,Y1,X2,Y2,P);
if P=1 theh
{отрезок расположен внутри области, записать}
RisLineBox(о, 2, Nam, Xs, Ys, Xm2, Ym2, XCm, YCm );
Возвращаем первоначальные значения X и Y начала дуги:
Xm1:=Xm1s; Ym1:=Ym1s;
end;
Задача 2. Записать в файл границы заштрихованного контура (рис. 110).
Диалог пользователя:
‘Укажите курсором линию контура’ X,Y.
Заштрихованный контур в нашем случае ограничен 2-я линиями:
- наружная состоит из отрезков прямых, дуг и окружности;
- внутренняя содержит отрезки прямых и дуги.
Следовательно, следует указать в любой последовательности обе линии, например, курсором внутри области поставить точку О. Программное обеспечение в этом случае находит ближайший элемент линии наружного контура и на нем ближайшую от О точку А или В, которая принимается за начальную точку обхода по контуру в направлении конечной точки элемента. Возврат в эту точку означает окончание выбора линии контура. Выбранный контур для наглядности и контроля со стороны пользователя желательно прорисовать другим цветом, а его линии записать во временный файл для продолжения работы с контуром.
Рис. 110
Procedure Lin_Kontur;
Строка параметров линий, образующих контур:
var Em, Nam : byte: Xm1, Ym1, Xm2, Ym2, XCm, YCm :float:
Строка параметров линий контура:
var Eo, Nao : byte: Xo1, Yo1, Xo2, Yo2, XCo, YCo :float:
Строка параметров очередного отрезка
var Et, Nat : byte; Xt1, Yt1, Xt2, Yt2, XCt, YCt :float;
Прочие переменные:
var Xs, Ys, L, L1, Lmin, Li :float;
P, P1, P2, обход, ход :byte;
begin
Nach_Lin; {выбор начала и направления обхода}
Och_Line; {выбор и запись в текущий файл очередной линии}
end;
Выбор начала и направления обхода
Procedure Nach_Lin; {выбор начальной линии}
var XA,YA,XB,YB :float;
Pd :byte;
begin
L:=0; Pd:=0;
Repeat
Читать с 1-й строки файл линий и заполнить строку параметров:
SledLine(Bx, El, Nag, Xm1, Ym1, Xm2, Ym2, XCm, YCm );
if Em=2 then begin { дуга }
Соединить указанную курсором точку (ХO, YO) с центром дуги (ХЦ, YЦ) и определить текущий угол этой прямой:
TekUgol(XO,YO,XCm,YCm,U);
Радиус дуги:
DlinaL(XCm,YCm,Xm1,Ym1,R);
Точки пересечения прямой ОЦ с дугой:
OtrDug(XO,YO,U,XCm,YCm,R,XP1,YP1,XP2,YP2,P);
Принадлежность точки (XP1,YP1) дуге:
PikDug(XP1,YP1,Xm1,Ym1,Xm2,Ym2,Nam,P1);
Принадлежность точки (XP1,YP1) отрезку:
PikOtr(XP1,YP1,XО,YО,XЦ,YЦ,P2);
if P1=1 and P2=1 then begin
XA:=XP1; YA:=YP1;
end
else begin
XA:=XP2; YA:=YP2;
end;
Точка начала обхода:
Xs:=XA; Ys:=YA;
Расстояние от точки О до дуги:
DlinaL(XО,YО,XА,YА,L1);
end;
if Em=1 then begin {отрезок прямой}
TekUgol(Xm1,Ym1,Xm2,Ym2,U);
Перпендикуляр на прямую из О:
DwaOtr(Xm1, Ym1,U, XO, YO,U+90,XP,YP,P);
XB:=XP; YB:=YP;
Точка начала обхода:
Xs:=XB; Ys:=YB;
Расстояние от точки О до прямой:
DlinaL(XО,YО,XB,YB,L1);
end;
Pd:=Pd+1; {Номер цикла}
1- й цикл:
if Pd=1 then begin
Расстояние от точки О до элемента:
L:= L1;
Параметры начального отрезка обхода контура:
Eo:=Em; XCo:=XCm; YCo:=YCm;
Xo1:=Xs; Yo1:=Ys; Xo2:=Xm2; Yo2:=Ym2;
end;
Очередной цикл:
if Pd >1 and L>L1 then begin
Заменить параметры начального элемента обхода контура
L:= L1;
Eo:=Em; XCo:=XCm; YCo:=YCm;
Xo1:=Xs; Yo1:=Ys; Xo2:=Xm2; Yo2:=Ym2;
end;
Until E=Nkm;
Направление обхода контура определяется операторами Sopr_LL (центр и направление дуги сопряжения прямых) и Sopr_LD (центр и направление дуги сопряжения прямой и дуги). Направление в них непосредственно определяет рассмотренный выше оператор:
Naprawl(XC,YC,Xn,Yn,Xk,Yk,обход) }
if Eo=1 then Sopr_LL(XC, YC, обход)
else Sopr_LD(XC, YC, обход);
Чтобы замкнуть контур в точке S(Xs,Ys), в файл следует добавить отрезок линии от начальной точки до точки пересечения S. По окончании выбора линии контура его следует удалить.
RisLineBox( Bx, Em, Nam, Xm1, Ym1, Xs, Ys, XCm, YCm );
end;
Алгоритм выбора линий контура
Рассмотрим алгоритм выбора линий контура от начальной точки Na прямой a(Na,Ka) в направлении ‘обход’ (рис. 111). Ее параметры
записаны предыдущим оператором Nach_Lin в строку линий контура (Xo1:=Xs; Yo1:=Ys; Xo2:=Xm2; Yo2:=Ym2).
Далее определяются точки пересечения S1, S2 этого элемента с другими, содержащимися в файле и сортируются по наименьшему расстоянию до начала исходного элемента(точка Na). Одновременно определяется длина дуги DL.
Если через точку S2 проходят 2 и более элементов (в данном случае дуга d и прямая с), то выбирается элемент с меньшим углом LD. В данном случае часть дуги d с начальной точкой S2 и конечной точкой Kd. Отрезок прямой a от начальной точки Na до точки S2 записывается в файл, содержащий линии определяемого контура.
Рис. 111
Дуга d становится начальным элементом. Предыдущий цикл повторяется. В этом цикле в файл будет записана дуга с начальной точкой S2 и конечной - S3.
Начальным элементом в следующем цикле будет отрезок S3Kc, на котором нет точки пересечения. В этом случае он будет записан в файл, а начальным элементом в следующем цикле будет тот же отрезок, но с обратным направлением KcS2.
Выбор контура будет закончен, если координаты конечной точки
очередного элемента будут равны Xs, Ys.
Выбор очередной линии
Procedure Och_Line; {выбор и запись линий контура}
var Xs1; Ys1, Lmin, Li :Float; Pd :byte;
begin
Pd:=0;
Repeat
SledLine( Bx, Em, Nam, Xm1, Ym1, Xm2, Ym2, XCm, YCm );
if Em=1 then TekUgol(Xm1, Ym1, Xm2, Ym2,Um);
if Em=2 then DlinaL(Xm1, Ym1, XCm , YCm ,R);
if Eo=1 and Em=1 then O_O;
if Eo=1 and Em=2 then O_D;
if Eo=2 and Em=1 then D_O;
if Eo=2 and Em=2 then D_D;
Записать начальный отрезок в файл линий границы контура:
RisLineBox( o, Eo, Nao, Xo1, Yo1, Xo2, Yo2, XCo, YCo );
Заменить строку параметров начального элемента параметрами бывшего очередным:
Eo:=Et; Nao:=Nat;
Xo1:=Xt1; Yo1:=Yt1; Xo2:=Xt2; Yo2:=Yt2; XCo:=XCt; YCo:=YCt;
Until Xt2=Xs and Yt2=Ys;
Записать в файл конечную линию обхода контура:
RisLineBox( o, Et, Nat, Xt1, Yt1, Xt2, Yt2, XCt, YCt );
end;
Начальный элемент - отрезок, очередной - отрезок
Procedure O_O;
Оператор определяет точку пресечения Р начального элемента - отрезка o(o1,o2) с текущим элементом - отрезком m(m1,m2). Если
Li < Lmin,то отрезок m делится на 2 отрезка Рm1 и Pm2 (рис. 112).
Далее оператор определяет, который из них может быть очередной линией контура после отрезка о.
begin
Определена Lmin при условии, что не было пересечений с текущим элементом (отрезком прямой или дугой):
Рис. 112
if Pd=0 then DlinaL(Xo1,Yo1,Xo2,Yo2,Lmin); {Pd - номер точки P на начальном элементе. Если не было пересечения с текущим элементом, Рd =0}
TekUgol(Xo1,Yo1,Xo2,Yo2,Uo); {начальной прямой}
TekUgol(Xm1,Ym1,Xm2,Ym2,Um); {текущей прямой}
Точка пересечения элементов:
DwaOtr(Xm1, Ym1,Um, Xo1, Yo1,Uo,XP,YP,P);
Принадлежность точки пересечения текущему элементу:
if P=1 then PikOtr(XP,YP,Xm1,Ym1,Xm2,Ym2,P);
Принадлежность точки пересечения начальному элементу:
if P=1 then PikOtr(XP,YP,Xo1,Yo1,Xo2,Yo2,P);
{Если P=1, то отрезки пересекаются}
if P=1 then begin
Расстояние точки пересечения от начала начального элемента:
DlinaL(Xo1,Yo1,XP,YP,Li);
if Li > 0 and Li <= Lmin then begin
if Pd=0 then
Определена начальная точка измерения дуги и LDk:
Tch_NiK(XCo,YCo,Xo1,Yo1,Xo2,Yo2,XP,YP,XTn,YTn,LDk);
Длина текущего отрезка от точки пересечения до конца:
DlinaL(XP,YP,Xm2,Ym2,L);
if L>0 then begin
Определена точка Tk(XTk,YTk) на отрезке(XP,YP.Xm2,Ym2):
OtrDug(XP,YP,Um,XP,YP,Ri,XP1,YP1,XP2,YP2,P);
PikOtr(XP1,YP1,XP,YP,Xm2,Ym2,P);
if P=1 then begin
XTk:=XP1; YTk:=YP1;
end
else begin
XTk:=XP2; YTk:=YP2;
end;
Определена длина дуги от Tn до Tk:
DlinaD(XP,YP,XTn,YTn,XTk,YTk,Hod,LD);
if LD<LDk then begin
Записать в текущую строку отрезок, который может быть очередным:
Et:=1; Xt1:=XP; Yt1:=YP; Xt2:=Xm2; Yt2:=Ym2;
Записать номер пересечения, новое значение LDk и Lmin:
Pd:=Pd+1; LDk:=LD; if Li<Lmin then Lmin:=Li;
end;
end;
То же выполнено для оставшейся части текущего отрезка:
DlinaL(XP,YP,Xm1,Ym1,L);
if L>0 then begin
Определен Um, т.к. изменилось направление:
TekUgol(XP,YP,Xm1,Ym1,Um);
OtrDug(XP,YP,Um,XP,YP,Ri,XP1,YP1,XP2,YP2,P);
PikOtr(XP1,YP1,XP,YP,Xm1,Ym1,P);
if P=1 then begin
XTk:=XP1; YTk:=YP1;
end
else begin
XTk:=XP2; YTk:=YP2;
end;
DlinaD(XP,YP,XTn,YTn,XTk,YTk,Hod,LD);
if LD<LDk then begin
Записать в текущую строку отрезок, который может быть очередным:
Et:=1; Xt1:=XP; Yt1:=YP; Xt2:=Xm2; Yt2:=Ym2;
Записать номер пересечения, новое значение LDk и Lmin:
Pd:=Pd+1; LDk:=LD; if Li<Lmin then Lmin:=Li;
end;
end;
if Li<Lmin then
{Изменилась длина начального отрезка}
Xo2:=XP; Yo2:=YP;
end;
end;
end;
Начальный элемент - отрезок, очередной - дуга
Procedure O_D;
Оператор определяет точку пресечения Р начального элемента - отрезка o(o1,o2) с текущим элементом - дугой m(m1,m2).
Если Li < Lmin,то дуга m делится на 2 части Рm1 и Pm2 (рис. 113). Далее оператор определяет, которая из дуг может быть очередной линией контура после отрезка о.
Рис. 113
begin
Определена Lmin при условии, что не было пересечений с текущим
элементом (отрезком прямой или дугой):
if Pd=0 then DlinaL(Xo1,Yo1,Xo2,Yo2,Lmin); {Pd - номер точки P на начальном элементе. Если не было пересечения с текущим элементом, то Рd =0}
TekUgol(Xo1,Yo1,Xo2,Yo2,Uo); {начальной прямой}
DlinaL(XСm,YCm,Xm1,Ym1,R); {радиус текущей дуги}
Определены 2 точки пересечении прямой с дугой:
OtrDug(Xo1,Yo1,Uo,XCm,YCm,R,XP1,YP1,XP2,YP2,P);
Принадлежность Р1 начальному элементу:
if P=1 then PikOtr(XP1,YP1,Xo1,Yo1,Xo2,Yo2,P1);
Принадлежность Р1 текущему элементу:
if P1=1 then
PikDug(XP1,YP1,XCm,YCm,Xm1,Ym1,Xm2,Ym2,Nam,P2);
if P1=1 and P2=1 then P3=1 else P3=0;
Принадлежность Р2 начальному элементу:
PikOtr(XP2,YP2,Xo1,Yo1,Xo2,Yo2,P1);
Принадлежность Р2 текущему элементу:
if P1=1 then
PikDug(XP2,YP2,XCm,YCm,Xm1,Ym1,Xm2,Ym2,Nam,P2);
if P1=1 and P2=1 then P4=1 else P4=0;
{Если P3=1 или P4=1, то элементы пересекаются. Если Р3=1 и Р4=1, то выбрать точку пересечения, которая ближе к началу начального элемента}
if P3=1 and P4=1 then begin
DlinaL(Xo1,Yo1,XP1,YP1,L1);
DlinaL(Xo1,Yo1,XP2,YP2,L2);
if L1<L2 then begin
XP:=XP1; YP:=YP1; Li:=L1;
end
else begin
XP:=XP2; YP:=YP2; Li:=L2;
end;
end;
if P3=1 and P4=0 then begin
XP:=XP1; YP:=YP1; Li:=L1;
end;
if P3=0 and P4=1 then begin
XP:=XP2; YP:=YP2; Li:=L2;
end;
if Li > 0 and Li <= Lmin then begin
if Pd=0 then
Определена начальная точка(XTn,YTn) измерения дуги и LDk:
Tch_NiK(XCo,YCo,Xo1,Yo1,Xo2,Yo2,XP,YP,XTn,YTn,LDk);
Измерить длину части текущей дуги от Р до конца:
DlinaD(XCm,YCm,XP,YP,Xm2,Ym2,Nam,LD);
if LD>0 then begin
Определена конечная точка(XTk,YTk) для измерения длины дуги:
DugDug(XCm,YCm,R,XP,YP,Ri,XP1,YP1,XP2,YP2,P);
PikDug(XP1,YP1,XCm,YCm,XP,YP,Xm2,Ym2,Nam,P);
if P=1 then begin
XTk:=XP1; YTk:=YP1;
end
else begin
XTk:=XP2; YTk:=YP2;
end;
Определена длина дуги:
DlinaD(XP,YP,XTn,YTn,XTk,YTk,Hod,LD);
if LD<LDk then begin
Записать в текущую строку элемент, который может быть очередным:
Et:=2; Xt1:=XP; Yt1:=YP; Xt2:=Xm2; Yt2:=Ym2;
XCt:=XCm; YCt:=YCm;
Записать номер пересечения, новое значение LDk и Lmin:
Pd:=Pd+1; LDk:=LD;
if Li<Lmin then begin
Lmin:=Li;
Изменилась длина начального отрезка:
Xo2:=XP; Yo2:=YP;
end;
end;
end;
Для второй части дуги необходимо изменить направление на противоположное:
if Nam=1 then Nam:=2 else Nam:=1;
DlinaD(XCm,YCm,XP,YP,Xm1,Ym1,Nam,LD);
if LD>0 then begin
DugDug(XCm,YCm,R,XP,YP,Ri,XP1,YP1,XP2,YP2,P);
PikDug(XP1,YP1,XCm,YCm,XP,YP,Xm1,Ym1,Nam,P);
if P=1 then begin
XTk:=XP1; YTk:=YP1;
end
else begin
XTk:=XP2; YTk:=YP2;
end;
DlinaD(XP,YP,XTn,YTn,XTk,YTk,Hod,LD);
if LD<LDk then begin
Et:=2; Xt1:=XP; Yt1:=YP; Xt2:=Xm1; Yt2:=Ym1;
XCt:=XCm; YCt:=YCm;
Записать номер пересечения, новое значение LDk и Lmin:
Pd:=Pd+1; LDk:=LD;
if Li<Lmin then begin
Lmin:=Li;
Изменилась длина начального отрезка:
Xo2:=XP; Yo2:=YP;
end;
end;
end;
end;
end;
Начальный элемент - дуга, очередной - отрезок
Procedure D_O;
Оператор определяет точку пресечения Р начального элемента - дуги o(o1,o2) с текущим элементом - отрезком m(m1,m2).
Если Li < Lmin,то отрезок m делится на 2 части Рm1 и Pm2 (рис. 114). Далее оператор определяет, который из отрезков может быть очередной линией контура после дуги о.
Рис. 114
begin
Определена Lmin при условии, что не было пересечений с текущим
элементом (отрезком прямой или дугой):
if Pd=0 then DlinaD(XCo,YCo,Xo1,Yo1,Xo2,Yo2,Nao,Lmin);
{Pd - номер точки P на начальном элементе. Если не было
пересечения с текущим элементом, то Рd =0}
TekUgol(Xm1,Ym1,Xm2,Ym2,Um); {текущей прямой}
DlinaL(XСo,YCo,Xo1,Yo1,R); {радиус начальной дуги}
Определены точки пересечения прямой с дугой:
OtrDug(Xm1,Ym1,Um,XCo,YCo,R,XP1,YP1,XP2,YP2,P);
Принадлежность Р1 текущему элементу:
if P=1 then PikOtr(XP1,YP1,Xm1,Ym1,Xm2,Ym2,P1);
Принадлежность Р1 начальному элементу:
if P1=1 then
PikDug(XP1,YP1,XCo,YCo, Xo1,Yo1,Xo2,Yo2,Nao,P2);
if P1=1 and P2=1 then P3=1 else P3=0;
Принадлежность Р2 текущему элементу:
if P=1 then PikOtr(XP2,YP2,Xm1,Ym1,Xm2,Ym2,P1);
Принадлежность Р2 начальному элементу:
if P1=1 then
PikDug(XP2,YP2,XCo,YCo,Xo1,Yo1,Xo2,Yo2,Nao,P2);
if P1=1 and P2=1 then P4=1 else P4=0;
Если Р3=1 и Р4=1, то выбрать точку пересечения, которая ближе к началу начального элемента:
if P3=1 and P4=1 then begin
DlinaD(XCo,YCo,Xo1,Yo1,XP1,YP1,Nao,L1);
DlinaD(XCo,YCo,Xo1,Yo1,XP2,YP2,Nao,L2);
if L1<L2 then begin
XP:=XP1; YP:=YP1; Li:=L1;
end
else begin
XP:=XP2; YP:=YP2; Li:=L2;
end;
end;
if P3=1 and P4=0 then begin
XP:=XP1; YP:=YP1; Li:=L1;
end;
if P3=0 and P4=1 then begin
XP:=XP2; YP:=YP2; Li:=L2;
end;
if Li > 0 and Li <= Lmin then begin
if Pd=0 then
Определена точка измерения дуги (XTn,YTn) и LDk:
Tch_NiK(XCo,YCo,Xo1,Yo1,Xo2,Yo2,XP,YP,XTn,YTn,LDk);
Длина текущего отрезка от точки пересечения до конца:
DlinaL(XP,YP,Xm2,Ym2,L);
if L>0 then begin
Определена точка Tk(XTk,YTk) на отрезке(XP,YP.Xm2,Ym2):
OtrDug(XP,YP,Um,XP,YP,Ri,XP1,YP1,XP2,YP2,P);
PikOtr(XP1,YP1,XP,YP,Xm2,Ym2,P);
if P=1 then begin
XTk:=XP1; YTk:=YP1;
end
else begin
XTk:=XP2; YTk:=YP2;
end;
Определена длина дуги от Tn до Tk:
DlinaD(XP,YP,XTn,YTn,XTk,YTk,Hod,LD);
if LD<LDk then begin
Записать в текущую строку отрезок, который может быть очередным:
Et:=1; Xt1:=XP; Yt1:=YP; Xt2:=Xm2; Yt2:=Ym2;
Записать номер пересечения, новое значение LDk и Lmin:
Pd:=Pd+1; LDk:=LD; if Li<Lmin then Lmin:=Li;
end;
end;
То же выполнено для оставшейся части текущего отрезка:
DlinaL(XP,YP,Xm1,Ym1,L);
if L>0 then begin
Определен Um, т.к. изменилось направление:
TekUgol(XP,YP,Xm1,Ym1,Um);
OtrDug(XP,YP,Um,XP,YP,Ri,XP1,YP1,XP2,YP2,P);
PikOtr(XP1,YP1,XP,YP,Xm1,Ym1,P);
if P=1 then begin
XTk:=XP1; YTk:=YP1;
end
else begin
XTk:=XP2; YTk:=YP2;
end;
DlinaD(XP,YP,XTn,YTn,XTk,YTk,Hod,LD);
if LD<LDk then begin
Записать в текущую строку отрезок, который может быть очередным:
Et:=1; Xt1:=XP; Yt1:=YP; Xt2:=Xm2; Yt2:=Ym2;
Записать номер пересечения, новое значение LDk и Lmin:
Pd:=Pd+1; LDk:=LD; if Li<Lmin then Lmin:=Li;
end;
end;
if Li<Lmin then
{Изменилась длина начального отрезка}
Xo2:=XP; Yo2:=YP;
end;
end;
end;
Procedure D_D;
Оператор определяет точку пресечения Р начального элемента - дуги o(o1,o2) с текущим элементом - дугой m(m1,m2).
Если Li < Lmin,то дуга m делится на 2 части Рm1 и Pm2 (рис. 115). Далее оператор определяет, которая из дуг может быть очередной линией контура после дуги о.
Рис. 115
begin
Определена Lmin при условии, что не было пересечений с текущим
элементом (отрезком прямой или дугой):
if Pd=0 then DlinaD(XCo,YCo,Xo1,Yo1,Xo2,Yo2,Nao,Lmin);
{Pd - номер точки P на начальном элементе. Если не было пересечения с текущим элементом, то Рd =0}
DlinaL(XСm,YCm,Xm1,Ym1,Rm); {радиус текущей дуги}
DlinaL(XСo,YCo,Xo1,Yo1,R); {радиус начальной дуги}
Определены точки пересечения дуг:
DugDug(XCm,YCm,Rm,XCo,YCo,R,XP1,YP1,XP2,YP2,P);
Принадлежность Р1 текущему элементу:
if P=1 then
PikDug(XP1,YP1,XCm,YCm,Xm1,Ym1,Xm2,Ym2,Nam,P1);
Принадлежность Р1 начальному элементу:
if P1=1 then
PikDug(XP1,YP1,XCo,YCo,Xo1,Yo1,Xo2,Yo2,Nao,P2);
if P1=1 and P2=1 then P3=1 else P3=0;
Принадлежность Р2 текущему элементу:
if P=1 then
PikOtr(XP2,YP2,XCm,YCm,Xm1,Ym1,Xm2,Ym2,P1);
Принадлежность Р2 начальному элементу:
if P1=1 then
PikDug(XP2,YP2,XCo,YCo,Xo1,Yo1,Xo2,Yo2,Nao,P2);
if P1=1 and P2=1 then P4=1 else P4=0;
Если Р3=1 и Р4=1, то выбрать точку пересечения, которая ближе к началу начального элемента:
if P3=1 and P4=1 then begin
DlinaD(XCo,YCo,Xo1,Yo1,XP1,YP1,Nao,L1);
DlinaD(XCo,YCo,Xo1,Yo1,XP2,YP2,Nao,L2);
if L1<L2 then begin
XP:=XP1; YP:=YP1; Li:=L1;
end
else begin
XP:=XP2; YP:=YP2; Li:=L2;
end;
end;
if P3=1 and P4=0 then begin
XP:=XP1; YP:=YP1; Li:=L1;
end;
if P3=0 and P4=1 then begin
XP:=XP2; YP:=YP2; Li:=L2;
end;
if Li > 0 and Li <= Lmin then begin
if Pd=0 then
Определена точка измерения дуги (XTn,YTn) и LDk:
Tch_NiK(XCo,YCo,Xo1,Yo1,Xo2,Yo2,XP,YP,XTn,YTn,LDk);
Измерена длина части текущей дуги от Р до конца:
DlinaD(XCm,YCm,XP,YP,Xm2,Ym2,Nam,LD);
if LD>0 then begin
Определена конечная точка(XTk,YTk) для измерения длины дуги:
DugDug(XCm,YCm,R,XP,YP,Ri,XP1,YP1,XP2,YP2,P);
PikDug(XP1,YP1,XCm,YCm,XP,YP,Xm2,Ym2,Nam,P);
if P=1 then begin
XTk:=XP1; YTk:=YP1;
end
else begin
XTk:=XP2; YTk:=YP2;
end;
Определена длина дуги:
DlinaD(XP,YP,XTn,YTn,XTk,YTk,Hod,LD);
if LD<LDk then begin
Записать в текущую строку элемент, который может быть очередным:
Et:=2; Xt1:=XP; Yt1:=YP;
Xt2:=Xm2; Yt2:=Ym2;
XCt:=XCm; YCt:=YCm;
Записать номер пересечения, новое значение LDk и Lmin:
Pd:=Pd+1; LDk:=LD;
if Li<Lmin then begin
Lmin:=Li;
Изменилась длина начального отрезка:
Xo2:=XP; Yo2:=YP;
end;
end;
end;
Для второй части дуги необходимо изменить направление на противоположное:
if Nam=1 then Nam:=2 else Nam:=1;
DlinaD(XCm,YCm,XP,YP,Xm1,Ym1,Nam,LD);
if LD>0 then begin
DugDug(XCm,YCm,R,XP,YP,Ri,XP1,YP1,XP2,YP2,P);
PikDug(XP1,YP1,XCm,YCm,XP,YP,Xm1,Ym1,Nam,P);
if P=1 then begin
XTk:=XP1; YTk:=YP1;
end
else begin
XTk:=XP2; YTk:=YP2;
end;
DlinaD(XP,YP,XTn,YTn,XTk,YTk,Hod,LD);
if LD<LDk then begin
Et:=2; Xt1:=XP; Yt1:=YP; Xt2:=Xm1; Yt2:=Ym1;
XCt:=XCm; YCt:=YCm;
Записать номер пересечения, новое значение LDk и Lmin:
Pd:=Pd+1; LDk:=LD;
if Li<Lmin then begin
Lmin:=Li;
Изменилась длина начального отрезка:
Xo2:=XP; Yo2:=YP;
end;
end;
end;
end;
end;