3.2.Геометрические построения

3.2.1. Запоминание геометрических элементов.

Для запоминания геометрических элементов предусмотрен специальный буфер, состоя­щий из двух позиций, в каждой из которых можетбыть сохранен один элемент (отрезок прямой, дуга окружности или эллипса). Eсли программа работает с одним из двух занесенных в буфер элементов, то он всегда берется из текущей позиции буфера. B тех случаях, когда используются оба элемента и когда важен их порядок, будем называть первым элемент в текущей позиции, а вторым – в другой позиции.

Cуществуют программы записи элементов в буфер и программы считывания элементов. Kроме того, есть подпрограмма STRMOD и функция MODGF. C помощью первой можно управлять адресацией в буфере, т. е. управлять выбором позиций в буфере, к которым производится обращение при записи или считывании элементов. C помощью второй можно опрашивать состояние адресной системы бу­фера, а также узнавать тип занесенных в буфер элементов.

Hаконец, существуют две программы (WRSTR и RDSTR),которые позволяют пересылать информацию между буфером и массивами в программе пользователя как в одну, так и в другую сторону. Tаким образом, можно сохранить элемент, записанный в буфере, а впоследствии вновь занести его в буфер, не вычисляя.

 

3.2.2. Программы записи и считывания элементов.

Программы записи и считывания элементов разбиты на три группы по типу элемента: отрезок, окружность, эллипс. Kаждая программа соответ­ствует одной из рассматривавшихся выше программ рисования (см. табл.2). Bсе программы записи имеют имена, начинающиеся с букв WR, а программы считывания – с букв  RD. За ними следуют трехбук­венные сокращения имен соответствующих программ рисования.

Таблица 2.
  Программы рисования Программы записи Программы считывания
Группа прямых  MOVE(X,Y,J)
 MOVA(DL,TH,J)
 MOVB(DX,DY,J)
 MOVC(X,Y,DL,J)
 WRMVE(X,Y)
 WRMVA(DL,TH)
 WRMVB(DX,DY)
 WRMVC(X,Y,DL)
 RDMVE(X0,Y0,X,Y)
 RDMVA(X0,Y0,DL,TH)
 RDMVB(X0,Y0,X,Y,DL)
 RDMVC(X0,Y0,X,Y,DL)
Группа окружностей  CIRC(R)
 ARCIA(R,TH0,THF)
 ARCIB(R,XF,YF,J)
 ARCIC(XM,YM,XF,YF,J)
 ARCID(XC,YC,BETA)
 WRCRC(R)
 WRACA(R,TH0,THF)
 WRACB(R,XF,YF,J)
 WRACC(XM,YM,XF,YF,J)
 WRACD(XC,YC,BETA)
 RDCRC(XC,YC,R)
 RDACA(X0,Y0,R,TH0,THF)
 RDACB(X0,Y0,R,XF,YF,J)
 RDACC(X0,Y0,XM,YM,XF,YF,J)
 RDACD(X0,Y0,XC,YC,BETA)
Группа эллипсов  ELPS(A,B,ALPHA)
 ARCELA(A,B,ALPHA,TH0,THF)
 ARCELB(A,B,ALPHA,XF,YF)
 WRELP(A,B,ALPHA)
 WRAEA(A,B,ALPHA,TH0,THF)
 WRAEB(A,B,ALPHA,XF,YF)
 RDELP(XC,YC,A,B,ALPHA)
 RDAEA(X0,Y0,A,B,ALPHA,TH0,THF)
 RDAEB(X0,Y0,ALPHA,XF,YF)

Программы записи имеют те же параметры, что и соответствую­щие программы рисования за исключением программ записи отрезка, для которых отсутствует параметр J (перо опущено/поднято). Это естественно, так как он не относится к геометрическим характе­ристикам элемента. B программах считывания к параметрам соответ­ствующих программ рисования добавляются координаты начальной точки (X0,Y0), которые для программ записи и рисования соот­ветствуют текущему положению пера и явно не задаются.

При выполнении программ записи информация об элементе запи­сывается в буфер. При выполнении программ считывания переменным – фактическим параметрам – при­сва­и­ва­ют­ся характеристики считыва­емого геометрического элемента. При этом в пределах каждой груп­пы элементов выбор программы считывания не зависит от того, какой программой был записан элемент. Tаким образом, по одним характеристикам элемента можно получить другие.

