中點畫線法(考慮所有情況)

使用了第三方圖形庫EGEv19.01,C++編寫。

#include <graphics.h>
#include <iostream>
using namespace std;

// 輸入直線的兩端點P0(x0,y0) 和 P1(x1,y1)
void Midpoint_Line(int x0, int y0, int x1, int y1)
{
    int a, b, d1, d2, d, x, y;
    float k;
    if (x1 < x0) {
        //置反操作,使得輸出結果平面左右水平翻轉,防止畫反線段
        d = x0, x0 = x1, x1 = d;
        d = y0, y0 = y1, y1 = d;
    }
    a = y0 - y1, b = x1 - x0;
    if (b == 0)
        //b==0,a<0(k->inf)則放入k>1,a>0(k->-inf)則放入k<-1
        //因爲C++除法操作除數爲零時候可能會出現undefined的結果
        k = -1 * a * 1000;
    else
        k = (float)a / (x0 - x1);
    x = x0, y = y0;
    putpixel(x, y, GREEN);
    // 0<=k<=1
    // 1.計算初始值,a=y0−y1, b=x1−x0, D=2a+b
    // 2.x=x0,y=y0
    // 3.繪製點(x,y),判斷D的符號
    // 若D<=0,則(x,y)更新爲(x+1,y+1),D更新爲D=D+2a+2b
    // 否則(x,y)更新爲(x+1,y), D更新爲D=D+2a
    // 4.當直線沒有畫完時,重複步驟3,否則結束
    if (k >= 0 && k <= 1) {
        d = 2 * a + b;
        d1 = 2 * a, d2 = 2 * (a + b);
        while (x < x1) {
            if (d <= 0) {
                ++x, ++y, d += d2;
            } else {
                ++x, d += d1;
            }
            putpixel(x, y, RED);
        }
    }
    // -1<=k<=0
    // 1.計算初始值,a=y0−y1, b=x1−x0, D=2a-b
    // 因爲當-1<=k<=0時,b爲負數,所以要2a-b
    // 2.x=x0,y=y0
    // 3.繪製點(x,y),判斷D的符號
    // 若D>0,則(x,y)更新爲(x+1,y-1),D更新爲D=D+2a-2b
    // 因爲當-1<=k<=0時,x越大,y越小
    // 否則(x,y)更新爲(x+1,y), D更新爲D=D+2a
    // 4.當直線沒有畫完時,重複步驟3,否則結束
    else if (k <= 0 && k >= -1) {
        d = 2 * a - b;
        d1 = 2 * a - 2 * b, d2 = 2 * a;
        while (x < x1) {
            if (d > 0) {
                ++x, --y, d += d1;
            } else {
                ++x, d += d2;
            }
            putpixel(x, y, BLUE);
        }
    }
    // k>1
    // 1.計算初始值  a=y0−y1, b=x1−x0, D=2a+b
    // 2.x=x0,y=y0
    // 3.繪製點(x,y),判斷D的符號
    // 若D>0,則(x,y)更新爲(x+1,y+1),D更新爲D=D+2a+2b
    // 否則(x,y)更新爲(y+1,y), D更新爲D=D+2b
    // 因爲當k>1時,y爲步進方向。
    // 4.當直線沒有畫完時,重複步驟3,否則結束
    else if (k > 1) {
        d = a + 2 * b;
        d1 = 2 * (a + b), d2 = 2 * b;
        while (y < y1) {
            if (d > 0) {
                ++x, ++y, d += d1;
            } else {
                ++y, d += d2;
            }
            putpixel(x, y, RED);
        }
    }
    // k<-1
    // 1.計算初始值  a=y0−y1, b=x1−x0, D=2a-b
    // 2.x=x0,y=y0
    // 3.繪製點(x,y),判斷D的符號
    // 若D<=0,則(x,y)更新爲(x+1,y-1),D更新爲D=D-2a-2b
    // 因爲當k<-1時,a,b均爲負數,所以要D=D-2a-2b
    // 因爲當k<-1時,x越大,y越小
    // 否則(x,y)更新爲(y-1,y), D更新爲D=D-2b
    // 因爲當k<-1時,y爲步進方向,且x越大y越小,即y-1
    // 4.當直線沒有畫完時,重複步驟3,否則結束
    else {
        d = a - 2 * b;
        d1 = -2 * b, d2 = 2 * a - 2 * b;
        while (y > y1) {
            if (d <= 0) {
                ++x, --y, d += d2;
            } else {
                --y, d += d1;
            }
            putpixel(x, y, BLUE);
        }
    }
}

int main()
{
    initgraph(640, 480);
    Midpoint_Line(30, 50, 10, 60); //-1<k<0
    Midpoint_Line(10, 60, 30, 50);

    Midpoint_Line(30, 50, 10, 90); //k<-1
    Midpoint_Line(10, 90, 30, 50);

    Midpoint_Line(30, 50, 10, 40); //0<k<1
    Midpoint_Line(10, 40, 30, 50);

    Midpoint_Line(30, 50, 10, 10); //k>1
    Midpoint_Line(10, 10, 30, 50);

    Midpoint_Line(10, 10, 10, 90); //k==0,x==10
    Midpoint_Line(10, 90, 10, 10);

    Midpoint_Line(10, 50, 30, 50); //k==0,y==50
    Midpoint_Line(30, 50, 10, 50);

    getch();
    closegraph();

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章