寻找大圆交点的第一点

时间:2013-09-27 22:40:34

标签: matlab mapping

我有一个问题,我一直试图解决,我无法想出答案。我在Matlab中编写了一个函数,给定两个lat / lon点和两个轴承,将返回两个很大的圆交点。

但是,我真正需要的是沿着两个初始标题的第一个大圆交点。即如果两架飞机在纬度/经度点1和2处开始,轴承1和轴承2的初始轴承,两个大圆交点中的哪一个是他们遇到的第一个?有很多解决方案(使用hasrsine)会让我更接近这两点,但我实际上并不关心哪一点更接近,我关心的是我会先遇到具体的起点和标题。在许多情况下,两个交叉点的距离实际上是第二个交叉点。

现在,我意识到我可以用很多条件语句来处理不同的情况,但我认为必须有一种方法来处理它我的所有交叉产品的顺序(下面给出的功能代码) ),但我根本无法想出正确的解决方案!我还要提一下,这个函数将用于大型计算密集型模型,所以我认为这个问题的解决方案需要相当优雅/快速。任何人都可以帮我解决这个问题吗?

以下不是我的功能代码(我不能在此列出),但它是我的功能基于的伪代码:

 %Given inputs of lat1,lon1,Bearing1,lat2,lon2,Bearing2:
%Calculate arbitrary secondary point along same initial bearing from first
%point
dAngle = 45;
lat3 = asind( sind(lat1)*cosd(dAngle) + cosd(lat1)*sind(dAngle)*cosd(Bearing1));
lon3 = lon1 + atan2( sind(Bearing1)*sind(dAngle)*cosd(lat1), cosd(dAngle)-sind(lat1)*sind(lat3) )*180/pi;
lat4 = asind( sind(lat2)*cosd(dAngle) + cosd(lat2)*sind(dAngle)*cosd(Bearing2));
lon4 = lon2 + atan2( sind(Bearing2)*sind(dAngle)*cosd(lat2), cosd(dAngle)-sind(lat2)*sind(lat4) )*180/pi;


%% Calculate unit vectors
% We now have two points defining each of the two great circles.  We need
% to calculate unit vectors from the center of the Earth to each of these
% points
[Uvec1(1),Uvec1(2),Uvec1(3)] = sph2cart(lon1*pi/180,lat1*pi/180,1);
[Uvec2(1),Uvec2(2),Uvec2(3)] = sph2cart(lon2*pi/180,lat2*pi/180,1);
[Uvec3(1),Uvec3(2),Uvec3(3)] = sph2cart(lon3*pi/180,lat3*pi/180,1);
[Uvec4(1),Uvec4(2),Uvec4(3)] = sph2cart(lon4*pi/180,lat4*pi/180,1);


%% Cross product
%Need to calculate the the "plane normals" for each of the two great
%circles
N1 = cross(Uvec1,Uvec3);
N2 = cross(Uvec2,Uvec4);


%% Plane of intersecting line
%With two plane normals, the cross prodcut defines their intersecting line
L = cross(N1,N2);
L = L./norm(L);
L2 = -L;
L2 = L2./norm(L2);


%% Convert normalized intersection line to geodetic coordinates
[lonRad,latRad,~]=cart2sph(L(1),L(2),L(3));
lonDeg = lonRad*180/pi;
latDeg = latRad*180/pi;
[lonRad,latRad,~]=cart2sph(L2(1),L2(2),L2(3));
lonDeg2 = lonRad*180/pi;
latDeg2 = latRad*180/pi;

更新:Mathworks论坛上的用户指出了这一点:

  

实际上他们可能各自都达到了不同的地步。我可能误解了这个问题,但是你的措辞表明两条轨迹都会朝着同一点收敛,这是不正确的。如果你想象的第一个点是在一个交叉点之后稍微一点而第二个点在另一个交叉点之后稍微一点,你就会遇到这样的情况,即每个“平面”将朝向最开始时与另一个平面最接近的交叉点行进。

我没想到这个。实际上很可能每个平面首先与不同的大圆交叉相交。这让事情变得更加复杂......

1 个答案:

答案 0 :(得分:1)

据推测,你有一个飞机方向的速度矢量(你想要寻找你的第一个交叉点的方向 - “地球表面上的方位矢量”)。你没有实际指定这个。我们称之为v

您还有两个点的笛卡尔坐标P1P2,以及平面的初始位置P0。假设每个都已经在单位球上(长度= 1)。

现在我们想要知道哪个是更短的距离 - 到P1或P2 - 所以我们需要知道角度“从法向量的方向看”。为此,我们需要sincos - 然后我们可以使用atan2找到角度。我们从交叉积中获得sin(记住所有向量都已归一化),并从点积中获得cos。为了从正确的方向看到sin“,我们采用带正常向量的点积。

这是一段将所有内容放在一起的代码 - 我使用非常简单的点和方向向量坐标,所以我可以在脑海中确认这给出了正确的答案:

% sample points of P0...P2 and v
P0 = [1 0 0];
P1 = [0 1 0];
P2 = [0 -1 0];
v = [0 1 0];
% compute the "start direction normal":
n0 = cross(P0, v);
n0 = n0 / norm( n0 );  % unit vector 

% compute cross and dot products:
cr01 = cross(P0, P1);
cr02 = cross(P0, P2);
cos01 = dot(P0, P1);
cos02 = dot(P0, P2);

% to get sin with correct sign, take dot product with direction normal:
sin01 = dot(cr01, n0);
sin02 = dot(cr02, n0);
% note - since P0 P1 and P2 are all in the same plane
% cr02 and cr02 are either pointing in the same direction as n0
% or the opposite direction. In the latter case we get a sign flip for the sin
% in the former case this does nothing

% Now get the angle, mapped from 0 to 2 pi:
ang1 = mod(atan2(sin01, cos01), 2*pi);
ang2 = mod(atan2(sin02, cos02), 2*pi);

if( ang1 < ang2 ) 
  fprintf(1,'point 1 is reached first\n');
  % point 1 is the first one reached
else
  fprintf(1,'point 2 is reached first\n');
  % point 2 is the first
end

当您更改速度矢量的方向(指向P2而不是P1)时,程序会正确地告诉您“首先到达点2”。

请告诉我这是否适合您!