LOOP 细分四面体(编辑中)

本文介绍了一个基于OpenGL的Loop细分算法实现,通过动态分配内存的方式构建复杂的三维几何模型,并演示了如何利用细分来增加模型细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通过之前的matlab实现了loop细分仅仅用了一点点代码,我收到了极大的启发,打算在这学期结束之前一定搞定LOOP细分,哦也!

#include <windows.h>  
#include<GL/GLUT.H>    
#include <math.h>        
#include <gl/GL.h>        
#include<iostream> 
#include <stdlib.h>

template <class T>
int getArrayLen(T& array)
{//使用模板定义一 个函数getArrayLen,该函数将返回数组array的长度
	return (sizeof(array) / sizeof(array[0]));
}


#define pi 3.1415927f;  
float a = 0.5f;
float u = sqrtf(2.0) / 3;
float v = float(1) / 3;
float t = sqrtf(6.0) / 3;

static const GLfloat vertex_list[][3] = {
	0.0f, 0.0f, a,
	-2 * a*u, 0, -a*v,
	a*u, a*t, -a*v,
	a*u, -a*t, -a*v
};

static const GLint index_list[][3] = {
	0, 1, 2,
	0, 2, 3,
	0, 1, 3,
	1, 2, 3,
};

int newIndexOfVertices;
int ***edgeVertice;
float newVertices[100][3];
int newFaces[100][3];

int jishu;

int nVertices = getArrayLen(vertex_list);
int nFaces = getArrayLen(index_list);

void idd()
{


	for (int i = 0; i < nVertices; i++)
		for (int j = 0; j < 3; j++)
		{
			newVertices[i][j] = vertex_list[i][j];
		}


	//动态定义三维数组:  
	edgeVertice = new int**[nVertices];
	for (int i = 0; i < nVertices; i++)
	{
		edgeVertice[i] = new int*[nVertices];
	}

	for (int i = 0; i <nVertices; i++)
		for (int j = 0; j < nVertices; j++)
			edgeVertice[i][j] = new int[3];
	//输入三维数组值:  

	for (int i = 0; i < nVertices; i++)
		for (int j = 0; j < nVertices; j++)
			for (int k = 0; k < 3; k++)
				edgeVertice[i][j][k] = 0;

	newIndexOfVertices = nVertices;
}





int addEdgeVertice(int v1Index,int v2Index,int v3Index)
{
	if (v1Index > v2Index)
	{
		int vTmp = v1Index;
		v1Index = v2Index;
		v2Index = vTmp;
	}

	if (edgeVertice[v1Index][v2Index][0] == 0)
	{
		newIndexOfVertices = newIndexOfVertices + 1;
		edgeVertice[v1Index][v2Index][0] = newIndexOfVertices-1;
		edgeVertice[v1Index][v2Index][1] = v3Index;
	}
	else
	{
        edgeVertice[v1Index][v2Index][2] = v3Index;
	}
		
	int vNIndex = edgeVertice[v1Index][v2Index][0];
	return vNIndex;
}



