Creating a Python Model for Bullet-Bullet Collision Dynamics
Written on
Chapter 1: Introduction to Bullet Collision Modeling
Whenever I come across something fascinating, I tend to show my appreciation by building a model. It's a ritual of mine. Recently, I was captivated by some impressive slow-motion footage of bullets colliding mid-air, featured by Smarter Every Day. It's definitely worth a watch.
In particular, I find the circular expansion of debris post-collision to be especially intriguing. The question arises: can I replicate this effect using basic physics and Python? For this project, I will be utilizing Web VPython, which offers convenient 3D objects for simulation.
This leads us to consider a straightforward scenario: the collision of two point particles approaching each other. How do we simulate the interaction between these two objects? Naturally, we will rely on fundamental physics principles.
Let's denote the two objects as A and B. When they collide, an interaction force arises between them. Notice that the force ( F_{B-A} ) is equal in magnitude but opposite in direction to ( F_{A-B} ), adhering to Newton's third law. A net force acting on an object results in a change in momentum, according to the momentum principle.
Since the forces are equal and opposite for the same duration, the momentum change of A will counterbalance the momentum change of B, indicating that total momentum remains conserved.
Now, how do we implement this in our model? One effective approach is to use springs. Imagine the two balls overlapping slightly. We can apply a force proportional to the extent of their overlap; if they don’t overlap, the force is zero—akin to "springy" balls.
The direction of the force is determined by the relative positions of balls A and B, making this model applicable to both glancing and direct collisions. To compute this force, we assume both balls have a radius ( R ), with vector positions ( r_A ) and ( r_B ). We will also introduce a spring constant ( k ) to quantify the force's magnitude.
The force expressions can be summarized as follows (assuming overlap exists):
# Pseudocode for force calculation
if overlap_exists:
force_A = -k * (2 * R - mag(r))
force_B = -force_A
The plan involves a numerical simulation where motion is divided into small time intervals. For each interval, we will:
- Calculate the vector distance between A and B. If this distance is less than ( 2R ), we will assess for overlap and calculate the force.
- Determine the forces acting on A and B (noting that they are equal and opposite).
- Update the momentum for each ball using the momentum principle.
- Adjust the positions of both balls based on their updated momentum.
Let's dive into the implementation in Python. Below is the code highlighting the essential parts.
# Initializing the balls
ballA = sphere(pos=vector(-0.03, 0, 0), radius=R, color=color.yellow)
ballB = sphere(pos=vector(0.03, 0, 0), radius=R, color=color.cyan)
# Setting initial conditions
v0 = 100 # initial velocity
k = 50000000 # spring constant
ballA.m = m
ballB.m = m
ballA.p = m * vector(v0, 0, 0)
ballB.p = m * vector(-v0, 0, 0)
Running this simulation reveals a straightforward interaction where the balls simply collide and bounce off each other. However, this doesn’t accurately reflect the complexity of high-speed bullet collisions.
Chapter 2: Advanced Bullet Collision Modeling
In the reality of high-speed bullet-bullet collisions, the bullets shatter into numerous small fragments. To effectively model this in Python, we can represent each bullet as a collection of tiny spheres. This way, when the bullets collide, all the tiny spheres can interact, potentially replicating the effect seen in the Smarter Every Day video.
Here's the plan for this enhanced simulation:
- Divide each bullet into ( N ) smaller spheres.
- Distribute these tiny spheres randomly within a spherical volume, simulating the original bullet's shape.
- Allow all tiny spheres to interact during the collision.
To efficiently manage the many spheres, we will utilize lists in Python. Here’s a snippet of the code that constructs a single bullet from multiple smaller spheres.
# Constants for bullet creation
R = (11.5e-3) / 2 # radius of bullet
m = 0.012 # mass of bullet
N = 20 # number of small spheres
dm = m / N # mass of each small sphere
# List to hold the small spheres
bs = []
To ensure that the tiny spheres are properly positioned without overlapping, I will implement a function that checks for overlaps. If a new sphere overlaps with an existing one, it will be repositioned until it fits without collisions.
def overlap(rt, radi, rlist):
for rtemp in rlist:
rdist = rtemp.pos - rt
if mag(rdist) < 2 * radi:
return Truereturn False
We will then initiate a loop to create the spheres, ensuring they are placed in a suitable arrangement.
Following the setup, we can move to the simulation of the bullets approaching each other and eventually colliding.
# Bullet collision simulation
while t < .8e-3:
rate(200)
for b in bs:
b.F = vector(0, 0, 0) # Reset forces
# Calculate forces between spheres
for b in bs:
for a in bs:
rab = b.pos - a.pos
if mag(rab) < 2 * rpiece:
a.F += -k * (2 * rpiece - mag(rab)) * norm(rab)
This loop iterates over all spheres, calculating forces based on overlaps and updating their momentum and positions accordingly.
The results of this simulation reveal a more complex interaction. However, if the bullets collide off-axis, we can adjust the initial positions slightly to observe different collision dynamics.
To further refine our model, we can examine the conservation of momentum throughout the collision. Ideally, the system's total momentum should remain constant, and we can visualize this through a plot of momentum over time.
Partially Elastic Collisions
In the Smarter Every Day video, we observe a cluster of bullet fragments that stick together upon collision. In our simulation, however, each sphere experiences perfectly elastic collisions, meaning they will never coalesce.
In perfectly elastic collisions, kinetic energy is conserved. However, to introduce the concept of partially elastic collisions, we can manipulate the spring constants governing the interactions between the spheres.
By using a stronger spring constant during compression and a weaker one during expansion, we can model the loss of kinetic energy during the collision. For example:
if mag(rab) < 2 * rpiece:
if dot(rab, dp) < 0:
k = k1 # Stronger spring for compressionelse:
k = k2 # Weaker spring for rebound
This adjustment allows us to see a more realistic representation of the collision dynamics, where kinetic energy is not fully conserved.
To summarize, through iterative modeling and simulation, we can better understand the physics behind bullet collisions, capturing the essence of their dynamic interactions.
Explore the intricacies of bullet projectile dynamics and collision detection in Python through this engaging tutorial.
Learn how to build a 3D Python model that effectively demonstrates the motion of a projectile, enhancing your understanding of physics in action.