Компьютерная графика | |||||||
теория, алгоритмы, примеры на С++ и OpenGL | |||||||
2D теория | 3D теория | OpenGL | Обратная связь / Авторам | ||||
Мы vkontakte.ru ДрузьяСловарь синонимов русского языка |
Алгоритм DDA-линииПрим. Название DDA расшифровывается как Digital Differential Analyzer (цифровой дифференциальный анализатор). Так назывались вычислительные устройства, в т.ч. применявшиеся для генерации векторов. Более подробно можно посмотреть по ссылке: Цифровой дифференциальный анализатор - Яндекс.Словари. Несмотря на то, что сейчас этот алгоритм практически не применяется, он позволяет понять сложности, которые встречаются при растеризации отрезка и способы их решения. На вход алгоритму подаются координаты точек p1(x1, y1) и p2(x2, y2). Причем координаты точек заданы в вещественном формате. #define roundf(x) floor(x + void line_DDA(HDC hdc, float x1, float y1, float x2, float y2) { // (1) Целочисленные значения координат начала и конца отрезка, // округленные до ближайшего целого int iX1 = roundf(x1); int iY1 = roundf(y1); int iX2 = roundf(x2); int iY2 = roundf(y2); // (2) Длина и высота линии int deltaX = abs(iX1 - iX2); int deltaY = abs(iY1 - iY2); // (3) Считаем минимальное количество итераций, необходимое // для отрисовки отрезка. Выбирая максимум из длины и высоты // линии, обеспечиваем связность линии int length = max(deltaX, deltaY); // особый случай, на экране
закрашивается ровно один пиксел Целочисленный алгоритм DDA-линииМодифицированный алгоритм выглядит следующим образом: #include "fixed.h" #define roundf(x) floor(x + void line_DDA_fixed(HDC hdc, float x1, float y1, float x2, float y2) { // (1) Целочисленные значения координат начала и конца отрезка, // округленные до ближайшего целого int iX1 = roundf(x1); int iY1 = roundf(y1); int iX2 = roundf(x2); int iY2 = roundf(y2); // (2) Длина и высота линии int deltaX = abs(iX1 - iX2); int deltaY = abs(iY1 - iY2); // (3) Считаем минимальное количество итераций, необходимое // для отрисовки отрезка. Выбирая максимум из длины и высоты // линии, обеспечиваем связность линии int length = max(deltaX, deltaY); // особый случай, на экране закрашивается ровно один пиксел if (length == 0) { SetPixel(hdc, iX1, iY1, 0); return; } // (4) Вычисляем приращения на каждом шаге по осям абсцисс и ординат fixed dX = frac_to_fixed(x2 - x1, length); fixed dY = frac_to_fixed(y2 - y1, length); // (5) Начальные значения fixed x = float_to_fixed(x1); fixed y = float_to_fixed(y1); // Основной цикл length++; while (length--) { SetPixel(hdc, round_fixed(x), round_fixed(y), 0); x += dX; y += dY; } } |
||||||