matlab練習程序(多邊形擴展算法)


這里提供兩種思路:

一、基於頂點的擴展

1. 確定擴展距離dis。

2. 計算每個頂點相鄰邊的單位向量。

3. 確定擴展方向,判斷依據是相鄰邊向量的行列式的正負號,記為sign(sina)。

4. 計算頂點相鄰兩邊的單位向量和,得到新向量,再對新向量進行單位化得到v。

5. 對每個頂點加上對應的sign(sina)*dis*v即可。

不過這種方法我發現最終擴展的多邊形和原多邊形的形狀有微小區別。

因為新多邊形和原多邊形的邊可能不完全平行。

二、基於邊的擴展

1. 確定擴展距離dis。

2. 計算邊的法線向量v。

3. 確定擴展方向,判斷依據是邊向量和其法線向量的行列式的正負號,記為sign(sina)。

4. 對邊上的兩個頂點分別加上sign(sina)*dis*v得到新邊的兩個頂線。

5. 計算所有邊的新頂點,並且根據新的頂點對計算其所在直線。

6. 計算所有直線的交點即得到新多邊形的頂點。

這種方法得到的多邊形每條邊和原多邊形的完全平行的。

matlab代碼如下:

clear all;
close all;
clc;

dis = 0.1;

n=5;
p=rand(n,2);
p=createSimplyPoly(p);  %創建簡單多邊形

p=[p;p(1,:)];
plot(p(:,1),p(:,2),'r-o')

%%第一種方法,對每個頂點延相鄰邊單位向量和的反方向擴展dis距離,得到新多邊形
R = [];
revR = [];
for i=1:length(p)-1             %計算每個頂點兩條邊的向量
    R = [R;p(i+1,:)-p(i,:)];
    if i==1
        revR =[revR;p(end-1,:)-p(1,:)];
    else
        revR =[revR;p(i-1,:)-p(i,:)];
    end
end

direct = [];
sina=[];
for i=1:length(R)               %計算頂點兩條邊單位向量求和並確定擴展方向
    D = R(i,:)/norm(R(i,:))+ revR(i,:)/norm(revR(i,:));
    sina = [sina;det([R(i,:);revR(i,:)])];
    direct = [direct;D/norm(D)];
end

newp = p;
newp(1:end-1,:) = p(1:end-1,:) + dis*sign(sina).*direct;
newp(end,:)=newp(1,:);

hold on;
plot(newp(:,1),newp(:,2),'b-o')
axis equal;

%%第二種方法,對每條邊向外擴展dis距離,再將每條擴展邊求交點得到新多邊形
new_line=cell(length(p),1);
for i=1:length(p)-1             %計算多邊形每條邊外擴dis距離得到新邊
    cur_line = p(i:i+1,:);
    k = (p(i+1,2) - p(i,2))/(p(i+1,1) - p(i,1));
    new_k  = -1/k;
    n = [1 ,new_k];
    n = n/norm(n);
    sina = det([p(i+1,:)-p(i,:);n]);
    new_line{i} = cur_line + n*sign(sina)*dis;
end

new_line{length(p)} = new_line{1};
newp2=[];
for i=1:length(p)-1             %對新邊求交點得到擴展多邊形
    
    line1 = new_line{i};
    line2 = new_line{i+1};
    
    k1 = (line1(2,2)-line1(1,2))/(line1(2,1) - line1(1,1));
    b1 = line1(1,2) - k1*line1(1,1);
    
    k2 = (line2(2,2)-line2(1,2))/(line2(2,1) - line2(1,1));
    b2 = line2(1,2) - k2*line2(1,1);
    
    x = (b2-b1)/(k1-k2);
    y = k1*x+b1;
    
    newp2=[newp2;x y];
end

figure;
plot(p(:,1),p(:,2),'r-o')
hold on;
newp2 =[newp2;newp2(1,:)];
plot(newp2(:,1),newp2(:,2),'b-o');
axis equal;

createSimplyPoly.m:

function p=createSimplyPoly(p)
    cen=mean(p);
    ang=atan2(p(:,1)-cen(1),p(:,2)-cen(2)); %每個點到坐標中心極角

    p=[p,ang];
    p=sortrows(p,3);    %按極角排序

    p=p(:,1:2);
end

第一種方法:

第二種方法:

 第二種方法從生成圖形的形狀上看會好看些。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM