中点画线算法
!参考视频
中点画线算法也是一个比较经典的算法
主要思想就是利用中点和线段上点的距离来选择取上方的点还是下方的点。
通过构造判别式d = F(x0+1,y+0.5)或者F(x0-1,y+0.5)来确定正向斜率和负斜率的值
对于的d<0的判别式,我们选择上方的点,同时利用d的递推公式来构造下一个点
同理对于d>=0的判别式我们选择左方或者右方的点。
我使用的是openGL c++版 库为freeglut 和glew
#include <gl/glew.h>
#include <gl/freeglut.h>
#include<stdlib.h>
#define h 500
#define w 500
void Bresenham(int x0, int y0, int x1, int y1) {
// 各方向上的增量
int dx = x1 - x0;
int dy = y1 - y0;
float k = (float) dy / (float) dx;
int d;
int status = 0;
// status = 1 斜率大于1
// status = 2 斜率大于0小于1
// status = 3 斜率大于-1 小于0
// status = 4 斜率小于-1
// 斜率为正
if (k > 0) {
if (k > 1.0) {
// 斜率大于1 2 3
status = 1;
d = dx - 2 * dy;
} else {
// 斜率0.5 0.2
status = 2;
d = dx - 2 * dy;
}
} else {
if (k < -1) {
// 斜率小于于-1 例如-2
status = 4;
d = dx + 2 * dy;
} else {
// 斜率 -0.5
status = 3;
d = dx + 2 * dy;
}
}
// 设置原点在屏幕中心
int x = x0 + w / 2, y = y0 + h / 2;
// 开始画点
glBegin(GL_POINTS);
switch (status) {
case 1: {
for (int i = 0; i < abs(dy); i++) {
glVertex3f(x, y, 0);
if (d < 0) {
x = x + 1;
y = y + 1;
d = d + 2 * dy - 2 * dx;
} else {
y = y + 1;
d = d - 2 * dx;
}
}
break;
}
case 2: {
for (int i = 0; i < abs(dx); i++) {
glVertex3f(x, y, 0);
if (d < 0) {
x = x + 1;
y = y + 1;
d = d + 2 * dx - 2 * dy;
} else {
x = x + 1;
d = d - 2 * dy;
}
}
break;
}
case 3: {
for (int i = 0; i < abs(dx); i++) {
glVertex3f(x, y, 0);
if (d < 0) {
x = x - 1;
y = y + 1;
d = d - 2 * dx;
} else {
x = x - 1;
d = d + 2 * dy + 2 * dx;
}
}
break;
}
case 4: {
for (int i = 0; i < abs(dy); i++) {
glVertex3f(x, y, 0);
if (d < 0) {
y = y + 1;
d = d - 2 * dx;
} else {
x = x - 1;
y = y + 1;
d = d - 2 * dy - 2 * dx;
}
}
break;
}
}
glEnd();
glutSwapBuffers();
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
Bresenham(100, -100, -100, 300);
}
//初始化方法
void init() {
glClearColor(1.0, 1.0, 1.0, 0.0);
glColor3f(0.0, 0.0, 0.0);
// 坐标范围
gluOrtho2D(0.0, w, 0.0, h);
}
int main(int argc, char *argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(w, h);
glutCreateWindow("中点画线算法");
init();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}