openGL画线算法,橡皮筋算法

计算机图形学里面的橡皮筋算法,具体解释已经包含在代码中,看代码应该就可以理解了

#include<gl/glut.h>
#include"datastruct.h"                    //导入头文件

static const  int screenwidth = 1000;    //自定义窗口宽度
static const int screenheight = 1000;     //自定义窗口高度
vector<point> p; //多边形点集向量
vector<polygon> s; //多边形类向量,用来保存已经画完的多边形
int move_x,move_y; //鼠标当前坐标值,在鼠标移动动态画线时使用
bool select = false; //多边形封闭状态判断变量,当为true时即按下鼠标右键,将多边形封闭
bool judge = false;
float red=1.0, green=0.0, blue=0.0;
int lineWidth=1;   //使用此来改变线段的样式
GLuint Line;

void init()
{
	glClearColor(1.0,1.0,1.0,0.0);              // glClearColor 的作用是,指定刷新颜色缓冲区时所用的颜色
	glMatrixMode(GL_PROJECTION);               //https://blog.csdn.net/caoshangpa/article/details/80266028
	gluOrtho2D(0.0,screenwidth,0.0,screenheight);         //对应的模型坐标范围
}
void lineSegment()
{
	glClear(GL_COLOR_BUFFER_BIT);    //清除颜色缓冲区的作用是,防止缓冲区中原有的颜色信息影响本次绘图
	glColor3f(red,green,blue);   //通过改变red, green,blue设定颜色,既是线段颜色也是填充色
	int num=0;//两个循环控制变量,在下面的向量循环和数组循环中将被多次调用。
	if(judge){
		if(!p.empty()) 
		{
			//Line = glGenLists(1);
			//glNewList(Line, GL_COMPILE);
			//	int i = p.size() - 1; //将确定的最后一个点与当前鼠标所在位置连线,即动态画线
			glBegin(GL_LINES);
			glVertex2i(p[num].x, p[num].y);    //将鼠标点击的左边点与鼠标当前点画出
			glVertex2i(move_x, move_y);
			glEnd();		 
		}
	}
	glFlush();
}
void myMouse(int button, int state ,int x, int y) //鼠标点击事件响应函数
{
	if(state == GLUT_DOWN && button == GLUT_LEFT_BUTTON)//当鼠标左键被点击
	{
		int num = p.size();
		if(!p.empty()){               //将栈里面的vector元素全部弹出,目的使画第二条线的时候将第一条直线删除
			for(int i = 0;i<num;i++){
				p.pop_back();
			}
		}
		point v;   //申请一个点类变量,点类为自定义类,在zl.h中定义
		v.x = x;   //将点击处的点坐标,即x和y的值存入v中
		v.y = screenheight - y;    
		p.push_back(v);    //将点信息存入多边形点集向量p中
		glutPostRedisplay();   //重绘窗口
	}

	if(state == GLUT_UP && button == GLUT_LEFT_BUTTON) //判断鼠标是不是松开,如如果鼠标松开则下一次点击鼠标左键的时候不会将线段连接
	{
		judge = false;
	}
}
void myMotionFunc(int x, int y) //鼠标移动事件响应函数
{
	move_x = x;          //保存当前鼠标所在的坐标的值
	move_y = screenheight - y;
	judge = true;            //对按下的按键进行判断如果松开鼠标并且进行移动则将线画出来
	glutPostRedisplay();
}

void processSpqcialKeys(int key, int x, int y){       //按下按键改变线条的颜色
	if (key == 27) 
		exit(0);
	switch (key) 
	{
	case GLUT_KEY_F1:              //当点击鼠标上F1键的时候改变线段的颜色
		red = 0.5;
		green = 0.5;
		blue = 0.0;
		break;
	case GLUT_KEY_F2:
		red = 0.0;
		green = 1.0;
		blue = 0.0;
		break;
	case GLUT_KEY_F3:
		red = 0.0;
		green = 0.0;
		blue = 1.0;
		break;
	case GLUT_KEY_UP:             //按键盘上的向上的方向键则将线段调粗
		lineWidth = lineWidth+2;
		glLineWidth(lineWidth);
		break;
	case GLUT_KEY_DOWN:  //按键盘上的向上的方向键则将线段调细
		lineWidth = lineWidth-2;
		glLineWidth(lineWidth);
		break;
	default:
		break;
	}
}

//此时注意按键的时候按住CTRL+a,此时a的ascall改变成1,z变成26其他的按此规律改变 
void processNormalKey(unsigned char key, int x, int y){   //使用组合键改变线段的颜色
	printf("shift:%d ",key);
	int mod = glutGetModifiers();
	if(mod == GLUT_ACTIVE_CTRL )   //按住CTRL+a 改变线段的颜色
	{
		if(key == 1)       //对应a
		{
			red = 1.0;
			green = 0.0;
			blue = 0.0;
		}
		if(key == 26)    //对应CTRL+z
		{
			red = 0.0;
			green = 1.0;
			blue = 0.0;
		}
		else if(key == 24)   //对应CTRL+x
		{
			red = 0.0;
			green = 0.0;
			blue = 1.0;
		}
		else
		{
			red = 1.0;
		}

	}
	else if(mod == GLUT_ACTIVE_SHIFT){    //按住shift + a时,将实线换成虚线,并且对应不同的格式
		if(key == 65)
		{
			glEnable(GL_LINE_STIPPLE);
			glLineStipple(2, 0x4444);  
			//printf("画线ok");   //对应a
		}
		else if(key == 90)    //对应z
		{
			glEnable(GL_LINE_STIPPLE);
			glLineStipple(2, 0xffcc);
			//printf("画线ok2");
		}
		else if(key == 88)   //对应x  将虚线换成实线
		{
			//Line = glGenLists(1);
			//glNewList(Line, GL_COMPILE);
			glDisable(GL_LINE_STIPPLE);           //此时将虚线的格式取消则回到原来的实线模式
			//glEnable(GL_LINES);
			//glTranslatef(-50.0, 20.0, 0.0);
			//printf("画线ok3");
		}
	}
}

int main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowPosition(50,100);
	glutInitWindowSize(screenwidth,screenheight);
	glutCreateWindow("橡皮筋算法");
	init();
	glutMouseFunc(myMouse); //鼠标点击消息监控,即监控鼠标是否被点击,若被点击就调用myMouse函数
	glutDisplayFunc(lineSegment);//1.  窗口内容绘制2.   窗口大小改变3.   窗口重绘  会重绘窗口
	glutMotionFunc(myMotionFunc); //鼠标移动消息监控,即监控鼠标是否移动,若移动就调用myPassiveMotion函数
	glutSpecialFunc(processSpqcialKeys);         //改变按下按键改变按键的颜色,以及线条的粗细
	glutKeyboardFunc(processNormalKey);       //当有组合键按下时改变线段的颜色
	glutMainLoop();
	return 0;
}

头文件

#ifndef DATA_H_         //if not define-如果没有定义头文件,就编译一下,若头文件已经存在就不再重复编译  
#define DATA_H_
#include<vector>
using namespace std;
class point //点类,存储了一个点的两坐标值
{
public:
	int x;
	int y;
};
class polygon             //多边形类,存了一个多边形
{
public:
	vector<point> p;                  //多边形的顶点
};
#endif
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值