What Is the Purpose of a Gear Joint in Planck.js?

In planck.js (the JavaScript rewrite of the Box2D physics engine), a Gear Joint is a specialized joint used to couple the movement of two other joints—specifically Revolute or Prismatic joints. By linking these joints, a Gear Joint enforces a strict coordinate constraint where the motion of one joint directly drives the motion of the other based on a defined gear ratio. This article explores how the Gear Joint functions, its unique requirements, and how to implement it effectively in your 2D physics simulations.

The Mechanics of a Planck.js Gear Joint

Unlike most joints that directly connect two rigid bodies, a Gear Joint acts as a coordinator between two other joints. These input joints must be attached to dynamic bodies and can only be a combination of:

When you turn one joint, the Gear Joint automatically calculates and applies the necessary forces to move the second joint. This allows you to simulate complex mechanical systems like clocks, car differentials, and pulley mechanisms without needing to manually calculate torque or forces.

Key Properties and Behavior

To understand how a Gear Joint alters the simulation, you need to understand its core configurations:

1. The Gear Ratio

The most critical property is the ratio. It defines how much the second joint moves in relation to the first joint.

2. Strict Constraints and the “Ground” Body

A Gear Joint requires a static “ground” body to serve as a reference point for the simulation’s internal coordinate math. Because it enforces a strict algebraic constraint between the two joints, it does not simulate realistic tooth-slipping or physical friction unless you explicitly program those forces elsewhere.

Implementing a Gear Joint

To create a Gear Joint, you must first instantiate the two joints you wish to connect.

// Step 1: Create the two base joints (e.g., two Revolute Joints)
const joint1 = world.createJoint(pl.RevoluteJoint({}, bodyA, bodyB, anchorA));
const joint2 = world.createJoint(pl.RevoluteJoint({}, bodyC, bodyD, anchorB));

// Step 2: Configure and create the Gear Joint
const gearJointDef = {
  joint1: joint1,
  joint2: joint2,
  ratio: 2.0 // Body D will rotate at twice the speed (or half, depending on orientation) of Body B
};

const gearJoint = world.createJoint(pl.GearJoint(gearJointDef));

Why Use a Gear Joint Over Physical Geometry?

While you could technically create gears by modeling individual teeth on circular bodies using polygon shapes, doing so is incredibly resource-intensive for a physics engine. Rigid body contact points can glitch, overlap, or cause jitter.

The Gear Joint provides a perfectly smooth, computationally lightweight alternative. It completely bypasses the need for complex collision detection by solving the rotational math directly in the physics solver, ensuring your mechanical simulations run flawlessly at 60 frames per second.