【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();
}
  • 5
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
计算机图形学课程实验 报 告 实验题目 设计算法绘制直线 班 级 姓 名 学 号 指导教师 日 期 "实验说明 试验目的: 掌握直线的基本生成算法思想,并上机编程实现相应的算法。 试验地点: 教九楼401 数学系机房 实验要求(Direction): 1. 每个学生单独完成;2.开发语言为TurboC或C++,也可使用其它语言;3.请在自己的实验 报告上写明、学号、班级;4.每次交的实验报告容包括:题目、试验目的和意义、程序 制作步骤、主程序、运行结果图以及参考文件;5. 自己保留一份可执行程序,考试前统一检查和上交。 "实验容 :实验题一 1.1实验题目 1).用DDA法在屏幕上画一条具有三个像素宽的直线段L1。要求:(1)直线段L1的两个 端点坐标和画线颜色都要求可以随机输入;(2)要求输出直线段L1上的各点坐标;(3)画 出直线的同时要求标明两端点坐标。 2).将课堂所讲的斜率0<K<1的中点画线算法推广到斜率K>1、-1<K<0和K<- 1的情况,编写一通用的中点画线算法。 1.2实验目的和意义 1.了解如何利用C语言和图形函数进行绘图; 2. 熟悉并掌握C语言的图形模式控制函数,图形屏幕操作函数,以及基本图形函数; 3. 通过对Turbo C进行图形程序设计的基本方法的学习,能绘制出简单的图形; 4. 熟悉并掌握DDA法在屏幕上画一条具有三个像素宽的直线段L1以及通用的中点画线算法。 通过DDA法及用的中点画线算法,了解图形系统初始化、图形系统关闭和图形模式的控制 ,并熟练运用图形坐标的设置,包括定点、读取光标以及图形颜色的设置。 1.3程序制作步骤(包括算法思想、算法流程图等) 1.自动搜索显示器类型和显示模式,初始化图形系统,通过printf、scanf语句控制线段 的端点坐标和画线颜色的自由输入; 2. DDAline:设直线之起点为(x1,y1),终点为(x2,y2),则斜率k为: 则有: .可通过计算由x方向的增量引起y的改变生成直线。由 (为直线上某步的初值)则 .也可通过计算由y方向的增量引起x的改变生成直线。由(为直线上某 步的初值)则: 3.Midpointline: .假定X坐标为的各像素点中,与直线最近点已确定为 (用实心小表示),那么下一个与直线最近的象素点只能是正右方的或右上方 两者之一。 . 再以M表示P1与P2的中点,即又设Q是理想直线与垂直线的交点 。显然有: .当M在Q的下方,则P2 离直线 近,应取为下一个象素点; .当M在Q的上方,则P1离直线 近,应取为下一个象素点。 .当M和Q重合,则P 1和P2离直线 一样近,两者均可取为下一个象素点 1.4主程序 1.4.1 DDA算法 #include "graphics.h" #include <stdlib.h> #include <stdio.h> #include <conio.h> #include <math.h> DDAline(int x1, int y1, int x2, int y2, int c) { float delta_x = 0; float delta_y = 0; float x = 0; float y = 0; int dx= 0; int dy = 0; int steps = 0; int k = 0; dx=x2-x1; dy=y2-y1; if (abs(dx)>abs(dy)) { steps=3*abs(dx); } else { steps=3*abs (dy); } delta_x=(float)dx / (float)steps; delta_y=(float)dy / (float)steps; x=float(x1); y=float(y1); for (k=1; k<=steps;k++) { putpixel(int(x+0.5), int(y+0.5), c); x+=delta_x; y+=delta_y; } return 0; } void main() { char t[100] = {0}; int x1 = 0; int y1 = 0; int x2 = 0; int y2 = 0; int c = 0; void dda_line(int x1,int y1,int x2,int y2,int c); int graphdriver=DETECT,graphmode; initgraph(&graphdriver,&graphmode,"D:\\TC"); /*初始化图形系统*/ printf("输入两端点坐标:\n"); scanf("<%d,%d>,<%d,%d>",&x1,&y1,&x2,&y2); printf("输入画线颜色:\n");

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值