|
Move
#08
18 июля 1997 |
|
Алгоритм - Алгоритм рисования линий.

АЛГОРИТМЫ
──────────────────────────────────────────
Алгоритм рисования линии
(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 не должен
находиться на границе двух секторов!
Другие статьи номера:
Похожие статьи:
В этот день... 17 ноября