I'm trying to determine the coordinates of the intersection point of three sphere surfaces utilizing either of fsolve and lsqnonlin. I chose these two because others have posted their code for comparable problems. The code for both seems to work. However, judging by my simple distance checks between the sphere centers and the solutions, lsqnonlin seems to result in a rather big variance (e.g. distances 11.7,10.0,12.97 for radii of 10) whereas fsolve seems to be spot-on (distances == 10). I'd therefore use fsolve although slight inaccuracies of ~+5% would be ok(-5% wouldn't be ok). On the other hand, fsolve doesn't support the bounds I need (e.g. x(1) > 0; [0;-Inf;-Inf] for lsqnonlin).
Q: Can I make fsolve return both intersection points (if both exist) so I can select the correct one manually? Or can I make lsqnonlin more accurate?
Code I use to call fsolve:
coord = [x1,y1,z1;x2,y2,z2;x3,y3,z3]; r = [r1;r2;r3] param = %irrelevant for this;
start=[0;0;0]; [x,fval]= fsolve(@(unknown)surfaceFunctions2(unknown, coord, r, param), start);%Distance check:
dist1=sqrt((x(1)-y1)^2+(x(2)-x1)^2+(x(3)-z1)^2); dist2=sqrt((x(1)-y2)^2+(x(2)-x2)^2+(x(3)-z2)^2); dist3=sqrt((x(1)-y3)^2+(x(2)-x3)^2+(x(3)-z3)^2);
surfaceFunctions2 contains:
function F = surfaceFunctions2(unknown, coord, r, opt) y = unknown(1); x = unknown(2); z = unknown(3); %Surface functions for the spheres
f1 = (x - coord(1,1))^2 + (y - coord(1,2))^2 + (z - coord(1,3))^2 - r(1)^2; f2 = (x - coord(2,1))^2 + (y - coord(2,2))^2 + (z - coord(2,3))^2 - r(2)^2; f3 = (x - coord(3,1))^2 + (y - coord(3,2))^2 + (z - coord(3,3))^2 - r(3)^2; F = [ f1 ; f2 ; f3]; end;
I use this to call lsqnonlin:
coord = [x1,y1,z1;x2,y2,z2;x3,y3,z3]; r = [r1;r2;r3] param = %irrelevant for this; start=[0;0;0]; lb = [0; -Inf;-Inf]; ub = [Inf;Inf;Inf]; [x, fval] = lsqnonlin(@(x)sphereSurfaces(x, coord,r,param), start, lb, ub, opt); %Distance check: dist1=sqrt((x(1)-y1)^2+(x(2)-x1)^2+(x(3)-z1)^2); dist2=sqrt((x(1)-y2)^2+(x(2)-x2)^2+(x(3)-z2)^2); dist3=sqrt((x(1)-y3)^2+(x(2)-x3)^2+(x(3)-z3)^2);
sphereSurfaces contains:
function err = sphereSurfaces( x,coord,r,param ) err = [sqrt(sum((x-coord(:,1)).^2)) - r(1); sqrt(sum((x-coord(:,2)).^2)) - r(2); sqrt(sum((x-coord(:,3)).^2)) - r(3)]; %experimented with this instead of the above block, gives the same results, not sure which one is better/faster
% err = [sum((x-M(:,1)).^2) - r(1)^2;
% sum((x-M(:,2)).^2) - r(2)^2;
% sum((x-M(:,3)).^2) - r(3)^2];
end
The main question is above, but what about the commented block in my sphereSurfaces function? Which one should I use or is it even incorrect?
If anyone wants to run the code themselves, they can use these values. However, they were picked at pretty much random. (probably poor choice by me, test with any other values you want): y1 = 5;x1 = 5;z1 = 0;r1 = 10;y2 = 5;x2 = 5;z2 = 5;r2 = 10;y3 = 5;x3 = 7.5;z3 = 2.5;r3 = 10;
Best Answer