Web/Javascript

4 Point Sphere

bitcoder 2022. 12. 14. 18:11
728x90
<!-- hide
var zero = parseFloat("0");
var Xo, Yo, Zo;
var P = [[zero,zero,zero],[zero,zero,zero],[zero,zero,zero],[zero,zero,zero]];

// evaluate the determinant
function compute()
{
    P[0][0] = parseFloat(calc.x1.value);
    P[0][1] = parseFloat(calc.y1.value);
    P[0][2] = parseFloat(calc.z1.value);
    P[1][0] = parseFloat(calc.x2.value);
    P[1][1] = parseFloat(calc.y2.value);
    P[1][2] = parseFloat(calc.z2.value);
    P[2][0] = parseFloat(calc.x3.value);
    P[2][1] = parseFloat(calc.y3.value);
    P[2][2] = parseFloat(calc.z3.value);
    P[3][0] = parseFloat(calc.x4.value);
    P[3][1] = parseFloat(calc.y4.value);
    P[3][2] = parseFloat(calc.z4.value);

    // check input
    if (isNaN(P[0][0])||isNaN(P[0][1])||isNaN(P[0][2])||
        isNaN(P[1][0])||isNaN(P[1][1])||isNaN(P[1][2])||
        isNaN(P[2][0])||isNaN(P[2][1])||isNaN(P[2][2])||
        isNaN(P[3][0])||isNaN(P[3][1])||isNaN(P[3][2]))
    {
        window.alert("Invalid input!");
        return;
    }
  
    var r = sphere();
    if (r > 0)
    {
        calc.x0.value = Xo;
        calc.y0.value = Yo;
        calc.z0.value = Zo;
        calc.r0.value = r;
    }
    else
        calc.r0.value = "Not a sphere";
}

// Calculate center and radius of sphere given four points
function sphere()
{
    var i;
    var r, m11, m12, m13, m14, m15;
    var a = [[zero,zero,zero,zero],[zero,zero,zero,zero],[zero,zero,zero,zero],[zero,zero,zero,zero]];

    for (i = 0; i < 4; i++)                    // find minor 11
    {
        a[i][0] = P[i][0];
        a[i][1] = P[i][1];
        a[i][2] = P[i][2];
        a[i][3] = 1;
    }
    m11 = determinant( a, 4 );

    for (i = 0; i < 4; i++)                    // find minor 12 
    {
        a[i][0] = P[i][0]*P[i][0] + P[i][1]*P[i][1] + P[i][2]*P[i][2];
        a[i][1] = P[i][1];
        a[i][2] = P[i][2];
        a[i][3] = 1;
    }
    m12 = determinant( a, 4 );

    for (i = 0; i < 4; i++)                    // find minor 13
    {
        a[i][0] = P[i][0]*P[i][0] + P[i][1]*P[i][1] + P[i][2]*P[i][2];
        a[i][1] = P[i][0];
        a[i][2] = P[i][2];
        a[i][3] = 1;
    }
    m13 = determinant( a, 4 );

    for (i = 0; i < 4; i++)                    // find minor 14
    {
        a[i][0] = P[i][0]*P[i][0] + P[i][1]*P[i][1] + P[i][2]*P[i][2];
        a[i][1] = P[i][0];
        a[i][2] = P[i][1];
        a[i][3] = 1;
    }
    m14 = determinant( a, 4 );


    for (i = 0; i < 4; i++)                    // find minor 15
    {
        a[i][0] = P[i][0]*P[i][0] + P[i][1]*P[i][1] + P[i][2]*P[i][2];
        a[i][1] = P[i][0];
        a[i][2] = P[i][1];
        a[i][3] = P[i][2];
    }
    m15 = determinant( a, 4 );

    if (m11 == 0)
    {
        r = 0;
    }
    else
    {
        Xo =  0.5*m12/m11;                     // center of sphere
        Yo = -0.5*m13/m11;
        Zo =  0.5*m14/m11;
        r  = Math.sqrt( Xo*Xo + Yo*Yo + Zo*Zo - m15/m11 );
    }

    return r;                                  // the radius
}


//  Recursive definition of determinate using expansion by minors.
function determinant( a, n )
{
    var i, j, j1, j2;
    var d = parseFloat("0");
    var m = [[zero,zero,zero,zero],[zero,zero,zero,zero],[zero,zero,zero,zero],[zero,zero,zero,zero]];

    if (n == 2)                                // terminate recursion
    {
        d = a[0][0]*a[1][1] - a[1][0]*a[0][1];
    }
    else 
    {
        d = 0;
        for (j1 = 0; j1 < n; j1++ )            // do each column
        {
            for (i = 1; i < n; i++)            // create minor
            {
                j2 = 0;
                for (j = 0; j < n; j++)
                {
                    if (j == j1) continue;
                    m[i-1][j2] = a[i][j];
                    j2++;
                }
            }
            
            // sum (+/-)cofactor * minor  
            d = d + Math.pow(-1.0, j1)*a[0][j1]*determinant( m, n-1 );
        }
    }

    return d;
}

// unhide -->
728x90