Bresenham算法中,斜率大于1时的e是怎么得出来的?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bresenham算法中,斜率大于1时的e是怎么得出来的?相关的知识,希望对你有一定的参考价值。
看到很多网上的代码都是这个形式的:
e=e+2*dy;、e=e-2*dx;、e=e+2*dx、 e=e-2*dy;……
这个 2 是怎么得出来的?或者说这个式子是怎么得来的?
我问的是e的值是怎么来的(从数学的角度解释),不是要代码
var datas:BitmapData=newBitmapData(550,400,false,0x000000);//位图数据
var map:Bitmap=new Bitmap(datas);//位图显示对象
this.addChildAt(map,0);
var theSize:int=5;//控制一个像素点的大小
//根据像素点的大小,在指定坐标绘制一个像素(其实是绘制一个矩形)
function drawPixel(thex:int,they:int):void
varstartx:int=theSize*thex;//矩形的左上角x坐标
varstarty:int=theSize*they;//矩形的左上角y坐标
if(startx>400||starty>550||startx+theSize<0||starty+theSize<0)return;//如果矩形超出范围,则退出
datas.fillRect(newRectangle(startx,starty,theSize,theSize),0xffffff);//在位图上绘制矩形
//根据Bresenham算法绘制直线,直线又两点式表示
functiondarwLine(x1:Number,y1:Number,x2:Number,y2:Number):void
varxadd:int;//x每次的增量,实际上只有1和-1两个值
varyadd:int;//y每次的增量
vark:Number;//直线斜率
vardx:int;//绘制像素的x坐标
vardy:int;//绘制像素的y坐标
vare:Number;//一个中间值,用来快速进行四舍五入,是算法高速的关键
if(x2>=x1)xadd=1;//要是第一个点在第二个点的左边,那么从第一个点绘制到第二个点,x坐标应该是单调递增的
elsexadd=-1;//否则就单调递减
if(y2>=y1)yadd=1;//同理,如果第一个点在第二个点下方,那么从第一个点绘制到第二个点,y坐标是单调递增的
elseyadd=-1;//否则单调递减
k=(y2-y1)/(x2-x1);//算出直线斜率
k=(k>0)?k:(-k);//取斜率绝对值
dx=int(x1+0.5);//将第一个点的x坐标四舍五入,作为第一个绘制点x的坐标
dy=int(y1+0.5);//将第一个点的y坐标四舍五入,作为第一个绘制点的y坐标
//Bresenham算法绘制直线对斜率要求是绝对值在0和1之间,所以要对斜率进行判断,如果斜率大于1,那么需要对x和y对换对待
if(k>1)//斜率大于1,那么把x看成y,把y看成x,这样x随着y的变化而变化
varmy:int//终点y坐标
k=1/k;//将斜率求倒数,因为x和y对换了嘛
e=x1-dx-0.5;//中间变量起始值。这个其中原理在最开始讲过
my=int(y2+0.5);//求助终点坐标值
drawPixel(dx,dy);//绘制第一个点
while(dy!=my)//到达终点才停止循环
dy+=yadd;//每一次循环,y都要自增一下(或自减)
e+=k;//中间变量加上斜率
if(e>=0)//如果e值超出
dx+=xadd;//那么因变量要增加(或减少)一个
e--;//e值倒退1
drawPixel(dx,dy);//绘制计算出来的点
//一下同理,就是x和y换一下
else
varmxx:int;
e=y1-dy-0.5;
mxx=int(x2+0.5);
drawPixel(dx,dy);
while(dx!=mxx)
dx+=xadd;
e+=k;
if(e>=0)
dy+=yadd;
e--;
drawPixel(dx,dy);
/*****
****UI
**/
b1.addEventListener(MouseEvent.CLICK,bt1Click);
b2.addEventListener(MouseEvent.CLICK,bt2Click);
function bt1Click(e:Event):void
theSize=int(t1.text);
darwLine(Number(t2.text),Number(t3.text),Number(t4.text),Number(t5.text));
function bt2Click(e:Event):void
datas.fillRect(newRectangle(0,0,550,400),0x000000);
bresenham算法是计算机图形学中为了“显示器(屏幕或打印机)系由像素构成”的这个特性而设计出来的算法,使得在求直线各点的过程中全部以整数来运算,因而大幅度提升计算速度,是计算机图形学领域使用最广泛的直线扫描转换方法。 参考技术A 。
下面是我编写的一个在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--;
bresenham算法的介绍
参考技术Abresenham算法是计算机图形学中为了“显示器(屏幕或打印机)系由像素构成”的这个特性而设计出来的算法,使得在求直线各点的过程中全部以整数来运算,因而大幅度提升计算速度。
以上是关于Bresenham算法中,斜率大于1时的e是怎么得出来的?的主要内容,如果未能解决你的问题,请参考以下文章