Skip to documentation
Documentation / Programming

Bézier paths & heading

Describe curved motion while keeping mecanum heading independent of travel direction.

A curve with fixed heading

Pass two control points for a line, three for a quadratic Bézier, or four for a cubic Bézier. Only their x/y coordinates define the curve; control-point headings are ignored.

This example moves along a quadratic curve while the robot keeps facing field +X, which represents strafing. Geometry does not send commands to motors.

Java · fixed-heading curve
import dev.cubiclib.path.BezierPath;
import dev.cubiclib.odometry.Pose2;

BezierPath curve = BezierPath.constantHeading(0,
    new Pose2(400, 400, 0),
    new Pose2(800, 1200, 0),
    new Pose2(1600, 1200, 0));

Pose2 halfway = curve.at(0.5);
// halfway.heading remains 0 radians.

Interpolate robot heading

Heading interpolation follows the shortest angular arc independently of the translation curve. From 170° to −170°, the robot rotates 20°, not 340°.

Java · cubic curve
BezierPath turning = BezierPath.interpolateHeading(
    Math.toRadians(170), Math.toRadians(-170),
    new Pose2(400, 400, 0), new Pose2(800, 1200, 0),
    new Pose2(1200, 1200, 0), new Pose2(1600, 400, 0));

Pose2 target = turning.at(0.5);
double travelDirection = turning.tangentHeading(0.5);
double lengthMm = turning.approximateLength(100);

Parameters, samples and limits

at(t) accepts t from 0 to 1. t is a curve parameter, not elapsed time or normalized distance: equal t steps need not move equal distances. sample(100) returns 101 poses; approximateLength(100) estimates length from those samples.

tangentHeading(t) gives travel direction, not robot orientation, and throws when the tangent is stationary. Bézier geometry is not collision-checked by the Java class.

Dashboard route suggestions separately round corners only when recursive control-point bounds prove field clearance. CubicLib has no autonomous follower, velocity profile or automatic motor output for these curves.