Skip to content

PhysicsUtils

A collection of physics-related mathematical utilities for handling angles, force vectors, and linear regression calculations.


📐 Core Functions

normalizeAngle(angle: number): number

Normalizes any angle to the 0-360 degree range.

Formula:

angle % 360 + (angle < 0 ? 360 : 0)

Usage Example:

PhysicsUtils.normalizeAngle(450); // Returns 90
PhysicsUtils.normalizeAngle(-90); // Returns 270

normalizeForceToAngle(v: Vec2D, angle: number, ratio: number): Vec2D

Blends a vector towards a specific angle while preserving magnitude.

Operation:

  1. Scales original vector by (1 - ratio)
  2. Creates new vector at target angle scaled by ratio
  3. Sums both vectors

Visualization:

graph LR
A[Original Vector] --> B[Scaled Down]
C[New Angle Vector] --> D[Scaled Up]
B --> E[Sum]
D --> E

linearRegression(samples: Vec2D[]): [number, number]

Calculates best-fit line through points using least squares method.

Returns:

  • [slope, y-intercept] for line equation y = ax + b
  • Special case: [Infinity, x-intercept] for vertical lines

Edge Cases:

CaseReturn ValueDescription
Empty/1-point array[0, 0]Warning logged
Perfect vertical line[Infinity, xPos]No error thrown

🧮 Mathematical Foundations

Linear Regression Formula

For n points:

slope (a) = (nΣxy - ΣxΣy) / (nΣx² - (Σx)²)
intercept (b) = (Σy - aΣx) / n

Special Cases Handling

  1. Vertical Line:

    • Detected when denominator = 0
    • Returns [Infinity, x-intercept]
  2. Insufficient Points:

    • Minimum 2 points required for valid regression
    • Gracefully falls back to [0, 0]

🏎️ Practical Applications

Force Normalization

Used in vehicle physics to:

  • Gradually align forces with vehicle orientation
  • Simulate traction/slippage effects

Angle Normalization

Critical for:

  • Sprite rotation calculations
  • Consistent steering angle representation

Linear Regression

Applied in:

  • Collision normal estimation
  • AI path prediction
  • Debug visualization of collision edges

⚠️ Error Handling

FunctionError CaseBehavior
linearRegressionInsufficient pointsReturns [0,0] + warning
linearRegressionVertical lineReturns [Infinity, x]
All functionsInvalid inputsNo explicit validation

📈 Performance Characteristics

FunctionTime ComplexityNotes
normalizeAngleO(1)Single modulo operation
normalizeForceToAngleO(1)Fixed vector operations
linearRegressionO(n)Single pass through points

💡 Usage Tips

  1. Check for Infinity:

    const [slope, intercept] = PhysicsUtils.linearRegression(points);
    if (slope === Infinity) {
    // Handle vertical line case
    }
  2. Ratio Selection:

    • Typical ratio values: 0.05-0.2 for smooth force alignment
    • Higher values = more aggressive normalization
  3. Debugging:

    • Log warnings from linearRegression indicate edge cases
    • Visualize regression results for validation

🧪 Test Cases

normalizeAngle

test("normalizes 450° to 90°", () => {
expect(PhysicsUtils.normalizeAngle(450)).toBe(90);
});

linearRegression

test("handles vertical line", () => {
const points = [{x:5,y:0}, {x:5,y:10}];
expect(PhysicsUtils.linearRegression(points)).toEqual([Infinity, 5]);
});