OpenGL:直線掃描轉(zhuǎn)換

直線掃描轉(zhuǎn)換

在顯示器上用最逼近直線的像素點來表示直線

1.DDA畫線法

思想:
即數(shù)值微分法,Digitical Differential Analyzer
x_{i+1}=x_{i}+1\\y_{i+1}=y_{i}+k
實現(xiàn):
plot(x,int(y))

#include <gl/glut.h>
#include <stdio.h>
#include <math.h>
int xs,ys,xe,ye;
//x0和y0為起始坐標坯汤,x1和y1為終止坐標

void DDALine(int x0, int y0, int x1, int y1){
int dy=y1-y0;
int dx=x1-x0;
float k=dy[表情];
int y=y0;
if(k<1){
    for (int x=x0;x<=x0;x++){
    glVertex2i(x,int(y+0.5));
    y+=k;
    }

}
else{
    int x=x0;
    for (;y<=y1;y++){
        glVertex2i(int(x+.5),y);
        x+=1/k;
    }
}
}



void lineSegment(){
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(0.0,0.0,0.0);
    glBegin(GL_POINTS);
    DDALine(xs,ys,xe,ye);
    glEnd();
    glFlush();
}

void main(int argc, char *argv[]){
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
    printf("輸出線段起始和終止坐標(范圍為0-500, 0-500):");
    scanf("%d,%d,%d,%d",&xs,&ys,&xe,&ye);
    glutInitWindowPosition(50,100);
    glutInitWindowSize(500,500);
    glutCreateWindow("中點畫線算法");
    glClearColor(1.0,1.0,1.0,0.0);
    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(0.0,500.0,0.0,500.0);
    glutDisplayFunc(lineSegment);
    glutMainLoop();
}
  • 采用微分思想
  • 計算y使用浮點數(shù)悼做、除法
  • 迭代算法
  • |k|>1將導(dǎo)致隔行顯示皆串,故|k|>1時采用y=y+1殷费,x=x+1/k

2.中點畫線法

思想:
|K|<1時,
y=y+1,d<0\\ y=y,d>=0
d=F(x+1,\frac{y_{i}+y_{i+1}}{2})
其中d又滿足迭代(帶入直線標準式推得)
d>=0,d=d+a\\d<0,d=d+a+b
實現(xiàn):

    1. a=y_0-y_1,b=x_1-x_0,c=x_0*y_1-x_1*y_0,d=2*a+b, x=x0,y=y0, d1=2*a, d2=2*(a+b)
    1. plot(x,y)
  • 3.x=x+1,y=y+1,d=d+d2,d<0 \\x=x+1,y=y,d=d+d1,d>=0
    1. 重復(fù)2-3斗幼,直到繪制完成
#include <gl/glut.h>
#include <stdio.h>
#include <math.h>
int xs,ys,xe,ye;
//x0和y0為起始坐標澎蛛,x1和y1為終止坐標

void MidPoint(int x0, int y0, int x1, int y1){
    int a=y0-y1;
    int b=x1-x0;
    int c=x0*y1-x1*y0;
    int d=2*a+b;
    int d1=2*a;
    int d2=2*(a+b);
    //斜率小于1時
        int y=y0;
        for (int x=x0;x<=x1;x++){
            if (d<0){
                y+=1;
                glVertex2i(x,y);
                d+=d2;
            }
            else{
                y=y;
                glVertex2i(x,y);
                d+=d1;
            }
        }

}



void lineSegment(){
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(0.0,0.0,0.0);
    glBegin(GL_POINTS);
    MidPoint(xs,ys,xe,ye);
    glEnd();
    glFlush();
}

void main(int argc, char *argv[]){
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
    printf("輸出線段起始和終止坐標(范圍為0-500, 0-500):");
    scanf("%d,%d,%d,%d",&xs,&ys,&xe,&ye);
    glutInitWindowPosition(50,100);
    glutInitWindowSize(500,500);
    glutCreateWindow("中點畫線算法");
    glClearColor(1.0,1.0,1.0,0.0);
    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(0.0,500.0,0.0,500.0);
    glutDisplayFunc(lineSegment);
    glutMainLoop();
}

特點:

  • 不必算斜率 蜕窿,無除法
  • 無浮點數(shù)谋逻,只有整數(shù)
  • 只有加法和乘2運算

3.Breshnham畫線法

image.png

d初始化為0呆馁,每次加K,但y每加1毁兆,d需要減1,d高于中點取上面的像素浙滤,否則取下面的像素
x_i=x_{i+1}\\{y_i=y_{i+1},d>0.5,d=d-1\\y_i=y_i,d<0.5\\ d=d+k}
有浮點數(shù)气堕、慢
改進1:
d與浮點數(shù)0.5比較太慢了纺腊,令e=d-0.5
x_i=x_{i+1}\\{y_i=y_{i+1},e>0,e=e-1\\y_i=y_i,e<=0\\ e=e+k}
只判斷e的符號即可

