【OpenGL】使用DDA算法绘制直线,使用Bresenham算法绘制直线和圆

//#include "stdafx.h"
#include <windows.h>
#include <GL/glu.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include<stdlib.h>  
#include <iostream>
#include <algorithm>
using namespace std;

void display(void);
void myInit(void);
void DDA_Line(int x0, int y0, int xEnd, int yEnd);
void Bres_Line(int x1, int y1, int x2, int y2);
void Bres_Circle(int x0, int y0, double r);
void Cirpot(int x0, int y0, int x, int y);          // 八路对称


int main(int argc, char* argv[])
{
	glutInit(&argc, argv);                          // 初始化
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);    // 单缓冲窗口,RGB颜色模式
	glutInitWindowSize(1000, 800);                  // 创建窗口
	glutInitWindowPosition(500, 250);               // 窗口位置
	glutCreateWindow("Widget");                     // 窗口名词

	glutDisplayFunc(display);                       // 绘制方法

	myInit();                                       // 初始化
	glutMainLoop();                                 // 循环渲染
	return(0);
}


void display(void)
{
	glClear(GL_COLOR_BUFFER_BIT);  // 清除当前可写的颜色缓冲
	glViewport(0, 0, 1000, 800);   // 视口矩形的范围(x, y, width, height)
	DDA_Line(30, 30, 400, 400);
	Bres_Line(50, 100, 100, 400);
	Bres_Circle(250, 250, 100);
}

void myInit(void)
{
	glClearColor(0.2f, 0.2f, 0.2f, 1.0f);           // 设置背景颜色
	glColor3f(1.0, 1.0, 1.0);                       // 设置点颜色
	gluOrtho2D(0.0, 500.0, 0.0, 500.0);             // 用来指定屏幕区域对应的模型坐标范围(left, right, bottom, top)
	glMatrixMode(GL_MODELVIEW);                     // 在进行变换前把当前矩阵设置为单位矩阵
}

void DDA_Line(int x0, int y0, int xEnd, int yEnd)
{
	int dx = xEnd - x0;			
	int dy = yEnd - y0;			
	int steps;
	float xIncrement, yIncrement, x = x0, y = y0;
	if (abs(dx) > abs(dy))	 // k < 1
		steps = abs(dx);
	else                     // k > 1
		steps = abs(dy);

	xIncrement = float(dx) / float(steps);         
	yIncrement = float(dy) / float(steps);			

	glBegin(GL_POINTS);            // 画点
	glVertex3f(x0, y0, 0);		   // 画起点
	for (int k = 0; k <= steps; k++)
	{
		x += xIncrement;		   // x点 + 增量
		y += yIncrement;		   // y点 + 增量
		glVertex3f(x, y, 0);       // 画点
	}
	glVertex3f(xEnd, yEnd, 0);	   // 画终点
	glEnd();
	glFlush();
}

void Bres_Line(int x1, int y1, int x2, int y2)
{
	glBegin(GL_POINTS);            // 画点
	glColor3f(0.7, 0.0, 0.6);
	glVertex3f(x1, y1, 0);		   // 画起点
	int dx = abs(x2 - x1), dy = abs(y2 - y1);
	if (dx == 0 && dy == 0)
		return;
	int flag = 0;
	if (dx < dy)    // k > 1
	{
		flag = 1;
		swap(x1, y1);
		swap(x2, y2);
		swap(dx, dy);
	}
	int tx = (x2 - x1 > 0 ? 1 : -1);
	int ty = (y2 - y1 > 0 ? 1 : -1);
	int curx = x1, cury = y1;
	int dS = 2 * dy, dT = 2 * (dy - dx);
	int d = dS - dT;               // 判别式
	while (curx != x2)
	{
		if (d < 0)
			d += dS;
		else
		{
			cury += ty;
			d += dT;
		}
		if (flag)  // k > 1
			glVertex3f(cury, curx, 0);
		else       // k <= 1
			glVertex3f(curx, cury, 0);
		curx += tx;
	}
	glEnd();
	glFlush();
}

void Cirpot(int x0, int y0, int x, int y)
{
	glVertex3f(x0 + x, y0 + y, 0);
	glVertex3f(x0 + y, y0 + x, 0);
	glVertex3f(x0 + y, y0 - x, 0);
	glVertex3f(x0 + x, y0 - y, 0);
	glVertex3f(x0 - x, y0 - y, 0);
	glVertex3f(x0 - y, y0 - x, 0);
	glVertex3f(x0 - y, y0 - x, 0);
	glVertex3f(x0 - y, y0 + x, 0);
	glVertex3f(x0 - x, y0 + y, 0);
}

