C Sierpinsky金字塔递归算法

C Sierpinsky金字塔递归算法,c,opengl,glut,C,Opengl,Glut,我正在尝试实现一个Sierpinsky金字塔,它类似于一个Sierpinsky三角形,但是是3D的。 我有这个结构来包含关于金字塔的所有数据: typedef struct { GLfloat xUp; GLfloat yUp; GLfloat zUp; GLfloat base; GLfloat height; }pyramid; 然后我编写了一个计算三个子金字塔的函数: void findSubPyramids( pyramid pyr, pyram

我正在尝试实现一个Sierpinsky金字塔,它类似于一个Sierpinsky三角形,但是是3D的。
我有这个结构来包含关于金字塔的所有数据:

typedef struct
{
    GLfloat xUp;
    GLfloat yUp;
    GLfloat zUp;
    GLfloat base;
    GLfloat height;
}pyramid;
然后我编写了一个计算三个子金字塔的函数:

void findSubPyramids( pyramid pyr, pyramid subs[3])
{
    for(int i=0; i<3; i++)
    {
        subs[i].height=pyr.height/2.0;
        subs[i].base=pyr.base/2.0;
    }

    memcpy(subs,&pyr,3*sizeof(GLfloat));

    subs[1].yUp= pyr.yUp-pyr.height/2.0;
    subs[1].xUp= pyr.xUp+pyr.base/4.0;
    subs[1].zUp= pyr.zUp-pyr.base/4.0;

    subs[2].yUp= subs[1].yUp;
    subs[2].xUp= pyr.xUp-pyr.base/4.0;
    subs[2].zUp= subs[1].zUp;

}
void drawSierpinskyPyramid (pyramid pyr)
{
    assert(EQUAL(pyr.height, pyr.base));
    if(pyr.base > 4.0)
    {
        setRandomColor();
        pyramid subs[3];
        drawPyramid(pyr);
        findSubPyramids(pyr, subs);
        for(int i=0; i<3; i++)
        {
            drawSierpinskyPyramid(subs[i]);
        }
    }
}
void findsub棱锥体(棱锥体pyr,棱锥体sub[3])
{
对于(int i=0;i 4.0)
{
setRandomColor();
金字塔型潜艇[3];
牵引金字塔(pyr);
发现子金字塔(pyr、Sub);
对于(int i=0;i,请尝试一下:

// gcc -std=c99 main.c -lglut -lGL -lGLU

#include <GL/glut.h>
#include <math.h>
#include <stdlib.h>

typedef struct
{
    float x, y, z;
} Vec3f;

void glTriangle( Vec3f* v0, Vec3f* v1, Vec3f* v2 )
{
    glColor3ub( rand() % 255, rand() % 255, rand() % 255 );
    glVertex3fv( (GLfloat*)v0 );
    glVertex3fv( (GLfloat*)v1 );
    glVertex3fv( (GLfloat*)v2 );
}

// v0, v1, v2 = base, v3 = top
void glTetrahedron( Vec3f* v0, Vec3f* v1, Vec3f* v2, Vec3f* v3 )
{
    glTriangle( v0, v2, v1 );
    glTriangle( v0, v1, v3 );
    glTriangle( v1, v2, v3 );
    glTriangle( v2, v0, v3 );
}

Vec3f Lerp( Vec3f* v0, Vec3f* v1, float u )
{
    Vec3f ret = {
        v0->x + ( v1->x - v0->x ) * u,
        v0->y + ( v1->y - v0->y ) * u,
        v0->z + ( v1->z - v0->z ) * u,
    };
    return ret;
}

void glSierpinskiPyramid( Vec3f* v0, Vec3f* v1, Vec3f* v2, Vec3f* v3, unsigned int level )
{
    if( level == 0 )
    {
        glTetrahedron( v0, v1, v2, v3 );
        return;
    }

    // midpoints
    Vec3f m01 = Lerp( v0, v1, 0.5 );
    Vec3f m12 = Lerp( v1, v2, 0.5 );
    Vec3f m02 = Lerp( v0, v2, 0.5 );
    Vec3f m03 = Lerp( v0, v3, 0.5 );
    Vec3f m13 = Lerp( v1, v3, 0.5 );
    Vec3f m23 = Lerp( v2, v3, 0.5 );

    glSierpinskiPyramid( v0, &m01, &m02, &m03, level-1 );
    glSierpinskiPyramid( &m01, v1, &m12, &m13, level-1 );
    glSierpinskiPyramid( &m02, &m12, v2, &m23, level-1 );
    glSierpinskiPyramid( &m03, &m13, &m23, v3, level-1 );
}

void display()
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    double w = glutGet( GLUT_WINDOW_WIDTH );
    double h = glutGet( GLUT_WINDOW_HEIGHT );
    gluPerspective( 60, w / h, 0.1, 100 );

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    glTranslatef( 0, 0, -9 );

    srand(0);
    glPushMatrix();
    glScalef( 3, 3, 3 );

    static float angle = 0;
    angle += 1;
    glRotatef( angle/3, 0.2, 1, 0 );

    Vec3f v0 = { -1, -1 / sqrtf(3), -1 / sqrtf(6) };
    Vec3f v1 = {  1, -1 / sqrtf(3), -1 / sqrtf(6) };
    Vec3f v2 = {  0,  2 / sqrtf(3), -1 / sqrtf(6) };
    Vec3f v3 = {  0,             0,  3 / sqrtf(6) };
    glBegin( GL_TRIANGLES );
    glSierpinskiPyramid( &v0, &v1, &v2, &v3, 3 );
    glEnd();
    glPopMatrix();

    glutSwapBuffers();
}

void timer(int extra)
{
    glutPostRedisplay();
    glutTimerFunc(16, timer, 0);
}

int main( int argc, char **argv )
{
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
    glutInitWindowSize( 640, 480 );
    glutCreateWindow( "Sierpinski Pyramid" );
    glutDisplayFunc( display );
    glutTimerFunc(0, timer, 0);

    glEnable( GL_DEPTH_TEST );
    glEnable( GL_CULL_FACE );

    glutMainLoop();
    return 0;
}
//gcc-std=c99 main.c-lglut-lGL-lGLU
#包括
#包括
#包括
类型定义结构
{
浮动x,y,z;
}Vec3f;
void glTriangle(Vec3f*v0、Vec3f*v1、Vec3f*v2)
{
glColor3ub(rand()%255,rand()%255,rand()%255);
glVertex3fv((GLfloat*)v0);
glVertex3fv((GLfloat*)v1);
glVertex3fv((GLfloat*)v2);
}
//v0,v1,v2=基础,v3=顶部
四面体(Vec3f*v0,Vec3f*v1,Vec3f*v2,Vec3f*v3)
{
GLV(v0、v2、v1);
GLV(v0、v1、v3);
glTriangle(v1、v2、v3);
gl三角形(v2,v0,v3);
}
Vec3f Lerp(Vec3f*v0,Vec3f*v1,浮点数u)
{
Vec3f ret={
v0->x+(v1->x-v0->x)*u,
v0->y+(v1->y-v0->y)*u,
v0->z+(v1->z-v0->z)*u,
};
返回ret;
}
无效glSierpinskiPyramid(Vec3f*v0,Vec3f*v1,Vec3f*v2,Vec3f*v3,无符号整数级别)
{
如果(级别==0)
{
gl四面体(v0,v1,v2,v3);
返回;
}
//中点
Vec3f m01=Lerp(v0,v1,0.5);
Vec3f m12=Lerp(v1,v2,0.5);
Vec3f m02=Lerp(v0,v2,0.5);
Vec3f m03=Lerp(v0,v3,0.5);
Vec3f m13=Lerp(v1,v3,0.5);
Vec3f m23=Lerp(v2,v3,0.5);
GLSIERPINSKI金字塔(v0、m01、m02、m03,一级);
GLSIERPINSKI金字塔(&m01,v1,&m12,&m13,1级);
GLSIERPINSKI金字塔(m02、m12、v2和m23,一级);
GLSIERPINSKI金字塔(m03、m13、m23、v3、1级);
}
无效显示()
{
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
glMatrixMode(GL_投影);
glLoadIdentity();
双w=glutGet(GLUT\U窗口\U宽度);
双h=glutGet(GLUT\U窗口\U高度);
谷氨酰胺(60,w/h,0.1100);
glMatrixMode(GLU模型视图);
glLoadIdentity();
glTranslatef(0,0,-9);
srand(0);
glPushMatrix();
glScalef(3,3,3);
静态浮动角度=0;
角度+=1;
glRotatef(角度/3,0.2,1,0);
vec3fv0={-1,-1/sqrtf(3),-1/sqrtf(6)};
vec3fv1={1,-1/sqrtf(3),-1/sqrtf(6)};
vec3fv2={0,2/sqrtf(3),-1/sqrtf(6)};
vec3fv3={0,0,3/sqrtf(6)};
glBegin(GL_三角形);
Glsierpinski金字塔(&v0,&v1,&v2,&v3,3);
格伦德();
glPopMatrix();
glutSwapBuffers();
}
无效计时器(整数额外)
{
再发现();
glutTimerFunc(16,定时器,0);
}
int main(int argc,字符**argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_深度| GLUT_双精度);
GLUTINITWindowsSize(640480);
glutCreateWindow(“锡宾斯基金字塔”);
glutDisplayFunc(显示器);
glutTimerFunc(0,定时器,0);
glEnable(GLU深度试验);
glEnable(GL_CULL_面);
glutMainLoop();
返回0;
}
试一试:

// gcc -std=c99 main.c -lglut -lGL -lGLU

#include <GL/glut.h>
#include <math.h>
#include <stdlib.h>

typedef struct
{
    float x, y, z;
} Vec3f;

void glTriangle( Vec3f* v0, Vec3f* v1, Vec3f* v2 )
{
    glColor3ub( rand() % 255, rand() % 255, rand() % 255 );
    glVertex3fv( (GLfloat*)v0 );
    glVertex3fv( (GLfloat*)v1 );
    glVertex3fv( (GLfloat*)v2 );
}

// v0, v1, v2 = base, v3 = top
void glTetrahedron( Vec3f* v0, Vec3f* v1, Vec3f* v2, Vec3f* v3 )
{
    glTriangle( v0, v2, v1 );
    glTriangle( v0, v1, v3 );
    glTriangle( v1, v2, v3 );
    glTriangle( v2, v0, v3 );
}

Vec3f Lerp( Vec3f* v0, Vec3f* v1, float u )
{
    Vec3f ret = {
        v0->x + ( v1->x - v0->x ) * u,
        v0->y + ( v1->y - v0->y ) * u,
        v0->z + ( v1->z - v0->z ) * u,
    };
    return ret;
}

void glSierpinskiPyramid( Vec3f* v0, Vec3f* v1, Vec3f* v2, Vec3f* v3, unsigned int level )
{
    if( level == 0 )
    {
        glTetrahedron( v0, v1, v2, v3 );
        return;
    }

    // midpoints
    Vec3f m01 = Lerp( v0, v1, 0.5 );
    Vec3f m12 = Lerp( v1, v2, 0.5 );
    Vec3f m02 = Lerp( v0, v2, 0.5 );
    Vec3f m03 = Lerp( v0, v3, 0.5 );
    Vec3f m13 = Lerp( v1, v3, 0.5 );
    Vec3f m23 = Lerp( v2, v3, 0.5 );

    glSierpinskiPyramid( v0, &m01, &m02, &m03, level-1 );
    glSierpinskiPyramid( &m01, v1, &m12, &m13, level-1 );
    glSierpinskiPyramid( &m02, &m12, v2, &m23, level-1 );
    glSierpinskiPyramid( &m03, &m13, &m23, v3, level-1 );
}

void display()
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    double w = glutGet( GLUT_WINDOW_WIDTH );
    double h = glutGet( GLUT_WINDOW_HEIGHT );
    gluPerspective( 60, w / h, 0.1, 100 );

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    glTranslatef( 0, 0, -9 );

    srand(0);
    glPushMatrix();
    glScalef( 3, 3, 3 );

    static float angle = 0;
    angle += 1;
    glRotatef( angle/3, 0.2, 1, 0 );

    Vec3f v0 = { -1, -1 / sqrtf(3), -1 / sqrtf(6) };
    Vec3f v1 = {  1, -1 / sqrtf(3), -1 / sqrtf(6) };
    Vec3f v2 = {  0,  2 / sqrtf(3), -1 / sqrtf(6) };
    Vec3f v3 = {  0,             0,  3 / sqrtf(6) };
    glBegin( GL_TRIANGLES );
    glSierpinskiPyramid( &v0, &v1, &v2, &v3, 3 );
    glEnd();
    glPopMatrix();

    glutSwapBuffers();
}

void timer(int extra)
{
    glutPostRedisplay();
    glutTimerFunc(16, timer, 0);
}

int main( int argc, char **argv )
{
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
    glutInitWindowSize( 640, 480 );
    glutCreateWindow( "Sierpinski Pyramid" );
    glutDisplayFunc( display );
    glutTimerFunc(0, timer, 0);

    glEnable( GL_DEPTH_TEST );
    glEnable( GL_CULL_FACE );

    glutMainLoop();
    return 0;
}
//gcc-std=c99 main.c-lglut-lGL-lGLU
#包括
#包括
#包括
类型定义结构
{
浮动x,y,z;
}Vec3f;
void glTriangle(Vec3f*v0、Vec3f*v1、Vec3f*v2)
{
glColor3ub(rand()%255,rand()%255,rand()%255);
glVertex3fv((GLfloat*)v0);
glVertex3fv((GLfloat*)v1);
glVertex3fv((GLfloat*)v2);
}
//v0,v1,v2=基础,v3=顶部
四面体(Vec3f*v0,Vec3f*v1,Vec3f*v2,Vec3f*v3)
{
GLV(v0、v2、v1);
GLV(v0、v1、v3);
glTriangle(v1、v2、v3);
gl三角形(v2,v0,v3);
}
Vec3f Lerp(Vec3f*v0,Vec3f*v1,浮点数u)
{
Vec3f ret={
v0->x+(v1->x-v0->x)*u,
v0->y+(v1->y-v0->y)*u,
v0->z+(v1->z-v0->z)*u,
};
返回ret;
}
无效glSierpinskiPyramid(Vec3f*v0,Vec3f*v1,Vec3f*v2,Vec3f*v3,无符号整数级别)
{
如果(级别==0)
{
gl四面体(v0,v1,v2,v3);
返回;
}
//中点
Vec3f m01=Lerp(v0,v1,0.5);
Vec3f m12=Lerp(v1,v2,0.5);
Vec3f m02=Lerp(v0,v2,0.5);
Vec3f m03=Lerp(v0,v3,0.5);
Vec3f m13=Lerp(v1,v3,0.5);
Vec3f m23=Lerp(v2,v3,0.5);
GLSIERPINSKI金字塔(v0、m01、m02、m03,一级);
GLSIERPINSKI金字塔(&m01,v1,&m12,&m13,1级);
GLSIERPINSKI金字塔(m02、m12、v2和m23,一级);
GLSIERPINSKI金字塔(m03、m13、m23、v3、1级);
}
无效显示()
{
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
glMatrixMode(GL_投影);
glLoadIdentity();
双w=glutGet(GLUT\U窗口\U宽度);
双h=glutGet(GLUT\U窗口\U高度);
谷氨酰胺(60,w/h,0.1100);
glMatrixMode(GLU模型视图);
glLoadIdentity();
glTranslatef(0,0,-9);
srand(0);
glPushMatrix();
glScalef(3,3,3);
静态浮动角度=0;
角度+=1;
glRotatef(角度/3,0.2,1,0);
vec3fv0={-1,-1/sqrtf(3),-1/sqrtf(6)};
vec3fv1={1,-1/sqrtf(3),-1/sqrtf(6)};
vec3fv2={0,2/sqrtf(3),-1/sqrtf(6)};
vec3fv3={0,0,3/sqrtf(6)};
glBegin(GL_三角形);
Glsierpinski金字塔(&v0,&v1,&v2,&v3,3);
格伦德();
glPopMatrix();
glutSwapBuffers();
}
无效计时器(整数额外)
{
再发现();
glutTimerFunc(16,定时器,0);
}
int main(int argc,字符**argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_深度| GLUT_双精度);
GLUTINITWindowsSize(640480);
glutCreateWindow(“锡宾斯基金字塔”);
glutDisplayFunc(显示器);
glutTimerFunc(0,定时器,0);
glEnable(GLU深度试验);
glEnable(GL_CULL_面);
glutMainLoop();
返回0;
}