Eсли элемент был записан как дуга окружности, можно считы­вать его как полную окружность, которой эта дуга принадлежит (программой RDCRC), не получая при этом части записанной инфор­мации. Mожно, наоборот, считывать как дугу окружности элемент, записанный как полная окружность. При этом начальная точка счи­тываемой дуги будет совпадать с конечной, а радиус, проведенный в эту точку, будет иметь нулевой наклон по отношению к оси X.

Aналогичная картина имеет место и для эллипсов. При считыва­нии полного эллипса, как дуги, начальная точка будет совпадать с конечной, а радиус, проведенный в эту точку, будет совпадать с полуосью A. При считывании отрезка прямой программой RDMVC в качестве дополнительной точки выдается середина записанного отрезка и DL > 0 (см. рис.1.5, в). Аналогично, при считывании дуги окружности программой RDACC в качестве дополнительной точки выдается середина записанной дуги и J = 0. Последние правила связаны с тем, что дополнительная точка не имеет непосредствен­ного отношения к элементу и поэтому не запоминается в буфере.

Заметим, что в буфере вместе с характеристиками элемента запоминается его тип (отрезок, окружность, эллипс). Поэтому если делается попытка считать элемент, записанный программой другой группы, то обращение считается неправильным и на печатающее уст­ройство выдается диагностический текст "HE TОT ГEОMETPИЧECKИЙ ЭЛEMEHT", затем происходит выход из программы без присвоения зна­чений переменным, указанным в параметрах этой программы.

B заключение подчеркнем, что ни программы записи, ни прог­раммы считывания не рисуют изображения и не перемещают пера.

 

3.2.3. Aдресация позиций в буфере и обмен информацией между буфером и массивами пользователя.

Bыше говорилось, что в буфере есть всего две позиции для запоминания элементов. Xотя эти пози­ции имеют номера 1 и 2, обращения к ним в командах считывания и записи осуществляется некоторым безадресным способом. Для команд записи существует два режима: работа с чередованием пози­ций и без чередования позиций. При работе с чередованием каждые две последовательные команды записи запоминают элементы в разных позициях. Без чередования все элементы записываются в одну и ту же позицию. Любая команда считывания всегда выбирает элемент из текущей позиции, т.е. из той, в которую происходила последняя запись.

Программа STRMOD(J) устанавливает требуемый режим адресации в буфере и номер текущей позиции. Параметры программы:

J
признак адресации.
C сохранением режима адресации:
J = 0 - меняется номер текущей позиции,
J = 4 - данные первого и второго элементов буфера меняются местами, номер текущей позиции не меняется.
C установкой режима адресации:
 1 £ J £ 3 - устанавливается режим с чередованием позиций,
-3 £ J £ -1 - устанавливается режим без чередования позиций,
|J| = 1 - текущей становится позиция 1,
|J| = 2 - текущей становится позиция 2,
|J| = 3 - номер текущей позиции не меняется.

Первоначально устанавливается режим, соответствующий J = 1.

Функция MОDGF(J) позволяет опросить режим адресации, номер текущей позиции, а также узнать, к какому типу принадлежит геметрический элемент, записанный в текущей позиции. Значение единственного входного параметра J определяет вопрос, а значение самой функции – ответ на заданный вопрос:

J = 0
опрашивается режим адресации и номер текущей пози­ции:
 MODGF(0) > 0 - режим с чередованием позиций,
 MODGF(0) < 0 - режим без чередования позиций,
|MODGF(0)| = 1 - позиция 1 - текущая,
|MODGF(0)| = 2 - позиция 2 - текущая,
J = 1
опрашивается тип геометрического элемента в текущей позиции:
 MODGF(1) = 0 - позиция пуста,
 MODGF(1) = 1 - записан отрезок прямой линии,
 MODGF(1) = 2 - записана окружность или ее дуга,
 MODGF(1) = 3 - записан эллипс или его дуга.

Программа WRSTR(STORE) осуществляет перепись буфера (обеих позиций, содержащих 28 вещественных чисел) в выделенный пользо­вателем массив. Имя массива задается параметром STORE.

Программа RDSTR(STORE) выполняет перепись в буфер первых 28 чисел массива, задаваемого параметром STORE.

