FINAL
PROJECT: Explorations in the Superformula and Hexany using OpenGL
Ryan McGee | MAT 594CM | Spring 2009
THE SUPERFORMULA
updated video: better sounding FM synthesis and audio waveform visualization added:
additional screen captures:
Perhaps attracted by the formulaÕs name as well
as its ability to create highly complex 3D shapes with only a few adjustable
parameters, I decided to focus my efforts on visualizing and sonifying the Superformula
rather than my initial exploration of Hexany. Implementing the Superformula in OpenGL exposed me to
working with the spherical coordinate system in OpenGL for the first time. Animating morphing of the resulting
shapes from one to another required use of the GLUT timer function.
The Superformula
Code Implementation
|
void superForm(){ // draw the superformula using
sphereical coordinates if(drawMethod
== 1){ // choose drawing mode glBegin(GL_QUAD_STRIP); } else
if (drawMethod == 2){ glBegin(GL_LINE_STRIP); } else
if (drawMethod == 3){ glBegin(GL_TRIANGLE_STRIP); } else
if (drawMethod == 4){ glBegin(GL_POINTS); } else
if (drawMethod == 5){ glBegin(GL_POLYGON); } float
x, y, z; // cartesian
coordinates for(float
thetaDeg = 0; thetaDeg < 360; thetaDeg+=1){ // compute by theta float
theta = (thetaDeg/180.0)*3.1459; // calc. theta in radians for(float
phiDeg = 0; phiDeg < 180; phiDeg+=1){ // compute by phi float
phi = (phiDeg/180.0)*3.1459; //
calc. phi in radians r
= 1* (pow((pow((cos(m*phi/4)/a), (n2)) + pow((sin(m*phi/4)/b), (n3))),
(-1.0/n1))); // superformula x
= r * cos(phi)*sin(theta); // convert from spherical to cartesian coordinates y
= r * sin(phi)*sin(theta); z
= r * cos(theta); glVertex3f(x,
y, z); } } glEnd(); } |
By modifying m, n1, n2, and n3 one can create
several shapes that are all elliptical in their boundary (as the superformula
is an extension of the superellipse equation). Modifying a and b allows one to change the height and width
of the Òsuper ellipseÓ. I was
introduced to the glutTimer function, which I used to animate morphing between
various shapes by generating random parameters with the c++ rand function. The user can change the drawing mode
(point, line, triangle, quad, or polygon) at any time. Using a simple FM
synthesis equation in the RT Audio callback function, I mapped n1, n2, and n3
to modulation indices for sonify the superformula. Parameter m was used as a multiplier for the carrier
frequency and a and b were used to specify the gain for the left and right
channels respectively. The user can also change the root pitch of the
sonification at runtime.
Morphing Function
|
void morphTimer(int value){ double
inc = ((double)value/100); m
= oldM + inc*(newM-oldM); n1
= oldN1 + inc*(newN1-oldN1); n2
= oldN2 + inc*(newN2-oldN2); n3
= oldN3 + inc*(newN3-oldN3); a
= oldA + inc*(newA-oldA); b
= oldB + inc*(newB-oldB); superR
= oldSR + inc*(newSR - oldSR); superG
= oldSG + inc*(newSG - oldSG); superB
= oldSB + inc*(newSB - oldSB); value++; if(value
<= 100){ // has the timer
been called less than 100 times? glutTimerFunc(5,
morphTimer, value); // recall timer function } //
if timer has been called 100 times then exit } void morph(int v){ //store
old parameter values oldM
= m; oldN1
= n1; oldN2
= n2; oldN3
= n3; oldA
= a; oldB
= b; //store
old color values oldSR
= superR; oldSG
= superG; oldSB
= superB; //compute
new parameter and color values newM
= oldM + (double)(rand()%41); newN1
= oldN1 + (double)(rand()%41); newN2=
oldN2 + (double)(rand()%41); newN3=
oldN3 + (double)(rand()%41); newA
= oldA + (double)(rand()%6); newB
= oldB + (double)(rand()%6); newSR
= (float)(rand()%2566)/100;; newSG
= (float)(rand()%2566)/100;; newSB
= (float)(rand()%2566)/100;; glutTimerFunc(5,
morphTimer, v); // call the
timer function to start morphing } |
The result is a system of generative visuals and
sound all based on the superformula.
By repeatedly calling the morph function the user can create some very
cool stuttering visual and audio effects.
Using camera controls to zoom and pan allows one to explore all aspects
of each shape. In, the future the
program could be made more aesthetically pleasing by adding texturing to the
shapes and using more advanced audio synthesis routines.
Example Output:
INITIAL FINAL PROJECT: HEXANY
(attempt)
I was inspired by the concept of Hexany
to construct a bounded particle system in OpenGL that used collision detection
to play notes on the Hexany scale using RT Audio. The challenge of this project was to track the XYZ
coordinates of the vertices of the Hexany octahedrons as they rotated in space,
bounced off boundaries, and collided with other particles. In my implementation I was able to
construct a system of free-floating particles that bounced off a boundary and
responded with a sound corresponding to the boundary hit.
I could give the particles rotation using the
glRotate function, but was not able to implement the math for this myself. Thus, the system only is only accurate
for non-rotating particles. I did
not reach the point of detecting collisions between particles, but this project
introduced me to the complexities of detecting collisions on non-spherical
surfaces such as an octahedron.
|
|
|