admin管理员组文章数量:1130349
【计算机图形学】中点画线法实现任意斜率直线的绘制
【计算机图形学】中点画线法实现任意斜率直线的绘制
一、中点画线法原理简介
1.建立基础
- 中点画线法的建立基础是数值微分画线法(DDA),其作为改进算法,沿用了DDA算法的增量思想,针对影响DDA算法效率的两点:(1)采用了浮点加法(2)浮点数在显示输出时需要取整;进行了改进,即中点画线法直接采用了整数的加法、比较。
2.具体分析
-
这里具体分析直线斜率 k ∈[0,1] 的情况,其他情况可以类推。
对于起始点(x0,y0)、结束点(x1,y1),有A=y0-y1、B=x1-x0、C=(x1-x0)(x0-x1)、k=(y1-y0)/(x1-x0)
设函数F(x,y) = Ax+By+C,则F(x,y)将平面分为三部分:
1)F(x,y) = 0,点在直线上
2)F(x,y) > 0,点在直线的上方
3)F(x,y) < 0,点在直线的下方 -
在画线过程中,对于每个当前像素点(xi,yi),每次在最大位移方向,即x方向上前进一步,在y方向上是否前进取决于前一格中点和直线的位置关系。
如上图所示,可判断中点Mid和直线的位置关系,来确定下一点的选取,令d为判别式:
1)d=F(xi+1,yi+0.5) = 0,Mid在直线上,可选取Pu/Pd,这里我们统一规定选取Pd
2)d=F(xi+1,yi+0.5) > 0,Mid在直线的上方,直线离Pd较近,选取Pd,则下一点y方向上不变
3)d=F(xi+1,yi+0.5) < 0,Mid在直线的下方,直线离Pu较近,选取Pu,则下一点y方向上前进 -
利用增量思想,每下一步的d的判别可以基于本步d的正负情况,分本步d<0和d>=0两种情况讨论。
1)d < 0: 本步选取Pu(xi+1,yi+1),则下一步中点(xi+2,yi+1.5):
dnew=F(xi+2,yi+1.5)
dnew=A(xi+2)+B(yi+1.5)+C
dnew=[A(xi+1)+B(yi+0.5)+C]+A+B
dnew=d+A+B
2)d >= 0: 本步选取Pd(xi+1,yi),则下一步中点(xi+2,yi+0.5):
dnew=F(xi+2,yi+0.5)
dnew=A(xi+2)+B(yi+0.5)+C
dnew=[A(xi+1)+B(yi+0.5)+C]+A
dnew=d+A -
在画线过程中每一点的情况都分析完了,也易得结束画线的条件。接下来只要确定初始值就能顺利地画线了。对于起始点(x0,y0),下一步中点为(x0+1,y0+0.5):
d0=F(x0+1,y0+0.5)
d0=A(x0+1)+B(y0+0.5)+C
d0=[Ax0+By0+C]+A+0.5B
d0=A+0.5B -
可以发现d0的计算中涉及到了浮点数0.5,为了改进我们可以用2d0代替d0,因为后续计算中只考虑d的正负,则扩大两倍不会对结果有所影响。此时的新d0为:
d0=2F(x0+1,y0+0.5)
d0=2A(x0+1)+2B(y0+0.5)+2C
d0=2[Ax0+By0+C]+2A+B
d0=2A+B对于k值的其他情况也可以照此分析,注意在k>1和k<-1时,每一步的最大位移方向是y方向,即每次在y方向上前进一步,在x方向上需要判断中点和直线关系。
3.分析总结
| k∈[0,1] | k ∈(1,+∞) | k∈[-1,0) | k∈(-∞,-1) |
|---|---|---|---|
| d0=2A+B | d0=A+2B | d0=2A-B | d0=A-2B |
| d<0:d+=2(A+B);x+=1;y+=1; | d<0:d+=2B;y+=1; | d<0:d+=2A;x+=1; | d<0:d+=2(A-B);y-=1;x+=1; |
| d>=0:d+=2A;x+=1; | d>=0:d+=2(A+B);y+=1;x+=1 | d>=0:d+=2(A-B);x+=1;y-=1; | d>=0:d-=2B;y-=1; |
二、代码实现
/*
程序:中点画线法画任意斜率直线
编译环境:Visual C++ 6.0 EasyX_20200109(beta)
作者ID:weixin_43536824
邮箱:changye303@163
*/
#include <easyx.h>
#include <graphics.h>
#include <conio.h>
#include <stdio.h>
//初始参数double A = y0-y1;double B = x1-x0;double k = -1*A/B;int x,y,d,t;
//要求x1>=x0,若x1<x0则互换两点if(x1<x0){t=x1;x1=x0;x0=t;t=y1;y1=y0;y0=t;}
//分四种情况,x,y,d均为整型
//情况1:if(k >= 0 && k <= 1){d = (int)(2*A+B);x = x0;y = y0;moverel(x,y);while(x != x1){if(d <= 0){x++;y++;d+=(int)(2*(A+B));lineto(x,y);}else{x++;d+=(int)(2*A);lineto(x,y);}}}
//情况2:
if(k>1){d = (int)(A+2*B);x = x0;y = y0;moverel(x,y); while(y != y1){if(d < 0){y+=1;d+=(int)(2*B);lineto(x,y);}else{y+=1;x+=1;d+=(int)(2*(A+B));lineto(x,y);}}
}
//情况3:if(k >= -1 && k < 0){d = (int)(2*A-B);x = x0;y = y0;moverel(x,y);while(x != x1){if(d < 0){x+=1;d+=(int)(2*A);lineto(x,y);}else{x+=1;y-=1;d+=(int)(2*(A-B));lineto(x,y);} }}
//情况4:if(k < -1){d = (int)(A-2*B);x = x0;y = y0;moverel(x,y);while(y != y1){if(d < 0){y-=1;x+=1;d+=(int)(2*(A-B));lineto(x,y);}else{y-=1;d-=(int)(2*B);lineto(x,y);}}}
【计算机图形学】中点画线法实现任意斜率直线的绘制
【计算机图形学】中点画线法实现任意斜率直线的绘制
一、中点画线法原理简介
1.建立基础
- 中点画线法的建立基础是数值微分画线法(DDA),其作为改进算法,沿用了DDA算法的增量思想,针对影响DDA算法效率的两点:(1)采用了浮点加法(2)浮点数在显示输出时需要取整;进行了改进,即中点画线法直接采用了整数的加法、比较。
2.具体分析
-
这里具体分析直线斜率 k ∈[0,1] 的情况,其他情况可以类推。
对于起始点(x0,y0)、结束点(x1,y1),有A=y0-y1、B=x1-x0、C=(x1-x0)(x0-x1)、k=(y1-y0)/(x1-x0)
设函数F(x,y) = Ax+By+C,则F(x,y)将平面分为三部分:
1)F(x,y) = 0,点在直线上
2)F(x,y) > 0,点在直线的上方
3)F(x,y) < 0,点在直线的下方 -
在画线过程中,对于每个当前像素点(xi,yi),每次在最大位移方向,即x方向上前进一步,在y方向上是否前进取决于前一格中点和直线的位置关系。
如上图所示,可判断中点Mid和直线的位置关系,来确定下一点的选取,令d为判别式:
1)d=F(xi+1,yi+0.5) = 0,Mid在直线上,可选取Pu/Pd,这里我们统一规定选取Pd
2)d=F(xi+1,yi+0.5) > 0,Mid在直线的上方,直线离Pd较近,选取Pd,则下一点y方向上不变
3)d=F(xi+1,yi+0.5) < 0,Mid在直线的下方,直线离Pu较近,选取Pu,则下一点y方向上前进 -
利用增量思想,每下一步的d的判别可以基于本步d的正负情况,分本步d<0和d>=0两种情况讨论。
1)d < 0: 本步选取Pu(xi+1,yi+1),则下一步中点(xi+2,yi+1.5):
dnew=F(xi+2,yi+1.5)
dnew=A(xi+2)+B(yi+1.5)+C
dnew=[A(xi+1)+B(yi+0.5)+C]+A+B
dnew=d+A+B
2)d >= 0: 本步选取Pd(xi+1,yi),则下一步中点(xi+2,yi+0.5):
dnew=F(xi+2,yi+0.5)
dnew=A(xi+2)+B(yi+0.5)+C
dnew=[A(xi+1)+B(yi+0.5)+C]+A
dnew=d+A -
在画线过程中每一点的情况都分析完了,也易得结束画线的条件。接下来只要确定初始值就能顺利地画线了。对于起始点(x0,y0),下一步中点为(x0+1,y0+0.5):
d0=F(x0+1,y0+0.5)
d0=A(x0+1)+B(y0+0.5)+C
d0=[Ax0+By0+C]+A+0.5B
d0=A+0.5B -
可以发现d0的计算中涉及到了浮点数0.5,为了改进我们可以用2d0代替d0,因为后续计算中只考虑d的正负,则扩大两倍不会对结果有所影响。此时的新d0为:
d0=2F(x0+1,y0+0.5)
d0=2A(x0+1)+2B(y0+0.5)+2C
d0=2[Ax0+By0+C]+2A+B
d0=2A+B对于k值的其他情况也可以照此分析,注意在k>1和k<-1时,每一步的最大位移方向是y方向,即每次在y方向上前进一步,在x方向上需要判断中点和直线关系。
3.分析总结
| k∈[0,1] | k ∈(1,+∞) | k∈[-1,0) | k∈(-∞,-1) |
|---|---|---|---|
| d0=2A+B | d0=A+2B | d0=2A-B | d0=A-2B |
| d<0:d+=2(A+B);x+=1;y+=1; | d<0:d+=2B;y+=1; | d<0:d+=2A;x+=1; | d<0:d+=2(A-B);y-=1;x+=1; |
| d>=0:d+=2A;x+=1; | d>=0:d+=2(A+B);y+=1;x+=1 | d>=0:d+=2(A-B);x+=1;y-=1; | d>=0:d-=2B;y-=1; |
二、代码实现
/*
程序:中点画线法画任意斜率直线
编译环境:Visual C++ 6.0 EasyX_20200109(beta)
作者ID:weixin_43536824
邮箱:changye303@163
*/
#include <easyx.h>
#include <graphics.h>
#include <conio.h>
#include <stdio.h>
//初始参数double A = y0-y1;double B = x1-x0;double k = -1*A/B;int x,y,d,t;
//要求x1>=x0,若x1<x0则互换两点if(x1<x0){t=x1;x1=x0;x0=t;t=y1;y1=y0;y0=t;}
//分四种情况,x,y,d均为整型
//情况1:if(k >= 0 && k <= 1){d = (int)(2*A+B);x = x0;y = y0;moverel(x,y);while(x != x1){if(d <= 0){x++;y++;d+=(int)(2*(A+B));lineto(x,y);}else{x++;d+=(int)(2*A);lineto(x,y);}}}
//情况2:
if(k>1){d = (int)(A+2*B);x = x0;y = y0;moverel(x,y); while(y != y1){if(d < 0){y+=1;d+=(int)(2*B);lineto(x,y);}else{y+=1;x+=1;d+=(int)(2*(A+B));lineto(x,y);}}
}
//情况3:if(k >= -1 && k < 0){d = (int)(2*A-B);x = x0;y = y0;moverel(x,y);while(x != x1){if(d < 0){x+=1;d+=(int)(2*A);lineto(x,y);}else{x+=1;y-=1;d+=(int)(2*(A-B));lineto(x,y);} }}
//情况4:if(k < -1){d = (int)(A-2*B);x = x0;y = y0;moverel(x,y);while(y != y1){if(d < 0){y-=1;x+=1;d+=(int)(2*(A-B));lineto(x,y);}else{y-=1;d-=(int)(2*B);lineto(x,y);}}}
本文标签: 计算机图形学中点画线法实现任意斜率直线的绘制
版权声明:本文标题:【计算机图形学】中点画线法实现任意斜率直线的绘制 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://it.en369.cn/jiaocheng/1707421093a442086.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。


发表评论