Линейный алгоритм Брезенхэма все случаи

Я создал функцию, которая принимает в 2D std::vector, 2 точки в векторе и «рисует» линию внутри вектора. Но это не охватывает все случаи (октанты). Под линией я подразумеваю точки, соединенные друг с другом прямой линией. Этот вектор будет записан в .ppm файл, поэтому он отображается в виде линии на изображении.

Я реализовал эту функцию, используя эту ссылку: https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm

Смотря здесь: https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm#All_cases

Я попытался выяснить, как изменить свою функцию, чтобы она «рисовала» линию для любых двух координат в 2D-векторе, но я немного запуталась. Я не понимаю, почему есть функция для применения на входе и выходе. И какой применить к какой координате. Кроме того, я не знаю, как определить, в каком октанте находится линия из двух координат.

2D вектор будет записан в .ppm файл как это:

255 255 255  255 255 255  255 255 255
255 255 255  0 0 0  255 255 255
255 255 255  255 255 255  255 255 255

Это изображение будет черной точкой в ​​центре.

#include <vector>
#include <tuple>
#include <utility>

using pixel  = std::tuple<unsigned, unsigned, unsigned>; // rgb pixel
using row_t  = std::vector<pixel>; // row in a 2D vector
using grid_t = std::vector<row_t>; // the grid made up of rows
// x, y coordinate - access is like grid[y][x] since grid is made of rows
using coord  = std::pair<long long, long long>;

// Bresenham's line algorithm
// 2 points to draw a line between
void draw(grid_t& grid, const coord& c1, const coord& c2)
{
long long dx{c2.first - c1.first},
dy{c2.second - c1.second},
D {2 * dy - dx},
y {c1.second};
// is the if/else needed?
if (c1.first <= c2.first)
for (long long x{c1.first}; x <= c2.first; ++x)
{
grid[y][x] = pixel{0, 0, 0};
if (D > 0)
{
++y;
D -= 2 * dx;
}
D += 2 * dy;
}
else
for (long long x{c1.first}; x >= c2.first; --x)
{
grid[y][x] = pixel{0, 0, 0};
if (D > 0)
{
++y;
D -= 2 * dx;
}
D += 2 * dy;
}
}

Любая помощь в том, чтобы эта функция работала для всех случаев (и как ее улучшить), и помогала мне понять, как это будет оценено.

0

Решение

Функция на входе преобразует координаты так, что после преобразования они всегда находятся в первом октанте. После применения алгоритма (который работает только для первого октанта), вам необходимо снова преобразовать их обратно в исходный октант.

Трюк используется, потому что алгоритм должен быть разным для каждого октанта. Вместо написания кода для всех различных случаев применяется преобразование, так что сам алгоритм остается простым.

Однако я также не совсем понимаю, как правильно применить это преобразование. Статья в Википедии не совсем ясна по этому поводу. В их примере они имеют (0, 1), (6, 4), которые находятся в двух разных октантах, но в следующем разделе они говорят, что он работает только для первого октанта.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]