public static BoundingSphere CreateFromPoints(XMFloat3[] points) { if (points == null) { throw new ArgumentNullException("points"); } if (points.Length == 0) { throw new ArgumentOutOfRangeException("points"); } // Find the points with minimum and maximum x, y, and z XMVector minX, maxX, minY, maxY, minZ, maxZ; minX = maxX = minY = maxY = minZ = maxZ = points[0]; for (int i = 1; i < points.Length; i++) { XMVector point = points[i]; float px = point.X; float py = point.Y; float pz = point.Z; if (px < minX.X) { minX = point; } if (px > maxX.X) { maxX = point; } if (py < minY.Y) { minY = point; } if (py > maxY.Y) { maxY = point; } if (pz < minZ.Z) { minZ = point; } if (pz > maxZ.Z) { maxZ = point; } } // Use the min/max pair that are farthest apart to form the initial sphere. XMVector deltaX = maxX - minX; XMVector distX = XMVector3.Length(deltaX); XMVector deltaY = maxY - minY; XMVector distY = XMVector3.Length(deltaY); XMVector deltaZ = maxZ - minZ; XMVector distZ = XMVector3.Length(deltaZ); XMVector v_center; XMVector v_radius; if (XMVector3.Greater(distX, distY)) { if (XMVector3.Greater(distX, distZ)) { // Use min/max x. v_center = XMVector.Lerp(maxX, minX, 0.5f); v_radius = distX * 0.5f; } else { // Use min/max z. v_center = XMVector.Lerp(maxZ, minZ, 0.5f); v_radius = distZ * 0.5f; } } else { //// Y >= X if (XMVector3.Greater(distY, distZ)) { // Use min/max y. v_center = XMVector.Lerp(maxY, minY, 0.5f); v_radius = distY * 0.5f; } else { // Use min/max z. v_center = XMVector.Lerp(maxZ, minZ, 0.5f); v_radius = distZ * 0.5f; } } // Add any points not inside the sphere. for (int i = 0; i < points.Length; i++) { XMVector point = points[i]; XMVector delta = point - v_center; XMVector dist = XMVector3.Length(delta); if (XMVector3.Greater(dist, v_radius)) { // Adjust sphere to include the new point. v_radius = (v_radius + dist) * 0.5f; v_center += (XMVector.Replicate(1.0f) - XMVector.Divide(v_radius, dist)) * delta; } } return(new BoundingSphere(v_center, v_radius.X)); }