In Part 1, we saw that when a tag "blinks," the time difference of arrival (TDOA) at two anchors creates a hyperbola. The tag must lie somewhere on this curve. But how does a simple time delay translate into such a specific shape?
It all starts with a fundamental principle of physics: Distance = Rate × Time. Let's break down the math.
Like all radio waves, UWB signals travel at the speed of light (approximately 299,792,458 meters per second). Since this rate is a known constant, the difference in signal arrival time is directly proportional to the difference in distance.
If a tag is closer to Anchor A than Anchor B, the signal travels a shorter distance to A. The TDOA is just the extra time it took for the signal to cover that extra distance to B.
This "distance difference" is the key. The interactive scene below shows this in action. Drag the tag around and watch how the time delay corresponds to a specific, constant distance difference.
Loading scene...
This leads us to the geometric definition of a hyperbola: It is the set of all points where the difference of the distances to two fixed points (called the foci) is constant.
In our UWB positioning system:
So, the system knows the tag is located on a specific hyperbola defined by the two anchors and that single time measurement.
To use this in a computer, we need an equation. The standard equation for a hyperbola centered at the origin is:
The values a, b, and c (distance from the center to a focus) are related by the equation c² = a² + b². Here's how they relate to our setup:
The simulation below lets you see how these parameters build the final equation. Adjust the sliders to explore different aspects of the hyperbola and see how the equation changes.
Loading scene...
hyperbola.js
// Hyperbola from TDOA (Time Difference of Arrival)
// TDOA = 0.0 ms
// Convert TDOA to distance difference
const speedOfLight = 299792458; // m/s
const tdoa = 0.0 * 1e-3; // Convert ms to seconds
const distanceDiff = speedOfLight * tdoa; // meters
// Hyperbola parameters
const segments = 20;
const anchorDistance = canvas.width - 100; // pixels between anchors
const c = anchorDistance / 2; // Half distance between foci
const a = Math.abs(distanceDiff) * scale; // Semi-major axis
const b = Math.sqrt(c*c - a*a); // Semi-minor axis
// Generate hyperbola points
const hyperbolaPoints = [];
const leftBranchPoints = [];
// Calculate points using parametric equations
for (let t = -2.0; t <= 2.0; t += 0.20) {
// Right branch: x = a * cosh(t), y = b * sinh(t)
const x = centerX + a * Math.cosh(t);
const y = centerY + b * Math.sinh(t);
// Clipping: Only show above baseline
if (y <= centerY) {
hyperbolaPoints.push({ x, y });
}
// Left branch (mirror)
const x_mirror = centerX - a * Math.cosh(t);
const y_mirror = centerY + b * Math.sinh(t);
if (y_mirror <= centerY) {
leftBranchPoints.push({ x: x_mirror, y: y_mirror });
}
}
// Return the points array(s)
return { rightBranch: hyperbolaPoints, leftBranch: leftBranchPoints };
We've now forged the mathematical link between a time delay and a curve. But a curve isn't a point. This is why we need to find the intersection of two or more hyperbolas to get the final, precise coordinates of our tag.
How do we find that intersection?
In Part 3 - Z Marks the Spot, we will explore how can we get out of the flat world of hyperbolas and find the exact location of our tag in 3D space.
BACK TO BLOG