Ejemplo n.º 1
0
    public SteerForSphericalObstacleAvoidance.PathIntersection FindNextIntersectionWithSphere(SphericalObstacle obs, Vector3 line)
    {
        Vector3 vector = base.Vehicle.Position - obs.center;

        SteerForSphericalObstacleAvoidance.PathIntersection result = new SteerForSphericalObstacleAvoidance.PathIntersection(obs);
        obs.annotatePosition();
        Debug.DrawLine(base.Vehicle.Position, base.Vehicle.Position + line, Color.get_cyan());
        float sqrMagnitude = line.get_sqrMagnitude();
        float num          = 2f * Vector3.Dot(line, vector);
        float num2         = obs.center.get_sqrMagnitude();

        num2 += base.Vehicle.Position.get_sqrMagnitude();
        num2 -= 2f * Vector3.Dot(obs.center, base.Vehicle.Position);
        num2 -= Mathf.Pow(obs.radius + base.Vehicle.ScaledRadius, 2f);
        float num3 = num * num - 4f * sqrMagnitude * num2;

        if (num3 >= 0f)
        {
            result.intersect = true;
            Vector3 vector2 = Vector3.get_zero();
            if (num3 == 0f)
            {
                float num4 = -num / (2f * sqrMagnitude);
                vector2 = num4 * line;
            }
            else
            {
                float num5 = (-num + Mathf.Sqrt(num3)) / (2f * sqrMagnitude);
                float num6 = (-num - Mathf.Sqrt(num3)) / (2f * sqrMagnitude);
                if (num5 < 0f && num6 < 0f)
                {
                    result.intersect = false;
                }
                else
                {
                    vector2 = ((Mathf.Abs(num5) >= Mathf.Abs(num6)) ? (num6 * line) : (num5 * line));
                }
            }
            Debug.DrawRay(base.Vehicle.Position, vector2, Color.get_red());
            result.distance = vector2.get_magnitude();
        }
        return(result);
    }
Ejemplo n.º 2
0
    /// <summary>
    /// Finds the vehicle's next intersection with a spherical obstacle
    /// </summary>
    /// <param name="obs">
    /// A spherical obstacle to check against <see cref="SphericalObstacle"/>
    /// </param>
    /// <param name="line">
    /// Line that we expect we'll follow to our future destination
    /// </param>
    /// <returns>
    /// A PathIntersection with the intersection details <see cref="PathIntersection"/>
    /// </returns>
    public PathIntersection FindNextIntersectionWithSphere(SphericalObstacle obs, Vector3 line)
    {
        /*
         * This routine is based on the Paul Bourke's derivation in:
         *   Intersection of a Line and a Sphere (or circle)
         *   http://www.swin.edu.au/astronomy/pbourke/geometry/sphereline/
         *
         * Retaining the same variable values used in that description.
         *
         */
        float a, b, c, bb4ac;
        var   toCenter = Vehicle.Position - obs.center;

        // initialize pathIntersection object
        var intersection = new PathIntersection(obs);

                #if ANNOTATE_AVOIDOBSTACLES
        obs.annotatePosition();
        Debug.DrawLine(Vehicle.Position, Vehicle.Position + line, Color.cyan);
                #endif

        // computer line-sphere intersection parameters
        a     = line.sqrMagnitude;
        b     = 2 * Vector3.Dot(line, toCenter);
        c     = obs.center.sqrMagnitude;
        c    += Vehicle.Position.sqrMagnitude;
        c    -= 2 * Vector3.Dot(obs.center, Vehicle.Position);
        c    -= Mathf.Pow(obs.radius + Vehicle.ScaledRadius, 2);
        bb4ac = b * b - 4 * a * c;

        if (bb4ac >= 0)
        {
            intersection.intersect = true;
            Vector3 closest = Vector3.zero;
            if (bb4ac == 0)
            {
                // Only one intersection
                var mu = -b / (2 * a);
                closest = mu * line;
            }
            else
            {
                // More than one intersection
                var mu1 = (-b + Mathf.Sqrt(bb4ac)) / (2 * a);
                var mu2 = (-b - Mathf.Sqrt(bb4ac)) / (2 * a);

                /*
                 * If the results are negative, the obstacle is behind us.
                 *
                 * If one result is negative and the other one positive,
                 * that would indicate that one intersection is behind us while
                 * the other one ahead of us, which would mean that we're
                 * just overlapping the obstacle, so we should still avoid.
                 */
                if (mu1 < 0 && mu2 < 0)
                {
                    intersection.intersect = false;
                }
                else
                {
                    closest = (Mathf.Abs(mu1) < Mathf.Abs(mu2)) ? mu1 * line : mu2 * line;
                }
            }
                        #if ANNOTATE_AVOIDOBSTACLES
            Debug.DrawRay(Vehicle.Position, closest, Color.red);
                        #endif

            intersection.distance = closest.magnitude;
        }
        return(intersection);
    }