Matlab:计算矩形上不同点之间的向量长度

Matlab: Calculate vector lengths between different points on a rectangle

我有兴趣创建一个 Matlab 脚本,该脚本将考虑一个矩形并允许我计算一个点与沿矩形周边放置的其他几个点之间的向量长度。例如,计算下图中所有红色标注的向量的长度,以点9为原点。

这将需要包括指定每个点的位置的能力,并且应该适应不同尺寸的矩形。我希望能够使用任何指定的点作为原点来计算矢量长度。例如从点 1 到周长上的所有其他点。

我意识到这可能是一项耗时的任务,因此我将不胜感激任何帮助,因为我是 Matlab 的新手。期待看到一些想法!干杯。

建立在@ihcgeneva 的post 之上,我会避免一起使用循环,而是使用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 Fun 动作。如果我们查看函数内部,我们将在索引 rootPoint 处找到的矩形中的单个点与矩形中所有其他 co-ordinates 之间调用 minus 函数。我们要做的是将 co-ordinates 放入二维矩阵中,其中第一列表示 x co-ordinate,第二列表示 y co-ordinate。接下来,bsxfun 正在做的是 复制 位于 rootPoint 的点,使其与此 2D 矩阵的大小相同。 bsxfun 然后将在这个复制矩阵与您创建的原始二维矩阵之间逐元素减法。

这将执行欧几里德距离的第一部分,您可以在其中减去相应的维度。这将创建一个输出二维矩阵,其中第一列是 x 分量的减法,第二列是 y 分量的减法。然后我们对矩阵中的每个值进行平方,然后对列求和,然后取平方根,从而完成欧氏距离运算。 @lhcgeneva 让您走上了正确的轨道,您正在查看的点与矩形中其他点之间的最短距离是欧几里得距离。


现在,如果您想像图像中那样绘制从一点到另一点的线条,实际上根本不需要计算长度。您只需要知道沿矩形的点所在的位置,显示图像,然后使用 plot 并绘制从矩形中的每个点到源点的线。这看起来很像 IC Pin 布局图,所以我将使用我在 Internet 上找到的一个:

让我们使用 pin #3 作为信号源。我还查看了图像和 pin-pointed 每个图钉中间的位置:

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 或列 co-ordinate,而第二列是 y 或行 co-ordinate 其中每个引脚的中心位置图片。现在,您所要做的就是显示此图像,使用 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 的了解,它会变得有点复杂。

无论如何,这就是我得到的:

编辑

在您的评论中,您说您想显示从根点到矩形中每个点的距离。你可以用一个循环来做到这一点。不幸的是,当涉及到打印时,没有一种方法可以通过矢量化轻松完成,但是循环打印语句应该花费很少的时间,所以我们不应该在这里担心矢量化。

因此,您可以这样做:

%// 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 索引的行的单行的所有列来轻松提取根点。接下来,我们循环 oer 从根点到矩形中每个点的每个距离,我们只需将它们打印出来。这是我得到的输出:

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 和它本身(print-out 的第 3 行)之间的距离是 0。