2013-05-30 290 views
0

假设我有一个矩阵A,它是一个n * 3矩阵,列出了n个点的笛卡尔坐标。我感兴趣的是找到北极和南极,它们基本上是两个坐标,最大距离相隔。我想要northPole和southPole分别有最小和最大z坐标,我想用x和y坐标来打破关系。这个问题很容易使用循环执行,但我想让我的代码有效,因为矩阵A真的很大。因此,我需要使用内置的MatLab函数来寻找northPole和southPole,以便代码高效。谢谢!使用MatLab找到最大距离

+1

'NORTHPOLE和southPole这两个基本的坐标与最大距离apart'这可能会为你的数据是真实的,但你要明白,这个不具有普遍持有? –

+0

“我想要northPole和southPole分别有最小和最大z坐标” - 所以为什么不在z坐标上使用'max'和'min'? –

+0

@DavidK,因为他想“打破关系” – Shai

回答

0

您自己描述了答案:首先找到最小或最大Z值的索引,然后使用最小的X距离来打破关系。

zmax = max(A(:,3)); 
zmaxNdx = find(zmax == A(:,3)); 
d2 = A(zmaxNdx,1).^2 + A(zmaxNdx,2).^2; 
[~, d2minNdx] = min(d2); 
northpoleNdx = zmaxNdx(d2minNdx) 

zmin = min(A(:,3)); 
zminNdx = find(zmin == A(:,3)); 
d2 = A(zminNdx,1).^2 + A(zminNdx,2).^2; 
[~, d2minNdx] = min(d2); 
southpoleNdx = zminNdx(d2minNdx) 
+0

我不确定您的d2计算是否正在寻找。找到zmaxNdx和zminNdx后,我怎么做:sqrt((x2-x1)^ 2 +(y2-y1)^ 2)),然后找到最小化这个表达式的点。 –

+0

@SahilChaudhary这几乎是我正在使用的公式。我假设在极点x == y == 0,所以'x1'和'y1'将为零。我也省略了'sqrt()'作为一个优化,因为你只需要找到最小值并且平方根不会改变,这是最小的。 – shoelzer

+0

嘿,请阅读我发布的答案,我遇到了问题。非常感谢! :) –

0

你提出的算法实际上并不能找到两个坐标间的最大距离。例如,如果距离最远的两个点有z = 0

这里有两个解决方案,一个实际上会给你两个距离最远的点,另一个是你的NorthPole-southPole算法的实现。请注意,在这两种解决方案中,我给出的函数都会返回候选点的索引,而不是点本身。您可以通过

north = A(iN, :); 
south = A(iS, :); 

解决方案1获得积分自己:找到两个点与最大距离相隔

尝试使用distmat功能从file exchange.这需要一个N x D阵列点A的,其中N是并且D是尺寸,并且返回N x N阵列的距离dist,其中dist(i, j)A(i,:)A(j,:)之间的距离。 distmat有4种不同的算法可用于生成矩阵,具体取决于哪种算法可以提供最佳性能。

您可以使用此功能创建距离矩阵,然后使用max来定位候选人的最大距离。那么你可以用任何你喜欢的方式打破关系。

在下面的函数中,我找到所有具有最大距离的点。如果有多对,那么我根据候选人之间的x-y距离打破关系。

function [iN, iS] = poles(A) 

% create the distance matrix 
dist = distmat(A); 

% find all candidate pairs of north and south poles 
[~, iMax] = max(dist(:)); 
[iN, iS] = ind2sub(size(dist), iMax); 

% If there is only one, you are done, otherwise break the ties. 
if length(iMax) == 1 
    return 
end 

% 
% break ties by the euclidean distance of the x-y coordinates 
% note that this may not result in a unique set of north and south poles, 
% but you can always break further ties. 
north = A(iN, 1:2); 
south = A(iS, 1:2); 

tieBreak = sum(abs(north-south).^2, 2); 

[~, iMax] = max(tieBreak); 

iN = iN(iMax); 
iS = iS(iMax); 
end 

解决方案2:找到 “北极” 和 “南极”

该解决方案还采用了distmat功能。首先找到具有最大和最小z值的点。如果没有关系,则停止。否则,它会找到一对具有最大距离的“北”和“南”点,并按上述方式进行打分。

function [iN, iS] = poles(A) 

% find the min and max z values 
[~, iMaxZ] = max(A(:, 3)); 
[~, iMinZ] = min(A(:, 3)); 
iMaxZ = iMaxZ(:); 
iMinZ = iMinZ(:); 

if length(iMaxZ) == 1 && length(iMinZ) == 1 
    iN = iMaxZ; 
    iS = iMinZ; 
    return 
end 

nMax = length(iMaxZ); 
nMin = length(iMinZ); 

% put the north and south poles together 
northSouth = A([iMaxZ; iMinZ], :); 

% find the distance between them 
dist = distmat(northSouth); 

% restrict to only north-south pairs 
dist = dist(1:nMax, nMax+1:end); 

% find the maximum distance 
[~, iMaxDist] = max(dist(:)); 
[iN, iS] = ind2sub(size(dist), iMax); 

if length(iMaxDist) == 1 
    return 
end 

% break ties by the euclidean distance of the x-y coordinates 
% note that this may not result in a unique set of north and south poles, 
% but you can always break further ties. 
north = A(iN, 1:2); 
south = A(iS, 1:2); 

tieBreak = sum(abs(north-south).^2, 2); 

[~, iMax] = max(tieBreak); 

iN = iN(iMax); 
iS = iS(iMax); 
end 
+0

嘿,请阅读我发布的答案,我有问题。非常感谢! :) –

+0

我用两种可能的解决方案编辑了我的答案。 – hoogamaphone