DDA算法、正负法、Bresenham算法

来源:互联网 发布:人工智能的细分领域 编辑:程序博客网 时间:2024/05/17 08:08

 1.实现直线的DDA算法、正负法、Bresenham算法。

2. 实现圆弧的正负法和Bresenham算法。

3. 利用上述完成的算法绘制中国象棋的棋盘和棋子。

// cpt1.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include<math.h>#include <GL/glut.h>void init(void){glClearColor(1.0, 1.0, 1.0, 0.0);//清屏颜色glMatrixMode(GL_PROJECTION); //设置投影矩阵glLoadIdentity();//单位化上述投影矩阵gluOrtho2D(-1000, 1000, -1000, 1000);//设置具体投影 矩阵为平面正交投影 }void gl_Point(int x, int y){glPointSize(2.0f);glBegin(GL_POINTS);//OpenGL绘图命令参数glVertex2i(x, y);   // 指定画线的端点坐标.glEnd();// OpenGL绘图结束命令参数}void gl_Pointdda(int x, int y){glPointSize(3.0f);glBegin(GL_POINTS);//OpenGL绘图命令参数glVertex2i(x, y);   // 指定画线的端点坐标.glEnd();// OpenGL绘图结束命令参数}void dda(int x1, int y1, int x2, int y2)//直线DDA算法{int k, i;float x, y, dx, dy;k = abs(x2 - x1);if (abs(y2 - y1)>k)k = abs(y2 - y1);dx = (float)(x2 - x1) / k;dy = (float)(y2 - y1) / k;x = (float)(x1);y = (float)(y1);for (i = 0; i<k; i++){gl_Pointdda((int)(x + 0.5), (int)(y + 0.5));x = x + dx;y = y + dy;}}//交换两个数字void swap(int x1, int x2){int temp = x2;x2 = x1;x1 = temp;}void MidpointLine(int xs, int ys, int xe, int ye)//画直线的正负法{if (xs>xe){swap(xs, xe);//因为书上的是假设s是起点,e是终点swap(ys, ye);}float a, b, dt1, dt2, d, x, y;a = ys - ye;b = xe - xs;float k = (float)(ye - ys) / (xe - xs);if (k >= 0 && k<1)//书上的都是假设直线斜率在0-1之间,所以得分情况类似讨论{                //参考http://cuiqingcai.com/1613.htmld = 2 * a + b;dt1 = 2 * a;dt2 = 2 * (a + b);}else if (k >= 1){d = a + 2 * b;dt1 = 2 * (a + b);dt2 = 2 * b;}else if (k<0 && k >= -1){d = 2 * a - b;dt1 = 2 * (a - b);dt2 = 2 * a;}else if (k<-1){d = a - 2 * b;dt1 = -2 * b;dt2 = 2 * (a - b);}x = xs;y = ys;gl_Point(x, y);if (k >= 0 && k<1){while (x<xe){if (d<0){x++;y++;d += dt2;}else{x++;d += dt1;}gl_Point(x, y);//在(x,y)处画点}}else if (k >= 1){while (y<ye){if (d<0){y++;d += dt2;}else{y++;x++;d += dt1;}gl_Point(x, y);}}else if (k<0 && k >= -1){while (x<xe){if (d<0){x++;d += dt2;}else{x++;y--;d += dt1;}gl_Point(x, y);}}else if (k<-1){while (y>ye){if (d<0){y--;x++;d += dt2;}else{y--;d += dt1;}gl_Point(x, y);}}}void Bresenhamline(int x1, int y1, int x2, int y2)//Bresenham画线算法{if (x2<x1){swap(x1, x2);swap(y1, y2);}float dx = x2 - x1;float dy = y2 - y1;float k = dy / dx;float m, e; int i;float x = x1, y = y1;if (k >= 0 && k<1){//斜率为0到1m = dy / dx;e = m - 0.5;for (i = 0; i<dx; i++){gl_Point(x, y);if (e >= 0){y += 1; e -= 1;}x += 1; e += m;}}else if (k >= 1){//x换为y,y换为xm = dx / dy;e = m - 0.5;for (i = 0; i<dy; i++){gl_Point(x, y);if (e >= 0){x += 1; e -= 1;}y += 1; e += m;}}else if (k<0 && k >= -1){//x不变,y换为-ym = -dy / dx;e = m + 0.5;for (i = 0; i<dx; i++){gl_Point(x, y);if (e <= 0){y -= 1; e += 1;}x += 1; e -= m;}}else{//将x换为-y,y换为xm = -dx / dy;e = m + 0.5;for (i = 0; i<-dy; i++){gl_Point(x, y);if (e <= 0){x += 1; e += 1;}y -= 1; e -= m;}}}void plot_circle_point(int xc, int yc, int x0, int y0){glPointSize(2);gl_Point(xc + x0, yc + y0);gl_Point(xc - x0, yc + y0);gl_Point(xc + x0, yc - y0);gl_Point(xc - x0, yc - y0);gl_Point(xc + y0, yc + x0);gl_Point(xc - y0, yc + x0);gl_Point(xc + y0, yc - x0);gl_Point(xc - y0, yc - x0);}void pnarc(int xc, int yc, int radius)//正负画圆算法{int x, y, f;x = 0;y = 0+radius;f = 0;while (y >= x){plot_circle_point(xc, yc, x, y);if (f>0){f = f - 2 * y + 1;y=y-1;}else{f = f + 2 * x + 1;x=x+1;}}}void Bresenham_arc(int xc, int yc, int radius)//Bresenham画圆算法{int x, y, d;x = 0;y = radius;d = 3 - 2 * radius;while (x<y){plot_circle_point(xc, yc, x, y);if (d<0)d = d + 4 * x + 6;else{d = d + 4 * (x - y) + 10;y=y-1;}x=x+1;}if (x == y)plot_circle_point(xc, yc, x, y);}void display(void){glClear(GL_COLOR_BUFFER_BIT);//清颜色缓存glColor3f(0.0, 0.0, 0.0); //绘图颜色设定//外框线dda(-850, 950,850, 950);dda(-850, -950, 850, -950);dda(-850, 950, -850, -950);dda(850, 950, 850, -950);//外边内框线Bresenhamline(-800,900,800,900);Bresenhamline(-800, -900, 800, -900);Bresenhamline(-800, 900, -800, -900);Bresenhamline(800, 900, 800, -900); //中间的网格线,注意最中间是空的GLint a = 100;  //是opengl里对Int的重定义。这个是gl.h里的  GLint b = 0;         //typedef int  GLint;int i;for (i = 0; i<4; i++){MidpointLine(-800,a,800,a);MidpointLine(-800, -a, 800, -a);MidpointLine(b, 900, b, 100);MidpointLine(-b, 900,-b, 100);MidpointLine(b, -100, b, -900);MidpointLine(-b, -100, -b, -900);a =a+200;b =b+200;} //斜线Bresenhamline(-200, 500, 200, 900);Bresenhamline(-200, -500, 200, -900);Bresenhamline(-200, 900, 200, 500);Bresenhamline(-200, -900, 200, -500);//棋子pnarc(-800, 900, 80);pnarc(-600, 900, 80);pnarc(-400, 900, 80);pnarc(-200, 900, 80);pnarc(0, 900, 80);pnarc(200, 900, 80);pnarc(400, 900, 80);pnarc(600, 900, 80);pnarc(800, 900, 80);pnarc(-600, 500, 80);pnarc(600, 500, 80);pnarc(-800, 100, 80);pnarc(-400, 100, 80);pnarc(0, 100, 80);pnarc(400, 100, 80);pnarc(800, 100, 80);Bresenham_arc(-800, -900, 80);Bresenham_arc(-600, -900, 80);Bresenham_arc(-400, -900, 80);Bresenham_arc(-200, -900, 80);Bresenham_arc(0, -900, 80);Bresenham_arc(200, -900, 80);Bresenham_arc(400, -900, 80);Bresenham_arc(600, -900, 80);Bresenham_arc(800, -900, 80);Bresenham_arc(-600, -500, 80);Bresenham_arc(600, -500, 80);Bresenham_arc(-800, -100, 80);Bresenham_arc(-400, -100, 80);Bresenham_arc(0, -100, 80);Bresenham_arc(400, -100, 80);Bresenham_arc(800, -100, 80);glFlush();//强制刷新缓冲}int main(int argc, char * argv[]) //主程序{glutInit(&argc, argv);  //初始化glutglutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);  //显示模式glutInitWindowSize(700, 650);// 视口大小glutInitWindowPosition((glutGet(GLUT_SCREEN_WIDTH) - 700) / 2, (glutGet(GLUT_SCREEN_HEIGHT) - 650) / 2);  //视口初始位置:centerglutCreateWindow("象棋"); //标题 init();            //执行初始化程序glutDisplayFunc(display); //绘图程序glutMainLoop();               //视窗系统被激活return 0;   /* ANSI C requires main to return int. */}

实验结果:


0 0