Я создал функцию, которая принимает в 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, 1), (6, 4), которые находятся в двух разных октантах, но в следующем разделе они говорят, что он работает только для первого октанта.
Других решений пока нет …