基于@ihcgeneva 的帖子,我会避免一起使用循环,而是使用bsxfun。 @ihcgeneva 的代码可以大大简化为:
xList = [1, 2, 3, 4, 5];
yList = [5, 4, 2, 2, 1];
rootPoint = 3; %The point you want as your 'base'
Distance = sqrt(sum(bsxfun(@minus, [xList; yList].', [xList(rootPoint) yList(rootPoint)]).^2, 2));
请注意,不需要定义匿名函数d。此外,也不需要循环。使用 MATLAB,我们始终鼓励您 vectorize 您的代码。向量化的意思是 MATLAB 中的某些函数将接受输入数组或矩阵,并且该函数将单独对每个条目进行操作。这些函数的输出将为您提供一个大小相同的数组或矩阵,其中每个值都具有应用于这些元素的函数。它已被证明比遍历数组或矩阵中的每个元素并一次将函数应用于每个元素要快得多。这主要是由于函数调用开销。对于想要应用函数的元素,只调用一次而不是多次调用函数会更有效。
现在,上面的代码很容易吸收,但一旦掌握了它,仍然很容易理解。 bsxfun 代表 Binary Singleton Expansion Function。如果我们查看函数内部,我们会在您的矩形中的单个点之间调用minus 函数,该点位于索引rootPoint 与矩形中的所有其他坐标之间。我们要做的是将坐标放入二维矩阵中,其中第一列表示x 坐标,第二列表示y 坐标。接下来,bsxfun 所做的是复制位于rootPoint 的点,使其与这个二维矩阵大小相同。然后bsxfun 将在这个复制的矩阵与您创建的原始二维矩阵之间进行逐个元素的减法。
这将执行欧几里得距离的第一部分,减去相应的尺寸。这将创建一个输出二维矩阵,其中第一列是x 分量的减法,第二列是y 分量的减法。然后我们将矩阵中的每个值平方,然后对列求和,然后取平方根,从而完成欧几里得距离运算。 @lhcgeneva 已将您置于正确的轨道上,您正在查看的点与矩形中其他点之间的最短距离是欧几里得距离。
现在,如果您想像在图像中那样绘制从一点到另一点的线,您实际上根本不需要计算长度。您只需要知道沿矩形的点在哪里,显示图像,然后使用plot 并绘制从矩形中的每个点到源点的线。这个看起来很像IC管脚布局图,所以我就用网上找的一个:
让我们使用 3 号引脚作为源。我还浏览了图像并指出了每个大头针中间的位置:
points = [49 84; 49 133; 49 178; 49 229; 49 277; 49 325; 49 372; 205 374; 205 325; 205 276; 205 228; 205 181; 205 131; 205 87];
第一列是x 或列坐标,而第二列是y 或此图像中每个引脚的中心所在的行坐标。现在,您所要做的就是显示此图像,使用hold on 确保您可以在绘图上放置多条线而不擦除它,并绘制从源点到矩阵中每个点的线:
im = imread('http://www.infraredremote.com/images/14-pin-IC.jpg');
imshow(im);
hold on;
points = [49 84; 49 133; 49 178; 49 229; 49 277; 49 325; 49 372; 205 374; 205 325; 205 276; 205 228; 205 181; 205 131; 205 87];
rootPoint = 3;
for idx = 1 : size(points, 1)
plot([points(rootPoint, 1) points(idx, 1)], [points(rootPoint, 2) points(idx, 2)], 'r', 'LineWidth', 5);
end
以上代码直接从互联网加载到图片中。然后我们使用imshow 显示图像,然后使用hold on,就像我们之前谈到的那样。接下来,我们选择根点,即引脚 3,然后遍历所有点并从根点到每个引脚画一条线。我们将线条设为红色,并将线条的宽度设为 5 个像素粗。在这种情况下,我们确实需要遍历这些点以使其变得容易。我们可以对绘图进行矢量化处理,但鉴于您目前对 MATLAB 的了解,它会变得有点复杂。
无论如何,这就是我得到的:
编辑
在您的 cmets 中,您说过要显示从根点到矩形中每个点的距离。你可以用一个循环来做到这一点。不幸的是,在打印方面,没有办法通过矢量化轻松完成,但循环打印语句应该花费很少的时间,所以我们不应该在这里担心矢量化。
因此,您可以这样做:
%// Define points along rectangle and root point
points = [49 84; 49 133; 49 178; 49 229; 49 277; 49 325; 49 372; 205 374; 205 325; 205 276; 205 228; 205 181; 205 131; 205 87];
rootPoint = 3;
%// Find distances
Distance = sqrt(sum(bsxfun(@minus, points, points(rootPoint,:)).^2, 2));
for idx = 1 : numel(Distance)
fprintf('Distance between reference point %d and point %d is %f\n', ...
rootPoint, idx, Distance(idx));
end
请注意,我必须根据距离稍微修改代码。因为我们的点现在是一个二维数组,所以核心算法还是一样的,但是我必须以稍微不同的方式来获取点。具体来说,我不需要在bsxfun 中构造二维矩阵,因为它已经创建好了。我还可以通过获取位于由rootPoint 索引的行的单行的所有列来轻松提取根点。接下来,我们遍历从根点到矩形中每个点的每个距离,然后简单地打印出来。这是我得到的输出:
Distance between reference point 3 and point 1 is 94.000000
Distance between reference point 3 and point 2 is 45.000000
Distance between reference point 3 and point 3 is 0.000000
Distance between reference point 3 and point 4 is 51.000000
Distance between reference point 3 and point 5 is 99.000000
Distance between reference point 3 and point 6 is 147.000000
Distance between reference point 3 and point 7 is 194.000000
Distance between reference point 3 and point 8 is 250.503493
Distance between reference point 3 and point 9 is 214.347848
Distance between reference point 3 and point 10 is 184.228119
Distance between reference point 3 and point 11 is 163.816971
Distance between reference point 3 and point 12 is 156.028843
Distance between reference point 3 and point 13 is 162.926364
Distance between reference point 3 and point 14 is 180.601772
这看起来是对的,当然是有道理的,因为点 3 和它自身(打印输出的第 3 行)之间的距离是 0。