OpenGL切角算法

考虑了很长时间的割圆术的算法,代码实现中遇到了些问题,主要的问题是不知道细分之后的点的坐标。后来将其抽象为对每一个角进行细分,一共细分四次成圆。不过细分的参数不太容易确定,代码如下

m是细分次数,weightValue是角起点的权重,即此值越大越靠近P1,P2。

 

#include "gl/glut.h"
#include "windows.h"
#include "math.h"
int m = -1;//divided cout
GLfloat weightValue = 0.29;//point weight value
//Control line
GLfloat v[3][2] = {-3.8,-3.8,3.8,3.8,-3.8,3.8 };//p1,p2,q
/*GLfloat v1[3][2] = {-1.2,2.0,1.4,1.7,0.0,-0.2};
GLfloat v2[3][2] = {0.0,-0.2,0.0,0.7,1.4,1.7};
GLfloat v3[3][2] = {1.4,1.7,-2.2,1.0,0.0,-0.2};
GLfloat v4[3][2] = {0.0,-0.7,-1.2,2.0,-2.2,-1.0};
*///divided line
void line(GLfloat* p1,GLfloat* p2)
{
	glBegin(GL_LINES);
	{
		glColor3f(1.0 ,0.0 ,0.0);
		glVertex2fv(p1);
		glVertex2fv(p2);
	}
	glEnd();
	//glFlush();
	
}
//original line
void OriLine(GLfloat *a,GLfloat* b, GLfloat* c)
{
	glColor3f(0.0 ,1.0 ,0.0);
	glBegin(GL_LINES);
	{
		glVertex2fv(a);
		glVertex2fv(c);
		glVertex2fv(c);
		glVertex2fv(b);
	}
	glEnd();
}
void chaikin(GLfloat * p1,GLfloat * p2,GLfloat * q,int m)
{
	GLfloat q1[2];
	GLfloat q2[2];
	GLfloat p3[2];
	GLfloat p4[2];
	
		for (int i = 0;i<2;i++)
		{
			q1[i] = (weightValue)*p1[i]+(1-weightValue)*q[i];
			p3[i] = (1-weightValue)*p1[i]+(weightValue)*q[i];
			q2[i] = (weightValue)*p2[i]+(1-weightValue)*q[i];
			p4[i] = (1-weightValue)*p2[i]+(weightValue)*q[i];
		}
	/*	for (int i = 0;i<2;i++)
		{
			q1[i] = (0.33)*p1[i]+(0.66)*q[i];
			p3[i] = (0.66)*p1[i]+(0.33)*q[i];
			q2[i] = (0.33)*p2[i]+(0.66)*q[i];
			p4[i] = (0.66)*p2[i]+(0.33)*q[i];
		}*/
		if (m>0)
	{
		
		chaikin(p3,q2,q1,m-1);
		chaikin(q1,p4,q2,m-1);
		
	}
	else
	{
		OriLine(p1,p2,q);
		line(q1,q2);
	}

}

void idle()
{
	
	if (m<7)
	{
		Sleep(1000);
		glutPostRedisplay();
		m++;
	}
	
}
void display()
{
	glClear(GL_COLOR_BUFFER_BIT);
	//OriLine(v[0],v[1],v[2]);
	chaikin(v[0],v[1],v[2],m);
	//OriLine(v1[0],v1[1],v1[2]);
	//chaikin(v1[0],v1[1],v1[2],m);
	//OriLine(v2[0],v2[1],v2[2]);
	//chaikin(v2[0],v2[1],v2[2],m);
	//OriLine(v3[0],v3[1],v3[2]);
	//chaikin(v3[0],v3[1],v3[2],m);
	//OriLine(v4[0],v4[1],v4[2]);
	//chaikin(v4[0],v4[1],v4[2],m);
	glFlush();
}
void init()
{
	
	glClearColor(0.0 , 0.0 ,0.0 , 0.0);
	glColor3f(1.0 ,1.0 ,1.0);
	
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(-4.0 ,4.0 ,-4.0 ,4.0);

}
void reshape(GLsizei w,GLsizei h)
{
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(-1.5 ,(GLfloat)(1.5/w) ,-1.5 ,(GLfloat)(1.5/h));
	glutPostRedisplay();
}
void main(int argc,char** argv)
{
	glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
	glutInitWindowSize(500,500);
	glutInitWindowPosition(100,200);
	glutCreateWindow("chaikin");
	glutDisplayFunc(display);
	glutIdleFunc(idle);
	//glutReshapeFunc(reshape);
	init();
	glutMainLoop();
}


这里的P1,P2是角的两个起点,即角P1QP2。

 

经过6次细分最终结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值