现在的位置: 首页 > 综合 > 正文

Sierpinski镂垫

2013年10月06日 ⁄ 综合 ⁄ 共 8074字 ⁄ 字号 评论关闭

      Sierpinski镂垫是一个非常有趣的图案,
有着悠久的历史, 在分形几何中等领域里引起了人们极大地兴趣, 是用递归和随机方式定义的几何形状, 在极限情况下, 它所表现的性质并没有随机性.

生成算法如下:
(1)在三角形内部随机选取一个点作为初始点
(2)在三角形的3个顶点中随机选取一个,求出该顶点与初始点连线的中点,画出该中点
(3)将(2)中的中点作为初始点,转到(2)

下面利用SDL+OpenGL分别在二维和三维中来实现。


二维

/*****************************************************************************
Copyright: 2012, ustc All rights reserved.
contact:k283228391@126.com
File name: main.c
Description:Sierpinski 2d.
Author:Silang Quan
Version: 1.0
Date: 2012.12.02
*****************************************************************************/
#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdio.h>
#include <stdlib.h>
SDL_Surface *screen;
void quit( int code )
{
    SDL_Quit( );
    /* Exit program. */
    exit( code );
}
void handleKeyEvent( SDL_keysym* keysym )
{
    switch( keysym->sym )
	{
    case SDLK_ESCAPE:
        quit( 0 );
        break;
    case SDLK_SPACE:
        break;
    default:
        break;
    }
}
void resizeGL(int width,int height)
{
    if ( height == 0 )  
    {  
        height = 1;  
    }  
    //Reset View 
    glViewport( 0, 0, (GLint)width, (GLint)height );  
    //Choose the Matrix mode 
    glMatrixMode( GL_PROJECTION );  
    //reset projection
    glLoadIdentity();  
    //set perspection 
    gluPerspective( 45.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0 );  
    //choose Matrix mode
    glMatrixMode( GL_MODELVIEW );  
    glLoadIdentity();  
}
void handleEvents()
{
    // Our SDL event placeholder. 
    SDL_Event event;
    //Grab all the events off the queue. 
    while( SDL_PollEvent( &event ) ) {
        switch( event.type ) {
        case SDL_KEYDOWN:
            // Handle key Event
            handleKeyEvent( &event.key.keysym );
            break;
        case SDL_QUIT:
            // Handle quit requests (like Ctrl-c). 
            quit( 0 );
            break;
        case SDL_VIDEORESIZE:
			//Handle resize event
            screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 16,
                                      SDL_OPENGL|SDL_RESIZABLE);
            if ( screen ) 
            {
                resizeGL(screen->w, screen->h);
            }
            break;
        }
    }
}

