0

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

4

2 回答 2

0

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

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)
于 2013-05-30T15:37:28.407 回答
0

您提出的算法实际上不会找到最大距离的两个坐标。例如,如果距离最大的两个点有z = 0?

这里有两个解决方案,一个实际上会给你两个最大距离的点,另一个是你的北极-南极算法的实现。请注意,在这两种解决方案中,我给出的函数都返回候选点的索引,而不是点本身。您可以自己获得积分

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

解决方案1:找到距离最大的两个点

尝试使用文件交换distmat中的功能。它需要一个点数组,其中是点的数量,并且是维度,并返回一个距离数组,其中是 和 之间的距离。有 4 种不同的算法可用于生成矩阵,具体取决于哪种算法为您提供最佳性能。N x DANDN x Ndistdist(i, j)A(i,:)A(j,:)distmat

您可以使用此函数创建一个距离矩阵,然后使用它max来定位最大距离的候选者。然后你可以以任何你喜欢的方式打破关系。

在下面的函数中,我找到了所有距离最大的点。如果有不止一对,那么我会根据候选人之间的 xy 距离打破平局。

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
于 2013-05-30T16:01:10.037 回答