Creating the Shape of a Baseball Seam in POV-Ray

sample image

Occasionally someone asks in one of the POV-Ray or other 3D graphics forums: "How do I make a shape or path like a baseball seam?" This page answers the question, with explanations.

The equations come out fairly simple, if not obvious. The curve that the seam follows is a closed loop, a topological circle, so I parametrize the points along it with an angle α with no direct geometric meaning, running from 0 to 360 degrees. (If you didn't see a lower case alpha, then your browser isn't understanding HTML entities for Greek letters -- α and the like, or it's not using the Symbol font.)

We create the basic formula in two steps, with some further steps that may be useful depending on what you're using the formula for.

  1. Guess a formula for <x,y,z> coordinates for a point S (for Seam) as a function of α Aim for the right general shape, with the right symmetries but don't worry about distance from the origin.
  2. Normalize the length of the vector defined by S from the origin to a fixed value R, the radius of the baseball.
  3. The spacing of points along the seam may turn out to be uneven with steadily increasing α; we find some way to fix this.
  4. To place objects along the seam - stitches, bugs, buildings - we need to define directions and transforms to orient them sensibly.

With xyz axes defined and a sketch of a baseball, I derived formula by visualizing the baseball seam's curve in my mind, sketching it on paper, considering its symmetries, inflection points and such, then sketching crude plots of x(α), y(α), and z(α). Z(α) came out as a roughly cosine shape with a frequency of two cycles. The other two coordinates were sine and cosine but needed some dimples to reverse their peaks. This can be done by adding a harmonic of frequency of 3.


With a little more thought and refinement, and defining a couple constants, B and F, i wrote down this formula for the unnormalized x,y,z coordinates:

xu = cos(α) - B cos(3α)
yu = sin(α) + B sin(3α)
zu = F cos(2α)

B is a constant with a value in the range of about 0.4 to 0.8, with 0.6 or a little more being the best-looking. It controls the shape of the curve, how much the loops backfold. The middle transparent ball in 3D rendering above shows this the best - how the top and bottom loops of the seam bend to the center. If B is too big, they would touch. Too small, and they'd not backfold at all. When B is zero, the seam, seen in that orientation, would appear as a circle with a wave bending it in and out of the screen.

The other constant F doesn't have as much effect on the curve, but after my first attempt where i omitted it (assuming F=1) i discovered it's better to allow for it. The image shown at the top of this page, made during that first attempt, used B=0.6 and F=1.0 which certainly looks baseballseamesque.

Of course, you may use any crazy values for B and F you like for making wild shapes.


B=0.4
F=1.0
B=0.6
F=1.0
B=0.8
F=1.0
click for larger image

Step Two is basic 3D math. A seam point S(α) should be on a sphere of radius R, but we have are given the unnormalized point <xu, yu, zu>.

ru2 =  xu2 +  yu2 +  zu2
    = 1+B2 + (F2-2B) cos2(2α)  + 2 B sin2(2α)
x = R xu / ru
y = R yu / ru
z = R zu / ru

Use these final x,y,z values for points of the seam. If you are puzzling over the algebra, try using a trig formula derivable from the real component of e3iθe = (e2iθ)2.

Note that the distance of the point, before we normalize it, varies with α in a way involving sin2(2α) and cos2(2α); if we choose B and F so that

F2 - 2B = 2 B
F2 = 4B
F = 2 sqrt(B)

then these terms will simplify to a constant. We then have ru = 1+B. This is not necessary, but an intersting case to remember.

A Simple POV Script

bbseam.pov is the file used to make the image shown above, using the math we've developed so far. Small balls are place along the path of the seam, one at every 5 degrees of angle A. One Seam object is declared and used repeatedly to make several baseballs.

I used color dispersion with glassy baseballs to make the image interesting, and show the seam from many angles. The script should work fine with any POV-Ray from 3.5 on, and Mega-POV. I think i used version 3.1g once upon a time. (This script has been revised since the original posting of these pages in 1999. Back then, I had hacked a bizarre 9-component color space to implement color dispersion with metamerism effects.)

Watching the Speedometer

As the seam-tracing parameter α increases, do we get points evenly spaced along the seam? By differentiating the coordinates <x,y,z> w.r.t. α, and now taking α as measured in radians, we define a velocity vector V:

Vx = -sin(α) + 3Bsin(3α)
Vy = cos(α) + 3Bcos(3α)
Vz = -2Fsin(2α)


V2 = 1 + 9B2 +  6Bcos2(2α) + (4F-6B)sin2(2α)
   = 1 + 9B2 + 6B+4(F-3B)sin2(2α)

Magic Numbers

Hmmm, if we choose F=3B, we get constant speed for free. Earlier, we had found a constant unnormalized radius by setting F2 = 4B. If we insist on both, we find B=4/9= 0.444… which is somewhat short of the artistic ideal of B near 0.6 found earlier. But then, we're now setting F=4/3 instead of F=1 like we had before - we might as well render an image to see what these "magic" numbers lead to:


Hey, looks great! Except for the even spacing of the beads along the seam path, it looks quite similar the B=0.6, F=1.0 case. Well let us officially adopt the values:

B = 4/9 = 0.4444…
F = 4/3
ru2 = 13/9
V2 =  1 + 9B2 + 6B
(geometry units per radian)

x = (1/13)R[9 cos(α) - 4 cos(3α)]
y = (1/13)R[9 sin(α) + 4 sin(3α)]
z = (12/13)R cos(2α)

A Travelling Triad

So far all we've done is find points along a seam. In a real projects, we would probably want to position complex objects in proper orientation along the seam, for example, a element of a stitch, to be repeated along the entire path. To do this we need a way of defining directions relative to the curve at any point along it. A set of mutuallly perpendicular, unit-lengths vectors, known as a triad, can be set up at each point along the seam with a little easy differential calculus.

One direction easily defined - the "V" vector we just defined above. This points straight along the curve.

Another direction easily defined is simply radially away from the center of the baseball - normal to the baseball's surface at any point along the seam. Call this N If for some given α our point S(α) is at <x, y, z> then N is simply <x, y, z> normalized to unit length.

The third unit vector in the travelling triad, call it W for sideWays, is just the cross product of V and N. If you were an ant walking along the seam in the direction of increasing α, W would always point to your right.

It is not worth the bother to write out an mathematical expression for W in terms of trig functions. V and N are easy enough to calculate, and all we need to do for W is figure a cross product, and be careful about normalizing.

Vx = -sin(α) + (4/3)sin(3α)
Vy = cos(α) + (4/3)cos(3α)
Vz = -(8/3)sin(2α)

V = vnormalize(V)

Nx = x(α)/R
Ny = y(α)/R
Nz = z(α)/R

Wx = VyNz - VzNy
Wy = VzNx - VxNz
Wz = VxNy - VyNx

A Stitchy POV Script

bbstitch.pov will paint a baseball with sorta-realistic stitches, using the triad of vectors to define the endpoints of each stitch. It uses the seam computation macro defined in bbcommon.povi which may also have some nice baseball-related textures.

Other Web Pages

Paul Bourke at Swinburne has a page describing a baseball seam curve using trig functions phase modulated by more trig functions. Not as analytically tractable as our truncated harmonic series. But he has pages describing many other interesting curves, the websurfing of which could kill for you a whole day of precious time.

Auto-CAD users may like this tutorial that creates a baseball seam with stitching using four circular arcs and Auto-CAD's ability to replicate objects and holes.



For questions, comments, beer critiquing sessions, or if you wish to make an irresponsibly large donation, contact Daren Scot Wilson at GreenSquiggle@comcast.com.
Last Updated June 18th, 2006
Previous major update: summer 1998.