• OpenGL编程学习笔记——交互与直线算法


    交互

    键盘交互(glutKeyboardFunc)

    例子:实现小方块的移动

    代码

    #include 
    
    int xd = 0, yd = 0;
    
    void myDisplay()
    {
    	int p1[] = { 10 + xd,10 + yd };
    	int p2[] = { 20 + xd,10 + yd };
    	int p3[] = { 20 + xd,0 + yd };
    	int p4[] = { 10 + xd,0 + yd };
    	glClear(GL_COLOR_BUFFER_BIT);
    	glColor3f(0.8, 0.5, 0.6);
    	glPointSize(5);
    	//glBegin(GL_POINTS);
    	//glBegin(GL_LINES);
    	//glBegin(GL_LINE_STRIP);
    	//glBegin(GL_LINE_LOOP);
    	//glBegin(GL_POLYGON);//多边形
    	//glBegin(GL_TRIANGLES);//三角形
    	glBegin(GL_QUADS);//四边形
    	glVertex2iv(p1);
    	glVertex2iv(p2);
    	glVertex2iv(p3);
    	glVertex2iv(p4);
    	glEnd();
    	glFlush();
    }
    
    void myKeyBorad(unsigned char key, int x, int y) 
    {
    	switch (key) 
    	{
    	case 'w': yd++; break;
    	case 's': yd--; break;
    	case 'a': xd--; break;
    	case 'd': xd++; break;
    	}
    	glutPostRedisplay();
    }
    
    void init()
    {
    	glClearColor(1.0, 1.0, 1.0, 0.0);
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();
    	gluOrtho2D(-20, 30, -20, 30);
    }
    
    int main(int argc, char* argv[])
    {
    	glutInit(&argc, argv);
    	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    	glutInitWindowPosition(300, 100);
    	glutInitWindowSize(600, 500);
    	glutCreateWindow("key interaction");
    
    	init();
    	glutDisplayFunc(myDisplay);
    	glutKeyboardFunc(myKeyBorad);//键盘交互
    	glutMainLoop();
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    鼠标交互(glutMouseFunc)

    例子:实现小方块的移动

    代码

    #include 
    
    GLint w = 600, h = 500;
    
    GLint xd = 0, yd = 0;
    
    void myDisplay()
    {
    	glClear(GL_COLOR_BUFFER_BIT);
    	glColor3f(0.87, 0.56, 0.4);
    	glPointSize(2);
    	//glBegin(GL_POINTS);
    	//glBegin(GL_LINES);
    	//glBegin(GL_LINE_STRIP);
    	//glBegin(GL_LINE_LOOP);
    	//glBegin(GL_TRIANGLES);//三角形
    	//glBegin(GL_QUADS);//四边形
    	glBegin(GL_POLYGON);//多边形
    	glVertex2i(10 + xd, 10 + yd);
    	glVertex2i(10 + xd,100 + yd);
    	glVertex2i(100 + xd,100 + yd);
    	glVertex2i(100 + xd,10 + yd);
    	glEnd();
    	glFlush();
    }
    
    void mouseMotion(GLint button, GLint state, GLint x, GLint y)
    {
    	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)//当鼠标左键按下去的时候
    	{
    		xd = x;//改变全局变量xd,改变矩形的位置
    		yd = h - y;//注意这里是h-y
    		glutPostRedisplay();
    	}
    }
    
    void myKeyBorad(unsigned char key, int x, int y)
    {
    	switch (key)
    	{
    	case 'w': yd++; break;
    	case 's': yd--; break;
    	case 'a': xd--; break;
    	case 'd': xd++; break;
    	}
    	glutPostRedisplay();
    }
    
    void init()
    {
    	glClearColor(1.0, 1.0, 1.0, 0.0);
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();
    	gluOrtho2D(0, w, 0, h);
    }
    
    int main(int argc, char* argv[])
    {
    	glutInit(&argc, argv);
    	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    	glutInitWindowPosition(300, 100);
    	glutInitWindowSize(w, h);
    	glutCreateWindow("Mouse Motion");
    
    	init();
    	glutDisplayFunc(myDisplay);
    	//glutKeyboardFunc(myKeyBorad);
    	glutMouseFunc(mouseMotion);
    	glutMainLoop();
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    直线算法

    DDA数值微分线段算法

    方法论

    1. 起始点 ( x 1 , y 1 ) (x_1,y_1) (x1,y1),终点 ( x n , y n ) (x_n,y_n) (xn,yn)
    2. Δ x = ∣ x n − x 1 ∣ , Δ y = ∣ y n − y 1 ∣ \Delta x=|x_n-x_1|,\Delta y=|y_n-y_1| Δx=xnx1,Δy=yny1
    3. 比较 Δ x \Delta x Δx Δ y \Delta y Δy的步长
    4. steps= Δ x \Delta x Δx Δ y \Delta y Δy的较大者
    5. s t e p X = Δ x s t e p s , s t e p Y = Δ y s t e p s stepX=\frac{\Delta x}{steps},stepY=\frac{\Delta y}{steps} stepX=stepsΔx,stepY=stepsΔy

    代码

    #include 
    #include
    
    GLint w = 600, h = 500;
    GLint xd = 0, yd = 0;
    
    void myDDA(GLfloat x1,GLfloat y1,GLfloat xn,GLfloat yn)
    {
    	float dx = fabs(xn - x1);//注意这里需要绝对值
    	float dy = fabs(yn - y1);//注意这里abs会报错
    	float steps;
    	if (dx > dy)
    		steps = dx;
    	else
    		steps = dy;
    	float stepX = dx / steps;
    	float stepY = dy / steps;
    	glBegin(GL_POINTS);
    	for (int i=0; i < (int)steps; i++) {
    		glVertex2f(x1, y1);
    		x1 += stepX;
    		y1 += stepY;
    	}
    }
    
    void myDisplay()
    {
    	glClear(GL_COLOR_BUFFER_BIT);
    	glColor3f(0.87, 0.56, 0.4);
    	glPointSize(1);
    	myDDA(1.5, 3.8, 189.8, 267.5);//调用myDDA
    	glEnd();
    	glFlush();
    }
    
    void init()
    {
    	glClearColor(1.0, 1.0, 1.0, 0.0);
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();
    	gluOrtho2D(-10, w, 0, h);
    }
    
    int main(int argc, char* argv[])
    {
    	glutInit(&argc, argv);
    	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    	glutInitWindowPosition(300, 100);
    	glutInitWindowSize(w, h);
    	glutCreateWindow("DDA application");
    
    	init();
    	glutDisplayFunc(myDisplay);
    	glutMainLoop();
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    效果

    在这里插入图片描述

    Bresenham直线算法

    方法论

    1. 输入起始点 ( x 1 , y 1 ) (x_1,y_1) (x1,y1),终点 ( x n , y n ) (x_n,y_n) (xn,yn)
    2. d x = x n − x 1 , d y = y n − y 1 dx=x_n-x_1, dy=y_n-y_1 dx=xnx1,dy=yny1
    3. 计算 2 d x 2dx 2dx 2 d y 2dy 2dy
    4. 计算 P 0 = 2 d y − d x P_0=2dy-dx P0=2dydx
    5. 循环
      如果 P k > 0 P_k\gt0 Pk>0,选上面点 ( x k + 1 , y k + 1 ) , P k + 1 = P k + 2 d y − 2 d x (x_k+1,y_k+1),P_{k+1}=P_k+2dy-2dx (xk+1,yk+1),Pk+1=Pk+2dy2dx
      如果 P k < 0 P_k\lt0 Pk<0,选下面点 ( x k + 1 , y k ) , P k + 1 = P k + 2 d y (x_k+1,y_k),P_{k+1}=P_k+2dy (xk+1,yk),Pk+1=Pk+2dy

    中点划线法

    方法论

    1. 输入起始点 ( x 1 , y 1 ) (x_1,y_1) (x1,y1),终点 ( x n , y n ) (x_n,y_n) (xn,yn)
    2. Δ x = ∣ x n − x 1 ∣ , Δ y = ∣ y n − y 1 ∣ \Delta x=|x_n-x_1|,\Delta y=|y_n-y_1| Δx=xnx1,Δy=yny1
    3. 计算 m = Δ x Δ y m=\frac{\Delta x}{\Delta y} m=ΔyΔx b = y 1 − m x 1 b=y_1-mx_1 b=y1mx1
    4. 计算 d = F ( x 1 , y 1 + 0.5 ) = y 1 + 0.5 − m x 1 − b d=F(x_1,y_1+0.5)=y_1+0.5-mx_1-b d=F(x1,y1+0.5)=y1+0.5mx1b
    5. 循环
      如果 d > 0 d\gt0 d>0 x + + , ( x , y ) , d + = − m x++,(x,y),d+=-m x++,(x,y),d+=m
      如果 d < 0 d\lt0 d<0 x + + , y + + , ( x , y ) , d + = 1 − m x++,y++,(x,y),d+=1-m x++,y++,(x,y),d+=1m
  • 相关阅读:
    Salesforce LWC学习(四十七) 标准页面更新以后自定义页面如何捕捉?
    java基于微信小程序的加油站加油服务系统uni-app
    多叉树构建和排序
    软件建模与分析
    Day10:基础入门-HTTP数据包&Postman构造&请求方法&请求头修改&状态码判断
    crypto:篱笆墙的影子
    请问这个用python代码尽量不要用函数要怎么写
    深入了解Java 8 新特性:Stream流的实践应用(二)
    马来酰亚胺/碳碳双键表面/硫硅烷基团/金属硫蛋白修饰二氧化硅微球的性能与制备
    Java 将 XML 转换为属性 – 从 XML 文件中读取属性
  • 原文地址:https://blog.csdn.net/weixin_51128278/article/details/126713416