# How to get ray to segment distance

For collision detection i used simple point QP to line segment S0-S1 closest distance test, with means of ortohonal projection like this:

s0s1 = s - s;
s0qp = qp - s;
len2 = dot(s0s1, s0s1);
t = max(0, min(len2, dot(s0s1, s0qp))) / len2; // t is a number in [0,1] describing the closest point on the line segment s, as a blend of endpoints
cp = s + s0s1 * t; // cp is the position (actual coordinates) of the closest point on the segment s
dv = cp - qp;
return dot(dv, dv);


But now i need a proximity sensor emulation. So how do i cast a ray from that point QP, but now given (unit) direction vector D? Could you point me a bit, please? :) • I find your question a bit unclear. Perhaps you could try better explaining your problem? – Fimpellizieri Feb 22 '18 at 15:06
• Drawing a picture of what you are trying to do would help a lot. – Ross Millikan Feb 22 '18 at 15:07
• my guess i should replace s0qp with something, but i also need to check if i miss the segment – xakepp35 Feb 22 '18 at 15:10
• Fimpellizieri, Ross Millikan, sure, i have added an illustration – xakepp35 Feb 22 '18 at 15:16

## 2 Answers

This problem is called ray-segment intersection if you wish to search for more answers online.

So you have your ray:

$$R(t) = Q + t D \quad\quad t \in [0,\infty)$$

and your segment:

$$S(s) = S_0 + s (S_1 - S_0) \quad\quad s \in [0,1]$$

and they intersect when:

$$R(t) = S(s) \wedge t \in [0,\infty) \wedge s \in [0,1]$$

In 2D, $R(t) = S(s)$ gives you 2 linear equations (for $x$ and $y$ coordinates) in 2 unknowns ($s$ and $t$), which you can solve(*). Then you can check if they intersect, by seeing if $t \in [0,\infty)$ and $s \in [0,1]$ (if not then they don't intersect), and you can find the point of intersection by $P = R(t) = S(s)$.

(*) for example see:

but note the caveats in comments about not taking the absolute value of the cross-product.

Thanks to all of our efforts! Here is working solution for what i need:

// convenient mapping for neural network distance sensor;
scalar get_distance_inverse_squared(const point& qp, const point& d, const segment& s)  {
auto s0s1 = s - s;
auto s0qp = qp - s;
auto dd = d * s0s1 - d * s0s1;
if (dd != 0) {
auto r = (s0qp * s0s1 - s0qp * s0s1) / dd;
auto s = (s0qp * d - s0qp * d) / dd;
if (r >= 0 && s >= 0 && s <= 1) {
// inverse square of distance, always less than 1.0
return scalar(1) / (r*r + 1);
}
}
return 0; // infinitely far, parallel, no signal, etc
}