从对象数组中获取最小属性值

时间:2012-04-07 15:21:00

标签: matlab

道歉,如果这是一个愚蠢的问题,我对Matlab来说相对较新。

我有一个Rectangle类的矩形数组,其属性为minx, miny, maxx, maxy,表示角坐标。

我正在尝试获取数组中左上角矩形的索引。

我可以遍历对象以获得与最小x和y坐标对应的对象,但这看起来不像是一个非常类似的(matlabian?听起来不像pythonic一样好)的方式来做。

minx = -1
miny = -1
tl_rect_id = 0

for id = 1:num_objects
    if ((rectangles(id).minx < minx || minx == -1) && (rectangles(id).miny < miny || miny == -1)) 
        tl_rect_id = id
        minx = rectangles(id).minx
        miny = rectangles(id).miny

    end

    % plot coordinates of top left corners
    plot(rectangles(id).minx,rectangles(id).miny,'+r')
end

2 个答案:

答案 0 :(得分:4)

您不需要使用arrayfun来操作matlab中的对象数组。从对象数组中获取属性数组有一个非常有用的简写:

[rectangles.minx]

这会产生数组中所有矩形的minx

所以要知道哪个是最接近原点的点,我会计算到原点的良好的'欧几里德距离'。随着手头的矢量,这是真的简单。

欧氏距离的定义如下:

d(a,b) = sqrt( (a.x - b.x)^2 + (a.y - b.y)^2);

用你的矢量计算它:

distances = sqrt([rectangles.minx].^2 + [rectangles.miny].^2)

这将产生一个具有所有点距离的向量。找到最小值是微不足道的:

[〜,idx] = min(距离);

min函数返回1x2数组,第一个位置是最小值,第二个是索引。我使用matlab表示法[~, idx]表示我对第一个返回值不感兴趣,第二个应存储在变量idx上。

我写了一个例子,我已经创建了我的矩形类来测试它,但它也适用于你的类。下面是我定义的类的代码和计算最接近(0,0)的点的代码。

运行它以发挥想法并根据您的需要进行调整:)

测试类定义(将其保存在名为Rectangle.m的文件中):

classdef Rectangle
    properties
        minx;
        miny;
    end
    methods
        function obj = Rectangle(v1,v2)
         if nargin > 1
            obj.minx = v1;
            obj.miny = v2;
         end
      end
    end
end

代码

clear all;
numRect = 100;
rect_array = Rectangle(numRect);

% initialize rectangles
for n=1:numRect
    r = Rectangle;
    r.minx = 100*rand(1,1);
    r.miny = 100*rand(1,1);
    rect_array(n) = r;
end

% find point closest to the origin

[~, idx] = min(sqrt([rect_array.minx].^2 + [rect_array.miny].^2));

close all;
figure;
% plot the points in blue
plot([rect_array.minx],[rect_array.miny],'b.');
hold on;
% mark a red cross on the point closest to the origin
plot(rect_array(idx).minx, rect_array(idx).miny, 'rx');

答案 1 :(得分:2)

您的代码正在查找更左侧的矩形或最远的矩形。如果你不担心具有相同minx值的多个重叠,你可以做

[v i] = min(arrayfun(@(i)rectangles(i).minx, 1:num_objects))
fprintf('Furthest left rectangle is %g\n', i);

或者,您可以这样做:

[v i] = sortrows(cell2mat(arrayfun(@(i)[rectangles(i).minx; rectangles(i).miny], 1:num_objects, 'uniformoutput', 0))');
fprintf('Furthest left rectangle is %g\n', i(1));

将按X和Y排序,然后按此顺序排在第一位。这样做比较慢,因为它会排序。为了获得上面算法的确切行为,你应该坚持使用for循环,我认为简洁地做它会很混乱。