又是計算幾何,我感覺最近對計算幾何上癮了。
當然,工作上也會用一些,不過工作上一般直接呼叫boost的geometry庫。
上次寫過最小包圍圓,這次是最小包圍矩形,要比最小包圍圓複雜些。
最小包圍矩形可不一定是個直立的矩形,也可能像下圖一樣是傾斜的。
求法如下:
1.求多邊形凸包,這裡凸包直接呼叫系統函式了,細節可以參考這裡,雖然當時寫的不怎麼樣。
2.將凸包兩個相鄰的點連線作為矩形一條邊。
3.尋找凸包上距離已得到的邊最遠的點,過該點做平行線,得到矩形第二條邊。
4.將凸包上點向已求得的邊投影,求得投影點相距最遠的兩個點,過該兩點做直線,作為矩形另外兩條邊。
5.遍歷凸包所有相鄰兩點從新執行2~4,將面積最小的矩形作為求得結果。
通常情況下,矩形會過隨機點中的5個點。
結果如下:
matlab**如下:
clear all;close all;clc;n=30
;p=rand(n,2
);ind=convhull(p(:,1),p(:,2
));l=length(ind);
hull=p(ind,:); %隨機點凸包
area=inf;
for i=2
:l p1=hull(i-1
,:); %凸包上兩個點
p2=hull(i,:);
k1=(p1(2)-p2(2))/(p1(1)-p2(1
)); %連線兩點的直線,作為矩形的一條邊
b1=p1(2)-k1*p1(1
);
d=abs(hull(:,1)*k1-hull(:,2)+b1)/sqrt(k1^2+1
); %所有凸包上的點到k1,b1直線的距離
[h ind]=max(d); %得到距離最大的點距離,即為高,同時得到該點座標
b2=hull(ind,2)-k1*hull(ind,1
); %相對k1,b1直線相對的另一條平行邊k1,b2;
k2=-1/k1; %以求得的直線的垂線斜率
b=hull(:,2)-k2*hull(:,1
); %過凸包所有點構成的k2,b直線系
x1=-(b1-b)/(k1-k2); %凸包上所有點在已求得的第一條邊的投影
y1=-(-b*k1+b1*k2)/(k1-k2);
x2=-(b2-b)/(k1-k2); %凸包上所有點在已求得的第二條邊的投影
y2=-(-b*k1+b2*k2)/(k1-k2);
[junk indmax1]=max(x1); %投影在第一條邊上x方向最大與最小值
[junk indmin1]=min(x1);
[junk indmax2]=max(x2); %投影在第二條邊上x方向最大與最小值
[junk indmin2]=min(x2);
w=sqrt((x1(indmax1)-x1(indmin1))^2+(y1(indmax1)-y1(indmin1))^2
); %矩形的寬
if area>=h*w %使面積最小
area=h*w;
pbar=[x1(indmax1) y1(indmax1); %矩形四個角點
x2(indmax2) y2(indmax2);
x2(indmin2) y2(indmin2);
x1(indmin1) y1(indmin1)];
endend
pbar(
5,:)=pbar(1
,:);
hold on;
plot(p(:,
1),p(:,2),'.'
);plot(pbar(:,
1),pbar(:,2),'r'
)axis equal;
matlab練習程式(最小包圍矩形)
又是計算幾何,我感覺最近對計算幾何上癮了。當然,工作上也會用一些,不過工作上一般直接呼叫boost的geometry庫。上次寫過最小包圍圓,這次是最小包圍矩形,要比最小包圍圓複雜些。最小包圍矩形可不一定是個直立的矩形,也可能像下圖一樣是傾斜的。求法如下 1.求多邊形凸包,這裡凸包直接呼叫系統函式了,...
matlab練習程式(Ritter s最小包圍圓)
原始演算法是sphere,我這裡簡化為circle了。ritter s求最小包圍圓為線性演算法,因為非常簡單,所以應用非常廣泛。該演算法求出的圓比最優圓大概會大個5 到20 左右,求最優圓應該可以用bouncing bubble演算法,以後有機會可以嘗試一下。ritter s演算法如下 1.從點集中...
最小包圍矩形
題目內容 給定一組二維座標,表示直角座標系內的乙個多邊形的連續的頂點的座標序列。計算能包圍這個多邊形的平行於座標軸的最小矩形,輸出它的左下角和右上角的座標。輸入格式 第一行是乙個正整數n表示頂點的數量,第二行是n組整數,依次表示每個頂點座標的x和y值。輸出格式 四個整數,依次表示所計算的矩形的左下角...