OpenGL进阶(四):用参数方程绘制椭球体
发表于2017-09-14
很多人知道球体的绘制,但要去绘制椭圆球体就不一定会了,为此本篇文章要教大家的是用参数方程绘制椭球体,一起来看看吧。
我们知道球体的参数方程是这样的:
x=r·sin(α)·cos(β)
y=r·sin(α)·sin(β)
z=r·cos(α)
椭圆的参数方程是:
x=rx·sin(α)·cos(β)
y=ry·sin(α)·sin(β)
z=rz·cos(α)
在这个基础上进行一些修改就可以实现椭圆的绘制了!
代码实现如下:
- /*****************************************************************************
- Copyright: 2012, ustc All rights reserved.
- contact:k283228391@126.com
- File name: main.c
- Description:using opengl in SDL.
- Author:Silang Quan
- Version: 1.0
- Date: 2012.12.01
- *****************************************************************************/
- #include
- #include
- #include
- #include
- #include
- #include
- #define pi 3.1415926
- SDL_Surface *screen;
- typedef struct Point3f
- {
- GLfloat x;
- GLfloat y;
- GLfloat z;
- }point;
- int getPoint2(GLfloat rx,GLfloat ry,GLfloat rz,GLfloat a,GLfloat b,point &p)
- {
- p.x=rx*sin(a*pi/180.0)*cos(b*pi/180.0);
- p.y=ry*sin(a*pi/180.0)*sin(b*pi/180.0);
- p.z=rz*cos(a*pi/180.0);
- return 1;
- }
- point* getPointMatrix2(GLfloat rx,GLfloat ry,GLfloat rz,GLint slices)
- {
- int i,j,w=2*slices,h=slices;
- float a=0.0,b=0.0;
- float hStep=180.0/(h-1);
- float wStep=360.0/w;
- int length=w*h;
- point *matrix;
- matrix=(point *)malloc(length*sizeof(point));
- if(!matrix)return NULL;
- for(a=0.0,i=0;i
- for(b=0.0,j=0;j
- getPoint2(rx,ry,rz,a,b,matrix[i*w j]);
- return matrix;
- }
- void drawSlice(point &p1,point &p2,point &p3,point &p4)
- {
- glBegin(GL_LINE_LOOP);
- glColor3f(0,1,0);
- glVertex3f(p1.x,p1.y,p1.z);
- glVertex3f(p2.x,p2.y,p2.z);
- glVertex3f(p3.x,p3.y,p3.z);
- glVertex3f(p4.x,p4.y,p4.z);
- glEnd();
- }
- int drawOval(GLfloat rx,GLfloat ry,GLfloat rz,GLint slices)
- {
- int i=0,j=0,w=2*slices,h=slices;
- point *mx;
- mx=getPointMatrix2(rx,ry,rz,slices);
- if(!mx)return 0;
- for(;i
- {
- for(j=0;j
- {
- drawSlice(mx[i*w j],mx[i*w j 1],mx[(i 1)*w j 1],mx[(i 1)*w j]);
- }
- drawSlice(mx[i*w j],mx[i*w],mx[(i 1)*w],mx[(i 1)*w j]);
- }
- free(mx);
- return 1;
- }
- 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( "OpenGL Test", 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( 0.0, 0.0, -25.0 );
- glRotatef(50.0f,0,1,1);
- //Draw a square
- drawSphere(10,20);
- //drawOval(5,8,15,20);
- 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;
- }
http://blog.csdn.net/silangquan/article/details/8351111