void myDisplay(void){
	glClear(GL_COLOR_BUFFER_BIT);
	glRotatef(45, 1, 1, 1);
	glFrontFace(GL_CCW);

	for (int i = 0; i < 4; ++i)      // 有四个面,循环六次  
	{
		glBegin(GL_LINE_LOOP);
		for (int j = 0; j < 3; ++j)     // 每个面有四个顶点,循环四次  
			glVertex3fv(vertex_list[index_list[i][j]]);
		glEnd();
	}

	idd();

	jishu = 0;

	for (int i = 0; i < nFaces; i++)
	{
		int vaIndex = index_list[i][0];
		int vbIndex = index_list[i][1];
		int vcIndex = index_list[i][2];

		int vpIndex = addEdgeVertice(vaIndex, vbIndex, vcIndex);
		int vqIndex = addEdgeVertice(vbIndex, vcIndex, vaIndex);
		int vrIndex = addEdgeVertice(vaIndex, vcIndex, vbIndex);
	
		newFaces[jishu][0] = vaIndex; newFaces[jishu][1] = vpIndex; newFaces[jishu][2] = vrIndex; jishu++;
		newFaces[jishu][0] = vpIndex; newFaces[jishu][1] = vbIndex; newFaces[jishu][2] = vqIndex; jishu++;
		newFaces[jishu][0] = vrIndex; newFaces[jishu][1] = vqIndex; newFaces[jishu][2] = vcIndex; jishu++;
		newFaces[jishu][0] = vrIndex; newFaces[jishu][1] = vpIndex; newFaces[jishu][2] = vqIndex; jishu++;
	}
	

	int vNOpposite2Index;
	int vNOpposite1Index;
	for (int v1 = 0; v1 < nVertices - 1; v1++)
		for (int v2 = 0; v2 < nVertices; v2++)
		{

			int vNIndex = edgeVertice[v1][v2][0];
			if (vNIndex != 0)
			{
				vNOpposite1Index = edgeVertice[v1][v2][1];
				vNOpposite2Index = edgeVertice[v1][v2][2];
			}

			if (vNOpposite2Index == 0)
			{
				for (int t = 0; t < 3; t++)
				{
					newVertices[vNIndex][t] = vertex_list[v1][t] + vertex_list[v2][t];
				}
			}
			else
			{
				for (int t = 0; t < 3; t++)
				{
					newVertices[vNIndex][t] = 3 / 8 * (vertex_list[v1][t] + vertex_list[v2][t]) + 1 / 8 * (vertex_list[vNOpposite1Index][t] + vertex_list[vNOpposite2Index][t]);
				}
			}

		}
	
	



	

	glFlush();
}


int main(int argc, char *argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(400, 400);
	glutCreateWindow("opengl1");
	glutDisplayFunc(&myDisplay);
	glutMainLoop();
	return 0;
}  

拜拜

#include <windows.h>    
#include<GL/GLUT.H>      
#include <math.h>          
#include <gl/GL.h>          
#include<iostream>   
#include <stdlib.h>  

template <class T>
int getArrayLen(T& array)
{//使用模板定义一 个函数getArrayLen,该函数将返回数组array的长度  
	return (sizeof(array) / sizeof(array[0]));
}


#define pi 3.1415927f;    
float a = 0.5f;
float u = sqrtf(2.0) / 3;
float v = float(1) / 3;
float t = sqrtf(6.0) / 3;

static const GLfloat vertex_list[][3] = {
	0.0f, 0.0f, a,
	-2 * a*u, 0, -a*v,
	a*u, a*t, -a*v,
	a*u, -a*t, -a*v
};

static const GLint index_list[][3] = {
	0, 1, 2,
	0, 2, 3,
	0, 1, 3,
	1, 2, 3,
};

int newIndexOfVertices;
int ***edgeVertice;
float newVertices[100][3];
int newFaces[100][3];

int jishu;

int nVertices = getArrayLen(vertex_list);
int nFaces = getArrayLen(index_list);

void idd()
{


	for (int i = 0; i < nVertices; i++)
		for (int j = 0; j < 3; j++)
		{
			newVertices[i][j] = vertex_list[i][j];
		}


	//动态定义三维数组:    
	edgeVertice = new int**[nVertices];
	for (int i = 0; i < nVertices; i++)
	{
		edgeVertice[i] = new int*[nVertices];
	}

	for (int i = 0; i <nVertices; i++)
		for (int j = 0; j < nVertices; j++)
			edgeVertice[i][j] = new int[3];
	//输入三维数组值:    

	for (int i = 0; i < nVertices; i++)
		for (int j = 0; j < nVertices; j++)
			for (int k = 0; k < 3; k++)
				edgeVertice[i][j][k] = 0;

	newIndexOfVertices = nVertices;
}





