Bresenham 畫直線演算法
阿新 • • 發佈:2019-01-26
Bresenham's畫線演算法作圖如下:
給定兩個點起點P1(x1, y1), P2(x2, y2),如何畫它們直連的直線呢,即是如何得到上圖所示的藍色的點。假設直線的斜率0<k>0,直線在第一象限,Bresenham演算法的過程如下:
1.畫起點(x1, y1).
2.準備畫下一個點,X座標加1,判斷如果達到終點,則完成。否則找下一個點,由圖可知要畫的點要麼為當前點的右鄰接點,要麼是當前點的右上鄰接點。
2.1.如果線段ax+by+c=0與x=x1+1的交點y座標大於(y+*y+1))/2則選右上那個點
2.2.否則選右下那個點。
3.畫點
4.跳回第2步
5.結束
具體的演算法如下,原理就是比較目標直線與x+1直線交點的縱座標,哪個離交點近就去哪個
void Bresenhamline(int x0, int y0, int x1, int y1) { int x, y, dx, dy; float k, e; dx = x1 -x0;//x偏移量 dy = y1 -y0;//y偏移量 k = dy / dx;//斜率 e = -0.5; x = x0; y = y0; for (x= x0;x < x1; x++) { printf("%d,%d\n",x,y);//需要的折線上的點 e = e + k; if (e > 0)//y超過半格就去右上的點(否則就是右下的點) { y++; e = e -1; } } }
上述Bresenham演算法在計算直線斜率與誤差項時用到小數與除法。可以改用整數以避免除法。等式兩邊同時乘以2*dx, 將e統一乘以2*dx即變成了整數的Bresenhan演算法了.
void DrawBresenhamline(int x0, int y0, int x1, int y1) { int dx = x1 - x0;//x偏移量 int dy = y1 - y0;//y偏移量 int dx2 = dx <<1;//x偏移量乘2 int dy2 = dy <<1;//y偏移量乘2 int e = -dx; //e = -0.5 * 2 * dx,把e 用2 * dx* e替換 int x = x0;//起點x座標 int y = y0;//起點y座標 for (x = x0; x < x1;x++) { printf ("%d,%d\n",x, y); e=e + dy2;//來自 2*e*dx= 2*e*dx + 2dy (原來是 e = e + k) if (e > 0)//e是整數且大於0時表示要取右上的點(否則是右下的點) { y++; e= e - dx2;//2*e*dx = 2*e*dx - 2*dx (原來是 e = e -1) } } }
最後,包含所有象限的程式碼如下:
void DrawBresenhamline(int x0, int y0, int x1, int y1)
{
int dx = x1 - x0;//x偏移量
int dy = y1 - y0;//y偏移量
int ux = dx >0 ?1:-1;//x伸展方向
int uy = dx >0 ?1:-1;//y伸展方向
int dx2 = dx <<1;//x偏移量乘2
int dy2 = dy <<1;//y偏移量乘2
if(abs(dx)>abs(dy))
{//以x為增量方向計算
int e = -dx; //e = -0.5 * 2 * dx,把e 用2 * dx* e替換
int x = x0;//起點x座標
int y = y0;//起點y座標
for (x = x0; x < x1;x+=ux)
{
printf ("%d,%d\n",x, y);
e=e + dy2;//來自 2*e*dx= 2*e*dx + 2dy (原來是 e = e + k)
if (e > 0)//e是整數且大於0時表示要取右上的點(否則是右下的點)
{
y += uy;
e= e - dx2;//2*e*dx = 2*e*dx - 2*dx (原來是 e = e -1)
}
}
}
else
{//以y為增量方向計算
int e = -dy; //e = -0.5 * 2 * dy,把e 用2 * dy* e替換
int x = x0;//起點x座標
int y = y0;//起點y座標
for (y = y0; y < y1;y += uy)
{
printf ("%d,%d\n",x, y);
e=e + dx2;//來自 2*e*dy= 2*e*dy + 2dy (原來是 e = e + k)
if (e > 0)//e是整數且大於0時表示要取右上的點(否則是右下的點)
{
x += ux;
e= e - dy2;//2*e*dy = 2*e*dy - 2*dy (原來是 e = e -1)
}
}
}
}