A flexible, modular package for running physics-based collision experiments with configurable conditions and visualization.
physicsTask/
├── core/
│ └── engine.py # Physics engine (entities, boundaries, collision detection)
├── experiment/
│ ├── conditions.py # Flexible condition configuration system
│ └── runner.py # ExperimentRunner for executing trials
├── visualization/
│ └── display.py # PyGame visualization
├── utils/
│ ├── analysis.py # Trajectory analysis and data loading utilities
│ ├── coordinates.py # Coordinate system calculations
│ └── plotting.py # Matplotlib plotting helpers
├── scripts/
│ ├── run_single.py # CLI: run a single trial
│ ├── run_batch.py # CLI: run batch experiments (programmatic design)
│ ├── run_from_config.py # CLI: run experiments from YAML/JSON config
│ ├── visualize.py # CLI: PyGame playback of results
│ └── generate_gifs.py # CLI: generate GIFs (--failures for failed trials)
├── config/ # Versioned experiment configurations (v2-v5)
└── examples/
├── example_batch_data.npy # Pre-computed 5-trial dataset (ready to visualize)
└── example_gifs/ # Pre-rendered GIFs of example trials
# Quick demo: generate 5 trials with GIFs
python -m physicsTask.scripts.run_from_config --quick-demo --gifs
# Run a single trial with specific conditions and visualize
python -m physicsTask.scripts.run_single --egress 15.0 --mass 2.0 --visualize
# Run a batch experiment from YAML config
python -m physicsTask.scripts.run_from_config config/example_experiment_config.yaml --output data/my_experiment
# Run a programmatic batch with full factorial design
python -m physicsTask.scripts.run_batch --design full_factorial --egress-levels 5 --output results/
# Visualize batch results interactively
python -m physicsTask.scripts.visualize data/batch_data.npy --filter "egress > 15" --show-aligned
# Generate GIFs from batch data
python -m physicsTask.scripts.generate_gifs data/batch_data.npy --output gifs/All CLI scripts support --help for full usage details.
Each trial shows side-by-side the full trajectory (left) and the occluded participant view (right). Conditions are labeled as O=overlap, E=egress angle, T=temporal delay, M=mass ratio, S=size ratio.
Baseline — physics-aligned collision (E:0°, no delay, equal mass):
Egress deviation — post-collision trajectory deviates 15° from the physics-aligned path:
Temporal delay — 3-frame gap between contact and launch, breaking causal continuity:
Generate your own with python -m physicsTask.scripts.run_from_config --quick-demo --gifs.
# example_config.yaml
conditions:
egress:
n_levels: 3
range_min: -15
range_max: 15
mass:
values: [0.5, 1.0, 2.0]
overlap:
values: [0.9, 1.0, 1.1]
temporal:
values: [0, 2, 4]
design_type: full_factorial
block_type: michottefrom physicsTask.experiment.conditions import ExperimentDesign, ConditionSet
from physicsTask.experiment.runner import ExperimentRunner
design = ExperimentDesign({
'egress': ConditionSet('egress', None, n_levels=5, range_min=-20, range_max=20),
'mass': [0.5, 1.0, 2.0],
'overlap': [0.9, 1.0, 1.1],
'temporal': [0, 2, 4],
})
design.generate_full_factorial(block_type='michotte')
design.add_control_trials(10)
design.randomize(seed=42)
runner = ExperimentRunner(experiment_design=design, frameN=120, max_retries=3)
results = runner.run_experiments()
runner.save_results('output_directory/')| Condition | Description | Typical values |
|---|---|---|
| Egress | Angle deviation from physics-aligned trajectory | -30° to +30° |
| Mass | Mass ratio (B/A) | 0.5, 1.0, 2.0 |
| Overlap | Spatial overlap between trajectories | 0.9, 1.0, 1.1 |
| Temporal | Frame delay between object movements | 0, 2, 4 frames |
| Size | Object size ratio | 1.0, 1.4 |
| Type | Description |
|---|---|
michotte |
Classic Michotte launching effect |
michotte_angle |
Angled collision variant |
two_random |
Two objects with random initial conditions |
psychophysics |
Specialized psychophysics configuration |
Batch experiments generate:
| File | Contents |
|---|---|
experiment_design.xlsx |
Full experimental design with all conditions |
batch_data.npy |
Complete simulation data (positions, velocities, conditions) |
reduced_paths.csv |
Occluded trajectories for participant viewing |
full_paths.csv |
Complete trajectory data for analysis |
Each trial result contains:
{
'run_index': int, # Trial identifier
'physics_conditions': dict, # Experimental conditions
'cutoff_index': int, # Frame where occlusion starts
# Physics-violating trajectory (A, B)
'A_pos': array, 'B_pos': array,
'A_pos_final': array, 'B_pos_final': array,
'A_pos_reduced': array, 'B_pos_reduced': array,
# Physics-aligned trajectory (C, D)
'C_pos': array, 'D_pos': array,
'C_pos_final': array, 'D_pos_final': array,
'C_pos_reduced': array, 'D_pos_reduced': array,
# Object diameters
'A_diameter': float, 'B_diameter': float,
'C_diameter': float, 'D_diameter': float,
}When using PyGame visualization: Space = Pause/Resume, Left/Right = Step frames, Escape = Exit.
This package is part of a three-component research ecosystem for studying physics intuition and hallucination-proneness:
| Component | Description | Repository |
|---|---|---|
| physicsTask (this repo) | Physics simulation engine | GitHub |
| physics_dev | Analysis pipeline (S00-S10) | GitHub |
| physics_v4 | PsychoPy experiment (Pavlovia) | Pavlovia |
Data flow: physicsTask generates stimuli → physics_v4 presents to participants → physics_dev analyzes responses.
pip install -e . # development mode (from cloned repo)
pip install git+https://github.com/adammanoogian/physicsTask.git # from GitHub

