Re: Re: Sphere through 4 points
- To: mathgroup at smc.vnet.net
- Subject: [mg85539] Re: [mg85415] Re: [mg85401] Sphere through 4 points
- From: Daniel Lichtblau <danl at wolfram.com>
- Date: Wed, 13 Feb 2008 04:26:08 -0500 (EST)
- References: <200802090915.EAA16803@smc.vnet.net> <200802101010.FAA17539@smc.vnet.net>
danl at wolfram.com wrote: >> Given 4 points in 3-space not lying in a plane, I want the >>center and radius of the incident sphere. I know about the elegant >>determinant solution (4 or 5 determinants, each 4x4, plus a few >>arithmetic operations) and I'm using that, but maybe someone has coded >>a faster version. >> Thanks for any information. >> >>Steve Gray >> > > > Not sure if this is faster, but could do: > > centerAndRadius[data_] := Module[ > {x, y, z, vars, rsq, coeffs, polys, lpolys, cen}, > vars = {x, y, z}; > polys = (vars.vars - rsq) /. > Thread[vars -> (vars - Transpose[data])]; > lpolys = Expand[Rest[polys] - First[polys]]; > coeffs = CoefficientArrays[lpolys, vars]; > cen = LinearSolve[Last[coeffs], First[coeffs]]; > {cen, Sqrt[rsq]} /. > First[Solve[(First[polys] /. Thread[vars -> cen]) == 0]] > ] > > In[147]:= SeedRandom[1111]; > data = RandomReal[{-5, 5}, {4, 3}]; > centerAndRadius[data] > > Out[149]= {{-2.25666, -13.9661, 7.0018}, 15.1774} > > Can do around 200+ per second, on my laptop. > > In[150]:= Timing[Do[centerAndRadius[data], {100}]] > Out[150]= {0.421, Null} > > Daniel Lichtblau > Wolfram Research It was pointed out to me that this code does not work correctly. Ther eason is I forgot to negate the constant terms, in effect moving them to the other side to make equations from linear polynomials. Here is the correct form. centerAndRadius[data_] := Module[{x, y, z, vars, rsq, coeffs, polys, lpolys, cen}, vars = {x, y, z}; polys = (vars.vars - rsq) /. Thread[vars -> (vars - Transpose[data])]; lpolys = Expand[Rest[polys] - First[polys]]; coeffs = CoefficientArrays[lpolys, vars]; cen = LinearSolve[Last[coeffs], -First[coeffs]]; {cen, Sqrt[rsq]} /. First[Solve[(First[polys] /. Thread[vars -> cen]) == 0]]] Check: In[85]:= SeedRandom[1111]; data = RandomReal[{-5, 5}, {4, 3}]; {cen, rad} = centerAndRadius[data] Out[87]= {{2.25666, 13.9661, -7.0018}, 17.9779} In[89]:= Map[Norm[# - cen] - rad &, data] Out[89]= {0., 0., 0., 0.} If raw speed is the issue, the variant below is faster. centerAndRadius2[data_] := Module[{x, y, z, x0, y0, z0, rsqr, coeffs, rules, polys, lpolys, cen}, rules = (Thread[{x, y, z} -> #1] &) /@ data; polys = x^2 - 2*x*x0 + y^2 - 2*y*y0 + z^2 - 2*z*z0 /. rules; lpolys = Rest[polys] - First[polys]; coeffs = Normal[CoefficientArrays[lpolys, {x0, y0, z0}]]; cen = LinearSolve[Last[coeffs], -First[coeffs]]; {cen, Norm[cen - First[data]]}] Daniel Lichtblau Wolfram Research
- Follow-Ups:
- Re: Re: Re: Sphere through 4 points
- From: Daniel Lichtblau <danl@wolfram.com>
- Re: Re: Re: Sphere through 4 points
- References:
- Sphere through 4 points
- From: Steve Gray <stevebg@roadrunner.com>
- Re: Sphere through 4 points
- From: danl@wolfram.com
- Sphere through 4 points