Circle line-segment collision detection algorithm?

前端 未结 28 2007
被撕碎了的回忆
被撕碎了的回忆 2020-11-22 06:38

I have a line from A to B and a circle positioned at C with the radius R.

\"Image\"

What is a good alg

28条回答
  •  猫巷女王i
    2020-11-22 06:54

    Circle is really a bad guy :) So a good way is to avoid true circle, if you can. If you are doing collision check for games you can go with some simplifications and have just 3 dot products, and a few comparisons.

    I call this "fat point" or "thin circle". its kind of a ellipse with zero radius in a direction parallel to a segment. but full radius in a direction perpendicular to a segment

    First, i would consider renaming and switching coordinate system to avoid excessive data:

    s0s1 = B-A;
    s0qp = C-A;
    rSqr = r*r;
    

    Second, index h in hvec2f means than vector must favor horisontal operations, like dot()/det(). Which means its components are to be placed in a separate xmm registers, to avoid shuffling/hadd'ing/hsub'ing. And here we go, with most performant version of simpliest collision detection for 2D game:

    bool fat_point_collides_segment(const hvec2f& s0qp, const hvec2f& s0s1, const float& rSqr) {
        auto a = dot(s0s1, s0s1);
        //if( a != 0 ) // if you haven't zero-length segments omit this, as it would save you 1 _mm_comineq_ss() instruction and 1 memory fetch
        {
            auto b = dot(s0s1, s0qp);
            auto t = b / a; // length of projection of s0qp onto s0s1
            //std::cout << "t = " << t << "\n";
            if ((t >= 0) && (t <= 1)) // 
            {
                auto c = dot(s0qp, s0qp);
                auto r2 = c - a * t * t;
                return (r2 <= rSqr); // true if collides
            }
        }   
        return false;
    }
    

    I doubt you can optimize it any further. I am using it for neural-network driven car racing collision detection, to process millions of millions iteration steps.

提交回复
热议问题