Построение геометрических фигур. Прямые линии.
Рисование гладких линий
Гладкие линии не содержат ступенек, они могут быть горизонтальными, вертикальными или наклонивши под углом, кратным 45 градусам. При их построении адреса смежных точек отличаются на некоторую постоянную величину. Например, у вертикальных линий ее модуль равен значению переменной Horsize.
В примере 3.11 приведен текст подпрограммы, которая рисует гладкие линии, при условии, что адреса их точек монотонно возрастают. Перед ее вызовом должно быть установлено окно видеопамяти, в котором расположена опорная точка, а ее адрес указан в регистре di. Количество выводимых точек (длина линии) и их коды (цвета) помешаются, соответственно, в регистры сх и ai. Кроме того, в регистр bx записывается приращение адреса каждой точки.
Пример 3.11. Подпрограмма для рисования гладких линий.
anyline: | mov | es: [di], al | запись кода точки в видеобуфер |
add | di, bx | коррекция текущего адреса | |
jnc | @F | › адрес в пределах окна | |
call | NxtWin | установка следующего окна | |
@@: | loop | anyline | управление повторами цикла |
ret | возврат из подпрограммы |
При рисовании гладких линий использовать операцию stosb для записи кодов точек в видеопамять нецелесообразно.
Давайте разберемся, что именно можно нарисовать с помощью подпрограммы, 3.11. Обозначим константу переадресации, значение которой записывался в Регистр bх' буквой n и условимся, что она может быть только положительным числом. Вспомните табл. 3.3 – положительные приращения адресов смежных точек могут иметь четыре значения: i, Horsize, Horsize+i HorSize-i. Если в качестве константы k использовать эти значения, то соответственно будут нарисованы горизонтальная, вертикальная и две наклонные прямые. Последние являются диагоналями квадрата, сторона которого содержит количество точек, указанное в регистре сх.
Подпрограмма 3.11 позволяет рисовать пунктирные линии. Например, если задавать k=2, k=2*Horsize, k=2*(Horsize+1) и k=2*(Horsize-1), то будут нарисованы пунктирные линии, у которых расстояние между соседними точками равно 2. Однако такая возможность является побочным эффектом и не представляет особого интереса.
Если вам часто приходится рисовать вертикальные линии, то сделайте копию примера 3.11, замените в ней команду add di, bx на add di, Horsize и подберите подходящее имя подпрограммы (не забудьте указать его в команде loop).
Произвольные линии
При рисовании произвольных линий, в отличие от гладких, вычисляется приращение адреса в каждой точке. В этом случае при перемещении от точки к точке значение одной координаты (х или Y) увеличивается на 1, а значение другой либо увеличивается на 1, либо остается неизменным. В результате на экране возникают ступеньки, размер и количество которых, при прочих равных условиях, зависят от угла наклона.
Рассмотрим, какие действия выполняют подпрограммы, предназначенные для рисования линии, проходящей через две заданные точки. При ее вызове задаются координаты двух крайних точек линии X1,Y1 и X2,Y2. Выполнение подпрограмм начинается с анализа значений координат. Если окажется, что > Х2, то производится перестановка значений координат в памяти так, чтобы Х2 > X1. Затем начало координат переносится в точку XI,YI, что позволит работать с приращениями адресов относительно этой точки. При выполнении дальнейших действий учитываются следующие величины:
Dx = Х2 -X1; Dy = Y2 -Y1
Если DX = 0 или Dy = 0, то задана вертикальная или горизонтальная линия, которая строится обычным способом, описанным в данной главе. В противном случае выбирается способ построения линии.
Если DX > оу, то линия строится относительно оси х. Это значит, что при проходе от точки к точке приращение значения координаты х равно 1, приращение координаты Y равно DY/DX, причем 0 < 0у/сх < 1.
Если Dх < Dy, то линия строится относительно оси Y. Это значит, что при проходе от точки к точке приращение значения координаты Y равно 1, а вращение координаты х равно DX/DV, причем 0 < Dx/Dy < 1.
При DX = Dy линия гладкая, например, с углом наклона 45 градусов, способ ее построения выбирается разработчиком.
Линия рисуется на экране последовательно точка за точкой, поэтому значение координат в любой точке равно сумме приращений их значений во всех предыдущих и в данной точке. В одних случаях эти суммы вычисляются явно, в других неявно, но без них линию нарисовать невозможно.
Значения одной координаты (х или Y) являются целыми числами и не требуют дополнительных преобразований. Значения другой координаты (Y или Х) могут иметь дробную часть, поэтому их надо преобразовать в целые числа. Описанные в литературе подпрограммы различаются, главным образом, способом вычисления ступенчатой функции, аппроксимирующей прямую, проходящую через две заданные точки. В простейшем случае при вычислении приращения адреса учитывается только целая часть числа, а при суммировании приращений – все число.
Приращения значений координат преобразуются в приращение адреса, и очередная точка выводится на экран. Знак приращения зависит от взаимного расположения крайних точек линии, поэтому в подпрограммах учитывается возможность как положительных, так и отрицательных приращений адресов.
Описание алгоритмов рисования линий и примеры подпрограмм, правда, предназначенных для работы в видеорежимах VGA, вы найдете в книге. Ее оригинал (на английском языке) распространялся на компакт-дисках вместе с текстами подпрограмм.