Sources/Geometry/TranguloidTrefoilGeometry.mm
//--------------------------------------------------------------------------------------- |
// |
// File: TranguloidTrefoilGeometry.m |
// |
// Abstract: Tranguloid Trefoil geometry class |
// |
// Disclaimer: IMPORTANT: This Apple software is supplied to you by |
// 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) 2007-2008 Apple Inc., All rights reserved. |
// |
//--------------------------------------------------------------------------------------- |
// |
// Uses techniques described by Paul Bourke 1999 - 2002 |
// Tranguloid Trefoil and other example surfaces by Roger Bagula |
// see <http://astronomy.swin.edu.au/~pbourke/surfaces/> |
// |
//--------------------------------------------------------------------------------------- |
//--------------------------------------------------------------------------------------- |
//--------------------------------------------------------------------------------------- |
#include <cmath> |
#include <vector> |
//--------------------------------------------------------------------------------------- |
#include "TranguloidTrefoilGeometry.h" |
//--------------------------------------------------------------------------------------- |
//--------------------------------------------------------------------------------------- |
static const GLdouble kTwoPi = 2.0 * M_PI; |
static const GLdouble kPi = M_PI; |
static const GLdouble kTwoPiThird = ( 2.0 * M_PI ) / 3.0; |
//--------------------------------------------------------------------------------------- |
//--------------------------------------------------------------------------------------- |
#pragma mark - |
#pragma mark Private Data Structures |
//--------------------------------------------------------------------------------------- |
struct Position |
{ |
union |
{ |
GLdouble P[3]; |
struct |
{ |
GLdouble x; |
GLdouble y; |
GLdouble z; |
}; // union |
}; // struct |
}; |
typedef Position Position; |
//--------------------------------------------------------------------------------------- |
struct TexCoords |
{ |
union |
{ |
GLdouble T[2]; |
struct |
{ |
GLdouble s; |
GLdouble t; |
}; // struct |
}; // union |
}; |
typedef TexCoords TexCoords; |
//--------------------------------------------------------------------------------------- |
struct Vertex |
{ |
Position positions; |
Position normals; |
TexCoords texCoords; |
}; |
typedef Vertex Vertex; |
//--------------------------------------------------------------------------------------- |
typedef std::vector<Vertex> Vertices; |
//--------------------------------------------------------------------------------------- |
struct Geometry |
{ |
GLint rows; |
GLint columns; |
Vertices vertices; |
}; |
typedef Geometry Geometry; |
//--------------------------------------------------------------------------------------- |
//--------------------------------------------------------------------------------------- |
#pragma mark - |
#pragma mark Vector Class |
//--------------------------------------------------------------------------------------- |
class Vector |
{ |
public: |
Vector(); |
Vector(const Position *p); |
Vector normalize(); |
Vector operator-(Vector &v); |
Vector operator^(Vector &v); // Exterior cross product |
Position position(); |
public: |
GLdouble x; |
GLdouble y; |
GLdouble z; |
}; // class Vector |
//--------------------------------------------------------------------------------------- |
Vector::Vector() |
{ |
x = 0; |
y = 0; |
z = 0; |
} // Default Constructor |
//--------------------------------------------------------------------------------------- |
Vector::Vector(const Position *p) |
{ |
if( p != NULL ) |
{ |
x = p->x; |
y = p->y; |
z = p->z; |
} // if |
else |
{ |
x = 0; |
y = 0; |
z = 0; |
} // else |
}// Constructor |
//--------------------------------------------------------------------------------------- |
Vector Vector::operator-(Vector &v) |
{ |
Vector w; |
w.x = x - v.x; |
w.y = y - v.y; |
w.z = z - v.z; |
return w; |
} // Vector::operator- |
//--------------------------------------------------------------------------------------- |
// |
// Exterior (vector) cross product |
// |
//--------------------------------------------------------------------------------------- |
Vector Vector::operator^(Vector &v) |
{ |
Vector w; |
w.x = y * v.z - z * v.y; |
w.y = z * v.x - x * v.z; |
w.z = x * v.y - y * v.x; |
return w; |
} // Vector::operator^ |
//--------------------------------------------------------------------------------------- |
Vector Vector::normalize() |
{ |
GLdouble L = (GLdouble)std::sqrt(x * x + y * y + z * z); |
Vector w; |
if( L != 0.0 ) |
{ |
L = 1.0/L; |
w.x = L * x; |
w.y = L * y; |
w.z = L * z; |
} // if |
return w; |
} // Vector::normalize |
//--------------------------------------------------------------------------------------- |
Position Vector::position() |
{ |
Position p; |
p.x = x; |
p.y = y; |
p.z = z; |
return p; |
} // Vector::position |
//--------------------------------------------------------------------------------------- |
//--------------------------------------------------------------------------------------- |
#pragma mark - |
#pragma mark Utility Vector Function |
//--------------------------------------------------------------------------------------- |
static Position ComputeNormals(const Position *p, |
const Position *q, |
const Position *r) |
{ |
Vector u(p); |
Vector v(q); |
Vector w(r); |
Vector n; |
Vector dv; |
Vector dw; |
Position normals; |
dv = v - u; |
dv = dv.normalize(); |
dw = w - u; |
dw = dw.normalize(); |
n = dv ^ dw; |
n = n.normalize(); |
normals = n.position(); |
return normals; |
} // ComputeNormals |
//--------------------------------------------------------------------------------------- |
#pragma mark - |
#pragma mark Tranguloid Trefoil Geometry |
//--------------------------------------------------------------------------------------- |
// |
// Note that -Pi <= u <= Pi and -Pi <= v <= Pi |
// |
//--------------------------------------------------------------------------------------- |
static Position TranguloidTrefoilGeometry(const GLdouble u, |
const GLdouble v) |
{ |
Position p; |
GLdouble t = v + kTwoPiThird; |
GLdouble w = 2.0 * u; |
GLdouble A = 2.0 + cos(t); |
GLdouble B = 2.0 + cos(v); |
p.x = 2.0 * sin(3.0 * u) / B; |
p.y = 2.0 * (sin(u) + 2.0 * sin(w)) / A; |
p.z = 0.25 * (cos(u) - 2.0 * cos(w)) * A * B; |
return p; |
} // TranguloidTrefoilGeometry |
//--------------------------------------------------------------------------------------- |
static void NewTranguloidTrefoilSurface(Geometry *geometry) |
{ |
GLint i; |
GLint j; |
GLint maxI = geometry->rows; |
GLint maxJ = geometry->columns; |
GLdouble invMaxI = 1.0 / (GLdouble)maxI; |
GLdouble invMaxJ = 1.0 / (GLdouble)maxJ; |
GLdouble delta = 0.0005; |
GLdouble u[2]; |
Vertex vertex; |
Position position[2]; |
for(i = 0; i < maxI; i++) |
{ |
for(j = 0; j < maxJ; j++) |
{ |
u[0] = kTwoPi * (i % maxI) * invMaxI - kPi; |
u[1] = kTwoPi * (j % maxJ) * invMaxJ - kPi; |
vertex.positions = TranguloidTrefoilGeometry(u[0], u[1]); |
position[0] = TranguloidTrefoilGeometry(u[0] + delta, u[1]); |
position[1] = TranguloidTrefoilGeometry(u[0], u[1] + delta); |
vertex.normals = ComputeNormals(&vertex.positions, &position[0], &position[1]); |
vertex.texCoords.s = (GLdouble)i * invMaxI * 5.0; |
vertex.texCoords.t = (GLdouble)j * invMaxJ; |
geometry->vertices.push_back(vertex); |
} // for |
} // for |
} // NewTranguloidTrefoilSurface |
//--------------------------------------------------------------------------------------- |
static void BuildVertex(const GLint index, |
Geometry *geometry) |
{ |
glNormal3dv(geometry->vertices[index].normals.P); |
glTexCoord2dv(geometry->vertices[index].texCoords.T); |
glVertex3dv(geometry->vertices[index].positions.P); |
} // BuildVertex |
//--------------------------------------------------------------------------------------- |
static GLuint NewTranguloidTrefoilDisplayList(Geometry *geometry) |
{ |
GLint i; |
GLint j; |
GLint k; |
GLint l; |
GLint m; |
GLint maxI = geometry->rows; |
GLint maxJ = geometry->columns; |
GLuint displayList; |
displayList = glGenLists(1); |
glNewList(displayList, GL_COMPILE); |
for(i = 0; i < maxI; i++) |
{ |
glBegin(GL_TRIANGLE_STRIP); |
for(j = 0; j <= maxJ; j++) |
{ |
m = (j % maxJ); |
k = (i % maxI) * maxJ + m; |
BuildVertex(k, geometry); |
l = ((i + 1) % maxI) * maxJ + m; |
BuildVertex(l, geometry); |
} // for |
glEnd(); |
} // for |
glEndList(); |
return displayList; |
} // NewTranguloidTrefoilDisplayList |
//--------------------------------------------------------------------------------------- |
static GLuint GetTranguloidTrefoilDisplayList(const GLuint subdivisions, |
const GLuint xyRatio) |
{ |
Geometry geometry; |
GLuint displayList = 0; |
geometry.rows = subdivisions * xyRatio; |
geometry.columns = subdivisions; |
// Build surface |
NewTranguloidTrefoilSurface(&geometry); |
// Now get the display list |
displayList = NewTranguloidTrefoilDisplayList(&geometry); |
return displayList; |
} // GetTranguloidTrefoilDisplayList |
//--------------------------------------------------------------------------------------- |
//--------------------------------------------------------------------------------------- |
#pragma mark - |
//--------------------------------------------------------------------------------------- |
@implementation TranguloidTrefoil |
//--------------------------------------------------------------------------------------- |
- (id) initTranguloidTrefoilWithAttribbutes:(const GLuint)theSubdivisions |
ratio:(const GLuint)theRatio |
{ |
self = [super init]; |
if( self ) |
{ |
displayList = GetTranguloidTrefoilDisplayList(theSubdivisions, theRatio); |
} // if |
return self; |
} // init |
//--------------------------------------------------------------------------------------- |
- (GLuint) displayList |
{ |
return displayList; |
} // displayList |
//--------------------------------------------------------------------------------------- |
- (void) dealloc |
{ |
// delete the last used display list |
if(displayList) |
{ |
glDeleteLists(displayList, 1); |
} // if |
[super dealloc]; |
} // dealloc |
//--------------------------------------------------------------------------------------- |
@end |
//--------------------------------------------------------------------------------------- |
//--------------------------------------------------------------------------------------- |
Copyright © 2008 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2008-07-30