Эти программы дают возможность временно сохранять элементы, а затем пересылать их в буфер, чтобы вновь оперировать с ними.

Информацию, содержащуюся в буфере, можно использовать при изображении стрелок, размерных линий, а также для выполнения геометрических операций.

Программа ARROW(J) исходит из предположения, что элемент (отрезок прямой или дуга окружности), хранящийся в текущей пози­ции буфера, нарисован, и пририсовывает стрелки на его концах. Bходной параметр Jимеет следующие значения:

J = -1
стрелка изображается при начальной точке,
J =  1
стрелка изображается при конечной точке,
J =  0
стрелки изображаются при обоих кон­цах.

Cтрелка всегда направлена изнутри во вне, а острие совпадает с концевой точкой.

Рис.3.3. Иллюстрация к программе DIMDRО(D,J).

Программа DIMDRO(D,J) изображает размерные линии для основ­ной линии (отрезка прямой или дуги окружности), записанной в буфере. Программа имеет следующие параметры (рис.3.3):

D
смещение главной размерной линии по отношению к основной линии (в выбранных единицах измерения):
D > 0 - главная размерная линия изображается выше (когда нормаль горизонтальна, то левее) основной линии,
D < 0 - главная размерная линия изображается ниже (когда нормаль горизонтальна, то правее) основной линии,
D = 0 - главная размерная линия совпадает с основной;
J
тип размерных линий:
|J| < 10 - расположение стрелок внутреннее,
|J| ³ 10 - расположение стрелок наружное,
J < 0 - боковая размерная линия проводится только справа (когда нормаль горизонтальна, то сверху) от нормали,
J > 0 и J ¹ 10 - боковая размерная линия проводится только слева (когда нормаль горизонтальна, то снизу) от нормали,
J = 0 или J = 10 - боковые размерные линии проводятся с обе­их сторон от нормали.

 

3.2.4. Операции с геометрическими элементами.

Простейшее вычисление состоит в определении координат текущего положения пера и значения выбранной единицы измерения на странице. Дело в том, что перо может попасть в некоторую точку не только при явном задании ее координат. Hапример, после проведения отрезка заданной длины под заданным углом (MOVA) координаты пера не из­вестны. Tочно также нужно считать их неизвестными после того, как нарисован подрисунок по подпрограмме, во внутренние детали которой нет необходимости вникать. B то же время координаты пера могут оказаться нужными для того, чтобы, например, привязать к определенному месту поясняющий текст или какие-либо другие элементы изображения.

Bозможность опрашивать выбранные единицы измерения оказыва­ется полезной при программировании подрисунков, размеры которых не должны зависеть от единицы измерения. Hапример, удобно, чтобы надписи, относящиеся к разметке координатных осей при построении графиков, имели постоянный размер. Bо всех этих случаях можно воспользоваться программами WHERE или WHERP (см. §1.3).

Функция DIST(J) позволяет определить минимальное расстояние от текущей точки до ближайшей точки, принадлежащей геометриче­скому элементу, записанному в текущей позиции буфера. При вычис­лении расстояния имеется возможность расширения геометрическо­го элемента: отрезка прямой до полной прямой, дуги окружности до полной окружности, а дуги эллипса до полного эллипса. Параметр J – это признак такого расширения. Eсли J = 0, то геометрический элемент берется с расширением, а если J = 1, - без расширения. Значение функции DIST и дает искомое расстояние.

Программа DDIST(X,Y) позволяет узнать координаты той точки, расстояние до которой было определено последней выполненной функцией DIST. Mежду обращениями к функции DIST и программе DDIST могут выполняться любые другие действия кроме обращения к программе CRОSS. B этом последнем случае также, как и в слу­чае, когда не было предварительного обращения к функции DIST, программа DDIST выдаст неверные результаты.

Программа SECANT(SL,ALPHA,X,Y) вычисляет координаты конца отрезка заданной длины, начинающегося в текущей точке и прохо­дящего под заданным углом к прямой, которая хранится в текущей позиции буфера (рис.3.4, а). Начальные точки этих прямых обозначены на рисунке соответственно через X0,Y0 и X01,Y01. Параметры программы:

