Continuous Collision Detection for 3D Cubic Spline Trajectories
How to algorithmically check for collisions between 3D trajectories using non-convex optimization.
Setup
This is a followup to this post on 3D trajectories with cubic splines.
Let’s now assume that we have two different rigid bodies moving through 3D space, and each rigid body has a trajectory given with 3D cubic splines:
defined for each segment .
3D Spline Intersections
As trajectories in 3D will never intersect exactly, it is not enough to just solve an equation. What we need to do instead is look at the distance between the trajectories, and do a search for the minimum value(s). This can be formulated as an optimization problem.

Begin by looking at the distance between two trajectories over a single spline segment and . For now, let’s also assume that the spline segments start and end at the same timepoints. Define the trajectory difference as , which is another polynomial of the same degree. The distance function at spline segment can then be expressed as:
for , and using the norm for the induced distance metric.
If and are vectors made up of cubic polynomials, then is now a single polynomial of degree . Finding the minimum distance over the segment interval is then equivalent minimizing this function over the interval:
This optimization problem is non-convex in the general case, as most polynomials will swing up and down multiple times. But for a polynomial, the minimum will always be at either an stationary point or at the interval boundary. Evaluating the polynomial at the boundary is trivial, so then it remains to find the stationary points.
Stationary points are located where the derivative of the function is zero. As it is trivial to differentiate a polynomial, this means that the minimum points can be found where the derivative is equal to zero, reducing the whole problem to finding polynomial roots.
Polynomial Root Finding (Tangent)
The fundamental theorem of algebra states that a polynomial of degree will always have complex-valued roots (when considering multiplicity). As this is about solving a minimization problem, we only care about the real roots. And in a given bounded interval, a polynomial can have anywhere between and real roots, including roots with higher multiplicities.
The standard way to find polynomial roots is to rely on some linear algebra. For a square matrix , the characteristic polynomial of the matrix is defined as:
and is a polynomial of degree in . It also has the property that the roots of the polynomial are equal to the eigenvalues of the matrix. When finding eigenvalues of and matrices by hand, this is a common method to use.
Doing this process in reverse and relying on existing eigenvalue solvers is then a way to find polynomial roots. Start with an degree polynomial of the form:
Such that the leading coefficient is . If it is different from , divide all the coefficients by this leading coefficient, as the resulting polynomial will have the same roots.
The companion matrix is defined like this:
and is deliberately defined to have the original polynomial as its characteristic polynomial. Finding the roots of this polynomial is then equivalent to finding the eigenvalues of the companion matrix. One option is to use the QR algorithm, which finds all the eigenvalues simultaneously. One way to do this is with an iterative algorithm that computes a QR decomposition every iteration, but there are ways to make the algorithm more efficient, giving a time complexity of as many linear algebra algorithms have.
Low Degree Polynomial Root Finding
The companion matrix / QR algorithm approach is probably the best method for higher degree polynomials / larger matrices. But for lower degrees, there are more efficient algorithms. The following is mostly an explanation of [Yuksel 2022]. It works as a recursive algorithm, so let’s start with defining the base cases.
A degree zero polynomial is not really well defined, so let’s here assume that it means a function of the form , meaning a constant. A degree zero polynomial will then have zero roots. For a degree polynomial of the form: , there is one real root found at . For a quadratic polynomial there is the familiar quadratic formula:
or alternatively the more numerically stable version:
giving either zero, one or two real roots. Continuing like this, there are explicit symbolic formulas for degree and polynomials, but those are too complicated to write out and use. Fifth-degree and higher polynomials are famously unsolvable with symbolic expressions in the general case.
One thing to realize is that every polynomial root lies in between two stationary points of the polynomial. So one way to find roots is to first find the stationary points, and then do a local search inside the interval of the stationary points. And stationary points can be found by differentiating the polynomial and finding the roots of the derivative, leading to the recursive step.

If we go back to a degree polynomial, there are at most two stationary points. Differentiating it gives a degree polynomial, whose roots can be found easily with the formulas above. If we find two distinct stationary points, and these stationary points evaluate to different signs (one positive and one negative), then there must be a root in between. This can be solved with for example Newton’s method.
So to find the roots of a degree polynomial, differentiate it and find the roots of the degree polynomial recursively. Then iterate over the intervals and solve the local convex optimization problem for each.
This method has a worse time complexity compared to the QR algorithm, but ends up being more performant anyways when the degree is small enough, as time complexity is only measuring the asymptotic performance. For a polynomial of degree 5, which is what we end up solving for with cubic splines, this is small enough to be worth it.
Cauchy Bound
In addition to searching between stationary points, it is also necessary to search from to the first stationary point, and from the last stationary point and to . To limit the search a little, it is enough to search inside what is called the Cauchy bound of the polynomial.
More specifically, all the roots of a polynomial with complex coefficients:
are guaranteed to lie within the following disk centered at the origin:
with the Cauchy bound defined as:
So when searching for roots, it is enough to limit the search to inside .
Intersecting Splines at Different Sampling Times
So far, the assumption has been that spline segments for the two trajectories have been at the same time interval. But one of the original motivations of using splines is because it works with irregularly sampled timepoints, so let’s correct this now.
Let’s explain with an example, and say that we have these timepoints: , and that . Then we’ll say that trajectory is given at , with spline segments: at , at and at . Trajectory is given at with spline segments at and at . When searching for the minimum distance, we need to split the intervals up with corresponding spline segments:
here assuming that the splines just continue with the first and last segment outside the first and last timepoint of the whole spline. This basically means taking the union of the two sets of timepoints, but restricting it to the intersection instead could also work if that is desirable.

Then solve the minimization problem for each of these intervals, and get the global minimum by taking the minimum of all of these again.
Putting it all together
- Inputs: timepoints, positions and velocities
- Trajectory with states:
- Trajectory with states:
- Trajectory with states:
- Compute cubic spline segments:
- Take the union of all the timepoints of both trajectories, and sort them in ascending order
- For each pair of timepoints, find the two spline segments that are defined in this interval
- Compute the spline segment difference and solve the minimization problem with the polynomial root finding method
- Find the global minimum over all the results from the minimization problems
Future work: Non-Spherical Hitboxes
The current approach described here works by comparing trajectories of the positions of the rigid body mass centers. Checking for a collision is to see if the minimum distance is smaller than some value. Using the norm is kind of like assuming each rigid body has a spherical hitbox. The main benefit of the is that it is easy to optimize for, as it is continuous and continuously differentiable in the inputs, allowing for continuous optimization methods. Basing the distance metric on the or the norms could also work, as it is still fundamentally polynomials, but requires some more workarounds.
What is actually needed is a distance metric, which is a lot more general than norms. This can in theory work with any hitbox shape, but is hard to fit into this framework.
An alternative way to fit other hitbox shapes is to approximate it with multiple spheres, and then check if any of them collide with the target(s), as is relatively common in games.