Bresenham 线算法所有情况
Posted
技术标签:
【中文标题】Bresenham 线算法所有情况【英文标题】:Bresenham's line algorithm all cases 【发布时间】:2017-08-10 09:29:26 【问题描述】:我创建了一个函数,它接收 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 矢量中的任何 2 个坐标“绘制”一条线,但我有点困惑。我不明白为什么有一个函数可以应用于输入和输出。以及在哪个坐标上应用哪个。另外,我不知道如何确定 2 个坐标的线在哪个八分圆内。
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 dxc2.first - c1.first,
dyc2.second - c1.second,
D 2 * dy - dx,
y c1.second;
// is the if/else needed?
if (c1.first <= c2.first)
for (long long xc1.first; x <= c2.first; ++x)
grid[y][x] = pixel0, 0, 0;
if (D > 0)
++y;
D -= 2 * dx;
D += 2 * dy;
else
for (long long xc1.first; x >= c2.first; --x)
grid[y][x] = pixel0, 0, 0;
if (D > 0)
++y;
D -= 2 * dx;
D += 2 * dy;
任何帮助使此功能适用于所有情况(以及如何使其更好)并帮助我了解如何将不胜感激。
【问题讨论】:
“在向量中画一条线”是什么意思? @tobi303 他有一个向量向量(也就是一个二维数组),这个二维数组的每个元素代表一个像素。 @tobi303 一条由一系列点组成的线,尽可能笔直地连接在一条线上。我将编辑问题。 【参考方案1】:输入函数对坐标进行变换,使变换后坐标始终位于第一个八分圆中。应用算法(仅适用于第一个八分圆)后,您必须再次将它们转换回原始八分圆。
使用了这个技巧,因为每个八分圆的算法需要不同。不是为所有不同的情况编写代码,而是应用转换以使算法本身保持简单。
但是,我也不完全了解如何正确应用该转换。***的文章对此并不十分清楚。在他们的示例中,它们有 (0, 1), (6, 4) 位于两个不同的八分圆中,但在下一节中他们说它仅适用于第一个八分圆。
【讨论】:
感谢您的澄清。看完文章有点懵。现在我只需要弄清楚如何确定由 2 个坐标点创建的线所在的八分圆。 为什么在应用算法后需要转换坐标?坐标已经被绘制(绘制)。 @cppxor2arr 您必须在绘制之前对其进行转换,或者将转换应用于我猜的整个图像。可以这样想:你只知道如何添加正数。如果我想让你把 -3 加到 -5 我会让你把 3 和 5 相加,你告诉我答案是 8 然后我仍然需要应用逆变换得到 -8 那么,有两种方法:1. 在运行算法之前转换 2 个坐标,然后在绘制点时运行它。通过遍历 2D 向量的元素来变换整个图像,变换每个当前坐标,并交换当前坐标和变换后的当前坐标的元素。 2. 在运行算法之前转换 2 个坐标。在运行算法时存储要绘制的坐标。转换存储的坐标并绘制它们。有错误吗? @cppxor2arr 我也不确定细节。我会在家里试试(但不是在工作时间;)。这是一个很好的问题,因为如果你做错了什么,你会立即看到哪里出了问题以上是关于Bresenham 线算法所有情况的主要内容,如果未能解决你的问题,请参考以下文章