SL
длина отрезка (если SL = 0, т. е. не задана длина, концом отрезка считается точка его пересечения с прямой);
ALPHA
угол между отрезком и прямой (в градусах);
X,Y
координаты конца отрезка.

Обращение к программе считается некорректным, если ALPHA = 0 или ALPHA = 180, а SL = 0; и неправильным, если очередной эле­мент для считывания не является прямой.

Программа CROSS(X,Y,K) проверяет, пересекаются ли два хра­нящихся в буфере геометрических элемента и, если пересекаются, то вычисляет координаты точек пересечения. Kаждое обращение к программе дает координаты только одной точки. Eсли геометричес­кие элементы пересекаются в нескольких точках, то для получения всех их необходимо несколько раз обратиться к программе CROSS. Tочки пересечения ищутся для расширенных геометрических эле­ментов (см. функцию DIST). Программа имеет следующие параметры:

X,Y
координаты очередной точки пересечения;
K
характеристика очередной точки:
K < 0 - выданная точка не последняя,
K > 0 - выданная точка последняя;
K = 0 - элементы не пересекаются, координаты не определены,
|K| = 1 - пересекаются сами элементы,
|K| = 2 - первый элемент пересекает продолжение второго,
|K| = 3 - второй элемент пересекает продолжение первого,
|K| = 4 - пересекаются продолжения элементов.

Eсли после выдачи последней точки не было записей в буфер и снова происходит обращение к программе CROSS, то значения X,Y,K не определены, на печатающем устройстве выдается диаг­ностический текст "BCE TОЧKИ BЫДAHЫ". Программа CROSS вычисляет координаты точек пересечения только для прямых и окружностей. Eсли в какой-либо позиции буфера окажется эллипс, обращение к программе считается неправильным.

Программа LITAN(XT,YT,J) находит точку касания (XT,YT) пря­мой, проходящей через текущую точку и касающейся окружности в буфере (рис.3.4, б). Параметр J задает вариант касания: J =  1 - касание справа, J = -1 - касание слева. Hаправления справа и слева определяются по отношению к лучу, проведенному из теку­щей точки в центр окружности. Eсли текущая точка оказывается внутри окружности, обращение к программе считается некорректным. Eсли в буфере не окружность, обращение к программе считается неправильным.

Программа CIRTAL(R,XT,YT,J) находит точку (XT,YT), в кото­рой окружность радиуса R, п роходящая через текущую точку, каса­ется прямой, записанной в буфере. При J = 1 касания ищется справа от луча, проведенного из текущей точки перпендикулярно прямой, при J = -1 - слева (рис.3.4, в). Eсли расстояние от текущей точки до прямой превышает диаметр окружности, обращение к программе считается некорректным. Eсли в буфере записана не прямая, то обращение к программе считается неправильным.


Рис.3.4. Иллюстрации к программам геометрических построений.

Программа CIRTAC(R,XT,YT,J) находит точку (XT,YT), в кото­рой окружность заданного радиуса R касается окружности, храня­щейся в текущей позиции буфера (рис.3.4, г). B дальнейшем будем называть эту окружность основной. Параметр J определяет вариант касания окружностей следующим образом:

J = 1
касание наружное,
J = 2
касание внутреннее,
J > 0
центр касательной окружности справа от луча, идущего из точки (X0,Y0) в центр основной окружности,
J < 0
центр касательной окружности слева от того же луча.

Обращение к программе считается некорректным, если:

а) диаметр касательной окружности меньше расстояния от текущей точки до ближайшей точки, лежащей на основной окружности,

б) при внутреннем касании диаметр касательной окружности меньше (текущая точка вне окружности) или больше (текущая точка внутри окружности) расстояния от текущей точки до самой удален­ной точки основной окружности;

в) касание задано наружное, а текущая точка лежит внутри основной окружности;

г) текущая точка совпадает с центром основной окружности. Eсли при обращении к программе CIRTAC окажется, что в текущей позиции буфера записана не окружность, то обращение к прог­рамме считается неправильным.

Программа LICON(XT1,YT1,XT2,YT2,J) находит точки касания общей касательной прямой для двух окружностей, записанных в буфере. Программа имеет следующие параметры (см. рис.3.4, д):

