Sources/Models/Torus/Classes/OpenGLTorusGenerator.cpp
//------------------------------------------------------------------------- |
// |
// File: OpenGLTorusGenerator.cpp |
// |
// Abstract: C++ class that implements a generator for an |
// ordinary torus (a surface having genus one). |
// |
// Disclaimer: IMPORTANT: This Apple software is supplied to you by |
// Apple Inc. ("Apple") in consideration of your agreement to the |
// following terms, and your use, installation, modification or |
// redistribution of this Apple software constitutes acceptance of these |
// terms. If you do not agree with these terms, please do not use, |
// install, modify or redistribute this Apple software. |
// |
// In consideration of your agreement to abide by the following terms, and |
// subject to these terms, Apple grants you a personal, non-exclusive |
// license, under Apple's copyrights in this original Apple software (the |
// "Apple Software"), to use, reproduce, modify and redistribute the Apple |
// Software, with or without modifications, in source and/or binary forms; |
// provided that if you redistribute the Apple Software in its entirety and |
// without modifications, you must retain this notice and the following |
// text and disclaimers in all such redistributions of the Apple Software. |
// Neither the name, trademarks, service marks or logos of Apple Inc. |
// may be used to endorse or promote products derived from the Apple |
// Software without specific prior written permission from Apple. Except |
// as expressly stated in this notice, no other rights or licenses, express |
// or implied, are granted by Apple herein, including but not limited to |
// any patent rights that may be infringed by your derivative works or by |
// other works in which the Apple Software may be incorporated. |
// |
// The Apple Software is provided by Apple on an "AS IS" basis. APPLE |
// MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION |
// THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS |
// FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND |
// OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. |
// |
// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL |
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
// INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, |
// MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED |
// AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), |
// STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE |
// POSSIBILITY OF SUCH DAMAGE. |
// |
// Copyright (c) 2008 Apple Inc., All rights reserved. |
// |
//------------------------------------------------------------------------- |
//------------------------------------------------------------------------- |
// |
// In here our implementation of an ordinary torus (a surface having genus |
// one) will be taking advantage of its parametric representation. That is |
// to say, |
// |
// x(theta, phi) = R cos(theta) + r cos(theta) cos(phi) |
// = ( R + r cos(phi) ) cos(theta) |
// |
// y(theta, phi) = R sin(theta) + r sin(theta) cos(phi) |
// = ( R + r cos(phi) ) sin(theta) |
// |
// z(theta, phi) = r sin(phi) |
// |
// where |
// |
// {theta, phi} are parameters in the open interval [0, 2π); |
// |
// R is the distance from the center of the tube to the center |
// of the torus, i.e., the outer radii; |
// |
// r is the radius of the tube, i.e., the inner radii. |
// |
// Equivalently, an equation in Cartesian coordinates for a torus |
// azimuthally (radially) symmetric about the z-axis is given by |
// |
// { R - ( x^2 + y^2 )^(1/2) }^2 + z^2 = r^2 |
// |
// Additionally, note that even though we have used a circle as the |
// generator for a torus, in general this need not be the case. In |
// fact, one can adopt an ellipse or any other conic section as the |
// generator. |
// |
//------------------------------------------------------------------------- |
//------------------------------------------------------------------------ |
#include "OpenGLModelTypes.h" |
#include "OpenGLTorusGenerator.hpp" |
//------------------------------------------------------------------------ |
//------------------------------------------------------------------------ |
static const GLdouble kTwoPi = 2.0 * M_PI; |
//------------------------------------------------------------------------ |
//------------------------------------------------------------------------ |
struct Vector |
{ |
union |
{ |
GLdouble v[3]; |
struct |
{ |
GLdouble x; |
GLdouble y; |
GLdouble z; |
}; // struct |
}; // union |
}; // Vector |
typedef struct Vector Vector; |
//------------------------------------------------------------------------ |
//------------------------------------------------------------------------ |
GLvoid Torus::ValidTorusModelType( const GLint theModelType ) |
{ |
if ( theModelType == modelTypeSolid ) |
{ |
torus.modelType = modelTypeSolid; |
} // if |
else |
{ |
torus.modelType = modelTypeWireFrame; |
} // else |
} // Torus::ValidTorusModelType |
//------------------------------------------------------------------------ |
GLvoid Torus::ValidTorusSidesCount( const GLint theSidesCount ) |
{ |
if ( theSidesCount < 1 ) |
{ |
torus.sidesCount = 64; |
} // if |
else |
{ |
torus.sidesCount = theSidesCount; |
} // else |
} // Torus::ValidTorusSidesCount |
//------------------------------------------------------------------------ |
GLvoid Torus::ValidTorusRingsCount( const GLint theRingsCount ) |
{ |
if ( theRingsCount < 1 ) |
{ |
torus.ringsCount = 63; |
} // if |
else |
{ |
torus.ringsCount = theRingsCount - 1; |
} // else |
} // Torus::ValidTorusRingsCount |
//------------------------------------------------------------------------ |
Torus::Torus( ) |
{ |
torus.modelType = modelTypeSolid; |
torus.sidesCount = 0; |
torus.ringsCount = 0; |
torus.innerRadii = 0.0; |
torus.outerRadii = 0.0; |
torus.ringDelta = 0.0; |
torus.sideDelta = 0.0; |
torus.factor = 0.0; |
} // Default Constructor |
//------------------------------------------------------------------------ |
Torus::Torus( const GLint theModelType, |
const GLint theSidesCount, |
const GLint theRingsCount, |
const GLdouble theInnerRadii, |
const GLdouble theOuterRadii ) |
{ |
ValidTorusModelType( theModelType ); |
ValidTorusSidesCount( theSidesCount ); |
ValidTorusRingsCount( theRingsCount ); |
torus.innerRadii = theInnerRadii; |
torus.outerRadii = theOuterRadii; |
torus.ringDelta = kTwoPi / torus.ringsCount; |
torus.sideDelta = kTwoPi / torus.sidesCount; |
torus.factor = 0.0; |
}// Constructor |
//------------------------------------------------------------------------ |
GLvoid Torus::SetTorusAttributes( ) |
{ |
if ( torus.modelType == modelTypeWireFrame ) |
{ |
glPushAttrib(GL_POLYGON_BIT); |
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); |
} // if |
} // Torus::SetTorusAttributes |
//------------------------------------------------------------------------ |
GLvoid Torus::ResetTorusAttributes( ) |
{ |
if ( torus.modelType == modelTypeWireFrame ) |
{ |
glPopAttrib(); |
} // if |
} // Torus::ResetTorusAttributes |
//------------------------------------------------------------------------ |
GLvoid Torus::GetTorusNormal( const Parameter &theParamTheta, const Parameter &theParamPhi ) |
{ |
Vector normal; |
normal.x = theParamTheta.cos( ) * theParamPhi.cos( ); |
normal.y = -theParamTheta.sin( ) * theParamPhi.cos( ); |
normal.z = theParamPhi.cos( ); |
glNormal3dv( normal.v ); |
} // Parmeter::GetTorusNormal |
//------------------------------------------------------------------------ |
GLvoid Torus::GetTorusVertex( const Parameter &theParamTheta, const Parameter &theParamPhi ) |
{ |
Vector vertex; |
vertex.x = torus.factor * theParamTheta.cos( ); |
vertex.y = -torus.factor * theParamTheta.sin( ); |
vertex.z = torus.innerRadii * theParamPhi.sin( ); |
glVertex3dv( vertex.v ); |
} // Parmeter::GetTorusVertex |
//------------------------------------------------------------------------ |
GLvoid Torus::GetTorusSegment( Parameter &theParamTheta, Parameter &theParamPhi ) |
{ |
theParamPhi += torus.sideDelta; |
torus.factor = torus.outerRadii + torus.innerRadii * theParamPhi.cos( ); |
// Begin the segment here with the normal and the vertex |
GetTorusNormal( theParamTheta, theParamPhi ); |
GetTorusVertex( theParamTheta, theParamPhi ); |
theParamTheta += torus.ringDelta; |
// End the segment here with the normal and the vertex |
GetTorusNormal( theParamTheta, theParamPhi ); |
GetTorusVertex( theParamTheta, theParamPhi ); |
} // TorusSegment::GetTorusSegment |
//------------------------------------------------------------------------ |
GLvoid Torus::GetTorusQuadStrip( Parameter &theParamTheta ) |
{ |
GLint sideIndex; |
Parameter phi; |
glBegin( GL_QUAD_STRIP ); |
// Generate segments having the total number of requested sides |
for ( sideIndex = torus.sidesCount; sideIndex >= 0; sideIndex-- ) |
{ |
GetTorusSegment( theParamTheta, phi ); |
} // for |
glEnd( ); |
} // Torus::GetTorusQuadStrip |
//------------------------------------------------------------------------ |
GLvoid Torus::GetTorus( ) |
{ |
Parameter theta( 0.0, 1.0, 0.0 ); |
GLint ringIndex; |
// Set OpenGL attributes for a torus if the requested model |
// was wireframe |
SetTorusAttributes( ); |
// Generate quad strips having the total number of requested rings |
for ( ringIndex = torus.ringsCount; ringIndex >= 0; ringIndex-- ) |
{ |
GetTorusQuadStrip( theta ); |
} // for |
// Reset OpenGL attributes for a torus if the requested model |
// was wireframe |
ResetTorusAttributes( ); |
} // Torus::GetTorus |
//------------------------------------------------------------------------ |
//------------------------------------------------------------------------ |
Copyright © 2008 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2008-02-06