void Bres_Circle(int x0, int y0, double r)
{
	int x = 0, y = (int)r;
	int d = int(3 - 2 * r);   // 判别式初始值
	glBegin(GL_POINTS);            // 画点
	glColor3f(1.0, 0.1, 0.0);
	while (x < y)
	{
		Cirpot(x0, y0, x, y);
		if (d < 0)
			d += (4 * x + 6);
		else
		{
			d += (4 * (x - y) + 10);
			y--;
		}
		x++;
	}
	if (x == y)
		Cirpot(x0, y0, x, y);
	glEnd();
	glFlush();
}

成品图:
在这里插入图片描述

使用鼠标交互

//#include "stdafx.h"
#include <windows.h>
#include <GL/glu.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include<stdlib.h>  
#include <iostream>
#include <algorithm>
using namespace std;

void display(void);
void myInit(void);
void DDA_Line(int x0, int y0, int xEnd, int yEnd);
void Bres_Line(int x1, int y1, int x2, int y2);
void Bres_Circle(int x0, int y0, double r);
void Cirpot(int x0, int y0, int x, int y);          // 八路对称
void Mouse0(int button, int state, int x, int y);    // 鼠标单击事件
void Mouse1(int button, int state, int x, int y);
int GLOBALx0 = 30, GLOBALy0 = 30;
int GLOBALx1 = 400, GLOBALy1 = 400;
int f = 0;

int main(int argc, char* argv[])
{
	glutInit(&argc, argv);                          // 初始化
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);    // 单缓冲窗口,RGB颜色模式
	glutInitWindowSize(1000, 800);                  // 创建窗口
	glutInitWindowPosition(0, 0);                   // 窗口位置
	glutCreateWindow("Widget");                     // 窗口名词

	glutDisplayFunc(display);                       // 绘制方法

	myInit();                                       // 初始化
	glutMainLoop();                                 // 循环渲染
	return(0);
}

void Mouse0(int button, int state, int x, int y)
{
	if (state == GLUT_DOWN)
	{
		f++;
		if (f % 2 == 1)
		{
			GLOBALx0 = x;
			GLOBALy0 = y;
		}
		else
		{
			GLOBALx1 = x;
			GLOBALy1 = y;
			DDA_Line(GLOBALx0, GLOBALy0, GLOBALx1, GLOBALy1);
		}
	}
	cout << "(" << GLOBALx0 << ", " << GLOBALy0 << ")  (" << GLOBALx1 << ", " << GLOBALy1 << ") \n";
}

void Mouse1(int button, int state, int x, int y)
{
	
}

void display(void)
{
	glClear(GL_COLOR_BUFFER_BIT);  // 清除当前可写的颜色缓冲
	glViewport(0, 0, 1000, 800);   // 视口矩形的范围(x, y, width, height)
	glutMouseFunc(Mouse0);
	// DDA_Line(GLOBALx0, GLOBALy0, GLOBALx1, GLOBALy1);
	Bres_Line(50, 100, 100, 400);
	Bres_Circle(250, 250, 100);
}

void myInit(void)
{
	glClearColor(0.2f, 0.2f, 0.2f, 1.0f);           // 设置背景颜色
	glColor3f(1.0, 1.0, 1.0);                       // 设置点颜色
	gluOrtho2D(0.0, 1000, 800.0, 0.0);              // 用来指定屏幕区域对应的模型坐标范围(left, right, bottom, top)
	glMatrixMode(GL_MODELVIEW);                     // 在进行变换前把当前矩阵设置为单位矩阵
}

void DDA_Line(int x0, int y0, int xEnd, int yEnd)
{
	int dx = xEnd - x0;			
	int dy = yEnd - y0;			
	int steps;
	float xIncrement, yIncrement, x = x0, y = y0;
	if (abs(dx) > abs(dy))	 // k < 1
		steps = abs(dx);
	else                     // k > 1
		steps = abs(dy);

	xIncrement = float(dx) / float(steps);         
	yIncrement = float(dy) / float(steps);			
	

	glBegin(GL_POINTS);            // 画点
	glVertex3f(x0, y0, 0);		   // 画起点
	for (int k = 0; k <= steps; k++)
	{
		x += xIncrement;		   // x点 + 增量
		y += yIncrement;		   // y点 + 增量
		glVertex3f(x, y, 0);       // 画点
	}
	glVertex3f(xEnd, yEnd, 0);	   // 画终点
	glEnd();
	glFlush();
}

