0
$\begingroup$

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[1] - s[0];
s0qp = qp - s[0];
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[0] + 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? :)

enter image description here

$\endgroup$
  • $\begingroup$ I find your question a bit unclear. Perhaps you could try better explaining your problem? $\endgroup$ – Fimpellizieri Feb 22 '18 at 15:06
  • $\begingroup$ Drawing a picture of what you are trying to do would help a lot. $\endgroup$ – Ross Millikan Feb 22 '18 at 15:07
  • $\begingroup$ my guess i should replace s0qp with something, but i also need to check if i miss the segment $\endgroup$ – xakepp35 Feb 22 '18 at 15:10
  • $\begingroup$ Fimpellizieri, Ross Millikan, sure, i have added an illustration $\endgroup$ – xakepp35 Feb 22 '18 at 15:16
1
$\begingroup$

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.

$\endgroup$
0
$\begingroup$

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[1] - s[0];
    auto s0qp = qp - s[0];
    auto dd = d[0] * s0s1[1] - d[1] * s0s1[0];
    if (dd != 0) {
        auto r = (s0qp[1] * s0s1[0] - s0qp[0] * s0s1[1]) / dd;
        auto s = (s0qp[1] * d[0] - s0qp[0] * d[1]) / 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
}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.