示例#1
0
        internal Pair <Vector2, Vector2> computeTangentsPoints(Agent observer, Agent agent)
        {
            // First element of the pair = left tangent
            // Second element of the pair = right tangent
            Pair <Vector2, Vector2> toReturn = new Pair <Vector2, Vector2>();
            Vector2 centers = agent.position_ - observer.position_;
            Vector2 r1a     = Vector2.normalize(Vector2.rotation(centers, (float)-Math.PI / 2)) * observer.radius_;
            Vector2 r1b     = Vector2.normalize(Vector2.rotation(centers, (float)Math.PI / 2)) * observer.radius_;
            // Compute intersection points between radius and circle
            // Right one
            Vector2 h1a = observer.position_ + r1a;
            // Left one
            Vector2 h1b = observer.position_ + r1b;

            // If the radius is the same, tangents points are perpendicular to centers vector
            if (Math.Abs(observer.radius_ - agent.radius_) < RVO_EPSILON)
            {
                toReturn.First  = h1a;
                toReturn.Second = h1b;
            }
            else
            {
                Vector2 r2a = Vector2.normalize(Vector2.rotation(centers, (float)-Math.PI / 2)) * agent.radius_;
                Vector2 r2b = Vector2.normalize(Vector2.rotation(centers, (float)Math.PI / 2)) * agent.radius_;
                Vector2 h2a = agent.position_ + r2a;
                Vector2 h2b = agent.position_ + r2b;
                // If tangents are parallel, radius are the same, i.e. there is no intersection point.
                if (Math.Abs(Vector2.det(h1a - h2a, h1b - h2b)) < RVO_EPSILON)
                {
                    Console.Write("Problem while computing tangent points\n SHALL NOT HAPPEN !!! \n");
                    toReturn.First  = h1a;
                    toReturn.Second = h1b;
                }
                else
                {
                    Vector2 intersectionPoint = Vector2.intersectOf2Lines(h1a, h2a, h1b, h2b);
                    // Equivalent to :
                    Vector2 circleCenter = (intersectionPoint + observer.position_) / 2;
                    toReturn = Vector2.intersectOf2Circles(circleCenter, Vector2.abs(circleCenter - observer.position_), observer.position_, observer.radius_);
                    // Test angles to know which one is right &  which one is left
                    if (Vector2.isOnTheLeftSide(toReturn.First - observer.position_, centers))
                    {
                        Vector2 temp = toReturn.First;
                        toReturn.First  = toReturn.Second;
                        toReturn.Second = temp;
                    }
                }
            }
            return(toReturn);
        }