Simulating Motor Protein Transport in Matter.js

This article explains how to simulate biological motor protein cargo transport along microtubule filaments using the Matter.js 2D physics engine. You will learn how to represent biological components—such as microtubules, motor heads (like kinesin), and vesicle cargo—as rigid bodies and constraints, while applying low Reynolds number dynamics, Brownian thermal noise, and step-wise propulsion to realistically mimic intracellular transport.

1. Conceptual Mapping to Matter.js

To model intracellular transport, biological structures must be mapped to 2D rigid body mechanics:

2. Setting Up the Environment

Intracellular environments operate at very low Reynolds numbers, meaning viscous drag dominates over inertia. Set the world's standard gravity to zero and apply high frictionAir to the cargo to simulate the viscosity of the cytosol.

const { Engine, Render, Runner, Bodies, Composite, Constraint, Body, Vector } = Matter;

const engine = Engine.create({
    gravity: { x: 0, y: 0, scale: 0 }
});

3. Creating Track, Motor, and Cargo Bodies

Define the static microtubule track, the stepping motor unit, and the suspended cargo.

// Microtubule track
const track = Bodies.rectangle(400, 300, 700, 10, {
    isStatic: true,
    isSensor: true, // Prevents physical collisions with the motor
    render: { fillStyle: '#4CAF50' }
});

// Cargo vesicle
const cargo = Bodies.circle(100, 240, 30, {
    mass: 5,
    frictionAir: 0.15, // High drag to simulate cytosol
    render: { fillStyle: '#FF5722' }
});

// Motor head
const motor = Bodies.circle(100, 290, 8, {
    mass: 0.5,
    frictionAir: 0.2,
    render: { fillStyle: '#2196F3' }
});

// Tether between motor and cargo
const tether = Constraint.create({
    bodyA: motor,
    bodyB: cargo,
    stiffness: 0.05,
    damping: 0.01,
    render: { strokeStyle: '#9E9E9E', lineWidth: 2 }
});

Composite.add(engine.world, [track, cargo, motor, tether]);

4. Simulating the Stepping Mechanism

Motor proteins like kinesin move processively along microtubules in discrete, hand-over-hand steps (typically 8 nm per ATP hydrolyzed). In Matter.js, this is simulated using an event loop listener (beforeUpdate) that applies intermittent forward forces or positional displacements along the track's directional vector.

const stepSize = 4; // Visual step magnitude
const stepInterval = 15; // Engine ticks between steps
let tick = 0;

Matter.Events.on(engine, 'beforeUpdate', () => {
    tick++;

    // Step-wise forward movement along the track (X-axis)
    if (tick % stepInterval === 0 && motor.position.x < 700) {
        Body.setPosition(motor, {
            x: motor.position.x + stepSize,
            y: track.position.y - 10
        });
    }

    // Brownian motion: Apply slight random thermal forces to cargo
    const thermalForce = Vector.create(
        (Math.random() - 0.5) * 0.002,
        (Math.random() - 0.5) * 0.002
    );
    Body.applyForce(cargo, cargo.position, thermalForce);
});

5. Tuning Physical Properties for Realism