Пример #1
0
        /// <summary>
        /// Constructs a <see cref="MyBoundingSphere" /> that fully contains the given points.
        /// </summary>
        /// <param name="points">The points that will be contained by the sphere.</param>
        /// <param name="start">The start index from points array to start compute the bounding sphere.</param>
        /// <param name="count">The count of points to process to compute the bounding sphere.</param>
        /// <param name="result">When the method completes, contains the newly constructed bounding sphere.</param>
        /// <exception cref="System.ArgumentNullException">points</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">
        /// start
        /// or
        /// count
        /// </exception>
        public static void FromPoints(MyVector3[] points, int start, int count, out MyBoundingSphere result)
        {
            if (points == null)
            {
                throw new ArgumentNullException("points");
            }

            // Check that start is in the correct range
            if (start < 0 || start >= points.Length)
            {
                throw new ArgumentOutOfRangeException("start", start, string.Format("Must be in the range [0, {0}]", points.Length - 1));
            }

            // Check that count is in the correct range
            if (count < 0 || (start + count) > points.Length)
            {
                throw new ArgumentOutOfRangeException("count", count, string.Format("Must be in the range <= {0}", points.Length));
            }

            var upperEnd = start + count;

            //Find the center of all points.
            MyVector3 center = MyVector3.Zero;

            for (int i = start; i < upperEnd; ++i)
            {
                MyVector3.Add(ref points[i], ref center, out center);
            }

            //This is the center of our sphere.
            center /= (float)count;

            //Find the radius of the sphere
            float radius = 0f;

            for (int i = start; i < upperEnd; ++i)
            {
                //We are doing a relative distance comparison to find the maximum distance
                //from the center of our sphere.
                float distance;
                MyVector3.DistanceSquared(ref center, ref points[i], out distance);

                if (distance > radius)
                {
                    radius = distance;
                }
            }

            //Find the real distance from the DistanceSquared.
            radius = (float)Math.Sqrt(radius);

            //Construct the sphere.
            result.Center = center;
            result.Radius = radius;
        }
Пример #2
0
        /// <summary>
        /// Determines whether a <see cref="MyOrientedBoundingBox"/> contains a <see cref="MyBoundingSphere"/>.
        /// </summary>
        /// <param name="sphere">The sphere to test.</param>
        /// <param name="IgnoreScale">Optimize the check operation by assuming that <see cref="MyOrientedBoundingBox"/> has no scaling applied</param>
        /// <returns>The type of containment the two objects have.</returns>
        /// <remarks>
        /// This method is not designed for <see cref="MyOrientedBoundingBox"/> which has a non-uniform scaling applied to its transformation matrix.
        /// But any type of scaling applied using Scale method will keep this method accurate.
        /// </remarks>
        public MyContainmentType Contains(MyBoundingSphere sphere, bool IgnoreScale = false)
        {
            MyMatrix invTrans;
            MyMatrix.Invert(ref Transformation, out invTrans);

            // Transform sphere center into the obb coordinates
            MyVector3 locCenter;
            MyVector3.TransformCoordinate(ref sphere.Center, ref invTrans, out locCenter);

            float locRadius;
            if (IgnoreScale)
                locRadius = sphere.Radius;
            else
            {
                // Transform sphere radius into the obb coordinates
                MyVector3 vRadius = MyVector3.UnitX * sphere.Radius;
                MyVector3.TransformNormal(ref vRadius, ref invTrans, out vRadius);
                locRadius = vRadius.Length();
            }

            //Perform regular BoundingBox to BoundingSphere containment check
            MyVector3 minusExtens = -Extents;
            MyVector3 vector;
            MyVector3.Clamp(ref locCenter, ref minusExtens, ref Extents, out vector);
            float distance = MyVector3.DistanceSquared(locCenter, vector);

            if (distance > locRadius * locRadius)
                return MyContainmentType.Disjoint;

            if ((((minusExtens.X + locRadius <= locCenter.X) && (locCenter.X <= Extents.X - locRadius)) && ((Extents.X - minusExtens.X > locRadius) &&
                (minusExtens.Y + locRadius <= locCenter.Y))) && (((locCenter.Y <= Extents.Y - locRadius) && (Extents.Y - minusExtens.Y > locRadius)) &&
                (((minusExtens.Z + locRadius <= locCenter.Z) && (locCenter.Z <= Extents.Z - locRadius)) && (Extents.Z - minusExtens.Z > locRadius))))
            {
                return MyContainmentType.Contains;
            }

            return MyContainmentType.Intersects;
        }