int addEdgeVertice(int v1Index, int v2Index, int v3Index)
{
	if (v1Index > v2Index)
	{
		int vTmp = v1Index;
		v1Index = v2Index;
		v2Index = vTmp;
	}

	if (edgeVertice[v1Index][v2Index][0] == 0)
	{
		newIndexOfVertices = newIndexOfVertices + 1;
		edgeVertice[v1Index][v2Index][0] = newIndexOfVertices - 1;
		edgeVertice[v1Index][v2Index][1] = v3Index;
	}
	else
	{
		edgeVertice[v1Index][v2Index][2] = v3Index;
	}

	int vNIndex = edgeVertice[v1Index][v2Index][0];
	return vNIndex;
}



void myDisplay(void) {
	glClear(GL_COLOR_BUFFER_BIT);
	glRotatef(45, 1, 1, 1);
	glFrontFace(GL_CCW);

	for (int i = 0; i < 4; ++i)      // 有四个面,循环六次    
	{
		glBegin(GL_LINE_LOOP);
		for (int j = 0; j < 3; ++j)     // 每个面有四个顶点,循环四次    
			glVertex3fv(vertex_list[index_list[i][j]]);
		glEnd();
	}

	idd();

	jishu = 0;

	for (int i = 0; i < nFaces; i++)
	{
		int vaIndex = index_list[i][0];
		int vbIndex = index_list[i][1];
		int vcIndex = index_list[i][2];

		int vpIndex = addEdgeVertice(vaIndex, vbIndex, vcIndex);
		int vqIndex = addEdgeVertice(vbIndex, vcIndex, vaIndex);
		int vrIndex = addEdgeVertice(vaIndex, vcIndex, vbIndex);

		newFaces[jishu][0] = vaIndex; newFaces[jishu][1] = vpIndex; newFaces[jishu][2] = vrIndex; jishu++;
		newFaces[jishu][0] = vpIndex; newFaces[jishu][1] = vbIndex; newFaces[jishu][2] = vqIndex; jishu++;
		newFaces[jishu][0] = vrIndex; newFaces[jishu][1] = vqIndex; newFaces[jishu][2] = vcIndex; jishu++;
		newFaces[jishu][0] = vrIndex; newFaces[jishu][1] = vpIndex; newFaces[jishu][2] = vqIndex; jishu++;
	}


	int vNOpposite2Index;
	int vNOpposite1Index;
	for (int v1 = 0; v1 < nVertices - 1; v1++)
		for (int v2 = v1; v2 < nVertices; v2++)
		{

			int vNIndex = edgeVertice[v1][v2][0];
			
				if (vNIndex != 0)
				{
				 {
					vNOpposite1Index = edgeVertice[v1][v2][1];
					vNOpposite2Index = edgeVertice[v1][v2][2];
			 	 }

				if (vNOpposite2Index == 0)
				 {
					for (int t = 0; t < 3; t++)
					{
						newVertices[vNIndex][t] = 1 / 2 * (vertex_list[v1][t] + vertex_list[v2][t]);
					}
				 }
				else
				 {
					for (int t = 0; t < 3; t++)
					{
						newVertices[vNIndex][t] = 3 / 8 * (vertex_list[v1][t] + vertex_list[v2][t]) + 1 / 8 * (vertex_list[vNOpposite1Index][t] + vertex_list[vNOpposite2Index][t]);
					}
				 }
			    }
		}







	glFlush();
}


int main(int argc, char *argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(400, 400);
	glutCreateWindow("opengl1");
	glutDisplayFunc(&myDisplay);
	glutMainLoop();
	return 0;
}  


#include <windows.h>      
#include<GL/GLUT.H>        
#include <math.h>            
#include <gl/GL.h>            
#include<iostream>     
#include <stdlib.h>    

template <class T>
int getArrayLen(T& array)
{//使用模板定义一 个函数getArrayLen,该函数将返回数组array的长度    
	return (sizeof(array) / sizeof(array[0]));
}


#define pi 3.1415927f;      
float a = 0.5f;
float u = sqrtf(2.0) / 3;
float v = float(1) / 3;
float t = sqrtf(6.0) / 3;

float M_PI = 3.14159265f;


