openGL画线算法,橡皮筋算法
程序员文章站
2022-07-04 15:00:53
...
计算机图形学里面的橡皮筋算法,具体解释已经包含在代码中,看代码应该就可以理解了
#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
上一篇: JS中浏览器兼容性问题