void initSDL(int width,int height,int bpp,int flags)
{
    // First, initialize SDL's video subsystem. 
    if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) 
    {
        fprintf( stderr, "Video initialization failed: %s\n",
                 SDL_GetError( ) );
        quit( 1 );
    }
    atexit(SDL_Quit);
	//Set some Attribute of OpenGL in SDL
    SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
    SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
    SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
    SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
    
    //Set the video mode  
    screen= SDL_SetVideoMode( width, height, bpp,flags);
    if(!screen ) 
    {
        fprintf( stderr, "Video mode set failed: %s\n",SDL_GetError( ) );
        quit( 1 );
    }
    resizeGL(screen->w, screen->h);
    //Set caption
    SDL_WM_SetCaption( "Sierpinski 2D", NULL ); 
}
void renderGL()
{
    // Clear the color and depth buffers. 
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    // We don't want to modify the projection matrix. */
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity( );
    // Move down the z-axis. 
    glTranslatef( -20.0, -20.0, -60.0 );
	//Draw a square
     /* A triangle */  
    GLfloat vertices[3][2]={{0.0,0.0},{25.0,50.0},{50.0,0.0}};  
  
    int i, j, k;  
    srand(10);        /* standard random number generator */  
    GLfloat p[2] ={7.5,5.0};  /* an arbitrary initial point inside 
                              traingle */  
    glClear(GL_COLOR_BUFFER_BIT);  /* clear the window */  
    glBegin(GL_POINTS);  
    /* compute and plots 5000 new points */  
    for( k=0; k<500000; k++)  
    {  
        j=rand()%3; /* pick a vertex at random */  
        /* Compute point halfway between selected vertex and old point */  
        p[0] = (p[0]+vertices[j][0])/2.0;  
        p[1] = (p[1]+vertices[j][1])/2.0;  
        /* plot new point */  
        glVertex2fv(p);  
    }  
    glEnd(); 
    SDL_GL_SwapBuffers( );
}
void initGL( int width, int height )
{
    float ratio = (float) width / (float) height;
    // Our shading model--Gouraud (smooth). 
    glShadeModel( GL_SMOOTH );
    // Set the clear color. 
    glClearColor( 0, 0, 0, 0 );
    // Setup our viewport. 
    glViewport( 0, 0, width, height );
    //Change to the projection matrix and set our viewing volume.
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    gluPerspective( 60.0, ratio, 1.0, 100.0 );
}
int main( int argc, char* argv[] )
{
    
    // Dimensions of our window.    
    int width = 640;
    int height = 480;
    // Color depth in bits of our window. 
    int bpp = 32;
    int flags= SDL_OPENGL|SDL_RESIZABLE;
    //Set the SDL
    initSDL(width, height, bpp,flags);
    //Set the OpenGL
    initGL( width, height );
    
    //main loop
    while(true) 
	{
        /* Process incoming events. */
        handleEvents( );
        /* Draw the screen. */
        renderGL( );
    }
    return 0;
}


三维

/*****************************************************************************
Copyright: 2012, ustc All rights reserved.
contact:k283228391@126.com
File name: main3D.c
Description:Sierpinski 3D.
Author:Silang Quan
Version: 1.0
Date: 2012.12.02
*****************************************************************************/
#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdio.h>
#include <stdlib.h>
SDL_Surface *screen;
GLfloat colors[4][3]={{1.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0},{0.0,1.0,1.0}};
void quit( int code )
{
    SDL_Quit( );
    /* Exit program. */
    exit( code );
}
void handleKeyEvent( SDL_keysym* keysym )
{
    switch( keysym->sym )
	{
    case SDLK_ESCAPE:
        quit( 0 );
        break;
    case SDLK_SPACE:
        break;
    default:
        break;
    }
}
void resizeGL(int width,int height)
{
    if ( height == 0 )  
    {  
        height = 1;  
    }  
    //Reset View 
    glViewport( 0, 0, (GLint)width, (GLint)height );  
    //Choose the Matrix mode 
    glMatrixMode( GL_PROJECTION );  
    //reset projection
    glLoadIdentity();  
    //set perspection 
    gluPerspective( 45.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0 );  
    //choose Matrix mode
    glMatrixMode( GL_MODELVIEW );  
    glLoadIdentity();  
}
void handleEvents()
{
    // Our SDL event placeholder. 
    SDL_Event event;
    //Grab all the events off the queue. 
    while( SDL_PollEvent( &event ) ) {
        switch( event.type ) {
        case SDL_KEYDOWN:
            // Handle key Event
            handleKeyEvent( &event.key.keysym );
            break;
        case SDL_QUIT:
            // Handle quit requests (like Ctrl-c). 
            quit( 0 );
            break;
        case SDL_VIDEORESIZE:
			//Handle resize event
            screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 16,
                                      SDL_OPENGL|SDL_RESIZABLE);
            if ( screen ) 
            {
                resizeGL(screen->w, screen->h);
            }
            break;
        }
    }
}

void initSDL(int width,int height,int bpp,int flags)
{
    // First, initialize SDL's video subsystem. 
    if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) 
    {
        fprintf( stderr, "Video initialization failed: %s\n",
                 SDL_GetError( ) );
        quit( 1 );
    }
    atexit(SDL_Quit);
	//Set some Attribute of OpenGL in SDL
    SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
    SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
    SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
    SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
    
    //Set the video mode  
    screen= SDL_SetVideoMode( width, height, bpp,flags);
    if(!screen ) 
    {
        fprintf( stderr, "Video mode set failed: %s\n",SDL_GetError( ) );
        quit( 1 );
    }
    resizeGL(screen->w, screen->h);
    //Set caption
    SDL_WM_SetCaption( "Sierpinski 3D", NULL ); 
}

