等值線追蹤演算法

2021-09-29 14:23:44 字數 3306 閱讀 2480

前篇提到了一種直接繪製等值線的方法,但是那種方法沒辦法確定每一條線上的點。如果我們想給等值線限定一些條件,如太短不繪製,標定等值線值等,上一種方法則無法使用。因此我又寫了乙個等值線的追蹤演算法。

等值線追蹤演算法,顧名思義,就是把每條線上的點,按順序追蹤出來,這樣直接按照順序繪製便能繪製出完整的線段。

如圖5號網格,要確定哪個線段是接下來要連線的線段,則需要遍歷周圍的網格確定線條。我們便可以發現2,4號網格內的線條是需要的線條,而六號網格內的則不是。我們如何確定周圍網格裡的線條是否是接下來要連線的線條呢。

我們曾今在等值線繪製演算法中記錄了乙個線表:

//矩形4位2進製對應連線線,連線線對應兩個邊(索引)上的點。

const unsigned char linetable[16][5]=,,,

,,,,

,,,,

,,,,

};

該**記錄了乙個網格中所有線條可能的情況,因此根據該錶在5號網格的情況下乙個查詢網格就變成2號和4號網格。由於5號網格內的頂點索引為0001,轉換為10進製為1,對應linetable[1]內為4,1。證明點落在4號邊和1號邊上,我們4號邊則查詢x-1的網格,1號邊則找y-1的網格(左上角為原點)。

如圖所示,我們查完線表之後,觀察邊編號,便可以直接獲得接下來需要查詢的網格,省去了對周圍每個網格的遍歷。我們發現1對3,2對4,3對1,4對2。因此可以同樣建立表:constunsignedcharpostable[5]=;幫助我們獲取接下來的網格點在哪個邊上。

和等值線繪製演算法相同,我們首先建立網格。然後遍歷所有網格,當在網格中發現有線存在,則根據上述追蹤規則重複追蹤迭代,我們用乙個bool的2維陣列m_btrick儲存該網格是否查詢過(初始化為1),每次遍歷或者迭代完成時,令bool置0。這時我們發現會有一種特殊情況,就是乙個網格中有可能出現2條線,如線表中第5種和第10種情況。因此我們只能將bool改為int,讓每次迭代時,若m_btrick為1,則判斷是否有可能為2條邊,如果為兩條邊則置為2,否則置為0。當下次查詢到該網格m_btrick為2時,則直接置為0即可。由於我們需要完整的查詢出完整的線段,因此我們需要雙向迭代,如圖1中5號網格,我們首先按照邊編號4方向迭代完所有的線,然後按照邊編號1方向迭代,最後連線兩個方向迭代的線,就是最後我們需要的等值線了。

按照該演算法,圖一的結果為上圖所示:黑色編號為網格編號,紅色編號為程式執行順序。我們首先遍歷到1號網格,發現無線,則置m_btrick為0,然後查詢2號網格,發現其中有線條,取出線條的兩個端點邊編號4和2,先從邊編號4進行迭代,查詢到5號網格,同理再是4號,7號。完成之後2號網格的邊編號4方向已經迭代完成,然後從邊編號2方向迭代到網格3,網格3之後該線便完成迭代,我們繼續遍歷,遍歷到網格4,5發現m_btrick為0。因此到網格6才發現線條,在迭代到網格9。所以8號網格成為了最後訪問的網格。

我們的追蹤**可以直接加入我們的等值線繪製**中。

我們增加**:

struct dpos

unsigned int l,r;

bool n;//是否有線

};//等值線值為isol時的所有線

struct clineisolevel;

typedef std::vectorctlinetrack;

class contour_line

實現**如下:

bool contour_line::creatlinetra(float* field,int n[2],vectorthreshold,vector&vrts,

ctlinetrack& lns)

/* 等值線資訊生成(等值線追蹤的迭代方式)

* @param [out] vrts等值線頂點

* @param [out] lns等值線資訊(頂點連線資訊)

*/void contour_line::tracklinev(vector&vrts,ctlinetrack& lns)

currentl.push_back(id);

lastl=np.r;

}np=fp; nx=x;ny=y;

while (np.n)

currentr.push_back(id);

lastr=np.r;

}for (int i=0; i

for (int i=0; i4?1:(nannum+1);

right=pow(2, right-1);

if ((tableindex&left)==(tableindex&right))

}if (edgetable[tableindex]!=0)

if (edgetable[tableindex]&8)

if(x==m_grid[0]-1)

}if(y==m_grid[1]-1)

}if (!nancount)

}else

if(linetable[tableindex][2]!=255)

else

m_btrick[y*m_grid[0]+x]=0;

return apos;}}

m_btrick[y*m_grid[0]+x]=0;

}apos.n=0;

return apos;

}/*!

* 複製資訊到頂點和線快取中

* @param [out] vrts頂點座標

* @param [out] nvrts頂點數

* @param [out] lns等值線的幾何資訊

*/void contour_line::renametrackverticesandlines(vector&vrts, unsigned int &nvrts,

ctlinetrack& lns)

//將等值線m_allisolines內的頂點編號更新為頂點快取中的編號

for (int j=0; j我們實現的效果圖如下:

由於追蹤出的線條可以做一些篩選操作,因此我們的效果可以比直接繪製的等值線好很多。

opencv 實現等值線 繪製等值線

例項簡介 等值線繪製 用於opengl環境下等值線的生成 例項截圖 核心 等值線繪製 等值線繪製 contour 2dmemallocator.cpp 2dmemallocator.h clrfiledialog.cpp clrfiledialog.h colorlookuptable.cpp co...

曲面等值線

clear,x linspace 1.5 pi,1.5 pi y linspace pi,pi z sin y cos x z 0.9 0.1 0.9 figure,contour x,y,z,z fs 16 title 等值線 fontsize fs xlabel itx fontsize fs ...

MATLAB等值線繪製

作平面等值線,x,y,z為確定三維曲面點的矩陣。matlab自選等值線的高度和條數。兩者區別是,contour x,y,z 限定了等高線的橫縱座標值而contour z 沒有限定。下面以contour x,y,z 為例,說明其他功能。contour x,y,z,n 是指定畫出n條等值線,而等值線的值...