void Sphere_Enclose(Sphere &s, const T &obj) { PointWithDistance corners[n]; for(int i = 0; i < n; ++i) { corners[i].pt = obj.CornerPoint(i); corners[i].d = s.pos.DistanceSq(corners[i].pt); } std::sort(corners, corners+n); for(int i = n-1; i >= 0; --i) s.Enclose(corners[i].pt); }
// Encloses n points into the Sphere s, in the order of farthest first, in order to // generate the tightest resulting enclosure. void Sphere_Enclose_pts(Sphere &s, const vec *pts, int n) { AutoArrayPtr<PointWithDistance> cornersPtr(AlignedNew<PointWithDistance>(n, 16)); PointWithDistance *corners = cornersPtr.ptr; for(int i = 0; i < n; ++i) { corners[i].pt = pts[i]; corners[i].d = s.pos.DistanceSq(corners[i].pt); } std::sort(corners, corners+n); for(int i = n-1; i >= 0; --i) s.Enclose(corners[i].pt); }
Sphere Sphere::FastEnclosingSphere(const vec *pts, int numPoints) { Sphere s; if (numPoints == 0) { s.SetNegativeInfinity(); return s; } assume(pts || numPoints == 0); #ifndef MATH_ENABLE_INSECURE_OPTIMIZATIONS if (!pts) return Sphere(); #endif // First pass: Pick the cardinal axis (X,Y or Z) which has the two most distant points. int minx, maxx, miny, maxy, minz, maxz; AABB::ExtremePointsAlongAABB(pts, numPoints, minx, maxx, miny, maxy, minz, maxz); float dist2x = pts[minx].DistanceSq(pts[maxx]); float dist2y = pts[miny].DistanceSq(pts[maxy]); float dist2z = pts[minz].DistanceSq(pts[maxz]); int min = minx; int max = maxx; if (dist2y > dist2x && dist2y > dist2z) { min = miny; max = maxy; } else if (dist2z > dist2x && dist2z > dist2y) { min = minz; max = maxz; } // The two points on the longest axis define the initial sphere. s.pos = (pts[min] + pts[max]) * 0.5f; s.r = pts[min].Distance(s.pos); // Second pass: Make sure each point lies inside this sphere, expand if necessary. for(int i = 0; i < numPoints; ++i) s.Enclose(pts[i]); return s; }