Skip to content

Commit

Permalink
Generalize sphere tessellation to other spherical shapes.
Browse files Browse the repository at this point in the history
  • Loading branch information
deanm committed Jul 4, 2010
1 parent c814e90 commit 097ef80
Showing 1 changed file with 25 additions and 13 deletions.
38 changes: 25 additions & 13 deletions pre3d_shape_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -292,16 +292,15 @@ Pre3d.ShapeUtils = (function() {
return s;
}

// Tessellate a sphere. There will be |tess_y| + 2 vertices along the Y-axis
// Tessellate a spherical parametric equation.
// (two extras are for zenith and azimuth). There will be |tess_x| vertices
// along the X-axis. It is centered on the Y-axis. It has a radius |r|.
// The implementation is probably still a bit convulted. We just handle the
// middle points like a grid, and special case zenith/aximuth, since we want
// them to share a vertex anyway. The math is pretty much standard spherical
// coordinates, except that we map {x, y, z} -> {z, x, y}. |tess_x| is phi,
// and |tess_y| is theta.
// TODO(deanm): This code could definitely be more efficent.
function makeSphere(r, tess_x, tess_y) {
function makeSphericalShape(f, tess_x, tess_y) {
// TODO(deanm): Preallocate the arrays to the final size.
var vertices = [ ];
var quads = [ ];
Expand All @@ -314,15 +313,8 @@ Pre3d.ShapeUtils = (function() {
for (var i = 0, theta = theta_step;
i < tess_y;
++i, theta += theta_step) { // theta
var sin_theta = Math.sin(theta);
var cos_theta = Math.cos(theta);
for (var j = 0; j < tess_x; ++j) { // phi
var phi = phi_step * j;
vertices.push({
x: r * sin_theta * Math.sin(phi),
y: r * cos_theta,
z: r * sin_theta * Math.cos(phi)
});
vertices.push(f(theta, phi_step * j));
}
}

Expand All @@ -345,8 +337,8 @@ Pre3d.ShapeUtils = (function() {
var last_row = vertices.length - tess_x;
var top_p_i = vertices.length;
var bot_p_i = top_p_i + 1;
vertices.push({x: 0, y: r, z: 0});
vertices.push({x: 0, y: -r, z: 0});
vertices.push(f(0, 0));
vertices.push(f(Math.PI, 0));

for (var i = 0; i < tess_x; ++i) {
// Top triangles...
Expand Down Expand Up @@ -396,6 +388,25 @@ Pre3d.ShapeUtils = (function() {
return s;
}

// Tessellate a sphere. There will be |tess_y| + 2 vertices along the Y-axis
// (two extras are for zenith and azimuth). There will be |tess_x| vertices
// along the X-axis. It is centered on the Y-axis. It has a radius |r|.
// The implementation is probably still a bit convulted. We just handle the
// middle points like a grid, and special case zenith/aximuth, since we want
// them to share a vertex anyway. The math is pretty much standard spherical
// coordinates, except that we map {x, y, z} -> {z, x, y}. |tess_x| is phi,
// and |tess_y| is theta.
// TODO(deanm): This code could definitely be more efficent.
function makeSphere(r, tess_x, tess_y) {
return makeSphericalShape(function(theta, phi) {
return {
x: r * Math.sin(theta) * Math.sin(phi),
y: r * Math.cos(theta),
z: r * Math.sin(theta) * Math.cos(phi)
};
}, tess_x, tess_y);
}

// Smooth a Shape by averaging the vertices / faces. This is something like
// Catmull-Clark, but without the proper weighting. The |m| argument is the
// amount to smooth, between 0 and 1, 0 being no smoothing.
Expand Down Expand Up @@ -785,6 +796,7 @@ Pre3d.ShapeUtils = (function() {
makeCube: makeCube,
makeBox: makeBox,
makeBoxWithHole: makeBoxWithHole,
makeSphericalShape: makeSphericalShape,
makeSphere: makeSphere,
makeOctahedron: makeOctahedron,

Expand Down

0 comments on commit 097ef80

Please sign in to comment.