Polar Coordinates

Thinking in angles and distances

So far, we have worked exclusively in Cartesian coordinates: x and y values that describe horizontal and vertical position. This system is intuitive for rectangles, grids, and straight lines. But some shapes are awkward to describe this way. Try drawing a circle in Cartesian coordinates, and you end up with square roots and implicit equations. Try describing a spiral, and the math becomes tangled.

There is another way to think about position in 2D space. Instead of asking "how far right and how far up?", we can ask "how far from the center, and in which direction?" This is the essence of polar coordinates.

From Cartesian to Polar

Every point in 2D space can be described by two numbers: its radius (distance from the origin) and its angle (direction from the positive x-axis). We call these r and theta.

Interactive: Explore Cartesian vs Polar

Cartesian
x = 2.00, y = 1.50
Polar
r = 2.50, angle = 37
Normalized angle: 0.602 (0 to 1)

Drag the point to explore polar coordinates

The conversion between coordinate systems is straightforward. Given a point at Cartesian coordinates (x, y):

  • Radius: r = length(vec2(x, y)) or equivalently sqrt(x*x + y*y)
  • Angle: theta = atan(y, x)

In GLSL, we can write this conversion as:

vec2 toPolar(vec2 p) {
  return vec2(length(p), atan(p.y, p.x));
}
glsl

The atan function with two arguments gives us the angle in radians, ranging from -PI to +PI. This is often called atan2 in other languages. The angle is measured counterclockwise from the positive x-axis.

Understanding the Angle

The angle returned by atan(y, x) spans from -PI (pointing left) through 0 (pointing right) to +PI (also pointing left, but approached from above). This range can be inconvenient. Often we want values normalized to 0-1 for easier manipulation.

To normalize the angle:

float angle = atan(p.y, p.x);
float normalized = (angle + 3.14159) / 6.28318;
glsl

Adding PI shifts the range from [-PI, PI] to [0, 2PI]. Dividing by 2PI maps it to [0, 1]. Now the angle sweeps smoothly from 0 to 1 as you rotate around the center.

Radial Patterns

The power of polar coordinates becomes apparent when you start using radius and angle to drive visual properties. The simplest example: a radial gradient.

Polar Gradients

Brightness decreases with distance from center

When brightness depends on radius alone, you get concentric circles. When it depends on angle alone, you get radiating lines. Combining both opens up infinite possibilities.

vec2 centered = uv * 2.0 - 1.0;
float r = length(centered);
float angle = atan(centered.y, centered.x);
 
float radialGradient = 1.0 - r;
float angularGradient = (angle + 3.14159) / 6.28318;
glsl

Spirals

Spirals emerge naturally when you combine angle and radius in a single expression. The key insight: a spiral is what happens when the "zero crossing" of a pattern depends on both how far out you are and what direction you are facing.

float spiral = fract(angle / 6.28318 + r * tightness);
glsl

Interactive: Spiral Generator

Spirals emerge from combining angle and radius

The fract function wraps values to the 0-1 range, creating repeating bands. Adding the radius term makes these bands twist outward. Multiplying the angle determines how many spiral arms appear. Multiplying the radius controls how tightly the spiral winds.

Star Shapes

Stars are perhaps the most elegant demonstration of polar thinking. A star is simply a shape where the radius varies with angle in a repeating pattern.

float star(vec2 p, float points, float inner, float outer) {
  float angle = atan(p.y, p.x);
  float segment = 6.28318 / points;
  float a = mod(angle + segment * 0.5, segment) - segment * 0.5;
  float r = mix(outer, inner, abs(a) / (segment * 0.5));
  return length(p) - r;
}
glsl

Interactive: Star Generator

Star shapes come from modulating radius by angle

The magic happens in the mod operation. By taking the angle modulo the segment size, we repeat the same pattern for each point of the star. The mix interpolates between the outer and inner radii based on how far through each segment we are.

A Gallery of Polar Patterns

Once you internalize polar thinking, patterns that seemed complex become simple. Concentric rings, radiating rays, polar checkerboards, flower petals: all emerge from basic operations on radius and angle.

Pattern Gallery

Each of these patterns uses the same fundamental approach: convert to polar coordinates, then apply familiar operations (sine waves, step functions, modular arithmetic) to the radius and angle values.

Animation in Polar Space

Polar coordinates shine for animation. Subtracting time from the angle creates rotation. Subtracting time from the radius creates expansion or contraction. Combining both creates mesmerizing spiral motion.

float spiral = sin(angle * 5.0 + r * 10.0 - u_time * 2.0);
float pulse = sin(r * 8.0 - u_time * 3.0);
glsl

Animated Polar Pattern

Animating polar patterns by subtracting time from angle and radius terms

The pattern seems to flow outward because we subtract time from terms that include radius. If we added time instead, it would flow inward. Adjusting the coefficients changes the speed and character of the motion.

When to Think in Polar

Polar coordinates are not always the right choice. For rectangular UI elements, grids, or text rendering, Cartesian coordinates remain more natural. But when your pattern has rotational symmetry, when it radiates from a center, or when you want circular motion, polar thinking often leads to simpler code.

The mental shift takes practice. Instead of thinking "move right and up," think "rotate and expand." Instead of "horizontal stripe," think "ring at a certain radius." The more you work with polar coordinates, the more intuitive this perspective becomes.

Key Takeaways

  • Polar coordinates describe position as radius (distance from center) and angle (direction)
  • Convert using length(p) for radius and atan(p.y, p.x) for angle
  • The angle ranges from -PI to PI; normalize to 0-1 with (angle + PI) / (2*PI)
  • Spirals combine angle and radius: fract(angle + r * tightness)
  • Stars modulate radius by angle using mod to create repeating segments
  • Subtracting time from angle or radius terms creates rotation or expansion
  • Use polar coordinates when patterns have radial symmetry or circular motion