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