前篇提到了一種直接繪製等值線的方法,但是那種方法沒辦法確定每一條線上的點。如果我們想給等值線限定一些條件,如太短不繪製,標定等值線值等,上一種方法則無法使用。因此我又寫了乙個等值線的追蹤演算法。
等值線追蹤演算法,顧名思義,就是把每條線上的點,按順序追蹤出來,這樣直接按照順序繪製便能繪製出完整的線段。
如圖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條等值線,而等值線的值...