光栅化算法-中点画圆算法

Posted 珂霖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了光栅化算法-中点画圆算法相关的知识,希望对你有一定的参考价值。

中点画圆算法绘制任意圆形的C++/OpenGL实现

光栅化算法-中点画圆算法

中点画圆算法

对圆形光栅化时,只需考虑在极坐标下 \\(\\theta\\in[\\pi/4,\\pi/2]\\) 的点即可,其他的点可通过对称法绘制。

将圆形光栅化的算法类似于Bresenham算法。设当前绘制的点的坐标为 \\(P_k(x_k,y_k)\\) ,那么下一个点的坐标为 \\(P_k+1(x_k+1,y_k+1)\\) 。从 \\(x\\) 轴开始取样,那么 \\(x_k+1=x_k+1\\) ,而 \\(y_k+1\\) 的值可能为 \\(y_k\\)\\(y_k-1\\) 。为确定具体绘制的点,需引入一个决策参数 \\(p\\)

设圆函数为 \\(f(x,y)=x^2+y^2-r^2\\) ,其中 \\(r\\) 表示圆的半径。取两个可能的点的中点 \\((x_k+1,y_k-\\frac12)\\) ,将其带入圆函数,定义决策参数为:

\\[p_k=f(x_k+1,y_k-\\frac12)=(x_k+1)^2+(y_k-\\frac12)^2-r^2 \\]

将初始顶点 \\(P_1(0, r)\\) 代入决策参数方程可得初始决策参数 \\(p_1=\\frac54-r\\) 。再通过 \\(p_k+1-p_k\\) 的方式即可得到决策参数 \\(p_k\\) 的递推方程:

\\[p_1=\\frac54-r \\]

\\[p_k+1=\\left\\\\beginmatrixp_k+2x_k+1-2y_k+1+1,p_k\\ge0\\\\p_k+2x_k+1+1,p_k<0\\endmatrix\\right. \\]

如果程序输入时的半径 \\(r\\) 恒为整数,则可将初始决策参数设置为 \\(p_1=1-r\\) 。由于递推方程中的计算均为整数计算,因此修改后不影响结果。

C++/OpenGL实现

下述代码为中点画圆算法绘制任意圆形的C++/OpenGL实现:

/**
 * 中点画圆算法
 */
void midPointCircle(GLint ox, GLint oy, GLint r) 
    int dx = 0, dy = r; // 当前绘制的点与圆心的横纵坐标差值
    int p = 1 - r; // 决策参数
    circlePlotPoints(ox, oy, dx, dy);
    while (dx < dy) 
        dx++;
        if (p >= 0) 
            dy--;
            p += ((dx - dy) << 1) + 1;
         else 
            p += (dx << 1) + 1;
        
        circlePlotPoints(ox, oy, dx, dy);
    

/**
 * 画出所有对称的点
 */
void circlePlotPoints(GLint ox, GLint oy, GLint dx, GLint dy) 
    glVertex2i(ox + dx, oy + dy);
    glVertex2i(ox + dx, oy - dy);
    glVertex2i(ox + dy, oy + dx);
    glVertex2i(ox + dy, oy - dx);
    glVertex2i(ox - dx, oy + dy);
    glVertex2i(ox - dx, oy - dy);
    glVertex2i(ox - dy, oy + dx);
    glVertex2i(ox - dy, oy - dx);

Python中具有抗锯齿的光栅化算法

【中文标题】Python中具有抗锯齿的光栅化算法【英文标题】:Rasterization algorithms with anti-aliasing in Python 【发布时间】:2022-01-22 14:15:06 【问题描述】:

我有矢量图形。 (在我的第一种情况下,它是epigraph of a function,它的公式是给定的。所以它是一个轮廓由parametric curve 给出的形状。)

我想用anti-aliasingrasterize 这张图片。所以我想要光栅图形,即一个 numpy 数组。我想以低级别的方式获得这个数组,避免使用用于带有绘图轴等的面向对象的交互式 GUI 可视化的库。我只想要一个数组。做类似Y,X=np.ogrid(...) 然后picture = Y&gt;f(X) 的唯一问题是它没有抗锯齿。 (请注意,模糊二进制图片比一个好的专用抗锯齿算法更糟糕。)如何在 Python 中使用抗锯齿进行光栅化,而不需要任何过度杀伤的以 GUI 为中心的库?

【问题讨论】:

考虑查找一些教程、论文和文档。你试图避免的图书馆可能有关于这个主题的有价值的信息。例如,您还可以在不触发 UI 的情况下将 matplotlib 图形生成为图像。 @MadPhysicist 我猜你的意思是matplotlib backends。也许matplotlib 的一些低级部分可以调用,它们甚至没有考虑绘制anything (like spines) 的开销,除了图像本身,而不是考虑它并决定隐藏它左右。 【参考方案1】:

如果曲线由隐式方程 F(x,y)=0 给出,则计算每个像素四个角处的函数值。如果符号相同,则像素完全在外部或内部。如果符号不同,由角和沿边缘的点形成的多边形内函数消失的区域(仅通过线性插值找到这些)会告诉您背景色和前景色的混合(alpha 混合系数)。

追踪多边形并不难:遍历正方形的四个边,并按照遇到它们的顺序保持正顶点和零点。你会从三角形变成六边形。面积由鞋带公式求得。


参数函数的情况有点困难。您需要找到曲线与网格线的交点,并在遍历的所有单元格中执行面积估计。为此,将曲线绘制为多段线(这称为展平),然后将多段线用水平线切割,然后再用垂直线切割。

【讨论】:

谢谢!有没有这样做的图书馆?使用库是可以的,而不是像考虑绘制 extra stuff such as spines and labels 然后决定隐藏它的选项那样有不必要的开销。 @root:在这种情况下,我会使用大脑而不是图书馆。

以上是关于光栅化算法-中点画圆算法的主要内容,如果未能解决你的问题,请参考以下文章

计算机图形学中的中点画线,中点画圆,Bresenham画线与画圆算法

光栅图形学:直线段的扫描转换算法

实心圆的中点圆算法

Python中具有抗锯齿的光栅化算法

直线光栅化-Bresenham算法

实验二 直线生成算法