Blog
Blog
How to draw a sphere in 3D
Thursday, 16 April 2009
Working through the OpenGl SuperBible, and converting the examples for the iPhone, I came across a problem – the book’s use of GLUT makes sphere drawing a simple task. Just a quick call to glutSolidSphere and it’s done. This, of course, isn’t available on the iPhone, so I needed to figure out some way create a sphere myself. Maybe my Googling ability isn’t up to par, but I struggled to find much useful info out there... I guess most other people have GLUT to rely on.
Luckily though, I do have a copy of Kreyszig’s Advanced Engineering Mathematics gathering dust on a shelf, and page 493 gave me:
which translates into:
The tricky bit was figuring out the path for the triangle strips, but a bit of trial and error gave me the following:
Source for exercises up to 4.1 here: files.me.com/ashleymills/jg2uam.
It took a while, but doesn’t it look beautiful... in a mathematical way.
A sphere x2 + y2 + z2 = a2 can be represented as
r (u,v) = a cos v cos u i + a cos v sin u j + a sin v k
for 0 ≤ u ≤ 2π and -π/2 ≤ u ≤ π/2
x =a cos v cos u y = a cos v sin u z = a sin v
int createSphere (GLfloat spherePoints[], GLfloat fRadius, GLfloat step)
{
int points = 0;
GLfloat uStep = DEGREES_TO_RADIANS (step);
GLfloat vStep = uStep;
for (GLfloat u = 0.0f; u <= (2 * M_PI); u += uStep) {
for (GLfloat v = -M_PI_2; v <= M_PI_2; v += vStep) {
// Point as per equation
points++;
spherePoints[(points - 1) * 3] = fRadius * cosf(v) * cosf(u); // x
spherePoints[((points - 1) * 3) + 1] = fRadius * cosf(v) * sinf(u); // y
spherePoints[((points - 1) * 3) + 2] = fRadius * sinf(v); // z
// Next point around
points++;
spherePoints[(points - 1) * 3] = fRadius * cosf(v) * cosf(u + uStep); // x
spherePoints[((points - 1) * 3) + 1] = fRadius * cosf(v) * sinf(u + uStep); // y
spherePoints[((points - 1) * 3) + 2] = fRadius * sinf(v); // z
// Next point up
points++;
spherePoints[(points - 1) * 3] = fRadius * cosf(v + vStep) * cosf(u); // x
spherePoints[((points - 1) * 3) + 1] = fRadius * cosf(v + vStep) * sinf(u); // y
spherePoints[((points - 1) * 3) + 2] = fRadius * sinf(v + vStep); // z
// Next point up and around
points++;
spherePoints[(points - 1) * 3] = fRadius * cosf(v + vStep) * cosf(u + uStep); // x
spherePoints[((points - 1) * 3) + 1] = fRadius * cosf(v + vStep) * sinf(u + uStep); // y
spherePoints[((points - 1) * 3) + 2] = fRadius * sinf(v + vStep); // z
}
}
return points;
}