OpenGL进阶(四)-用参数方程绘制椭球体

本文介绍如何使用OpenGL和参数方程来绘制一个椭球体。通过调整三个半径参数,可以绘制不同形状的椭圆体,并提供了完整的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

OpenGL进阶(四)-用参数方程绘制椭球体

分类: 计算机图形学 364人阅读 评论(0) 收藏 举报

首先参考这篇文章绘制一个球体:OpenGL 用参数方程绘制球

我们知道球体的参数方程是这样的:

x=r·sin(α)·cos(β)
y=r·sin(α)·sin(β)
z=r·cos(α)

椭圆的参数方程是:

x=rx·sin(α)·cos(β)
y=ry·sin(α)·sin(β)
z=rz·cos(α)

在这个基础上进行一些修改就可以实现椭圆的绘制了!

代码实现如下:

  1. /***************************************************************************** 
  2. Copyright: 2012, ustc All rights reserved. 
  3. contact:k283228391@126.com 
  4. File name: main.c 
  5. Description:using opengl in SDL. 
  6. Author:Silang Quan 
  7. Version: 1.0 
  8. Date: 2012.12.01 
  9. *****************************************************************************/  
  10. #include <SDL/SDL.h>  
  11. #include <GL/gl.h>  
  12. #include <GL/glu.h>  
  13. #include <stdio.h>  
  14. #include <stdlib.h>  
  15. #include <math.h>  
  16. #define pi 3.1415926  
  17. SDL_Surface *screen;  
  18. typedef struct Point3f  
  19. {  
  20.  GLfloat x;  
  21.  GLfloat y;  
  22.  GLfloat z;  
  23. }point;  
  24.   
  25.   
  26. int getPoint2(GLfloat rx,GLfloat ry,GLfloat rz,GLfloat a,GLfloat b,point &p)  
  27. {  
  28.     p.x=rx*sin(a*pi/180.0)*cos(b*pi/180.0);  
  29.     p.y=ry*sin(a*pi/180.0)*sin(b*pi/180.0);  
  30.     p.z=rz*cos(a*pi/180.0);  
  31.     return 1;  
  32. }  
  33. point* getPointMatrix2(GLfloat rx,GLfloat ry,GLfloat rz,GLint slices)  
  34. {  
  35.  int i,j,w=2*slices,h=slices;  
  36.  float a=0.0,b=0.0;  
  37.  float hStep=180.0/(h-1);  
  38.  float wStep=360.0/w;  
  39.  int length=w*h;  
  40.  point *matrix;  
  41.  matrix=(point *)malloc(length*sizeof(point));  
  42.  if(!matrix)return NULL;  
  43.  for(a=0.0,i=0;i<h;i++,a+=hStep)  
  44.   for(b=0.0,j=0;j<w;j++,b+=wStep)  
  45.    getPoint2(rx,ry,rz,a,b,matrix[i*w+j]);  
  46.  return matrix;  
  47. }  
  48.   
  49.   
  50. void drawSlice(point &p1,point &p2,point &p3,point &p4)  
  51. {  
  52.  glBegin(GL_LINE_LOOP);  
  53.  glColor3f(0,1,0);  
  54.  glVertex3f(p1.x,p1.y,p1.z);  
  55.  glVertex3f(p2.x,p2.y,p2.z);  
  56.  glVertex3f(p3.x,p3.y,p3.z);  
  57.  glVertex3f(p4.x,p4.y,p4.z);  
  58.  glEnd();  
  59. }  
  60.   
  61. int drawOval(GLfloat rx,GLfloat ry,GLfloat rz,GLint slices)  
  62. {  
  63.     int i=0,j=0,w=2*slices,h=slices;  
  64.     point *mx;  
  65.     mx=getPointMatrix2(rx,ry,rz,slices);  
  66.     if(!mx)return 0;  
  67.     for(;i<h-1;i++)  
  68.  {  
  69.     for(j=0;j<w-1;j++)  
  70.     {  
  71.         drawSlice(mx[i*w+j],mx[i*w+j+1],mx[(i+1)*w+j+1],mx[(i+1)*w+j]);  
  72.     }  
  73.     drawSlice(mx[i*w+j],mx[i*w],mx[(i+1)*w],mx[(i+1)*w+j]);  
  74.  }  
  75.  free(mx);  
  76.  return 1;  
  77. }  
  78. void quit( int code )  
  79. {  
  80.     SDL_Quit( );  
  81.     /* Exit program. */  
  82.     exit( code );  
  83. }  
  84. void handleKeyEvent( SDL_keysym* keysym )  
  85. {  
  86.     switch( keysym->sym )  
  87.     {  
  88.     case SDLK_ESCAPE:  
  89.         quit( 0 );  
  90.         break;  
  91.     case SDLK_SPACE:  
  92.         break;  
  93.     default:  
  94.         break;  
  95.     }  
  96. }  
  97. void resizeGL(int width,int height)  
  98. {  
  99.     if ( height == 0 )  
  100.     {  
  101.         height = 1;  
  102.     }  
  103.     //Reset View  
  104.     glViewport( 0, 0, (GLint)width, (GLint)height );  
  105.     //Choose the Matrix mode  
  106.     glMatrixMode( GL_PROJECTION );  
  107.     //reset projection  
  108.     glLoadIdentity();  
  109.     //set perspection  
  110.     gluPerspective( 45.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0 );  
  111.     //choose Matrix mode  
  112.     glMatrixMode( GL_MODELVIEW );  
  113.     glLoadIdentity();  
  114. }  
  115. void handleEvents()  
  116. {  
  117.     // Our SDL event placeholder.  
  118.     SDL_Event event;  
  119.     //Grab all the events off the queue.  
  120.     while( SDL_PollEvent( &event ) ) {  
  121.         switch( event.type ) {  
  122.         case SDL_KEYDOWN:  
  123.             // Handle key Event  
  124.             handleKeyEvent( &event.key.keysym );  
  125.             break;  
  126.         case SDL_QUIT:  
  127.             // Handle quit requests (like Ctrl-c).  
  128.             quit( 0 );  
  129.             break;  
  130.         case SDL_VIDEORESIZE:  
  131.             //Handle resize event  
  132.             screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 16,  
  133.                                       SDL_OPENGL|SDL_RESIZABLE);  
  134.             if ( screen )  
  135.             {  
  136.                 resizeGL(screen->w, screen->h);  
  137.             }  
  138.             break;  
  139.         }  
  140.     }  
  141. }  
  142.   
  143. void initSDL(int width,int height,int bpp,int flags)  
  144. {  
  145.     // First, initialize SDL's video subsystem.  
  146.     if( SDL_Init( SDL_INIT_VIDEO ) < 0 )  
  147.     {  
  148.         fprintf( stderr, "Video initialization failed: %s\n",  
  149.                  SDL_GetError( ) );  
  150.         quit( 1 );  
  151.     }  
  152.     atexit(SDL_Quit);  
  153.     //Set some Attribute of OpenGL in SDL  
  154.     SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );  
  155.     SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );  
  156.     SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );  
  157.     SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );  
  158.     SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );  
  159.   
  160.     //Set the video mode  
  161.     screen= SDL_SetVideoMode( width, height, bpp,flags);  
  162.     if(!screen )  
  163.     {  
  164.         fprintf( stderr, "Video mode set failed: %s\n",SDL_GetError( ) );  
  165.         quit( 1 );  
  166.     }  
  167.     resizeGL(screen->w, screen->h);  
  168.     //Set caption  
  169.     SDL_WM_SetCaption( "OpenGL Test", NULL );  
  170. }  
  171.   
  172. void renderGL()  
  173. {  
  174.     // Clear the color and depth buffers.  
  175.     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );  
  176.     // We don't want to modify the projection matrix. */  
  177.     glMatrixMode( GL_MODELVIEW );  
  178.     glLoadIdentity( );  
  179.     // Move down the z-axis.  
  180.     glTranslatef( 0.0, 0.0, -25.0 );  
  181.     glRotatef(50.0f,0,1,1);  
  182.     //Draw a square  
  183.     drawSphere(10,20);  
  184.     //drawOval(5,8,15,20);  
  185.     SDL_GL_SwapBuffers( );  
  186. }  
  187. void initGL( int width, int height )  
  188. {  
  189.     float ratio = (float) width / (float) height;  
  190.     // Our shading model--Gouraud (smooth).  
  191.     glShadeModel( GL_SMOOTH );  
  192.     // Set the clear color.  
  193.     glClearColor( 0, 0, 0, 0 );  
  194.     // Setup our viewport.  
  195.     glViewport( 0, 0, width, height );  
  196.     //Change to the projection matrix and set our viewing volume.  
  197.     glMatrixMode( GL_PROJECTION );  
  198.     glLoadIdentity();  
  199.     gluPerspective( 60.0, ratio, 1.0, 100.0 );  
  200. }  
  201. int main( int argc, char* argv[] )  
  202. {  
  203.   
  204.     // Dimensions of our window.  
  205.     int width = 640;  
  206.     int height = 480;  
  207.     // Color depth in bits of our window.  
  208.     int bpp = 32;  
  209.     int flags= SDL_OPENGL|SDL_RESIZABLE;  
  210.     //Set the SDL  
  211.     initSDL(width, height, bpp,flags);  
  212.     //Set the OpenGL  
  213.     initGL( width, height );  
  214.   
  215.     //main loop  
  216.     while(true)  
  217.     {  
  218.         /* Process incoming events. */  
  219.         handleEvents( );  
  220.         /* Draw the screen. */  
  221.         renderGL( );  
  222.     }  
  223.     return 0;  
  224. }  
/*****************************************************************************
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 <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#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<h;i++,a+=hStep)
  for(b=0.0,j=0;j<w;j++,b+=wStep)
   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<h-1;i++)
 {
    for(j=0;j<w-1;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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值