BEVERLYQIN

Back to Projects

Particle-Based Crowd Dispersal Model

my role

Researcher, Developer, Designer

year

2025

contribution

Research, Design, Development

tools

C, Python, PCA Analysis

team

Robert Stott, Sanjay Kumar

Overview

This project demonstrates how low-level simulation programming and linear algebra (PCA, eigen decomposition, covariance matrices) can be combined to model real-world crowd dynamics and generate actionable insights for spatial planning.

Project Media

Crowd Dispersal Model

Problem Statement

This project combined systems programming in C with linear algebra and probability to model crowd dispersal in complex environments. I implemented a hybrid simulation engine where each agent is governed by mathematical force equations, and analyzed the emergent dynamics through matrix transformations and eigenvalue decomposition.

Forces and Behaviors Modeled with Linear Algebra

- POI and Negative POI Attraction and Repulsion

- Boundary and Exit Forces

- Gaussian Wander (Ornstein-Uhlenbeck like noise)

- Exponential exit-time sampling

- Spawn accumulator (constant-rate vs Bernoulli spawn) and clump breakup

- Initial POI selection

- POI visit threshold & continuous exit-urge

Example: Boids (Flocking) Mathematical Formulation

We've designed it such that agents attempt to separate, align, and cohere with their neighbors, inspired by algorithms like the one presented by Craig Reynolds in the 1987 paper “Flocks, Herds, and Schools: A Distributed Behavioral Model.” For each i, we compute for all j ≠ i within a certain neighbor-radius Rn:

Separation (S):

S = Σj wsep(dij) (xi - xj) / ||xi - xj||

Alignment (A):

A = Σj wali(dij) vj

Cohesion (C):

C = Σj wcoh(dij) xj

with exponential distance-weights:

wsep(d) = e(-d/λsep)

wali(d) = e(-d/λali)

wcoh(d) = e(-d/λcoh)

We then form unit-directions for the different behaviors and scale with user-tunable weights αsep, αali, αcoh before adding up to ai.

Implementation

// --- Boids flocking ---
for(int i=0;i<count;i++){
    Vec2 sep={0,0}, align={0,0}, coh={0,0};
    float ss=0, sa=0, sc=0;
    
    for(int j=0;j<count;j++) if(j!=i){
        Vec2 d = vsub(agents[j].pos, agents[i].pos);
        float dist = vlen(d);
        
        if(dist < NEIGHBOR_RADIUS){
            float wsep = expf(-dist/SEP_DECAY);
            sep = vadd(sep, vmul(vnorm(vsub(agents[i].pos,agents[j].pos)),wsep));
            ss += wsep;
            
            float wal = expf(-dist/ALIGN_DECAY);
            align = vadd(align, vmul(agents[j].vel,wal));
            sa += wal;
            
            float wco = expf(-dist/COH_DECAY);
            coh = vadd(coh, vmul(agents[j].pos,wco));
            sc += wco;
        }
    }
    
    if(sc>0){
        Vec2 dir = vnorm(vsub(vmul(coh,1.0f/sc), agents[i].pos));
        agents[i].acc = vadd(agents[i].acc, vmul(dir, COH_WEIGHT));
    }
    if(sa>0){
        Vec2 dir = vnorm(vsub(vmul(align,1.0f/sa), agents[i].vel));
        agents[i].acc = vadd(agents[i].acc, vmul(dir, ALIGN_WEIGHT));
    }
    if(ss>0){
        Vec2 dir = vnorm(sep);
        agents[i].acc = vadd(agents[i].acc, vmul(dir, SEP_WEIGHT));
    }
}

Methodology

Our simulation integrates both physics-based and rule-based models:

- Social Repulsion – modified from Helbing's Social Force Model to prevent collisions.

- Flocking Behaviors – adapted from Reynolds' Boids model for alignment, separation, and cohesion.

- Attraction to POIs – inverse-square forces toward stalls, entrances, and exits.

- Boundary Forces – keep agents within Plaza limits.

- Gaussian Noise – introduce natural randomness and wandering

PCA Process - Pattern Analysis

Principal Component Analysis (PCA) visualizes changes in multivariable data sets. We collect raw positional, velocity, and time data, then calculate derived metrics per agent over 600 seconds:

A principal component analysis graph comparing principal components 1 and 2. PC1 accounts for 37.8% of the total dataset variance, and PC2 accounts for 29.0% of the variance. In total, their 2-dimensional space accounts for 66.8% of the variance observed across all 7 experimental conditions.

Each dot represents one specific agent (person) in its respective simulation. The color is defined by the experimental condition where motion algorithms were removed: Boid's Flocking, Family Spawning, Noise, Pedestrian-Pedestrian Repulsion, POI Attraction and Neg POI Repulsion, POI goal, and standard conditions. Each condition has a corresponding statistical ellipse covering a 95% confidence interval.

- mean speed

- speed standard deviation

- total displacement

- path length

- tortuosity (path length / total displacement)

- visited count (max number of POI visited)

- mean exit urge

Data is cleaned by scaling, removing outliers, and eliminating NA values. We use standard processing: mean centering and dividing by standard deviation.

The covariance matrix C = (1/(n-1)) A · AT is computed from the normalized matrix A. We then calculate eigenvalues λ₁ ≥ λ₂ ≥ ... ≥ λp and eigenvectors, projecting the transformation to obtain principal components P = A · S. Principal components are organized by variance explained, with the first component describing the most variance in the data.

Results

PCA Analysis Results

PCA Analysis Graph

Figure 1: PCA of Per-Agent Summary Metrics Across Ablation Study Conditions

A principal component analysis graph comparing principal components 1 and 2. PC1 accounts for 37.8% of the total dataset variance, and PC2 accounts for 29.0% of the variance. In total, their 2-dimensional space accounts for 66.8% of the variance observed across all 7 experimental conditions.

Each dot represents one specific agent (person) in its respective simulation. The color is defined by the experimental condition where motion algorithms were removed: Boid's Flocking, Family Spawning, Noise, Pedestrian-Pedestrian Repulsion, POI Attraction and Neg POI Repulsion, POI goal, and standard conditions. Each condition has a corresponding statistical ellipse covering a 95% confidence interval.