void Bres_Line(int x1, int y1, int x2, int y2)
{
	glBegin(GL_POINTS);            // 画点
	glColor3f(0.7, 0.0, 0.6);
	glVertex3f(x1, y1, 0);		   // 画起点
	int dx = abs(x2 - x1), dy = abs(y2 - y1);
	if (dx == 0 && dy == 0)
		return;
	int flag = 0;
	if (dx < dy)    // k > 1
	{
		flag = 1;
		swap(x1, y1);
		swap(x2, y2);
		swap(dx, dy);
	}
	int tx = (x2 - x1 > 0 ? 1 : -1);
	int ty = (y2 - y1 > 0 ? 1 : -1);
	int curx = x1, cury = y1;
	int dS = 2 * dy, dT = 2 * (dy - dx);
	int d = dS - dT;               // 判别式
	while (curx != x2)
	{
		if (d < 0)
			d += dS;
		else
		{
			cury += ty;
			d += dT;
		}
		if (flag)  // k > 1
			glVertex3f(cury, curx, 0);
		else       // k <= 1
			glVertex3f(curx, cury, 0);
		curx += tx;
	}
	glEnd();
	glFlush();
}

void Cirpot(int x0, int y0, int x, int y)
{
	glVertex3f(x0 + x, y0 + y, 0);
	glVertex3f(x0 + y, y0 + x, 0);
	glVertex3f(x0 + y, y0 - x, 0);
	glVertex3f(x0 + x, y0 - y, 0);
	glVertex3f(x0 - x, y0 - y, 0);
	glVertex3f(x0 - y, y0 - x, 0);
	glVertex3f(x0 - y, y0 - x, 0);
	glVertex3f(x0 - y, y0 + x, 0);
	glVertex3f(x0 - x, y0 + y, 0);
}

void Bres_Circle(int x0, int y0, double r)
{
	int x = 0, y = (int)r;
	int d = int(3 - 2 * r);   // 判别式初始值
	glBegin(GL_POINTS);            // 画点
	glColor3f(1.0, 0.1, 0.0);
	while (x < y)
	{
		Cirpot(x0, y0, x, y);
		if (d < 0)
			d += (4 * x + 6);
		else
		{
			d += (4 * (x - y) + 10);
			y--;
		}
		x++;
	}
	if (x == y)
		Cirpot(x0, y0, x, y);
	glEnd();
	glFlush();
}
好的,我可以为您提供一个Bresenham算法的代码示例,以使用OpenGL的C语言编写直线段。以下是示例代码: ``` #include <GL/glut.h> #include <stdio.h> int winWidth = 640; int winHeight = 480; int pointCount = 0; int points[2][2]; void init(void) { glClearColor(0.0, 0.0, 0.0, 0.0); glMatrixMode(GL_PROJECTION); gluOrtho2D(0.0, winWidth, 0.0, winHeight); } void display() {} void bresenham(int x1, int y1, int x2, int y2) { int dx = abs(x2-x1), dy = abs(y2-y1); int p = 2*dy-dx; int x = x1, y = y1; glBegin(GL_POINTS); glVertex2i(x, y); while (x < x2) { if (p >= 0) { y++; p += 2*dy-2*dx; } else { p += 2*dy; } x++; glVertex2i(x, y); } glEnd(); glFlush(); } void mouse(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { points[pointCount][0] = x; points[pointCount][1] = winHeight - y; pointCount++; } else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) { bresenham(points[0][0], points[0][1], points[1][0], points[1][1]); pointCount = 0; } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(winWidth, winHeight); glutInitWindowPosition(100, 100); glutCreateWindow("Bresenham Line Drawing"); glutDisplayFunc(display); glutMouseFunc(mouse); init(); glutMainLoop(); return 0; } ``` 该代码使用OpenGL库和GLUT库来实现直线段的创建和显示。Bresenham算法是在while循环中执行的,以在屏幕上绘制直线。当用鼠标左键单击时,该代码会记录所选点的坐标,并在用鼠标右键单击时使用这些点的坐标来绘制直线
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值