flutter3d
Showcase Changelog 38 packages API reference

A Catmull-Rom path

since 0.4.0 or earlier Simulation, audio and XR

A cubic spline is naturally parameterised by a number that runs one unit a segment, and that number moves at a different speed everywhere along the curve. CatmullRom measures the curve once when it is built and takes distance in metres everywhere after that, which is what anything driving along a track actually wants.

Step 1: Build a closed loop #

Four points, a little over a metre from the centre, joined into a loop.

late final CatmullRom _track = CatmullRom(<Vector3>[
  Vector3(1.2, 0, 0),
  Vector3(0, 0, 1.2),
  Vector3(-1.2, 0, 0),
  Vector3(0, 0, -1.2),
]);

Step 2: Sample it by distance #

sampleAt writes the point a given distance along the curve into a vector. wrap brings a distance back into range, looping past the end of a closed curve instead of clamping.

@override
void update(DemoContext context, double dt) {
  distance = _track.wrap(distance + dt * 2.0);
  _track.sampleAt(distance, _point);
  _car.setPositionFrom(_point);
}

The car on this page advances two metres a second along the loop, wrapping back to the start once it has gone all the way round.

Step 3: Check it closes #

// A closed loop through four points three metres from the centre comes
// back to its own start.
final start = Vector3.zero();
_track.sampleAt(0.0, start);
final afterALap = Vector3.zero();
_track.sampleAt(_track.length, afterALap);
final gap = (start - afterALap).length;

Sampling at zero and at the curve's own length gives the same point, because a closed curve is exactly that: one loop, with no seam to fall off of.