% XNAVAI locate a point on a spheroid using circular or hyperbolic navigation % % SYNOPSIS: % function [pnt]=xnavai(sosopos,dist,refpoint,mindex) % % DESCRIPTION: % XNAVAI locates a point from a spheroid using circular or hyperbolic % navigation. % % ARGUMETNS: % INPUT: sosopos matrix of the size 2 by 2 which contains the % positions (latitude, longitude) of the sound % sources used for this point in radiants. % The matrix should look like: % [soso_lat1, soso_long1; % soso_lat2, soso_long2] % dist vector which contains the distance of each % sound source in km used for this point. % refpoint vector with length 2, which contains the % position of the refpoint in radiants. % The vector should look like: % [ref_lat, ref_lon] % mindex =2 --> circular navigation % =3 --> hyperbolic navigation % % OUTPUT: pnt vector with length 2, which contains the % calculated floatposition in radiants.# % The vector will look like: % [pnt_lat, pnt_lon] % % Maximum number of iteration steps set to 20 function [pnt]=xnavai(sosopos,dist,refpoint,mindex) a(1:3)=999; dt1=999; dt2=999; dt3=999; dt4=999; dt5=999; dt6=999; TOL=0.1; INCR=0.000156788; ERAD=6377; imax=20; icnt=0; stop=0; pnt=[NaN, NaN]; if mindex==2 % the circular case if ~(isnan(dist(1)) || isnan(dist(2))) % if neither dist(1) nor dist(2) = NaN d1=dist(1); d2=dist(2); sosoposition(1,:) = sosopos(1,:); sosoposition(2,:) = sosopos(2,:); elseif ~(isnan(dist(1)) || isnan(dist(3))) % if neither dist(1) nor dist(3) = NaN d1=dist(1); d2=dist(3); sosoposition(1,:) = sosopos(1,:); sosoposition(2,:) = sosopos(3,:); elseif ~(isnan(dist(2)) || isnan(dist(3))) % if neither dist(1) nor dist(3) = NaN d1=dist(2); d2=dist(3); sosoposition(1,:) = sosopos(2,:); sosoposition(2,:) = sosopos(3,:); end elseif mindex==3 % the hyperbolic case d1=dist(2)-dist(1); d2=dist(3)-dist(1); sosoposition(1,:) = sosopos(1,:); sosoposition(2,:) = sosopos(2,:); sosoposition(3,:) = sosopos(3,:); end istop=0; while ((icnt < imax) && ~stop) istop=istop+1; if istop > 20 pnt=[NaN, NaN]; stop=1; end ps=refpoint; a(1)=artoa.data.calculateEllipk4(ps,sosoposition(1,:)); a(2)=artoa.data.calculateEllipk4(ps,sosoposition(2,:)); if mindex==3 a(3)=artoa.data.calculateEllipk4(ps,sosoposition(3,:)); end if ((a(1)<0) || (a(2)<0) || (a(3)<0)) stop=1; else if mindex==2 cr1=d1-a(1); cr2=d2-a(2); elseif mindex==3 cr1=d1-a(2)+a(1); cr2=d2-a(3)+a(1); end % check if the error is small enough err=abs(cr1)+abs(cr2); if (err <= TOL) pnt=refpoint; stop=1; else % if not, go on incrementing position ps(1)=refpoint(1); ps(2)=refpoint(2)+INCR; dt1=artoa.data.calculateEllipk4(ps,sosoposition(1,:)); dt2=artoa.data.calculateEllipk4(ps,sosoposition(2,:)); if mindex==3 dt3=artoa.data.calculateEllipk4(ps,sosoposition(3,:)); end if ((dt1<0) || (dt2<0) || (dt3<0)) stop=1; else ps(1)=refpoint(1)+INCR; ps(2)=refpoint(2); dt4=artoa.data.calculateEllipk4(ps,sosoposition(1,:)); dt5=artoa.data.calculateEllipk4(ps,sosoposition(2,:)); if mindex==3 dt6=artoa.data.calculateEllipk4(ps,sosoposition(3,:)); end if ((dt4<0) || (dt5<0) || (dt6<0)) stop=1; else if mindex==2 b1=dt1-a(1); b2=dt2-a(2); b3=dt4-a(1); b4=dt5-a(2); elseif mindex==3 b1=(dt2-dt1)-(a(2)-a(1)); b2=(dt3-dt1)-(a(3)-a(1)); b3=(dt5-dt4)-(a(2)-a(1)); b4=(dt6-dt4)-(a(3)-a(1)); end dnom=(b1*b4-b2*b3)*ERAD; c(2)=(cr1*b4-b3*cr2)/dnom; c(1)=(cr2*b1-b2*cr1)/dnom; im=max(abs(c))==abs(c); cc=c(im); if mindex==2 im=min(abs(a(1:2)))==abs(a(1:2)); aa=a(im); elseif mindex==3 im=min(abs(a(1:3)))==abs(a(1:3)); aa=a(im); end cp=2*cc*ERAD/aa; if cp < 1 cp=1; end refpoint=refpoint+c/cp; end end end end end