cd "<REPO_PATH>/when_worlds_collide"
base='when_worlds_collide' && g++ -std=c++14 "${base}.cpp" geometry_utils.cpp -o "${base}.out" && "./${base}.out" --help
cd "<REPO_PATH>/when_worlds_collide"
base='sphere_test' && g++ -std=c++14 "${base}.cpp" geometry_utils.cpp -o "${base}.out" && "./${base}.out"
The unit normal vector perpendicular to each of the spheres is contained within the SphereOverlapCentroidDetails
datatype's centroid_normal_vector
member. This value is generated by a call to CalculateCentroid
and can be printed by a call to the wrapper function CalculateCentroidThenPrintResults
which is executed in when_worlds_collide.cpp
. A demonstration of the behavior of CalculateCentroid
can be seen in sphere_test.cpp
.
Let's consider when two spheres that are moving at a fixed velocity will collide and determine the force at impact
Lets start by organizing all the relevant math formulas.
Let Sphere 1 initial center position be {x1_0, y1_0, z1_0}
Let Sphere 2 initial center position be {x2_0, y2_0, z2_0}
Let Sphere 1 fixed velocity be {v1x, v1y, v1z}
Let Sphere 2 fixed velocity be {v2x, v2y, v2z}
Let Sphere 1 radius be r1
Let Sphere 2 radius be r2
Let Sphere 1 mass be m1
Let Sphere 2 mass be m2
(1) The equations for the center coordinates at a given time:
x1(t) = x1_0 + v1x * t
y1(t) = y1_0 + v1y * t
z1(t) = z1_0 + v1z * t
x2(t) = x2_0 + v2x * t
y2(t) = y2_0 + v2y * t
z2(t) = z2_0 + v2z * t
(2) The distance between two cartesian points in 3D space:
d = sqrt((x2 - x1)^2 + (y2 - y1)^2 + (z2 - z1)^2)
(3) The moment of collision will be when d = r1 + r2
(4) by substituting (1) and (3) into (2) we get:
r1 + r2 = sqrt(
(x2_0 + v2x * t - x1_0 - v1x * t)^2 +
(y2_0 + v2y * t - y1_0 - v1y * t)^2 +
(z2_0 + v2z * t - z1_0 - v1z * t)^2
)
Which after squaring both sides and simplfying becomes:
(r1 + r2)^2 =
(v2x - v1x)^2 * t^4 +
2 * (v2x - v1x) * (x2_0 - x1_0) * t^3 +
2 * (v2x - v1x) * (v2y - v1y) * t^2 +
2 * (v2x - v1x) * (v2z - v1z) * t^2 +
(v2y - v1y)^2 * t^2 +
2 * (v2y - v1y) * (v2z - v1z) * t^2 +
(v2z - v1z)^2 * t^2
2 * (v2x - v1x) * (y2_0 - y1_0) * t +
2 * (v2y - v1y) * (y2_0 - y1_0) * t +
2 * (v2z - v1z) * (z2_0 - z1_0) * t +
(y2_0 - y1_0)^2 +
(z2_0 - z1_0)^2 +
Equation (4) can be solved for t using numerical methods (such as Newtons method) as long as there is a provided constant value for each of r1, r2, v1x, v1y, v1z, v2x, v2y, v2z, x1_0, y1_0, z1_0, x2_0, y2_0, and z2_0. In the event that there is no real solution for t, there will be no collision.
(5) The formula for force is F = m * a
where m is mass and a is acceleration
(6) Lets assume that the collision causes the spheres to stop (velocity = 0), and that it takes t_s
amount of time in order to stop.
(7) The formula for acceleration is a = (vf - v_0) / t
where vf = final velocity, v_0 = initial velocity and t is amount of time to in order to stop.
(8) Applying (5), (6), and (7) independently in each dimension and subtacting each sphere's contribution provides:
Fx = (v2x - v1x) / t_s
Fy = (v2y - v1y) / t_s
Fz = (v2z - v1z) / t_s
Where F can be taken as the sum of all forces in each direction.
NOTE: These calculations are made more difficult if the sphere is not considered a rigid body or if the collison is elastic ( i.e. bouncing).
In contrast to a sphere, all of the datatypes mentioned require orientation information to be passed to command line. Additionally, depending on the shape given we may also need height, length, and width.