dda画线算法
A. 分别解释直线生成算法DDA法、中点画线法和Bresenham法的基本原理
DDA称为数值微分画线算法,是直线生成算法中最简单的一种。原理相当简单,就是最直观的根据斜率的偏移程度,决定是以x为步进方向还是以y为步进方向。然后在相应的步进方向上,步进变量每次增加一个像素,而另一个相关坐标变量则为Yk_1=Yk+m(以x为步进变量为例,m为斜率)
假定直线斜率k在0~1之间,当前象素点为(xp,yp),则下一个象素点有两种可选择点P1(xp+1,yp)或P2(xp+1,yp+1)。若P1与P2的中点(xp+1,yp+0.5)称为M,Q为理想直线与x=xp+1垂线的交点。当M在Q的下方时,则取P2应为下一个象素点;当M在Q的上方时,则取P1为下一个象素点。这就是中点画线法的基本原理
Bresenham:过各行、各列像素中心构造一组虚拟网格线,按直线从起点到终点的顺序计算直线各垂直网格线的交点,然后确定该列像素中与此交点最近的像素。该算法的优点在于可以采用增量计算,使得对于每一列,只要检查一个误差项的符号,就可以确定该列所求的像素。
大概就是这样,预知详细,可以参考图形学的书籍
B. dda法生成直线的基本原理是什么为什么说Bersenham画圆的算法效率较高
DDA算法主要是根据直线公式y = kx + b来推导出来的,其关键之处在于如何设定单位步进,即一个方向的步进为单位步进,另一个方向的步进必然是小于1。算法的具体思路如下:
1. 输入直线的起点、终点;
2. 计算x方向的间距:△X和y方向的间距:△Y。
3. 确定单位步进,取MaxSteps = max(△X,△Y); 若△X>=△Y,则X方向的步进为单位步进,X方向步进一个单位,Y方向步进△Y/MaxSteps;否则相反。
4. 设置第一个点的像素值
5. 令循环初始值为1,循环次数为MaxSteps,定义变量x,y,执行以下计算:
a. x增加一个单位步进,y增加一个单位步进
b. 设置位置为(x,y)的像素值
Bresenham算法是DDA算法画线算法的一种改进算法。本质上它也是采取了步进的思想。不过它比DDA算法作了优化,避免了步进时浮点数运算,同时为选取符合直线方程的点提供了一个好思路。首先通过直线的斜率确定了在x方向进行单位步进还是y方向进行单位步进:当斜率k的绝对值|k|<1时,在x方向进行单位步进;当斜率k的绝对值|k|>1时,在y方向进行单位步进。
1. 输入线段的起点和终点。
2. 判断线段的斜率是否存在(即起点和终点的x坐标是否相同),若相同,即斜率不存在,
只需计算y方向的单位步进(△Y+1次),x方向的坐标保持不变即可绘制直线。
3. 计算线段的斜率k,分为下面几种情况处理
a. k等于0,即线段平行于x轴,即程序只需计算x方向的单位步进,y方向的值不变
b. |k|等于1,即线段的x方向的单位步进和y方向的单位步进一样,皆为1。直接循环△X次计算x和y坐标。
4. 根据输入的起点和终点的x、y坐标值的大小决定x方向和y方向的单位步进是1还是-1
6. 画出第一个点。
7. 若|k| <1,设m =0,计算P0,如果Pm>0,下一个要绘制的点为(Xm+单位步进,Ym),
Pm+1 = Pm -2*△Y;
否则要绘制的点为(Xm+单位步进,Ym+单位步进)
Pm+1 = Pm+2*△X-2*△Y;
8. 重复执行第七步△X-1次;
9. 若|k| <1,设m =0,计算Q0,如果Qm>0,下一个要绘制的点为(Xm,Ym+单位步进),
Pm+1 = Pm -2*△X;
否则要绘制的点为(Xm+单位步进,Ym+单位步进)
Pm+1 = Pm+2*△Y-2*△X;
10. 重复执行第9步△Y-1次;
C. bresenham算法 和 dda 算法哪个效果好
esenham算法的特点是:
1,不必计算直线之斜率,因此不做除法;
2,不用浮点数,只用整数;
3,只做整数加减法和乘2运算,而乘2运算可以用硬件移位实现.
Bresenham算法速度很快,并适于用硬件实现.
DDA算法的特点:
浮点数运算
不易硬件实现
中点画线法特点:
只有整数运算,不含乘除法
可用硬件实现
因(X0,Y0)在直线上,所以F(X0,Y
D. DDA算法:如何画出斜率大于1的直线
下面是我编写的一个在12864上画线的函数,可以画任意方向的线段。但先要有一个画点函数:Lcd_PutPixel(x,y,1)。
line(int x0,int y0,int x1,int y1)
{
int i,dx,dy,e,x,y;
Lcd_PutPixel(x0,y0,1);
Lcd_PutPixel(x1,y1,1);
dx=x1-x0;
dy=y1-y0;
x=x0;
y=y0;
if(dx>0&&dy>0)
{
if(dx>dy)
{
e=-dx;
for(i=0;i<dx;i++)
{
Lcd_PutPixel(x,y,1);
x++;
e=e+2*dy;
if(e>=0)
{
y++;
e=e-2*dx;
}
}
}
else
{
e=-dy;
x=x0;
y=y0;
for(i=0;i<dy;i++)
{
Lcd_PutPixel(x,y,1);
y++;
e=e+2*dx;
if(e>=0)
{
x++;
e=e-2*dy;
}
}
}
}
if(dx<0&&dy<0)
{
dx=x0-x1;
dy=y0-y1;
if(dx>dy)
{
e=-dx;
for(i=0;i<dx;i++)
{
Lcd_PutPixel(x,y,1);
x--;
e=e+2*dy;
if(e>=0)
{
y--;
e=e-2*dx;
}
}
}
else
{
e=-dy;
for(i=0;i<dy;i++)
{
Lcd_PutPixel(x,y,1);
y--;
e=e+2*dx;
if(e>=0)
{
x--;
e=e-2*dy;
}
}
}
}
if(dx>0&&dy<0)
{
dy=y0-y1;
if(dx>dy)
{
e=-dx;
for(i=0;i<dx;i++)
{
Lcd_PutPixel(x,y,1);
x++;
e=e+2*dy;
if(e>=0)
{
y--;
e=e-2*dx;
}
}
}
else
{
e=-dy;
for(i=0;i<dy;i++)
{
Lcd_PutPixel(x,y,1);
y--;
e=e+2*dx;
if(e>=0)
{
x++;
e=e-2*dy;
}
}
}
}
if(dx<0&&dy>0)
{
dx=x0-x1;
if(dx>dy)
{
e=-dx;
for(i=0;i<dx;i++)
{
Lcd_PutPixel(x,y,1);
x--;
e=e+2*dy;
if(e>=0)
{
y++;
e=e-2*dx;
}
}
}
else
{
e=-dy;
for(i=0;i<dy;i++)
{
Lcd_PutPixel(x,y,1);
y++;
e=e+2*dx;
if(e>=0)
{
x--;
e=e-2*dy;
}
}
}
}
if(dx!=0&&dy==0)
{
if(dx>0)
{
for(i=0;i<dx;i++)
{
Lcd_PutPixel(x,y,1);
x++;
}
}
else
{
dx=x0-x1;
for(i=0;i<dx;i++)
{
Lcd_PutPixel(x,y,1);
x--;
}
}
}
if(dx==0&&dy!=0)
{
if(dy>0)
{
for(i=0;i<dy;i++)
{
Lcd_PutPixel(x,y,1);
y++;
}
}
else
{
dy=y0-y1;
for(i=0;i<dy;i++)
{
Lcd_PutPixel(x,y,1);
y--;
}
}
}
}
E. 如何用dda算法在vc++中画线
在你的CXXXview类上右键 添加成员函数类型void 函数名DDALine(参数是两个点的xy坐标 还有颜色值RGB 一共五个参数)
再次鼠标右键CXXXView添加成员变量 参数两个点的坐标 四个参数 都是float 公有成员public
如果直接在窗体里根据已知参数话直线的话 把你的代码放在OnDraw()函数里
如果用鼠标操作的话 那你要添加windows消息 按快捷键ctrl+w 类向导找到你的CXXXView在消息里添加WM_OnLButtonDown(鼠标按下) WM_OnMouseMove(鼠标移动) WM_OnButtonUp(鼠标抬起) 并设置一个BOOL变量控制画线
在OnLButtonDown里传递参数point.x point.y等于初始点xy坐标 bool量=true
OnMouseMove里的point是第二坐标的xy
OnButtonUp bool量等于false
F. 与DDA算法相比,中点画线法有什么优点
void DDALine(int x0,int y0,int x1,int y1,int color) {
int x;
float dx, dy, y, k;
dx = x1-x0; dy=y1-y0;
k=dy/dx,;y=y0;
for (x=x0;x< x1;x++) {
drawpixel (x, int(y+0.5), color);
y=y+k;
}
}
…… top↑
如上面代码所示,DDA算法中的y和k都必须用浮点数表示,并且每一步运算都要对y进行舍入取整,这不利于硬件实现。中点画线法只包含整数变量,并且不含乘除法,因而解决了上述问题
G. 如何用java实现DDA画线算法,逐点画线算法,BRESENHAM画线算法
C++ JAVA 或其它语言, 他们的+-*/ if else while 这些都几乎一样, API和数据类型有差异, 但不影响读懂算法,还是去试着看懂吧,
而且我搜了一下, 网上有很多这些算法的文字描述, 理解起来不难;
研究算法还是自己动手吧;
LZ加油;
H. VC++怎么实现用户给出两点,用DDA算法连成线段
在你的CXXXview类上右键 添加成员函数类型void 函数名DDALine(参数是两个点的xy坐标 还有颜色值RGB 一共五个参数)
再次鼠标右键CXXXView添加成员变量 参数两个点的坐标 四个参数 都是float 公有成员public
如果直接在窗体里根据已知参数话直线的话 把你的代码放在OnDraw()函数里
如果用鼠标操作的话 那你要添加windows消息 按快捷键ctrl+w 类向导找到你的CXXXView在消息里添加WM_OnLButtonDown(鼠标按下) WM_OnMouseMove(鼠标移动) WM_OnButtonUp(鼠标抬起) 并设置一个BOOL变量控制画线
在OnLButtonDown里传递参数point.x point.y等于初始点xy坐标 bool量=true
OnMouseMove里的point是第二坐标的xy
OnButtonUp bool量等于false
I. 如何用java实现在一个画布上画一个像素
DDA用来画线而不是一个像素点。当然因为其算法肯定要用到画像素点的函数。
DDA称为数值微分画线算法,是直线生成算法中最简单的一种。原理相当简单,就是最直观的根据斜率的偏移程度,决定是以x为步进方向还是以y为步进方向。然后在相应的步进方向上,步进变量每次增加一个像素,而另一个相关坐标变量则为Yk_1=Yk+m(以x为步进变量为例,m为斜率)
绘制一个像素点,java貌似没有相应函数,可以用1个像素的直线代替,或者其他图形,只要是大小一个像素,直线效率最高。
但是我觉得违背了DDA的本意。
不过,只是演示DDA的算法,那不需要考虑画着个像素点的方法,关键在于对前边描述的算法的表达式上