Find the center of a sphere / circle given points on the surface / edge?

I am trying to compute the center of a sphere given a set of non colinear points. How can I do this ? Is there any helper for this ? getBoundingSphere did not work as the sphere encompasses my points. I want a sphere that CONTAINS as opposed to just minimizes all points within it.

I’m not sure I understand what you mean here. Can you please explain in more detail why you can’t use Sphere.setFromPoints() and then evaluate the center property of the resulting bounding sphere?

Hi @Mugen87. Thanks for your reply. Basically when i tried the getBoundingSphere() method it returned the smallest sphere that could contain all my given points. These points were not necessarily on the surface of the sphere (two points were) while all others were inside it. So I am assuming the bounding sphere is the smallest sphere that can ‘bound’ a set of points.

I actually don’t want this but instead I want the sphere that has all of the given points on its surface (or atleast 3 points). Just like how it is possible to draw a 2-D circle with 3 given points, is there any function on three.js that can give me my sphere or circle with 3 given points instead of having to calculate it mathematically ?

Sorry, but I don’t understand what you mean by that. You can’t draw a circle so that three arbitrary points in 2D space lie on its contour. And it certainly does not work for a sphere in 3D space.

It can be done mathematically as long as the points are not collinear. I wanted to know if there was any helper for this: https://www.wikihow.com/Draw-a-Circle-Given-Three-Points

1 Like

Ah okay, assuming this property it works. But unfortunately, there is no out-of-the-box routine that can compute the intended result for you.

No problem. Thanks for your help. I will try to create the helper function myself and share it here just so it might be useful for others.

1 Like

Here is my solution. I hope this helps :

getCenterOfSphereOrCircle(points): function that takes an array of three Vector3() points and returns the center of the circle on which the points lie in global coordinates. Additionally, if 4 points are passed instead, returns the center of the sphere on which the points lie. Returns null if the 3 points are collinear or if the 4 points (incase of a sphere) are coplanar.

  const getCenterOfSphereOrCircle = function (points) {
    // check if inputs are valid and return null object if they are:
    if (!Array.isArray(points) || (points.length !== 3 && points.length !== 4))
        return { exists: false, center: null };

    if (points.length === 4) {
        var p1 = points[0];
        var p2 = points[1];
        var p3 = points[2];
        var p4 = points[3];
        var c1 = p2.clone().sub(p1);
        var c2 = p3.clone().sub(p1);
        var c3 = p4.clone().sub(p1);
        // check for co-planarity and return null if found:
        if (c1.clone().dot(c2.clone().cross(c3)) === 0)
            return { exists: false, center: null };

        var d1s = p1.lengthSq();
        var d2s = p2.lengthSq();
        var d3s = p3.lengthSq();
        var d4s = p4.lengthSq();

        var d21 = (d2s - d1s) / 2;
        var d32 = (d3s - d2s) / 2;
        var d43 = (d4s - d3s) / 2;

        var x21 = p2.x - p1.x;
        var y21 = p2.y - p1.y;
        var z21 = p2.z - p1.z;

        var x32 = p3.x - p2.x;
        var y32 = p3.y - p2.y;
        var z32 = p3.z - p2.z;

        var x43 = p4.x - p3.x;
        var y43 = p4.y - p3.y;
        var z43 = p4.z - p3.z;

        var A32 = (d32 * x21) - (x32 * d21);
        var B32 = (x32 * z21) - (z32 * x21);
        var C32 = (y32 * x21) - (x32 * y21);

        var A43 = (d43 * x21) - (x43 * d21);
        var B43 = (x43 * z21) - (z43 * x21);
        var C43 = (y43 * x21) - (x43 * y21);

        var c = ((A32 * C43) - (A43 * C32)) / ((B43 * C32) - (B32 * C43));
        var b = (A32 + (c * B32)) / C32;
        var a = (d21 - (b * y21) - (c * z21)) / x21;

        var center = new THREE.Vector3(a, b, c);
        return { exists: true, center: center };
    }
    else if (points.length === 3) {

       var p1 = points[0];
        var p2 = points[1];
        var p3 = points[2];
        var c1 = p2.clone().sub(p1);
        var c2 = p3.clone().sub(p1);
        // check for co-linearity and return null if found:
        if (c1.clone().cross(c2).length() === 0)
            return { exists: false, center: null };

        var c11 = c1.x * c1.x + c1.y * c1.y + c1.z * c1.z;
        var c22 = c2.x * c2.x + c2.y * c2.y + c2.z * c2.z;
        var c12 = c1.x * c2.x + c1.y * c2.y + c1.z * c2.z;
        var k = 1 / (2 * (c11 * c22 - c12 * c12));
        var k1 = k * c22 * (c11 - c12);
        var k2 = k * c11 * (c22 - c12);
        var a = p1.x + k1 * c1.x + k2 * c2.x;
        var b = p1.y + k1 * c1.y + k2 * c2.y;
        var c = p1.z + k1 * c1.z + k2 * c2.z;

        var center = new THREE.Vector3(a, b, c);
        return { exists: true, center: center };
    }

},
1 Like

Thanks for sharing your code :+1:

1 Like