久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费
標題:
Bresenham畫線算法的推導
[打印本頁]
作者:
51黑黑黑
時間:
2016-2-12 21:18
標題:
Bresenham畫線算法的推導
以前看到Bresenham畫線算法,直接拿來用,沒有去推導它,近日,參考一些資料,特整理其算法推導過程如下。各位大蝦如果知道其細節,趕緊閃過,不用浪費時間了。
基本上Bresenham畫線算法的思路如下:
// 假設該線段位于第一象限內且斜率大于0小于1,設起點為(x1,y1),終點為(x2,y2).
// 根據對稱性,可推導至全象限內的線段.
1.畫起點(x1,y1).
2.準備畫下個點。x坐標增1,判斷如果達到終點,則完成。否則,由圖中可知,下個要畫的點要么為當前點的右鄰接點,要么是當前點的右上鄰接點.
2.1.如果線段ax+by+c=0與x=x1+1的交點的y坐標大于M點的y坐標的話,下個點為U(x1+1,y1+1)
2.2.否則,下個點為B(x1+1,y1)
3.畫點(U或者B).
4.跳回第2步.
5.結束.
這里需要細化的是怎么判斷下個要畫的點為當前點的右鄰接點還是當前點的右上鄰接點.
設線段方程:ax+by+c=0(x1<x<x2,y1<y<y2)
令dx=x2-x1,dy=y2-y1
則:斜率-a/b = dy/dx.
從第一個點開始,我們有F(x,1,y1) = a*x1+b*y1+c=0
下面求線段ax+by+c=0與x=x1+1的交點:
由a*(x1+1)+b*y+c = 0, 求出交點坐標y=(-c-a(x1+1))/b
所以交點與M的y坐標差值Sub1 = (-c-a(x1+1))/b - (y1+0.5) =-a/b-0.5,即Sub1的處始值為-a/b-0.5。
則可得條件當 Sub1 = -a/b-0.5>0時候,即下個點為U.
反之,下個點為B.
代入a/b,則Sub1 = dy/dx-0.5.
因為是個循環中都要判斷Sub,所以得求出循環下的Sub表達式,我們可以求出Sub的差值的表達式.下面求x=x1+2時的Sub,即Sub2
1.如果下下個點是下個點的右上鄰接點,則
Sub2 = (-c-a(x1+2))/b - (y1+1.5) = -2a/b - 1.5
故Sub差值Dsub = Sub2 - Sub1 = -2a/b - 1.5 - (-a/b-0.5) = -a/b -1.代入a/b得Dsub = dy/dx -1;
2.如果下下個點是下個點的右鄰接點,
Sub2 = (-c-a(x1+2))/b - (y1+0.5) = -2a/b - 0.5
故Sub差值Dsub = Sub2 - Sub1 = -2a/b - 0.5 - (-a/b-0.5) = -a/b.代入a/b得Dsub = dy/dx;
于是,我們有了Sub的處始值Sub1 = -a/b-0.5 = dy/dx-0.5,又有了Sub的差值的表達式Dsub =dy/dx -1 (當Sub1 > 0)或 dy/dx(當Sub1 <0).細化工作完成。
于是pcode可以細化如下:
// Pcode for Bresenham Line
// By SoRoMan
x=x1;
y=y1;
dx = x2-x1;
dy = y2-y1;
Sub = dy/dx-0.5; // 賦初值,下個要畫的點與中點的差值
DrawPixel(x, y); // 畫起點
while(x<x2)
{
x++;
if(Sub > 0) // 下個要畫的點為當前點的右上鄰接點
{
Sub += dy/dx - 1; //下下個要畫的點與中點的差值
y++; // 右上鄰接點y需增1
}
else// 下個要畫的點為當前點的右鄰接點
{
Sub += dy/dx;
}
// 畫下個點
DrawPixel(x,y);
}
PS:一般優化:
為避免小數轉整數以及除法運算,由于Sub只是用來進行正負判斷,所以可以令Sub= 2*dx*Sub = 2dy-dx,則
相應的DSub = 2dy - 2dx或2dy.
思考1:
如果Sub = 0時,會產生取兩個點都可以的問題。這個問題還沒深入。
//========================================以上部分轉===========================================
優化后的代碼:
void GUI_Line(u8 x1,u16 y1,u8 x2,u16 y2,u16 Color)
{
s16 dx,dy,d;
u16 y=y1;
u8 x;
dx=x2-x1;
dy=y2-y1;
d=2*dy-dx;
for(x=x1;x<x2+1;x++)
{
GUI_Pixel(x,y,Color);
if(d>0)
{
y++;
d+=2*(dy-dx);
}
else
{
d+=2*dy;
}
}
}
而適合任意斜率的代碼如下:
void GUI_Line(u8 x1,u16 y1,u8 x2,u16 y2,u16 Color)
{
s16 d,d1,d2;
s16 x=x1,y=y1,a=y1-y2,b=x2-x1;
s16 cx=(b>=0 ? 1 :(b=-b,-1));
s16 cy=(a<=0 ? 1 :(a=-a,-1));
if(-a<=b)//斜率絕對值 <=1
{
d=2*a+b;
d1=2*a;
d2=2*(a+b);
while(x!=x2+1)
{
GUI_Pixel(x,y,Color);
if (d< 0)
y+= cy, d += d2;
else
d+= d1;
x +=cx;
}
}
else//斜率絕對值 > 1
{
d = 2 * b + a;
d1 = 2 * b;
d2 = 2 * (a + b);
while(y != y2+1)
{
GUI_Pixel(x,y,Color);
if(d<0)
d+=d1;
else
x+=cx,d+=d2;
y+=cy;
}
}
}
歡迎光臨 (http://www.zg4o1577.cn/bbs/)
Powered by Discuz! X3.1
主站蜘蛛池模板:
国产精品影视在线观看
|
久久久精品一区
|
天堂一区二区三区四区
|
精品一区二区在线观看
|
粉嫩av
|
免费看国产片在线观看
|
色香蕉在线
|
人人操日日干
|
av天天爽
|
国产精品永久免费视频
|
一区二区三区日韩精品
|
在线欧美一区二区
|
一区二区三区精品在线
|
99久久99
|
国产99热在线
|
亚洲九九
|
中文字幕亚洲欧美
|
国产精品黄视频
|
久久成人免费视频
|
日韩精品视频在线免费观看
|
日韩国产高清在线观看
|
在线观看亚洲精品
|
亚洲一区二区三区在线
|
久久久精品久
|
久久av一区二区三区
|
99re视频精品
|
视频一区在线观看
|
99免费在线
|
欧美片网站免费
|
97成人在线
|
日韩一二三区视频
|
成年男女免费视频网站
|
免费欧美
|
欧美日日
|
黄色免费在线网址
|
91精品国产91久久久久久不卞
|
亚洲欧美精品国产一级在线
|
成人h动漫精品一区二区器材
|
午夜免费小视频
|
日韩三区在线观看
|
欧美一区二区三区在线观看
|