Глава 4. Вывод на терминал.

Раздел 4. Вывод точечной графики.

4.4.5 Рисование линий на экране.

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

Hизкий уровень.

Hижеприведенная процедура использует алгоритм Брезенхэма для вывода прямой линии, соединяющей любые две точки. Она использует функцию BIOS установки точек и ее можно убыстрить если заменить эту функцию на встроенную процедуру, использующую прямое отображение в память. Kак и все быстрые алгоритмы данная процедура избегает операций умножения и деления. Линия рассматривается как набор сегментов двух типов: тех которые расположены диагонально и тех, которые расположены горизонтально или вертикально. Для линий с наклоном больше 1 прямые сегменты вертикальны, в противном случае они горизонтальны; первая задача алгоритма состоит в вычислении наклона. Затем вычисляется выравнивающий фактор, который следит чтобы некоторое число прямых сегментов имело большую длину, чем остальные. И, наконец, сложный цикл поочередно выводит диагональные и прямые сегменты. BX поочередно принимает то положительные, то отрицательные значения, отмечая какой тип сегмента выводится. Hиже готовятся данные для вывода диагонали из одного угла экрана в противоположный:
;---в сегменте данных
START_X DW 0
END_X DW 319
START_Y DW 0
END_Y DW 199
COLOR DB 2
DIAGONAL_Y_INCREMENT DW ?
DIAGONAL_X_INCREMENT DW ?
SHORT_DISTANCE DW ?
STRAIGHT_X_INCREMENT DW ?
STRAIGHT_Y_INCREMENT DW ?
STRAIGHT_COUNT DW ?
DIAGONAL_COUNT DW ?
;---установка режима дисплея
MOV AH,0 ;функция установки режима
MOV AL,4 ;цветной 320*200
INT 10H ;установка режима
;---установка начальных инкрементов для каждой позиции точки
MOV CX,1 ;инкремент для оси x
MOV DX,1 ;инкремент для оси y
;---вычисление вертикальной дистанции
MOV DI,END_Y ;вычитаем координату начальной
SUB DI,START_Y ;точки из координаты конечной
JGE KEEP_Y ;вперед если наклон < 0
NEG DX ;иначе инкремент равен -1
NEG DI ;а дистанция должна быть > 0
KEEP_Y: MOV DIAGONAL_Y_INCREMENT,DX
;---вычисление горизонтальной дистанции
MOV SI,END_X ;вычитаем координату начальной
SUB SI,START_X ;точки из координаты конечной
JGE KEEP_X ;вперед если наклон < 0
NEG CX ;иначе инкремент равен -1
NEG SI ;а дистанция должна быть > 0
KEEP_X: MOV DIAGONAL_Y_INCREMENT,CX
;---определяем горизонтальны или вертикальны прямые сегменты
CMP SI,DI ;горизонтальные длиннее?
JGE HORZ_SEG ;если да, то вперед
MOV CX,0 ;иначе для прямых x не меняется
XCHG SI,DI ;помещаем большее в CX
JMP SAVE_VALUES;сохраняем значения
HORZ_SEG: MOV DX,0 ;теперь для прямых не меняется y
SAVE_VALUES: MOV SHORT_DISTANCE,DI ;меньшее расстояние
MOV STRAIGHT_X_INCREMENT,CX ;один из них 0,
MOV STRAIGHT_Y_INCREMENT,DX ;а другой - 1.
;---вычисляем выравнивающий фактор
MOV AX,SHORT_DISTANCE ;меньшее расстояние в AX
SHL AX,1 ;удваиваем его
MOV STRAIGHT_COUNT,AX ;запоминаем его
SUB AX,SI ;2*меньшее - большее
MOV BX,AX ;запоминаем как счетчик цикла
SUB AX,SI ;2*меньшее - 2*большее
MOV DIAGONAL_COUNT,AX ;запоминаем
;---подготовка к выводу линии
MOV CX,START_X ;начальная координата x
MOV CX,START_Y ;начальная координата y
INC SI ;прибавляем 1 для конца
MOV AL,COLOR ;берем код цвета
;---теперь выводим линию
MAINLOOP: DEC SI ;счетчик для большего расстояния
JZ LINE_FINISHED ;выход после последней точки
MOV AH,12 ;функция вывода точки
INT 10H ;выводим точку
CMP BX,0 ;если BX < 0, то прямой сегмент
JGE DIAGONAL_LINE ;иначе диагональный сегмент
;---выводим прямые сегменты
ADD CX,STRAIGHT_X_INCREMENT ;определяем инкре-
ADD DX,STRAIGHT_Y_INCREMENT ;менты по осям
ADD BX,STRAIGHT_COUNT ;фактор выравнивания
JMP SHORT MAINLOOP ;на следующую точку
;---выводим диагональные сегменты
DIAGONAL_LINE: ADD CX,DIAGONAL_X_INCREMENT ;определяем инкре-
ADD DX,DIAGONAL_Y_INCREMENT ;менты по осям
ADD BX,DIAGONAL_COUNT ;фактор выравнивания
JMP SHORT MAINLOOP ;на следующую точку
LINE_FINISHED:


<~-4.4.4 Определение цвета точки экрана.
Содержание
4.4.6 Заполнение областей экрана.-~>

Сайт управляется системой uCoz