在matlab中给出两个向量计算三角形的所有角度

时间:2018-03-10 10:42:54

标签: matlab vector

考虑以下几点散布示例:

x=[-1.6794 -2.6072 0.4175 0.1898 -0.7749 1.8392 1.7411];
y=[7.9969 9.5312 8.0302 7.2956 6.5550 9.9890 7.9462];

带参考点:

xc = -0.9311; yc = 9.1109;

绘制散点图:

 figure(1)
 hold on
 scatter(x,y,'.b')
 scatter(xc,yc,'.r')
 xlim([-10 10]); ylim([0 15]);

enter image description here

我可以通过以下方式计算从[xc,yc]开始的所有向量之间的所有角度:

v=[x-xc;y-yc]';
dot_v=v*v';
norm_v=sqrt(v(:,1).^2+v(:,2).^2);
angles=acosd(dot_v./(norm_v.*norm_v'));

下图将可视化矢量及它们之间的角度:

figure(1)
hold on
scatter(x,y,'.b')
scatter(xc,yc,'.r')
xlim([-10 10]); ylim([0 15]);
for i=1:length(x)
    for j=1:length(x)
        hh1=plot([xc x(i)],[yc y(i)]);
        hh2=plot([xc x(j)],[yc y(j)]);
        th=title(num2str(angles(i,j)));        
        pause
        delete(hh1); delete(hh2); delete(th);
    end   
end

enter image description here

然而,我希望获得由这两个向量创建的三角形中的所有角度,例如:

enter image description here

我可以使用循环并计算由数据中的两个点组成的每个向量之间的角度,但是,我所拥有的数据包含非常多的点,因此我想避免使用循环并使用matlab以矩阵形式写东西的能力,因此请提供一个优雅而有效的答案。

1 个答案:

答案 0 :(得分:2)

实际上,创建三角形的缺失线非常容易......它由以下坐标给出:

[x(i) x(j)] [y(i) y(j)]

收回您的代码,您可以按如下方式获得所需的结果:

x = [-1.6794 -2.6072 0.4175 0.1898 -0.7749 1.8392 1.7411];
y = [7.9969 9.5312 8.0302 7.2956 6.5550 9.9890 7.9462];

xc = -0.9311;
yc = 9.1109;

v = [x - xc; y - yc].';
d = v * v.';
n = sqrt(v(:,1).^2 + v(:,2).^2);

angles = acosd(d ./ (n .* n.'));
angles = round(real(angles),2);

f = figure();    
hold on;
scatter(x,y,'.b');
scatter(xc,yc,'.r');
xlim([-10 10]);
ylim([0 15]);
hold off;

len = numel(x);

for i = 1:len
    for j = 1:len
        ang = angles(i,j);

        if (ang == 0)
            continue;
        end

        xi = x(i); xj = x(j);
        yi = y(i); yj = y(j);  

        hold on;
        p1 = plot([xc xi],[yc yi],'b');
        p2 = plot([xc xj],[yc yj],'b'); 
        p3 = plot([xi xj],[yi yj],'b'); 
        t = title(num2str(ang));
        hold off;

        pause(2);
        delete(p1);
        delete(p2);
        delete(p3);
        delete(t);
    end   
end

A做了一些调整:

  • 我使用了真实的转置函数(.')而不是共轭转置函数('),这是你在这种情况下应该应用的。
  • 我只考虑了他们真实的角度。
  • 我修复了循环中的暂停,使一切更顺畅。
  • 我缓存了循环索引。
  • 我穿着三角线的颜色。
  • 我跳过了平面三角形的绘图(angle = 0)。

使用矢量化代码时,Matlab会产生惊人的性能......但这并非总是如此。我知道如何将你的两个循环减少为一个...但是如果你想使用这种绘图方法,你或者很快就必须在你的代码中实现至少一次迭代,你无能为力。以下是您可以实现的目标:

f = figure();    
hold on;
scatter(x,y,'.b');
scatter(xc,yc,'.r');
xlim([-10 10]);
ylim([0 15]);
hold off;

len = numel(x);

ang = angles(:);
ang_ok = ang ~= 0;
ang = ang(ang_ok);

idx = [repelem((1:len).',len,1) repmat((1:len).',len,1)];
idx = idx(ang_ok,:);

for k = 1:size(idx,1)
    i = idx(k,1);
    j = idx(k,2);

    xi = x(i); xj = x(j);
    yi = y(i); yj = y(j);  

    hold on;
    p1 = plot([xc xi],[yc yi],'b');
    p2 = plot([xc xj],[yc yj],'b'); 
    p3 = plot([xi xj],[yi yj],'b'); 
    t = title(num2str(ang(k)));
    hold off;

    pause(2);
    delete(p1);
    delete(p2);
    delete(p3);
    delete(t); 
end

内角,即三角形完成后创建的内角,可以使用当前使用的方法在循环内部计算,只需移动坐标。事实上,由于三角形内部的角度总和为180° ...您只需要计算其中的两个,第三个可以使用以下等式获得:AngleC = 180 - AngleA - AngleB