/// <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; }
/// <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; }