直线渲染算法
概述
目前直线渲染算法主要分为五种:
- 朴素算法
- DDA(Digital Differential Analyzer)算法
- Bresenham算法
- Xiaolin Wu算法
- Gupta-Sproull算法
Xiaolin Wu算法和Gupta-Sproull算法主要解决直线渲染抗锯齿的问题,意义不大,暂时搁置。下面详细介绍主流算法:DDA和Bresenham算法。
朴素算法
直接根据微分方程计算,源代码如下:
//plot (x1,y1) to (x2,y2)
//x1,y1,x2,y2 是整型
double dx=x2-x1; //由于要做乘除法,所以使用double型
double dy=y2-y1;
double k=dy/dx;
for(int x=x1;x<=x2;x++) //逐像素
{
y=k*x+x1;
drawPixel(x,round(y))
}
如下图所示:网格上每个点代表像素点,蓝色的点代表被渲染的点。当k绝对值小于1时(左图),较为正常,但当k的绝对值大于1时(右图),会造成像素点过于稀疏(左侧)。此时,交换x,y即可(右侧)。


DDA算法
DDA算法实际上就是综合考虑了斜率绝对值小于1以及大于等于1的情况,源代码如下:
//plot (x1,y1) to (x2,y2)
//x1,y1,x2,y2 是整型
double dx=x2-x1; //由于要做乘除法,所以使用double型
double dy=y2-y1;
double step;
if(abs(dx)>abs(dy)) step=abs(dx);
else step=abs(dy);
dx=dx/step;
dy=dy/step;
int i=0;
while(i<step)
{
drawPixel(round(x),round(y));
x+=dx;
y+=dy;
i++;
}
Bresenham算法
Bresenham算法主要解决DDA算法中使用浮点数运算的问题。由于浮点数运算速度比整数运算要慢,所以为提高效率,Bresenham算法只使用整数运算。Bresenham算法将直线分为八个计算域,如下图左。首先需要说的的是:对于任意一条直线,可以把平面分为两个部分,对于两个相邻的像素点,如果它们的中间点,在直线下方,则渲染上面的像素;如果中间点在直线上方,则渲染下面的像素。如下图右,可以看到中间点


已知直线:起点
其中
在第1个计算域中,直线斜率小于1,所以如果第k个被渲染的像素点为
记
//plot from (x0,y0) to (xn,yn)
int a=yn-y0;
int b=-(xn-x0);
int d=2*a+b;
int x=x0,y=y0;
while(x<xn)
{
if(d>=0)
{
drawPixel(++x,++y);
d+=2a+2b;
y++;
}else
{
drawPixel(++x,y);
d+=2a;
}
}
Reference
本文来自博客园,作者:木子七维,转载请注明原文链接:https://www.cnblogs.com/naiveDevil/p/16999809.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!