MATLAB 最小包圍矩形
阿新 • • 發佈:2020-09-10
又是計算幾何,我感覺最近對計算幾何上癮了。
當然,工作上也會用一些,不過工作上一般直接呼叫boost的geometry庫。
上次寫過最小包圍圓,這次是最小包圍矩形,要比最小包圍圓複雜些。
最小包圍矩形可不一定是個直立的矩形,也可能像下圖一樣是傾斜的。
求法如下:
1.求多邊形凸包,這裡凸包直接呼叫系統函數了,細節可以參考這裡,雖然當時寫的不怎麼樣。
2.將凸包兩個相鄰的點連線作為矩形一條邊。
3.尋找凸包上距離已得到的邊最遠的點,過該點做平行線,得到矩形第二條邊。
4.將凸包上點向已求得的邊投影,求得投影點相距最遠的兩個點,過該兩點做直線,作為矩形另外兩條邊。
5.遍歷凸包所有相鄰兩點從新執行2~4,將面積最小的矩形作為求得結果。
通常情況下,矩形會過隨機點中的5個點。
結果如下:
matlab程式碼如下:
1 clear all;close all;clc;
2
3 n=30;
4 p=rand(n,2);
5
6 ind=convhull(p(:,1),p(:,2));
7 l=length(ind);
8
9 hull=p(ind,:); %隨機點凸包
10
11 area=inf;
12 for i=2:l
13 p1=hull(i-1,:); %凸包上兩個點
14 p2=hull(i,:);
15
16 k1=(p1(2)-p2(2 ))/(p1(1)-p2(1)); %連線兩點的直線,作為矩形的一條邊
17 b1=p1(2)-k1*p1(1);
18
19 d=abs(hull(:,1)*k1-hull(:,2)+b1)/sqrt(k1^2+1); %所有凸包上的點到k1,b1直線的距離
20
21 [h ind]=max(d); %得到距離最大的點距離,即為高,同時得到該點座標
22 b2=hull(ind,2)-k1*hull(ind,1); %相對k1,b1直線相對的另一條平行邊k1,b2;
23
24 k2=-1/k1; %以求得的直線的垂線斜率
25
26 b=hull(:,2)-k2*hull(:,1); %過凸包所有點構成的k2,b直線系
27 x1=-(b1-b)/(k1-k2); %凸包上所有點在已求得的第一條邊的投影
28 y1=-(-b*k1+b1*k2)/(k1-k2);
29
30 x2=-(b2-b)/(k1-k2); %凸包上所有點在已求得的第二條邊的投影
31 y2=-(-b*k1+b2*k2)/(k1-k2);
32
33 [junk indmax1]=max(x1); %投影在第一條邊上x方向最大與最小值
34 [junk indmin1]=min(x1);
35
36 [junk indmax2]=max(x2); %投影在第二條邊上x方向最大與最小值
37 [junk indmin2]=min(x2);
38
39 w=sqrt((x1(indmax1)-x1(indmin1))^2+(y1(indmax1)-y1(indmin1))^2); %矩形的寬
40
41 if area>=h*w %使面積最小
42 area=h*w;
43 pbar=[x1(indmax1) y1(indmax1); %矩形四個角點
44 x2(indmax2) y2(indmax2);
45 x2(indmin2) y2(indmin2);
46 x1(indmin1) y1(indmin1)];
47 end
48 end
49 pbar(5,:)=pbar(1,:);
50
51 hold on;
52 plot(p(:,1),p(:,2),'.');
53 plot(pbar(:,1),pbar(:,2),'r')
54 axis equal;