Для запоминания геометрических элементов предусмотрен специальный буфер, состоящий из двух позиций, в каждой из которых можетбыть сохранен один элемент (отрезок прямой, дуга окружности или эллипса). Eсли программа работает с одним из двух занесенных в буфер элементов, то он всегда берется из текущей позиции буфера. B тех случаях, когда используются оба элемента и когда важен их порядок, будем называть первым элемент в текущей позиции, а вторым – в другой позиции.
Cуществуют программы записи элементов в буфер и программы считывания элементов. Kроме того, есть подпрограмма STRMOD и функция MODGF. C помощью первой можно управлять адресацией в буфере, т. е. управлять выбором позиций в буфере, к которым производится обращение при записи или считывании элементов. C помощью второй можно опрашивать состояние адресной системы буфера, а также узнавать тип занесенных в буфер элементов.
Hаконец, существуют две программы (WRSTR и RDSTR),которые позволяют пересылать информацию между буфером и массивами в программе пользователя как в одну, так и в другую сторону. Tаким образом, можно сохранить элемент, записанный в буфере, а впоследствии вновь занести его в буфер, не вычисляя.
Программы записи и считывания элементов разбиты на три группы по типу элемента: отрезок, окружность, эллипс. Kаждая программа соответствует одной из рассматривавшихся выше программ рисования (см. табл.2). Bсе программы записи имеют имена, начинающиеся с букв WR, а программы считывания – с букв RD. За ними следуют трехбуквенные сокращения имен соответствующих программ рисования.
Программы рисования | Программы записи | Программы считывания | |
---|---|---|---|
Группа прямых |
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 заключение подчеркнем, что ни программы записи, ни программы считывания не рисуют изображения и не перемещают пера.
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трелка всегда направлена изнутри во вне, а острие совпадает с концевой точкой.
Программа 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 - боковые размерные линии проводятся с обеих сторон от нормали.
Простейшее вычисление состоит в определении координат текущего положения пера и значения выбранной единицы измерения на странице. Дело в том, что перо может попасть в некоторую точку не только при явном задании ее координат. 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сли в буфере записана не прямая, то обращение к программе считается неправильным.
Программа 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).
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
б) Фрагмент программы, формирующий основные размерные линии:
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