直線掃描轉(zhuǎn)換
在顯示器上用最逼近直線的像素點來表示直線
1.DDA畫線法
思想:
即數(shù)值微分法,Digitical Differential Analyzer
實現(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時,
其中d又滿足迭代(帶入直線標準式推得)
實現(xiàn):
- plot(x,y)
- 3.
- 重復(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高于中點取上面的像素浙滤,否則取下面的像素
有浮點數(shù)气堕、慢
改進1:
d與浮點數(shù)0.5比較太慢了纺腊,令e=d-0.5
只判斷e的符號即可
終結(jié)版:
e的初值依然是浮點數(shù)茎芭,而且還要算k揖膜,不如令e=2e*dx(dx=x1-x0,dy=y1-y0梅桩,原先算斜率用的)壹粟,就可以抵消分母,并把自帶的0.5取整
算法:
- 輸入(x0宿百,y0)趁仙,(x1,y1)
- dx=x1-x0, dy=y1-y0,e=-dx,x=x0,y=y0
- plot(x,y)
- 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互換即可