void triangle( GLfloat *va, GLfloat *vb, GLfloat *vc)
{
       glVertex3fv(va);
       glVertex3fv(vb);
       glVertex3fv(vc);
}

void tetra(GLfloat *a, GLfloat *b, GLfloat *c, GLfloat *d)
{

      glColor3fv(colors[0]);
      triangle(a,b,c);
      glColor3fv(colors[1]);
     triangle(a,c,d);
      glColor3fv(colors[2]);
      triangle(a,d,b);
      glColor3fv(colors[3]);
      triangle(b,d,c);
}

void divide_tetra(GLfloat *a, GLfloat *b, GLfloat *c, GLfloat *d, int m)
{
    GLfloat mid[6][3];
    int j;
    if(m>0)
       {
        
              /* compute six midpoints */
        for(j=0; j<3; j++) mid[0][j]=(a[j]+b[j])/2;
        for(j=0; j<3; j++) mid[1][j]=(a[j]+c[j])/2;
        for(j=0; j<3; j++) mid[2][j]=(a[j]+d[j])/2;
        for(j=0; j<3; j++) mid[3][j]=(b[j]+c[j])/2;
        for(j=0; j<3; j++) mid[4][j]=(c[j]+d[j])/2;
        for(j=0; j<3; j++) mid[5][j]=(b[j]+d[j])/2;

              /* create 4 tetrahedrons  by subdivision */
        divide_tetra(a,mid[0],mid[1],mid[2], m-1);
        divide_tetra(mid[0],b,mid[3],mid[5], m-1);
        divide_tetra(mid[1],mid[3],c,mid[4], m-1);
        divide_tetra(mid[2],mid[4],d,mid[5], m-1);

    }
    else
    tetra(a,b,c,d); /* draw tetrahedron at end of recursion */
}

void renderGL()
{
    //Define a triangle in space
    GLfloat v[4][3]={{0.0, 0.0, 1.0},{0.0, 0.942809, -0.33333},{-0.816497, -0.471405, -0.333333},{0.816497, -0.471405, -0.333333}};

    // Clear the color and depth buffers. 
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    // We don't want to modify the projection matrix. */
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity( );
    // Move down the z-axis. 
    glTranslatef( 0.0, 0.0, -2.0 );
    glRotatef(50,0,1,0);
    glRotatef(30,1,0,0);

    glClear(GL_COLOR_BUFFER_BIT);  /* clear the window */  
    glBegin(GL_TRIANGLES);  
        divide_tetra(v[0],v[1],v[2],v[3],3);
    glEnd();
    SDL_GL_SwapBuffers( );
}
void initGL( int width, int height )
{
    float ratio = (float) width / (float) height;
    // Our shading model--Gouraud (smooth). 
    glShadeModel( GL_SMOOTH );
    // Set the clear color. 
    glClearColor( 0, 0, 0, 0 );
    // Setup our viewport. 
    glViewport( 0, 0, width, height );
    //Change to the projection matrix and set our viewing volume.
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    gluPerspective( 60.0, ratio, 1.0, 100.0 );
}
int main( int argc, char* argv[] )
{
    
    // Dimensions of our window.    
    int width = 640;
    int height = 480;
    // Color depth in bits of our window. 
    int bpp = 32;
    int flags= SDL_OPENGL|SDL_RESIZABLE;
    //Set the SDL
    initSDL(width, height, bpp,flags);
    //Set the OpenGL
    initGL( width, height );
    
    
    //main loop
    while(true) 
	{
        /* Process incoming events. */
        handleEvents( );
        /* Draw the screen. */
        renderGL( );
    }
    return 0;
}


参考:Sierpinski镂垫程序-http://www.codeforge.com/read/45707/Sierpinski%E9%95%82%E5%9E%AB%E7%A8%8B%E5%BA%8F.txt__html

抱歉!评论已关闭.