static float c = M_PI / 180.0f; //弧度和角度转换参数    
static int du = 90, oldmy = -1, oldmx = -1; //du是视点绕y轴的角度,opengl里默认y轴是上方向    
static float r = 3.1f, h = 0.0f; //r是视点绕y轴的半径,h是视点高度即在y轴上的坐标    
float zoom = 1.0f;


static const GLfloat vertex_list[][3] = {
	0.0f, 0.0f, a,
	-2 * a*u, 0, -a*v,
	a*u, a*t, -a*v,
	a*u, -a*t, -a*v
};

static const GLint index_list[][3] = {
	0, 1, 2,
	0, 2, 3,
	0, 1, 3,
	1, 2, 3,
};

int newIndexOfVertices;
int ***edgeVertice;
float newVertices[100][3];
int newFaces[100][3];

int jishu;

int nVertices = getArrayLen(vertex_list);
int nFaces = getArrayLen(index_list);

void idd()
{


	for (int i = 0; i < nVertices; i++)
		for (int j = 0; j < 3; j++)
		{
			newVertices[i][j] = vertex_list[i][j];
		}


	//动态定义三维数组:      
	edgeVertice = new int**[nVertices];
	for (int i = 0; i < nVertices; i++)
	{
		edgeVertice[i] = new int*[nVertices];
	}

	for (int i = 0; i <nVertices; i++)
		for (int j = 0; j < nVertices; j++)
			edgeVertice[i][j] = new int[3];
	//输入三维数组值:      

	for (int i = 0; i < nVertices; i++)
		for (int j = 0; j < nVertices; j++)
			for (int k = 0; k < 3; k++)
				edgeVertice[i][j][k] = 0;

	newIndexOfVertices = nVertices;
}





int addEdgeVertice(int v1Index, int v2Index, int v3Index)
{
	if (v1Index > v2Index)
	{
		int vTmp = v1Index;
		v1Index = v2Index;
		v2Index = vTmp;
	}

	if (edgeVertice[v1Index][v2Index][0] == 0)
	{
		newIndexOfVertices = newIndexOfVertices + 1;
		edgeVertice[v1Index][v2Index][0] = newIndexOfVertices - 1;
		edgeVertice[v1Index][v2Index][1] = v3Index;
	}
	else
	{
		edgeVertice[v1Index][v2Index][2] = v3Index;
	}

	int vNIndex = edgeVertice[v1Index][v2Index][0];
	return vNIndex;
}



