最小覆盖圆及备用算法

这是一个经典的最小覆盖圆算法,但对某些情况存在不能全覆盖的漏洞,所以本然添加了输出最舵覆盖的备用选项,希望能有点用。

clear;
clc;
close all;
%% 
xx=rand(10,2);
bianyuan=xx;
z=xx(:,1);
y=xx(:,2);
%grid on%

if length(z)==2 %判定是否只有两个点,如果只有两个点则直接画圆
    cc=sqrt(((z(1)-z(2))^2+(y(1)-y(2))^2));
    r=cc/2;
    a=(z(1)+z(2))/2;
    b=(y(1)+y(2))/2;
    R=[a b r]
    alpha=0:pi/20:2*pi;%角度[0,2*pi]
    plot(a+r*cos(alpha),b+r*sin(alpha),'--r');%中心点在(a,b)半径为r的圆
    axis equal;
    
else % 当存在三个及三个以上的点时
    
    [s,d]=size(xx);
for i=1:1:s
    for j=i:1:s
        summ=0;
        for k=1:1:d
            summ=summ+(xx(i,k)-xx(j,k))^2;   %计算数据集中的点间距,
        end
        DistanceBO(i,j)=sqrt(summ);       %构造出点间距矩阵DistanceBO
    end
end
fprintf('算完每个点距离了\n');
for i=1:1:s            %找到各个点间距离
    for j=i:1:s
        DD(i,j)=DistanceBO(i,j);
    end
end
 aaa=DD(:);
 TempSortDistanceBO=sort(aaa); %将距离进行排序
 bbb=fliplr(TempSortDistanceBO');
 fprintf('排完序号了\n');
 
 %下边找出3个距离最远的点
 maxfrist=[];
 maxsecond=[];
 maxtwo=[];
 allmaxfrist=[];
 finalpoints=[];

for i=1:1:s                            %找到相互距离最大的第一个点
    for j=i:1:s
        if DD(i,j)==bbb(1)
            maxfrist=[i j];
        end
    end
end
fprintf('找到最大距离对应的两个点了\n');
rSet=zeros(10,4);
flag=0;
 for i=1:1:s                            %找到各个点间距离
    if i~=maxfrist(1) && i~=maxfrist(2)
        finalpoints=[maxfrist i];% 循环取点,直到找到可以全部覆盖的点
        
        A=[z(finalpoints(1)) y(finalpoints(1))];

        B=[z(finalpoints(2)) y(finalpoints(2))];

        C=[z(finalpoints(3)) y(finalpoints(3))];


    R=minCirclePoints3(A,B,C);
    rSet(i,:)=[R,i];
    rSet=sortrows(rSet,3);%按照半径排序
    
    cr=[R(1),R(2)];

    r=zeros(1,length(z));

    for i=1:length(z)

       r(i)=sqrt((z(i)-cr(1))^2+(y(i)-cr(2))^2);

    end
    maxValue=max(r);    %或者N=max(r(:))
    [mc]=find(maxValue==r);%找到最大距离对应的点
  
    
    if (r(mc)-R(3)<=0.000001)%没有点在圆外,结束回家吃饭去
        flag=1;
        figure(1)
        set(gcf,'color','white');%白色
        plot(z,y,'*');hold on;
        alpha=0:pi/20:2*pi;%角度[0,2*pi]
        plot(R(1)+R(3)*cos(alpha),R(2)+R(3)*sin(alpha),'--r');%中心点在(R(1),R(2))半径为R(3)的圆
        axis equal;
        title('最小覆盖圆图示')
        break
        %所有点都被圆覆盖 
    end
   
    end
    
        
 end
     if  flag==0
        figure(2)
        set(gcf,'color','white');%白色
        plot(z,y,'b*');hold on;
        alpha=0:pi/20:2*pi;%角度[0,2*pi]
        for i=1:length(rSet)

         r(i)=rSet(i,3);

        end
        maxValue=max(r);    %或者N=max(r(:))
        [n]=find(maxValue==r);%找到最大距离对应的点
        plot(rSet(n,1)+rSet(n,3)*cos(alpha),rSet(n,2)+rSet(n,3)*sin(alpha),'--r');%中心点在(R(1),R(2))半径为R(3)的圆
        axis equal;
        title('备用最小覆盖圆图示')
    end
end

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值