【发布时间】:2018-03-31 02:11:29
【问题描述】:
我想沿光栅化圆弧迭代像素,给定它的半径、开始和结束角度(以弧度表示),例如:
template<typename Functor>
void arc(float startRadians, float endRadians, int radius, Functor f);
用法如下:
arc(0.f, M_PI, 10, [](int x, int y) {
std::cout << "got: " << x << " " << y << "\n";
});
有几个问题:
- 像素具有整数坐标
-
radius也以整数形式给出 - 光栅化圆弧实际上是半径为
radius的圆弧和半径为radius-1的圆弧之间的扇区中的每个像素
如下图:
- 蓝色像素已被访问,红色像素是下一个要访问的像素
- 弧由两条由开始/结束角度定义的径向线以及两条弧之间的扇区
radius、radius-1限定。 - 最后,如果要绘制半径为 0 到 100 的每条弧,角度为 0 到 2*PI,那么我们将得到一个半径为 100 的填充圆盘/圆,并且不会访问任何像素两次强>。
我认为Bresenham's circle algorithm 并不直接适用于这个问题,因为角度限制和访问顺序。
在stackoverflow中,我相信这是最相关的问题:
最后,OpenCV 在精神上也有类似/相关的东西,但仅限于行:
【问题讨论】:
-
呃,不,Bresenham 的算法正是你想要的......你只需要在基本算法中添加逻辑:跳过 8 象限优化(在您希望的顺序),并在重要的象限中观察入/出角。另一种选择是直接使用浮点计算。
-
哦,所以您的想法是使用标准 Bresenham 生成所有点,然后过滤掉那些超出所需角度/象限的点? Bresenham 是否具有访问所有像素所需的属性(当每个整数半径被光栅化时填充圆盘)并且不访问像素两次?
-
不,只生成象限所需的部分(当 y/x 或 x/y 达到 tan(角度)限制时停止)
-
我知道 Bresenham 的,但我仍然不明白使它在我的情况下正常工作的适应......我想它的代码或伪代码会受到欢迎。
-
我想你会想在内半径和外半径上使用 Bresenham,然后填充你自己之间的光栅线,基本上。但是,如果没有深思熟虑,我很确定您的“最终”要点是不可能的,在“没有像素访问两次”位中。
标签: c++ algorithm math geometry rasterizing