В строке 80 байт. В байте 8 точек. Адрес байта = Y*80 + целое (X/8). Положение битов кода цвета в 4-х байтах определяется как положение “1” в регистре маски битов (по тому же принципу, что в CGA черно-белом).
VGA – 256 цветов. В байте 1 пиксель. Адрес байта = Y * (число пикселей в строке) + X.
Могут быть другие форматы растров, например, 1024 x 1024 точек, черно-белое изображение, развертка чересстрочная.
Построение вертикальной и горизонтальных линий на растре
Самый простой вариант: использовать процедуру построения точки и в цикле, меняя одну из координат (инкрементируя или декрементируя), выводить точки, количество которых определяется длиной линии.
Это не быстрый способ, так как каждый раз при выводе очередной точки надо определять адрес байта и положение бита(битов) в байте. А можно один раз определить адрес байта начальной точки и положение бита(ов), затем использовать простые способы модификации адреса или/и положения бита(ов)
При построении вертикальной линии, например, сверху вниз, можно найти адрес байта и положение бита для верхней точки линии, а затем увеличивать адрес байта (на количество байт в строке) для следующих точек линии.
Байты видеопамяти
Главное требование: работать не в координатном пространстве, а в адресном и битовом пространстве видеопамяти!
Построение вертикальной линии (x, y1, y2)
CGA адаптер черно/белый
X
79 байт
B800H
. . .
. . .
0 байт
0 1 2 3 4 5
. . .
0 байт
+2000H
. . .
80 байт
. . .
80 байт
200 строк
199
Y
Построение вертикальной линии (продолжение)
EGA адаптер
79 байт
X
A000H
. . .
. . .
0 байт
0 1 2 3 4 5
. . .
80 байт
. . .
160 байт
. . .
80 байт
350 строк
349
Y
Построение горизонтальной линии (x1, y, x2)
3 варианта расположения линии в ВП
Строим линию слева направо
Сдвинутая маска 00010000
Еще одни сдвиг вправо 00001000
Результат по “OR” = 00011000
Продолжаем в цикле число раз = длине линии
Если линия располагается в 2-х соседних байтах
Что делать?
Проверка: не вышли ли мы за границу байта.
При циклическом сдвиге маски 10000000 вправо, когда она вновь становится = 10000000, мы переходим границу байта.
К адресу байта надо добавить «1», длину линии уменьшить на 1 и продолжать сдвигать маску вправо и выполнять “OR”, пока длина линии в цикле не станет = 0
Что делать, если внутри линии есть “целые байты”?
После того, как определили границу между 1 и 2 байтами, оставшуюся длину линии делим на число точек в байте. Целое от этого частного = числу целых байтов в линии. Заполняем целые байты, например, FFH (в случае черно- белого CGA или EGA). Достраиваем оставшийся правый байт.
Произвольная линия на растре
Целочисленные координаты x1, y1, x2, y2
Y
x2, y2
X
x1, y1
Надо найти пиксели, ближайшие к идеальной прямой.
Предполагая, что x1<x2 последовательно пробегаем значение x координаты от x1 до x2, для каждого x вычисляем значение y и округляем его до ближайшего целого.
Вычисление y может быть основано на уравнении прямой y = mx+b, где m – коэффициент (тангенс угла) наклона прямой. Проблемы: операция умножения m*x; для повышения точности надо воспользоваться представлением данных с плавающей точкой. Операцию умножения можно устранить. x = 1, тогда m = y/x = y Таким образом, если xi+1 = xi+1, то yi+1 = yi + m для всех точек отрезка, т.е. последующие значения x и y определяются, исходя из предыдущих. Если m > 1, то шаг по x, будет приводить к шагу по y > 1. Поэтому следует x и y поменять ролями, придавая y единичные приращения, а x будет увеличиваться на x = y/m= 1/m.
Этот алгоритм назван пошаговым алгоритмом: на каждом шаге производится инкрементальное вычисление, основанное на предыдущем шаге. Трудности пошагового алгоритма состоят в том, что округление y до целого значения требует времени и, кроме того, y и m должны быть вещественными переменными или двоичными дробями, но не целыми переменными, так как тангенс угла наклона есть дробь.
Алгоритм Брезенхэма
Построение прямой линии на растре
Для алгоритма Брезенхэма необходима только целая арифметика. Вещественные переменные не используются и, следовательно, округление не требуется. Для простоты будем считать, что тангенс угла наклона принимает значения в диапазоне 0-1.
Ti
t
s
Si
Pi-1
Пусть пиксель Pi-1 уже найден, как ближайший к заданному отрезку и теперь требуется определить, какой пиксель будет установлен следующим: Si или Ti. Если s<t, то Si ближе к отрезку и необходимо выбрать его; в противном случае ближе будет Ti. Другими словами, если s-t<0, то выбирается Si , в противном случае - Ti.
В алгоритме используется управляющая переменная di, которая на каждом шаге пропорциональная разности между s и t. Кроме того, введены значения dx=|x2-x1| и dy=|y2-y1|. Т.о., если di ≥ 0, выбирается Ti, тогда yi = yi-1+1 и di+1 = di + 2(dy-dx) (1) Если di < 0, выбирается Si, тогда yi = yi-1 и di+1 = di + 2dy (2) Т.о., получен итеративный способ вычисления di+1 по предыдущему значению di и выбор между Ti и Si. Что требуется еще?
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.