АЛГОРИТМЫ ────────────────────────────────────────── Алгоритм рисования линии (c) Ars Для вывода прямой линии, соединяющей любые две точки можно использовать алгоритм Брезенхема. Смысл его состоит в следующем: линия рассматривается как набор сегментов двух типов: тех, которые расположены диагонально, и тех, которые расположены горизонтально или вертикально. Для линий с наклоном больше 1 прямые сегменты вертикальны, в противном случае они горизонтальны. Первая задача алгоритма состоит в определении наклона. Затем рассчитывается выравнивающий фактор, который следит, чтобы некоторое число прямых сегментов имело большую длину, чем остальные. И наконец, в цикле поочередно выводятся диагональные и прямые сегменты. Выравнивающий фактор поочередно принимает то положительные, то отрицательные значения, отмечая какой тип сегмента выводится. Процедура LINE выводит прямую линию через 2 точки, координаты которых заданы в регистрах DE (начало) и BC (конец). Процедура PIXEL выводит точку с координатами в рег. DE (D-Y, E-X). LM1 LD H,E JR PM1 LM2 LD L,C JR PM2 LM3 LD H,A ;dY=0, т.е. прямые LD (ST_XY),HL ;сегменты горизон- EXX ;тальные LD C,L ;большее расстояние LD L,H ;в рег.C, меньшее в JR PM3 ;рег. L LINE EXX LD DE,#1514 ;коды DEC D и INC D LD BC,#1D1C ;коды DEC E и INC E EXX LD A,B SUB D ;проверка Yк > Yн ? EXX ;если да, то берем JR NC,LM1 ;код INC D, иначе NEG ;берем модуль расс- LD H,D ;тояния и код DEC D PM1 EXX LD H,A ;получили │Yк-Yн│ LD A,C SUB E ;проверка Xк > Xн ? EXX ;если да, то берем JR NC,LM2 ;код INC E, иначе NEG ;берем модуль расс- LD L,B ;тояния и код DEC E PM2 LD (DI_XY),HL ;запись кодов EXX LD L,A ;получили │Xк-Xн│ SUB H ;определяем тип EXX ;прямых сегментов LD A,0 JR NC,LM3 LD L,A ;dX=0, т.е. прямые PM0 LD (ST_XY),HL ;сегменты верти- EXX ;кальные LD C,H ;см. прим. к LM3 PM3 LD B,A ;A=0! LD H,A ;A=0! ADD HL,HL ;удваиваем меньшее LD (ST_CO+1),HL ;расстояние SBC HL,BC ;вычисляем: OR A ;2 x меньшее минус SBC HL,BC ;2 x большее LD (DI_CO+1),HL ADD HL,BC ;счетчик цикла в LD A,C ;рег. A=большему PIXEL PUSH HL ;расстояию BIT 7,H ;HL-фактор вырав- PUSH DE ;нивания, если EX AF,AF' ;Н<0 (т.e H>127) EX DE,HL ;то сегмент пря- LD A,H ;мой, иначе - AND 7 ;диагональный OR #40 ;в регистре DE - LD D,A ;текущие коорди- RR H ;наты RR H RR H LD A,H AND #18 OR D LD D,A LD A,H AND 7 RRCA RRCA RRCA LD E,A ;расчет байта LD A,L ;на экране, куда AND 7 ;будет выводить- LD C,A ;ся текущая точка LD A,L SRL A SRL A SRL A OR E LD E,A LD HL,DATA_P ;расчет пикселя LD A,L ;для текущей точки ADD A,C LD L,A LD A,(DE) OR (HL) LD (DE),A ;рисуем точку EX AF,AF' POP DE POP HL JR Z,DI_XY ;вывод прямых ST_XY DW 0 ;сегментов и ST_CO LD BC,0 ;пересчет фактора JR DECDIST ;выравнивания DI_XY DW 0 ;вывод диагональных DI_CO LD BC,0 ;сегментов и DECDIST ADD HL,BC ;пересчет фактора DEC A JP P,PIXEL ;следующая точка RET DATA_P DB 128,64,32,16,8,4,2,1 Недостатком данной процедуры является то, что max длина рассчитываемой линии - 127 точек. Блок данных DATA_P не должен находиться на границе двух секторов!