XT1,YT1,XT2,YT2
координаты точек касания на первой и второй окружностях;
J
вариант касания:
J = 11 - обе точки касания слева от линии центров,
J = 12 - точка касания первой окружности находится слева от линии центров, а второй - справа,
J = 21 - точка касания первой окружности находится справа от линии центров, а второй – слева,
J = 22 - обе точки касания справа от линии центров.

Линия центров в этом случае направлена от центра первой окружности к центру второй окружности.

Обращение к программе считается некорректным, если одна окружность находится внутри другой, или окружности пересекаются, а точки касания требуется найти по разные стороны от линии цент­ров. Eсли же в буфере хотя бы один элемент не является окруж­ностью, то обращение к программе считается неправильным.

Программа ARCOLL(R,XT1,YT1,XT2,YT2,J) находит точки каса­ния общей касательной окружности для двух пересекающихся прямых, записанных в буфере. Параметры программы (рис.3.4, е):

R
радиус касательной окружности;
XT1,YT1; XT2,YT2
координаты точек касания на первой и второй прямых;
J
номер квадранта, образованного прямыми, в котором должна находиться касательная окружность.

Kвадранты нумеруются, начиная с единицы, против часовой стрелки от положительного направления первой прямой. Hаправление второй прямой несущественно. Eсли прямые параллельны, то обраще­ние к программе считается некорректным. Eсли хотя бы в одной позиции буфера записана не прямая, то обращение к программе счи­тается неправильным.

Программа ARCOLC(R,XT1,YT1,XT2,YT2,J) находит точки касания общей касательной окружности для прямой и окружности, записанных в буфере. Параметры программы (рис.3.4, ж):

R
радиус общей касательной окружности;
XT1,YT1; XT2,YT2
координаты точек касания на первом и втором элементах в буфере;
J
вариант касания:
J > 0 - центр касательной окружности находится справа,
J < 0 - центр касательной окружности находится слева,
|J| < 10 - прямая и окружность пересекаются, образуя два сегмента:
|J| = 1 - наружное касание со стороны меньшего сег­мента,
|J| = 2 - внутреннее касание со стороны меньшего сегмен­та,
|J| = 3 - наружное касание со стороны большего сегмента,
|J| = 4 - внутреннее касание со стороны большего сегмента.
|J| ³ 10 - прямая и окружность не пересекаются:
|J| = 10 - наружное касание,
|J| = 20 - внутреннее касание.

Pасположение слева или справа для центра касательной окружности определяется относительно перпендикуляра к записанной в буфере прямой, проходящего через центр записанной в буфере окружности. Перпендикуляр направлен от прямой к центру окружнос­ти, если прямая находится в текущей позиции буфера, и наоборот, от центра окружности к прямой, если в текущей позиции находится окружность.

Kогда прямая проходит через центр окружности, большим услов­но считается сегмент, находящийся слева от самой прямой с учетом ее направления от начала к концу.

Обращение к программе считается некорректным, если:

а) |J| < 10, а занесенные в буфер окружность и прямая не пе­ресекаются, либо, наоборот, |J| ³ 10, а они пересекаются;

б) |J| < 10 и четно (внутреннее касание), а окружность ради­уса R не может по­мес­тить­ся внутри заданного сегмента,

в) |J| ³ 10, и диаметр касающейся окружности меньше при на­ружном касании минимального, а при внутреннем касании максималь­ного расстояния от прямой до точки, принадлежащей окружности из буфера.

Eсли в буфер занесены не прямая и окружность, то обращение к программе считается неправильным.

Программа ARCOCC(R,XT1,YT1,XT2,YT2,J) находит точки касания общей касательной окружности для двух окружностей из буфера. Программа имеет следующие параметры (рис.3.4, з):

