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

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

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

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 <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;
}


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值