void myDisplay(void) {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glEnable(GL_DEPTH_TEST);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(80.0f, 1.0f, 1.0f, 1000.0f);
	glMatrixMode(GL_MODELVIEW);


	//printf("At:%.2f %.2f %.2f\n",r*cos(c*du),h,r*sin(c*du)); //这就是视点的坐标    
	glLoadIdentity();
	gluLookAt(r*cos(c*du)*cos(c*h)*zoom, r*sin(c*h)*zoom, r*sin(c*du)*cos(c*h)*zoom, 0, 0, 0, 0, 1, 0); //从视点看远点,y轴方向(0,1,0)是上方向    
	glFrontFace(GL_CCW);

	//for (int i = 0; i < 4; ++i)      // 有四个面,循环六次      
	//{
	//	glBegin(GL_LINE_LOOP);
	//	for (int j = 0; j < 3; ++j)     // 每个面有四个顶点,循环四次      
	//		glVertex3fv(vertex_list[index_list[i][j]]);
	//	glEnd();
	//}

	idd();

	jishu = 0;

	for (int i = 0; i < nFaces; i++)
	{
		int vaIndex = index_list[i][0];
		int vbIndex = index_list[i][1];
		int vcIndex = index_list[i][2];

		int vpIndex = addEdgeVertice(vaIndex, vbIndex, vcIndex);
		int vqIndex = addEdgeVertice(vbIndex, vcIndex, vaIndex);
		int vrIndex = addEdgeVertice(vaIndex, vcIndex, vbIndex);

		newFaces[jishu][0] = vaIndex; newFaces[jishu][1] = vpIndex; newFaces[jishu][2] = vrIndex; jishu++;
		newFaces[jishu][0] = vpIndex; newFaces[jishu][1] = vbIndex; newFaces[jishu][2] = vqIndex; jishu++;
		newFaces[jishu][0] = vrIndex; newFaces[jishu][1] = vqIndex; newFaces[jishu][2] = vcIndex; jishu++;
		newFaces[jishu][0] = vrIndex; newFaces[jishu][1] = vpIndex; newFaces[jishu][2] = vqIndex; jishu++;
	}


	int vNOpposite2Index;
	int vNOpposite1Index;
	for (int v1 = 0; v1 < nVertices - 1; v1++)
		for (int v2 = v1; v2 < nVertices; v2++)
		{

			int vNIndex = edgeVertice[v1][v2][0];

			if (vNIndex != 0)
			{
				{
					vNOpposite1Index = edgeVertice[v1][v2][1];
					vNOpposite2Index = edgeVertice[v1][v2][2];
				}

				if (vNOpposite2Index == 0)
				{
					for (int t = 0; t < 3; t++)
					{
						newVertices[vNIndex][t] = 1 / 2 * (vertex_list[v1][t] + vertex_list[v2][t]);
					}
				}
				else
				{
					for (int t = 0; t < 3; t++)
					{
						newVertices[vNIndex][t] = 3 / 8 * (vertex_list[v1][t] + vertex_list[v2][t]) + 1 / 8 * (vertex_list[vNOpposite1Index][t] + vertex_list[vNOpposite2Index][t]);
					}
				}
			}
		}

	for (int v = 0; v < nVertices; v++)
	{

		
		int **p = new int*[nVertices];
		for (int i = 0; i<nVertices; i++)
		{
			p[i] = new int[Column];
		}


		for (int t = 0; t < 3; t++)
		{
			newVertices[v][t] = vertex_list[v][t] ;
		}
	}

	for (int i = 0; i < 16; ++i)      // 有四个面,循环六次      
	{
		glBegin(GL_LINE_LOOP);
		for (int j = 0; j < 3; ++j)     // 每个面有四个顶点,循环四次      
			glVertex3fv(newVertices[newFaces[i][j]]);
		glEnd();
	}





	glFlush();
	glutSwapBuffers();
}

void Mouse(int button, int state, int x, int y) //处理鼠标点击    
{
	if (state == GLUT_DOWN) //第一次鼠标按下时,记录鼠标在窗口中的初始坐标    
		oldmx = x, oldmy = y;


	if (state == GLUT_UP && button == GLUT_WHEEL_UP)
	{
		zoom = zoom + 0.2;
		if (zoom >= 2)zoom = 2;

		//glutPostRedisplay();  
	}
	if (state == GLUT_UP && button == GLUT_WHEEL_DOWN)
	{
		zoom = zoom - 0.2;
		if (zoom <= 0.6) zoom = 0.6;
		//glutPostRedisplay();  
	}
}

void onMouseMove(int x, int y) //处理鼠标拖动      
{
	//printf("%d\n",du);      
	du += x - oldmx; //鼠标在窗口x轴方向上的增量加到视点绕y轴的角度上,这样就左右转了      
	h += (y - oldmy); //鼠标在窗口y轴方向上的改变加到视点的y坐标上,就上下转了      
	if (h > 90)
	{
		h = 90;
	}
	else if (h < -90)
	{
		h = -90;
	}
	//if (h>1.0f) h = 1.0f; //视点y坐标作一些限制,不会使视点太奇怪      
	//else if (h<-1.0f) h = -1.0f;      
	oldmx = x, oldmy = y; //把此时的鼠标坐标作为旧值,为下一次计算增量做准备      
}



int main(int argc, char *argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(400, 400);
	glutCreateWindow("OpenGL");
	glutDisplayFunc(myDisplay);
	glutIdleFunc(myDisplay);  //设置不断调用显示函数    
	glutMouseFunc(Mouse);
	glutMotionFunc(onMouseMove);
	glutMainLoop();
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拉风小宇

请我喝个咖啡呗

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值