以等边三角形实现迭代次数在6次以内的kock雪花曲线并用键盘交互控制迭代次数

https://blog.csdn.net/derbi123123/article/details/105397176中详细说明了kock曲线的原理并以直线段实现迭代次数在6次以内的kock曲线并用键盘交互控制迭代次数

代码:

功能:按a增加迭代次数,按d减少迭代次数。
迭代六次(按六次a)效果:
在这里插入图片描述

#include <GL/freeglut.h>
#include <math.h>
#include <vector>
#define max_iteration_num 6//最多迭代六次
using namespace std;

struct Vertex{
	GLfloat x,y;
};
vector<Vertex> V[3][max_iteration_num+1];//分别记录3条边各自6次迭代的数据(0、1、2、3、4、5、6)
int iteration_num=0;//记录迭代次数
GLfloat width=800.0,height=800.0;

//用户初始化函数
void myinit(void)
{
	//设置清除屏幕的颜色
	glClearColor(0.0f,0.0f,0.0f,0.0f);

	Vertex Start[3],End[3];//初始元(三角形)的三个端点(每条边两个,有重合的)
	Start[0].x=400.0;
	Start[0].y=800.0;
	End[0].x=(800.0-400.0*sqrt(3.0))/2;
	End[0].y=200.0;
	Start[1].x=End[0].x;
	Start[1].y=End[0].y;
	End[1].x=400+200*sqrt(3.0);
	End[1].y=200;
	Start[2].x=End[1].x;
	Start[2].y=End[1].y;
	End[2].x=Start[0].x;
	End[2].y=Start[0].y;
	//第零次迭代(没迭代)
	for(int i=0;i<3;i++){
		V[i][0].push_back(Start[i]);
		V[i][0].push_back(End[i]);
	}
	
}

//窗口大小变化时的回调函数
void myReshape(GLsizei w, GLsizei h)
{
	//设定视区
    glViewport(0, 0, w, h);

	//设定透视方式
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
	gluOrtho2D(0.0,800.0,0.0,800.0);
}
//计算当前迭代次数下的各顶点坐标
void compute()
{
	static int tmp=0;//记录上次绘制时迭代次数
	int flag=0;//记录迭代次数是否被更新过
	if(tmp<iteration_num){
		int len=V[0][iteration_num-1].size();
		for(int j=0;j<3;j++){
			for(int i=0;i<len-1;i++){
				V[j][iteration_num].push_back(V[j][iteration_num-1][i]);
				Vertex tmp;
				tmp.x=V[j][iteration_num-1][i].x+(V[j][iteration_num-1][i+1].x-V[j][iteration_num-1][i].x)/3;
				tmp.y=V[j][iteration_num-1][i].y+(V[j][iteration_num-1][i+1].y-V[j][iteration_num-1][i].y)/3;
				V[j][iteration_num].push_back(tmp);
				tmp.x=(V[j][iteration_num-1][i].x+V[j][iteration_num-1][i+1].x)/2-(V[j][iteration_num-1][i].y-V[j][iteration_num-1][i+1].y)*sqrt(3.0)/6;
				tmp.y=(V[j][iteration_num-1][i].y+V[j][iteration_num-1][i+1].y)/2-(V[j][iteration_num-1][i+1].x-V[j][iteration_num-1][i].x)*sqrt(3.0)/6;
				V[j][iteration_num].push_back(tmp);
				tmp.x=V[j][iteration_num-1][i].x+2*(V[j][iteration_num-1][i+1].x-V[j][iteration_num-1][i].x)/3;
				tmp.y=V[j][iteration_num-1][i].y+2*(V[j][iteration_num-1][i+1].y-V[j][iteration_num-1][i].y)/3;
				V[j][iteration_num].push_back(tmp);
			}
			V[j][iteration_num].push_back(V[j][iteration_num-1][len-1]);
		}
		tmp=iteration_num;
	}
}
//每桢OpenGL都会调用这个函数,用户应该把显示代码放在这个函数中
void display(void)
{
	//清除屏幕缓冲  
    glClear(GL_COLOR_BUFFER_BIT);
	compute();
	//开始绘制
	glColor3f(1.0,1.0,1.0);
	for(int j=0;j<3;j++){
		glBegin(GL_LINE_STRIP);
		for(int i=0;i<V[j][iteration_num].size();i++){
			glVertex2f(V[j][iteration_num][i].x,V[j][iteration_num][i].y);
		}
		glEnd();
	}
	//交换前后缓冲区
	glutSwapBuffers();
}
void processNormalKeys(unsigned char key,int x,int y)
{
	switch(key) {
		case 97:	//按a增加迭代次数
			if(iteration_num<max_iteration_num){
				iteration_num++;
			}
			break;
		case 100:	//按d减少迭代次数
			if(iteration_num>0){
				iteration_num--;
			}
			break;
		case 27:	//"esc"
			exit(0);
	}
	glutPostRedisplay();
}

//主函数
int main(int argc, char* argv[])
{
	glutInit(&argc, argv);
	//初始化OPENGL显示方式
	glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA);
	//设定OPENGL窗口位置和大小
	glutInitWindowSize (800, 800); 
	glutInitWindowPosition (100, 100);
	//打开窗口
	glutCreateWindow ("kock曲线");
	//调用初始化函数
    myinit();
	//设定窗口大小变化的回调函数
	glutReshapeFunc(myReshape);
	//设定键盘控制的回调函数
	glutKeyboardFunc(processNormalKeys);
	//开始OPENGL的循环
	glutDisplayFunc(display); 
	glutMainLoop();

	return 0;
}


  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值