引言
Day7連結: https://ithelp.ithome.com.tw/articles/10218420
昨天我們講解了DDA演算法的原理與解釋,今天我們來實作它。
因為只是單純實作這個演算法,我們還沒實作螢幕的部分。
因此我們會先設計一個簡單的二維陣列當作螢幕來顯示計算出來的直線!
實作細節
我們將以條列式列出昨天演算法的細節,並一邊使用C語言實作在下方:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main()
{
char screen[21][41] = {}; // 顯示直線的二維陣列,
// 大小21*41(cmd文字的高會是寬的兩倍,且因需取中點考量,會取奇數當長寬)
int p1x = 0, p2x = 0, p1y = 0, p2y = 0; // P1與P2的x, y分量
int dx = 0, dy = 0, steps = 0; // dx: P1與P2的x分量差, dy: P1與P2的y分量差, steps: 總步數
float xinc, yinc, currX, currY; // xinc, yinc為x, y方向每一步的距離,
// currX, currY用來記錄目前畫到的點座標
int rx = 0, ry = 0; // rx, ry為做過四捨五入後的currX, currY
printf("請輸入P1的x, y及P2的x, y:\n");
scanf("%d %d %d %d",&p1x, &p1y, &p2x, &p2y);
dx = p2x - p1x; // x分量差
dy = p2y - p1y; // y分量差
if(abs(dx) > abs(dy)) steps = abs(dx); // dx, dy可能為正數或負數,因此加上絕對值比較
else steps = abs(dy);
xinc = dx/(float)steps; // xinc, yinc為浮點數,因此須將int強轉為浮點數再相除
yinc = dy/(float)steps;
currX = p1x; // 以P1作為繪製的第一個點
currY = p1y;
rx = round(currX); // 四捨五入currX, currY
ry = round(currY);
if((ry + (21/2) >= 0 && ry + (21/2) < 21) && (rx + (41/2) >= 0 && rx + (41/2) < 41))
// 檢測是否超出邊界
{
screen[ry + (21/2)][rx + (41/2)] = '#'; // '#'當作一個點,為了將(0, 0)校正到中心,需進行平移
}
int i = 0;
for(i=0;i<steps;i++) // 加上上面的第一個點,一共(steps + 1)個點
{
currX += xinc; // 每步分別加上xinc及yinc,成為下一步
currY += yinc;
rx = round(currX); // 四捨五入
ry = round(currY);
if((ry + (21/2) >= 0 && ry + (21/2) < 21) && (rx + (41/2) >= 0 && rx + (41/2) < 41))
{
screen[ry + (21/2)][rx + (41/2)] = '#';
}
}
// 印出screen上畫好的點
int j = 0;
for(i = 0; i < 21; i++)
{
for(j = 0; j < 41; j++)
{
printf("%c", screen[i][j]);
}
printf("\n");
}
// 須注意y方向的正向是往「下」的!
return 0;
}
程式執行結果
(-2, -2) & (3, 5)
(6, -9) & (11, -3)
(-100, 80) & (80, -100)
超出範圍的話,會將超出的部分裁去忽略
這樣就是一個簡單利用DDA設計的繪圖器。