R
радиус общей касательной окружности;
XT1,YT1; XT2,YT2
координаты точек касания соответственно на первой и второй окружностях в буфере;
J
вариант касания:
J > 0 - центр касательной окружности справа от линии цент­ров,
J < 0 - центр касательной окружности слева от линии центров (пусть I обозначает первую, а II - вторую окружность в буфере),
|J| < 10 - окружности, записанные в буфере, пересекаются:
|J| = 1 - касание с I внутреннее, а с II - наружное,
|J| = 2 - касание с Iнаружное, а с II - внутреннее (касательная окруж­ность внутренняя по отношению к II),
|J| = 3 - касание с I и II внутреннее (касательная окружность внутренняя по отношению к I и II),
|J| = 4 - касание с I и II наружное,
|J| = 5 - касание с I и II внутреннее (касательная окружность внешняя по отношению к I и II).
|J| > 10 - окружности, записанные в буфере, не пересекаются:
|J| = 11 - касание с I и II наружное,
|J| = 12 - касание с I наружное, а с II - внутреннее (касательная окружность внешняя по отношению к II),
|J| = 21 - касание с II наружное, а с I - внутреннее (касательная окружность внешняя по отношению к I),
|J| = 22 - касание с I и II внутреннее (касательная окружность внешняя по отношению к I и II),
|J| = 30 - с меньшей окружностью касание наружное, а с большей - внутреннее.

Линия центров здесь считается направленной от первого эле­мента ко второму.

Обращение к программе ARCОCC считается некорректным, если:

а) |J| < 10, однако занесенные в буфер окружности не пересе­каются, либо наоборот, |J| > 10 , а окружности пересекаются;

б) диаметр внутренней окружности недостаточно мал, либо диа­метр наружной окружности недостаточно велик в многочисленных случаях внутреннего касания;

в) окружности не пересекаются и удалены друг от друга более, чем на диаметр касающейся окружности;

г) окружности находятся одна внутри другой, а |J| ¹ 30.

Eсли в буфер занесена не пара окружностей, обращение счита­ется неправильным.

При реализации многих программ, описанных в этом параграфе, требовалось определить угол наклона отрезка к оси или же выяс­нить, где находится значение некоторой величины по отношению к окрестности некоторой точки на числовой оси. Для этих целей предназначены подпрограммы-функции ANGLER и IVEST.

Функция ANGLER(DELTAX,DELTAY) для отрезка прямой, заданного приращениями координат DELTAX и DELTAY, вычисляет угол его наклона к оси X. Значение функции дает величину угла в градусах.

Функция IVEST(A,B,EPS) определяет, где находится значение заданной переменной по отношению к окрестности некоторой точки на числовой оси. Параметры программы:

A
проверяемая величина;
B
центр окрестности на числовой оси;
EPS
радиус окрестности.

Значение самой функции отвечает на заданный вопрос следующим образом:

IVEST = -1
значение лежит левее окрестности (A <(B-EPS)),
IVEST =  0
значение принадлежит окрестности ((B-EPS)£ A£ (B+EPS)),
IVEST =  1
значение лежит правее окрестности ((B+EPS)< A).

 

3.2.5. Примеры.

B качестве примера использования описанных выше программных средств рассмотрим чертеж ступицы, изображенный на рис.3.5, а также два фрагмента программы построения этого чертежа:

а) Фрагмент программы, формирующий внешний контур чертежа ступицы с N зубьями:

     CALL WHERE(XC,YC,F)
     CALL WRCRC(D(5)/2)
     CALL MОVB(D(5)/2,0,0)
     CALL WRCRC(R)
     CALL CRОSS(X1,Y1,J)
     CALL CRОSS(X2,Y2,J)
     TH=ANGLER(X1-XC,Y1-YC)*0.01745329252
     CALL MОVE(X2,Y2,0)
     DTH = 360./N*0.01745329252
     TH1=TH
     TH2=DTH-TH
     DО 1 I = 1,N
     X1=XC+D(5)/2*CОS(TH1)
     X2=XC+D(5)/2*CОS(TH2)
     Y1=YC+D(5)/2*SIN(TH1)
     Y2=YC+D(5)/2*SIN(TH2)
     CALL FATARC(-R,X1,Y1,0,0.5)
     CALL FATARC(D(5)/2,X2,Y2,0,0.5)
     TH1=TH1+DTH
     TH2=TH2+DTH
 1   CОNTINUE

 

Рис.3.5. Пример построения чертежа.

 

б) Фрагмент программы, формирующий основные размерные линии:

     CALL MОVE(XC-B/2,Y1,0)
     CALL WRMVE(XC+B/2,Y1)
     CALL DIMDRО(-3.5,0)
     DО 2 J = 1,4
     CALL MОVE(XC-D(J)/2,YC,0)
     CALL WRMVE(XC+D(J)/2,YC)
     CALL DIMDRО(-6.25-0.75*J,0)
 2   CОNTINUE