예제 #1
0
파일: RayD.cs 프로젝트: AlexMacocian/Cosmos
        public void Intersects(ref BoundingSphereD sphere, out double?result)
        {
            // Find the vector between where the ray starts the the sphere's center.
            Vector3D difference = sphere.Center - this.Position;

            double differenceLengthSquared = difference.LengthSquared();
            double sphereRadiusSquared     = sphere.Radius * sphere.Radius;

            double distanceAlongRay;

            /* If the distance between the ray start and the sphere's center is less than
             * the radius of the sphere, it means we've intersected. Checking the
             * LengthSquared is faster.
             */
            if (differenceLengthSquared < sphereRadiusSquared)
            {
                result = 0.0f;
                return;
            }

            Vector3D.Dot(ref this.Direction, ref difference, out distanceAlongRay);
            // If the ray is pointing away from the sphere then we don't ever intersect.
            if (distanceAlongRay < 0)
            {
                result = null;
                return;
            }

            /* Next we kinda use Pythagoras to check if we are within the bounds of the
             * sphere.
             * if x = radius of sphere
             * if y = distance between ray position and sphere centre
             * if z = the distance we've travelled along the ray
             * if x^2 + z^2 - y^2 < 0, we do not intersect
             */
            double dist = (
                sphereRadiusSquared +
                (distanceAlongRay * distanceAlongRay) -
                differenceLengthSquared
                );

            result = (dist < 0) ? null : distanceAlongRay - (double?)Math.Sqrt(dist);
        }
예제 #2
0
        /// <summary>
        /// Containment test between this <see cref="BoundingFrustumD"/> and specified <see cref="BoundingSphereD"/>.
        /// </summary>
        /// <param name="sphere">A <see cref="BoundingSphereD"/> for testing.</param>
        /// <param name="result">Result of testing for containment between this <see cref="BoundingFrustumD"/> and specified <see cref="BoundingSphereD"/> as an output parameter.</param>
        public void Contains(ref BoundingSphereD sphere, out ContainmentType result)
        {
            bool intersects = false;

            for (int i = 0; i < PlaneCount; i += 1)
            {
                PlaneIntersectionTypeD planeIntersectionType = default(PlaneIntersectionTypeD);

                // TODO: We might want to inline this for performance reasons.
                sphere.Intersects(ref this.planes[i], out planeIntersectionType);
                switch (planeIntersectionType)
                {
                case PlaneIntersectionTypeD.Front:
                    result = ContainmentType.Disjoint;
                    return;

                case PlaneIntersectionTypeD.Intersecting:
                    intersects = true;
                    break;
                }
            }
            result = intersects ? ContainmentType.Intersects : ContainmentType.Contains;
        }
예제 #3
0
 public void Contains(ref BoundingSphereD sphere, out ContainmentType result)
 {
     result = this.Contains(sphere);
 }
예제 #4
0
 public void Intersects(ref BoundingSphereD sphere, out bool result)
 {
     result = Intersects(sphere);
 }
예제 #5
0
        public ContainmentType Contains(BoundingSphereD sphere)
        {
            if (sphere.Center.X - Min.X >= sphere.Radius &&
                sphere.Center.Y - Min.Y >= sphere.Radius &&
                sphere.Center.Z - Min.Z >= sphere.Radius &&
                Max.X - sphere.Center.X >= sphere.Radius &&
                Max.Y - sphere.Center.Y >= sphere.Radius &&
                Max.Z - sphere.Center.Z >= sphere.Radius)
            {
                return(ContainmentType.Contains);
            }

            double dmin = 0;

            double e = sphere.Center.X - Min.X;

            if (e < 0)
            {
                if (e < -sphere.Radius)
                {
                    return(ContainmentType.Disjoint);
                }
                dmin += e * e;
            }
            else
            {
                e = sphere.Center.X - Max.X;
                if (e > 0)
                {
                    if (e > sphere.Radius)
                    {
                        return(ContainmentType.Disjoint);
                    }
                    dmin += e * e;
                }
            }

            e = sphere.Center.Y - Min.Y;
            if (e < 0)
            {
                if (e < -sphere.Radius)
                {
                    return(ContainmentType.Disjoint);
                }
                dmin += e * e;
            }
            else
            {
                e = sphere.Center.Y - Max.Y;
                if (e > 0)
                {
                    if (e > sphere.Radius)
                    {
                        return(ContainmentType.Disjoint);
                    }
                    dmin += e * e;
                }
            }

            e = sphere.Center.Z - Min.Z;
            if (e < 0)
            {
                if (e < -sphere.Radius)
                {
                    return(ContainmentType.Disjoint);
                }
                dmin += e * e;
            }
            else
            {
                e = sphere.Center.Z - Max.Z;
                if (e > 0)
                {
                    if (e > sphere.Radius)
                    {
                        return(ContainmentType.Disjoint);
                    }
                    dmin += e * e;
                }
            }

            if (dmin <= sphere.Radius * sphere.Radius)
            {
                return(ContainmentType.Intersects);
            }

            return(ContainmentType.Disjoint);
        }
예제 #6
0
 public void Intersects(ref BoundingSphereD sphere, out PlaneIntersectionTypeD result)
 {
     sphere.Intersects(ref this, out result);
 }
예제 #7
0
 public PlaneIntersectionTypeD Intersects(BoundingSphereD sphere)
 {
     return(sphere.Intersects(this));
 }