# Smallest bounding sphere

I need to set a sphere collider for a diamond-shape model. When I add the component the sphere doesn’t cover the entire shape. With the next code I manage to set the center and radius of the sphere based on the mesh center and extents magnitude:

``````Bounds meshBounds = piece.GetComponent<MeshFilter>().mesh.bounds;
sphereCollider.center = meshBounds.center;
``````

However, it ends up covering more than necessary. Something to consider is that the pivot point of the Model is not centered, and the original rotation of the model may be in an almost random direction. Here’s a graphical example:

There is no easy solution to this problem. See [Bounding Sphere] for possible solutions / approximations.

edit
I found [this implementation of Ritter’s algorithm] and just ported it to C# / Unity:

``````using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public struct BoundingSphere
{
public Vector3 center;
{
center = aCenter;
}

public static BoundingSphere Calculate(IEnumerable<Vector3> aPoints)
{
Vector3 xmin, xmax, ymin, ymax, zmin, zmax;
xmin = ymin = zmin = Vector3.one * float.PositiveInfinity;
xmax = ymax = zmax = Vector3.one * float.NegativeInfinity;
foreach(var p in aPoints)
{
if(p.x < xmin.x) xmin = p;
if(p.x > xmax.x) xmax = p;
if(p.y < ymin.y) ymin = p;
if(p.y > ymax.y) ymax = p;
if(p.z < zmin.z) zmin = p;
if(p.z > zmax.z) zmax = p;
}
var xSpan = (xmax - xmin).sqrMagnitude;
var ySpan = (ymax - ymin).sqrMagnitude;
var zSpan = (zmax - zmin).sqrMagnitude;
var dia1 = xmin;
var dia2 = xmax;
var maxSpan = xSpan;
if (ySpan > maxSpan)
{
maxSpan = ySpan;
dia1 = ymin; dia2 = ymax;
}
if (zSpan > maxSpan)
{
dia1 = zmin; dia2 = zmax;
}
var center = (dia1 + dia2) * 0.5f;
var sqRad = (dia2 - center).sqrMagnitude;
foreach (var p in aPoints)
{
float d = (p - center).sqrMagnitude;
{
var r = Mathf.Sqrt(d);
var offset = r - radius;
center = (radius * center + offset * p) / r;
}
}
}
}
``````

Note: haven’t tested it yet It’s just a 1 to 1 translation. This could be a usage:

``````void Start()
{
MeshFilter mf = GetComponent<MeshFilter>();
Mesh m = mf.sharedMesh;
var sphere = BoundingSphere.Calculate(m.vertices);
col.center = sphere.center;
}
``````

Keep in mind that this will use all vertices in the mesh. If you have unused vertices and just want to include “used” vertices you would have to iterate through the triangles and grab all referenced vertices. The easiest way is to linq like this:

``````void Start()
{
MeshFilter mf = GetComponent<MeshFilter>();
Mesh m = mf.sharedMesh;
var verts = m.vertices;
var tris = m.triangles;
var sphere = BoundingSphere.Calculate(tris.Select(i=>verts*));*
``````