Пример #1
0
        /// <summary>
        /// Time to collision of a ray to a disc.
        /// </summary>
        /// <param name="p">The start position of the ray</param>
        /// <param name="v">The velocity vector of the ray</param>
        /// <param name="p2">The center position of the disc</param>
        /// <param name="radius">The radius of the disc</param>
        /// <param name="collision">Specifies whether the time to collision is computed (false), or the time from collision (true).计算将要发生碰撞的时间,或者发生碰撞后经过的时间</param>
        /// <returns>Returns the time to collision of ray p + tv to disc D(p2, radius), and #RVO_INFTY when the disc is not hit. If collision is true, the value is negative.</returns>
        //点到直线距离公式:d = |AX0+BY0+C|/sqrt(A*A+B*B)
        //直线AX+BY+C=0,A=-V.y B=V.x C =P.x*V.y-V.x*P.y
        //可能碰撞:d<r=>d*d-r*r<0
        //p2带入AX0+BY0+C
        //AX0+BY0+C = -v.y*p2.x+v.x*p2.y+p.x*v.y-v.x*p.y=v.x(p2.y-p.y)-v.y(p2.x-p.x)=det(v, ba)
        //d*d = det(v, ba)*det(v, ba)/absSq(v)
        //r*r-d*d>0 => r*r-det(v, ba)*det(v, ba)/absSq(v)>0 => discr = r*r*absSq(v) - det(v, ba)*det(v, ba)>0
        //
        private float time2Collision(Vector2 p, Vector2 v, Vector2 p2, float radius, bool collision)
        {
            Vector2 ba      = p2 - p;
            float   sq_diam = radius * radius;
            float   time;

            float discr = -RVOMath.Sqr(RVOMath.Det(v, ba)) + sq_diam * RVOMath.AbsSq(v);

            if (discr > 0)
            {
                if (collision)
                {
                    time = (Vector2.Dot(v, ba) + Mathf.Sqrt(discr)) / RVOMath.AbsSq(v);//脱落碰撞需要的时间
                    if (time < 0)
                    {
                        time = -float.MaxValue;                //
                        Debug.LogError("isCollide time < 0 "); //?
                    }
                }
                else
                {
                    time = (Vector2.Dot(v, ba) - Mathf.Sqrt(discr)) / RVOMath.AbsSq(v);//将要发生碰撞的时间
                    if (time < 0)
                    {
                        time = float.MaxValue;//永远不会发生碰撞
                    }
                }
            }
            else
            {//不碰撞
                if (collision)
                {
                    time = -float.MaxValue;
                }
                else
                {
                    time = float.MaxValue;
                }
            }
            return(time);
        }