Skip to content

Bezier utility

This module provides tools for parsing SVG path data and generating evenly spaced points along the path with curvature information. It’s particularly useful for game development, animation systems, and any application requiring precise path following.

Functions

parseSVGPath(svgPath: string): SVGCommand[]

Parses an SVG path string into a structured array of commands.

Parameters:

  • svgPath (string): The SVG path data string (e.g., “M10,10 L20,20 C30,30,40,40,50,50”)

Returns: Array of SVGCommand objects representing each path segment

Supported Commands:

CommandDescriptionRequired Properties
M/mMove tox, y
L/lLine tox, y
H/hHorizontal linex
V/vVertical liney
C/cCubic Beziercp1x, cp1y, cp2x, cp2y, x, y
Q/qQuadratic Beziercp1x, cp1y, x, y
Z/zClose path(none)

Example:

const commands = parseSVGPath("M0,0 L100,100 Q150,50 200,100");
// Returns:
// [
// { type: 'M', x: 0, y: 0 },
// { type: 'L', x: 100, y: 100 },
// { type: 'Q', cp1x: 150, cp1y: 50, x: 200, y: 100 }
// ]

getEvenlySpacedPoints(commands: SVGCommand[], numPoints: number): CheckPoint[]

Generates evenly spaced points along the path with tangent and curvature data.

Parameters:

  • commands: Array of parsed SVG commands
  • numPoints: Number of points to generate per segment

Returns: Array of CheckPoint objects containing:

  • point: { x, y } coordinates
  • tangent: Normalized direction vector
  • curvature: Curvature at this point (0 for straight lines)

Sampling Details:

  • Bezier Curves: Uses the bezier-js library for precise sampling
  • Straight Lines: Linear interpolation between points
  • Closed Paths (Z): Automatically connects back to the start point

Example:

const points = getEvenlySpacedPoints(commands, 10);
// Returns array of 10 points per segment with curvature data

Data Structures

SVGCommand

interface SVGCommand {
type: 'M'|'L'|'C'|'Q'|'V'|'H'|'Z';
x?: number;
y?: number;
cp1x?: number;
cp1y?: number;
cp2x?: number;
cp2y?: number;
}

CheckPoint

interface CheckPoint {
point: Vec2D;
tangent: Vec2D;
curvature: number;
}

Advanced Usage

Handling Relative Commands

The parser automatically converts relative commands (lowercase) to absolute coordinates for consistent processing.

Debugging Tips

// Visualize tangents:
points.forEach(p => {
drawLine(p.point, Vector.add(p.point, Vector.scale(p.tangent, 10)));
});
// Highlight high-curvature areas:
points.filter(p => p.curvature > 0.1).forEach(p => {
drawCircle(p.point, 5, 'red');
});