終結(jié)版:
e的初值依然是浮點數(shù)茎芭,而且還要算k揖膜,不如令e=2e*dx(dx=x1-x0,dy=y1-y0梅桩,原先算斜率用的)壹粟,就可以抵消分母,并把自帶的0.5取整
算法:

    1. 輸入(x0宿百,y0)趁仙,(x1,y1)
    1. dx=x1-x0, dy=y1-y0,e=-dx,x=x0,y=y0
    1. plot(x,y)
    1. e=e+2dy if e>0 (x,y)更新為(x+1,y+1)e=e-2dy 垦页,else (x,y)更新為(x+1雀费,y)
  • 5.重復(fù)3-4直到畫完
#include <gl/glut.h>
#include <stdio.h>
#include <math.h>
int xs, ys, xe, ye;
//x0和y0為起始坐標,x1和y1為終止坐標

void BreshnhamLine(int x0, int y0, int x1, int y1) {
    int dy = y1 - y0;
    int dx = x1 - x0;
    if (dx == 0) {
        printf("error");
    }float k = dy / dx;
    float d = 0;
    int x = x0, y = y0;
    int e = -dx;
    for (x; x <= x1; x++) {
        glVertex2i(x, y);
        e += 2 * dy;
        if (e) {
            y += 1;
            e -= 2 * dx;
        }
    }
}



void lineSegment() {
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(0.0, 0.0, 0.0);
    glBegin(GL_POINTS);
    BreshnhamLine(xs, ys, xe, ye);
    glEnd();
    glFlush();
}

void main(int argc, char *argv[]) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    printf("輸出線段起始和終止坐標(范圍為0-500痊焊, 0-500):");
    scanf("%d,%d,%d,%d", &xs, &ys, &xe, &ye);
    glutInitWindowPosition(50, 100);
    glutInitWindowSize(500, 500);
    glutCreateWindow("中點畫線算法");
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(0.0, 500.0, 0.0, 500.0);
    glutDisplayFunc(lineSegment);
    glutMainLoop();
}

特點:只有加法和乘法運算盏袄,全是整數(shù)運算,乘法也只是乘2宋光,可以用移位位實現(xiàn)貌矿,便于硬件實現(xiàn)

小結(jié)

畫線主要還是要簡化步驟炭菌,盡量避免浮點數(shù)和除法罪佳,盡量多用加法,少用乘法
上述算法主要討論了K<1的情況黑低,k>1時將x赘艳,y互換即可

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市克握,隨后出現(xiàn)的幾起案子蕾管,更是在濱河造成了極大的恐慌,老刑警劉巖菩暗,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掰曾,死亡現(xiàn)場離奇詭異,居然都是意外死亡停团,警方通過查閱死者的電腦和手機旷坦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門掏熬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人秒梅,你說我怎么就攤上這事旗芬。” “怎么了捆蜀?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵疮丛,是天一觀的道長。 經(jīng)常有香客問我辆它,道長誊薄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任锰茉,我火速辦了婚禮暇屋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘洞辣。我一直安慰自己咐刨,他們只是感情好,可當我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布扬霜。 她就那樣靜靜地躺著定鸟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪著瓶。 梳的紋絲不亂的頭發(fā)上联予,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天,我揣著相機與錄音材原,去河邊找鬼沸久。 笑死,一個胖子當著我的面吹牛余蟹,可吹牛的內(nèi)容都是我干的卷胯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼威酒,長吁一口氣:“原來是場噩夢啊……” “哼窑睁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起葵孤,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤担钮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后尤仍,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體箫津,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了苏遥。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片送挑。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖暖眼,靈堂內(nèi)的尸體忽然破棺而出惕耕,到底是詐尸還是另有隱情,我是刑警寧澤诫肠,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布司澎,位于F島的核電站,受9級特大地震影響栋豫,放射性物質(zhì)發(fā)生泄漏挤安。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一丧鸯、第九天 我趴在偏房一處隱蔽的房頂上張望蛤铜。 院中可真熱鬧,春花似錦丛肢、人聲如沸围肥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽穆刻。三九已至,卻和暖如春杠步,著一層夾襖步出監(jiān)牢的瞬間氢伟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工幽歼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留朵锣,地道東北人。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓甸私,卻偏偏與公主長得像诚些,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子颠蕴,可洞房花燭夜當晚...
    茶點故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 定點小數(shù)運算 來自:http://www.eepw.com.cn/article/17893.htm 在DSP世界...
    郝宇峰閱讀 9,130評論 0 2
  • "use strict";function _classCallCheck(e,t){if(!(e instanc...
    久些閱讀 2,031評論 0 2
  • 在C語言中,五種基本數(shù)據(jù)類型存儲空間長度的排列順序是: A)char B)char=int<=float C)ch...
    夏天再來閱讀 3,345評論 0 2
  • 1. 拉格朗日多項式插值 了解概念 插值多項式插值節(jié)點范德蒙特(Vandermonde)行列式截斷誤差泣刹、插值余項...
    野狗子嗷嗷嗷閱讀 2,551評論 0 3
  • 我們很沒有安全感,很害怕失去我們喜歡的東西和人外冀,我們冷漠的不想讓其他人靠近寡键,其實我們何曾不渴望溫暖,可是害...
    塵落1204閱讀 260評論 0 3