標(biāo)題: MATLAB等距線掃描程序?qū)崿F(xiàn)思路與源程序 [打印本頁(yè)]
作者: JAIA 時(shí)間: 2018-7-12 20:21
標(biāo)題: MATLAB等距線掃描程序?qū)崿F(xiàn)思路與源程序
由于網(wǎng)上多數(shù)都是c語(yǔ)言實(shí)現(xiàn)多邊形掃描的例子我這就給大家一個(gè)matlab實(shí)現(xiàn)的方法吧
結(jié)果圖.jpg (43.58 KB, 下載次數(shù): 87)
下載附件
結(jié)果的實(shí)現(xiàn)大概就是這樣
2018-7-12 20:19 上傳
實(shí)現(xiàn)思路如下:
6月19作業(yè)題任務(wù)是用等距離的掃描線掃描下不規(guī)則多邊形,如例圖所示,獲得掃描區(qū)間,并畫出結(jié)果。
B是多邊形頂點(diǎn)坐標(biāo)
B=[0 1 2 3 6 7 9 10 9 8 7 5 4 3 2 1;
5 2 3 0 0 1 5 6 13 13 15 15 14 15 11 10]
Ymin=0,Ymax=15,需要n=100個(gè)掃描間隔,那么掃描距離就0.15,101條掃描線。
上面這部分編程肯定是沒問題,接下就是模型的難點(diǎn):
1、如何求掃描線與間隔的交點(diǎn);
2、如果掃描線剛好掃描到多邊形的頂點(diǎn),要如何處理;
3、如果掃描線剛好掃描到多邊形的邊,要如何處理;
步驟:
1、從第一條掃描線開始掃描,掃描線為yi
2、從多邊形的第一個(gè)點(diǎn)開始,取第一個(gè)點(diǎn)n1, n1的上一個(gè)點(diǎn)n0,n1的下一個(gè)點(diǎn)n2,n2的下一個(gè)點(diǎn)n3。那么n1-n2就表示當(dāng)前多邊形的邊,n0-n1表示前一條邊,n2-n3表示后一條邊,等下需要用到。
3、判斷掃描線yi與n1-n2是否有交點(diǎn),有就求交點(diǎn),沒有就回到步驟2,取下一個(gè)點(diǎn)n1;
判斷是否有交點(diǎn)公式:abs(Y(n1)-yi)+ abs(Y(n2)-yi)== abs(Y(n1)-Y(n2)),abs(.)是絕對(duì)值的函數(shù)。
4、求得交點(diǎn)后,要判斷如何記錄。如果是普通的交點(diǎn),就直接可以記錄。如果交點(diǎn)剛好是多邊形的頂點(diǎn),或者掃描到多邊形的邊,就需要處理。
(1)情況1,掃描到普通交點(diǎn),直接記錄
(2)情況2,掃描到橫線,這個(gè)時(shí)候就需要用到n0-n1,n2-n3,即前邊與后邊。
<1> 如果是下圖的情況,記錄n1,n2
<2> 如果是下圖的情況,記錄n1
<3> 如果是下圖的情況,記錄n2
(3)情況3,掃描到頂點(diǎn)每一條邊的兩個(gè)頂點(diǎn),第一個(gè)點(diǎn)是不算的,第二個(gè)點(diǎn)算。類似這樣,實(shí)心表示這個(gè)點(diǎn)算上,空心表示不算。這樣的目的是為了不讓掃描到頂點(diǎn)時(shí),會(huì)記錄兩次。
<1>遇到極大小值
<2>遇到下一條邊n2-n3是橫線的話,這個(gè)點(diǎn)就不用記錄了。不然會(huì)多記錄了該點(diǎn)
5、循環(huán)完所有的掃描線,就OK啦。最終就獲得了一個(gè)所有掃描線多邊形的交點(diǎn)的矩陣!
6、每一條掃描線掃描到的交點(diǎn)肯定是偶數(shù)滴,每?jī)牲c(diǎn)畫起來(lái)就OK。
程序方面:
最終我是寫了如下兩個(gè)函數(shù)的形式,這題是我最近在做的項(xiàng)目的中間環(huán)節(jié),方便調(diào)用:
function [smqj]=saomiao(B,dt)
輸入:B表示多邊形,dt表示掃描間隔
輸出:smqj表示最終的掃描區(qū)間 (英語(yǔ)特水,只能用拼音命名,用英語(yǔ)命名才高大上)
function huaxian(jl,ZB,MB,dt)(畫線的函數(shù)自己寫一下,我這里是有其他作用,多輸入了一個(gè)ZB參數(shù),所以有所區(qū)別)
輸入:jl 表示掃描區(qū)間,ZB 表示子板多邊形,MB 表示母板多邊形,dt 表示掃描間隔
輸出:直接顯示圖像
這題只是讓你們處理母板多邊形而已,所以調(diào)用的時(shí)候,直接 huaxian(M_QJ,MB,MB,dt)就可以了,自己運(yùn)行程序看看。
注:程序里面出現(xiàn)這樣的
其實(shí)是表示
abs(Y(n1)-yi)+ abs(Y(n2)-yi)== abs(Y(n1)-Y(n2))
(道理如A1==A2 ,寫成 abs(A1-A2)<=0.000001)
在matlab里面,有可能會(huì)出現(xiàn)A1跟A2相等,卻判斷A1==A2為0的情況。如果測(cè)試A1-A2的話,會(huì)出現(xiàn) e-14,也就是無(wú)窮小量,這是matlab本身精確度的問題,把他們當(dāng)作不相等了。
在測(cè)試程序的時(shí)候就被這情況干擾了,才做了abs(A1-A2)<=0.000001的處理。
題外話:
1、上面也說(shuō)了,這個(gè)題目是我最近在做的“皮革排版”項(xiàng)目的小部分內(nèi)容。任務(wù)大概是:一張大的不規(guī)則母板皮革,要用它來(lái)裁剪 如皮帶,皮包等材料的子板,如何排版這些材料,優(yōu)化的處理這張母板皮革。
如輸入5個(gè)圖1,10個(gè)圖2,6個(gè)圖3,4個(gè)圖4。用我們上面的母板,如何最優(yōu)。
這個(gè)項(xiàng)目涉及到數(shù)學(xué)建模,比如:”如何把子板放到母板里面”,這個(gè)東西如何轉(zhuǎn)化為數(shù)學(xué)描述就很有難度。 還有涉及到智能優(yōu)化算法,如遺傳算法,模擬退火算法等用于求最優(yōu)解。 有參加數(shù)學(xué)建模的,有時(shí)間的可以考慮跟著做這個(gè)項(xiàng)目,還是有一定的幫助。
MATLAB源程序:
- %輸出smqj為掃描區(qū)間,輸入B為板塊頂點(diǎn),dt為掃描距離
- function [smqj]=saomiao(B,dt)
- X=B(:,1);
- Y=B(:,2);
- Y_MIN=min(Y);
- Y_MAX=max(Y);
- %%這一步是為了刪除一些頂點(diǎn),可有可無(wú),還是保留一下。相鄰兩條線段斜率一樣,刪中間點(diǎn)
- k=[];
- for n1=1:size(Y,1) %計(jì)算斜率
- if n1~=size(Y,1)
- n2=n1+1;
- else
- n2=1;
- end
- ki=(Y(n1)-Y(n2))/(X(n1)-X(n2));
- k=[k ki];
- end
- d_p=[]; %刪除某些不必要頂點(diǎn)
- for n1=1:size(Y,1)
- if n1~=size(Y,1)
- n2=n1+1;
- else
- n2=1;
- end
- if k(n1)==k(n2)
- d_p=[d_p n1];
- end
- end
- X(d_p+1,:)=[]; %刪除數(shù)據(jù)
- Y(d_p+1,:)=[]; %刪除數(shù)據(jù)
- k(:,d_p+1)=[]; %刪除數(shù)據(jù)
- %%下面才是掃描的重點(diǎn)
- %%開始掃描線
- smqj=[]; %用來(lái)保存交點(diǎn)
- for yi=Y_MIN:dt:Y_MAX
- smqji=[]; %用于記錄每行交點(diǎn)
- for n1=1:size(Y,1)
- %n0-n1為上一條線段
- if n1~=1
- n0=n1-1;
- else
- n0=size(Y,1);
- end
- %n1-n2為當(dāng)前線段
- if n1~=size(Y,1)
- n2=n1+1;
- else
- n2=1;
- end
- %n2-n3為下一條線段
- if n2~=size(Y,1)
- n3=n2+1;
- else
- n3=1;
- end
-
-
- %*******求交點(diǎn)坐標(biāo)********
- xi=[]; %初始無(wú)交點(diǎn)
- if abs(abs(Y(n1)-yi)+abs(Y(n2)-yi)-abs(Y(n1)-Y(n2)))<=0.000001 %說(shuō)明存在交點(diǎn)
- if (X(n1)-X(n2))~=0 && (Y(n1)-Y(n2))~=0
- ki=(Y(n1)-Y(n2))/(X(n1)-X(n2));
- xi=(yi-Y(n2))/ki+X(n2);
- p=[xi;yi]; %交點(diǎn)坐標(biāo)
- elseif (X(n1)-X(n2))==0
- xi=X(n1);
- p=[xi;yi];
- elseif (Y(n1)-Y(n2))==0 %先取兩個(gè)端點(diǎn)交點(diǎn),再判斷是否取
- xi=X(n1);%表示存在而已,不記錄
- p1=[X(n1);yi];
- p2=[X(n2);yi];
- end
- end
- %*****判斷改坐標(biāo)是否記錄*****
- if isempty(xi)==0 %如果存在xi,即有交點(diǎn)
- if sum(Y(find(X==xi))==yi)==0 %說(shuō)明不是多邊形頂點(diǎn)
- smqji=[smqji p]; %直接記錄
- else %下面是頂點(diǎn)的情況
- if sign(Y(n1)-Y(n2))==0 %本條線是橫線
- if (sign(Y(n0)-Y(n1))+sign(Y(n2)-Y(n3)))==0
- smqji=[smqji p1 p2]; %兩點(diǎn)都記錄
- end
- if sign(Y(n0)-Y(n1))>0 && sign(Y(n2)-Y(n3))>0
- smqji=[smqji p1]; %只取前一個(gè)
- end
- if sign(Y(n0)-Y(n1))<0 && sign(Y(n2)-Y(n3))<0
- smqji=[smqji p2]; %只取后一個(gè)
- end
- elseif xi==X(n2) %如果不是橫線,后交點(diǎn)才記錄,前交點(diǎn)不用管
- if (sign(Y(n1)-Y(n2))+sign(Y(n2)-Y(n3)))==0 %說(shuō)明是極大極小值
- smqji=[smqji p p]; %需要記錄兩個(gè)
- else
- if sign(Y(n2)-Y(n3))~=0 %下一條如果是橫線,也不用記錄
- smqji=[smqji p]; %記錄1個(gè)
- end
- end
- end
- end
- end
- end
- smqji=sort(smqji,2); %按從小到大排列
- smqj=[smqj smqji];
- end
-
復(fù)制代碼
0.png (46.12 KB, 下載次數(shù): 84)
下載附件
2018-7-12 20:36 上傳
全部資料51hei下載地址:
作者: rnl 時(shí)間: 2019-4-28 22:00
您好,能提供一下子板材的程序嗎,我郵箱:1764245803@qq.com,謝謝
作者: rnl 時(shí)間: 2019-4-28 22:08
您好啊,能提供一下子板材的程序么
作者: stan13 時(shí)間: 2019-7-14 22:07
樓主能把排版放置那部分的算法給一下嗎?
作者: billions1943 時(shí)間: 2020-5-21 16:28
定定 ,介紹不錯(cuò),不過(guò)感覺這個(gè)思想還是沒有掌握
作者: billions1943 時(shí)間: 2020-5-27 15:52
好奇下,如果是多連通區(qū)域呢 ,就是中間有孔洞呢,掃描線要怎么避開然后實(shí)現(xiàn)連接?
歡迎光臨 (http://www.torrancerestoration.com/bbs/) |
Powered by Discuz! X3.1 |