?? contourtracer.cpp
字號:
if( ySide[i-1][j] > 0 )
HandlingAfterNextPointFounded(i-1,j,FALSE);
else
HandlingAfterNextPointFounded(i-1,j+1,FALSE);
}
else if( ySide[i-1][j] == ySide[i-1][j+1] )
{
if( ySide[i-1][j] < 0 /*即ySide[i-1][j] == ySide[i-1][j+1] ==-2*/)
{
HandlingAfterNextPointFounded(i-1,j,TRUE);//下一點(diǎn)在對面的橫邊上
}
else
{
//注意:這里需要重新計算xSide[i][j],因?yàn)樵谏弦淮我呀?jīng)被置為-2.0
float xSideIJ = ( m_valueTracing - m_ppGridData[i][j] ) / ( m_ppGridData[i][j+1] - m_ppGridData[i][j] );
if( xSideIJ <= 0.5f )
{
HandlingAfterNextPointFounded(i-1,j,FALSE);
}
else
{
HandlingAfterNextPointFounded(i-1,j+1,FALSE);
}
}
}
else if( ySide[i-1][j] > ySide[i-1][j+1] )
{
if( ySide[i-1][j+1] > 0 )
HandlingAfterNextPointFounded(i-1,j+1,FALSE);
else
HandlingAfterNextPointFounded(i-1,j,FALSE);
}
}
//由右向左
void CContourTracer::FromRight2LeftTracing()
{
/*
橫邊(i+1,j-1)
xSide[i+1][j-1]
∣
∣
(i+1,j-1) ↓ (i+1,j)
|-----------|
| |
縱邊(i,j-1)--→ | ·←----等前等值點(diǎn)(P2)
ySide[i][j-1] | |
| |
|-----------|
(i,j-1) ↑ (i,j)
∣
橫邊(i,j-1)
xSide[i][j-1]
*/
ASSERT( CurrentPoint.bHorV == FALSE );
int i = CurrentPoint.i;
int j = CurrentPoint.j;
if( IsHavingPoint(xSide[i][j-1]) && IsHavingPoint(xSide[i+1][j-1]) )
{
if( xSide[i][j-1] < xSide[i+1][j-1] )
{
HandlingAfterNextPointFounded(i,j-1,TRUE);//在橫邊(i,j-1)上
}
else if( xSide[i][j] == xSide[i+1][j-1] )
{
//注意:這里需要重新計算ySide[i][j],因?yàn)樵谏弦淮我呀?jīng)被置為-2.0
float ySideIJ = ( m_valueTracing - m_ppGridData[i][j]) / ( m_ppGridData[i+1][j] - m_ppGridData[i][j] );
if( /*ySide[i][j]*/ ySideIJ <= 0.5f )
{
HandlingAfterNextPointFounded(i,j-1,TRUE);//在橫邊(i,j-1)上
}
else
{
HandlingAfterNextPointFounded(i+1,j-1,TRUE);//在橫邊(i+1,j-1)上
}
}
else
{
HandlingAfterNextPointFounded(i+1,j-1,TRUE);//在橫邊(i+1,j-1)上
}
}
else
{
if( IsHavingPoint(xSide[i][j-1]) )
{
HandlingAfterNextPointFounded(i,j-1,TRUE);//在橫邊(i,j-1)上
}
else if( IsHavingPoint(xSide[i+1][j-1]) )
{
HandlingAfterNextPointFounded(i+1,j-1,TRUE);//在橫邊(i+1,j-1)上
}
else if( IsHavingPoint(ySide[i][j-1]) )
{//兩橫邊上都沒有
HandlingAfterNextPointFounded(i,j-1,FALSE);//在縱邊(i,j-1)上
}
else
{//三邊上都沒有
ASSERT(FALSE);
}
}
}
//由右向左(第二版本)
void CContourTracer::FromRight2LeftTracingV2()
{/*
橫邊(i+1,j-1)
xSide[i+1][j-1]
∣
(i+1,j-1) ↓ (i+1,j)
|-----------|
| |
縱邊(i,j-1)--→ | ·←----等前等值點(diǎn)(P2)
ySide[i][j-1] | |
| |
|-----------|
(i,j-1) ↑ (i,j)
∣
橫邊(i,j-1)
xSide[i][j-1]
*/
ASSERT( CurrentPoint.bHorV == FALSE );
int i = CurrentPoint.i;
int j = CurrentPoint.j;
if( xSide[i][j-1] < xSide[i+1][j-1] )
{
if( xSide[i][j-1] > 0 )
HandlingAfterNextPointFounded(i,j-1,TRUE);
else
HandlingAfterNextPointFounded(i+1,j-1,TRUE);
}
else if( xSide[i][j-1] == xSide[i+1][j-1] )
{
if( xSide[i][j-1] < 0 /*namely, xSide[i][j-1] == xSide[i+1][j-1] == -2.0f*/ )
{
HandlingAfterNextPointFounded(i,j-1,FALSE);
}
else
{
float ySideIJ = ( m_valueTracing - m_ppGridData[i][j]) / ( m_ppGridData[i+1][j] - m_ppGridData[i][j] );
if( ySideIJ <= 0.5f )
HandlingAfterNextPointFounded(i,j-1,TRUE);
else
HandlingAfterNextPointFounded(i+1,j-1,TRUE);
}
}
else if( xSide[i][j-1] > xSide[i+1][j-1] )
{
if( xSide[i+1][j-1] > 0 )
HandlingAfterNextPointFounded(i+1,j-1,TRUE);
else
HandlingAfterNextPointFounded(i,j-1,TRUE);
}
}
//追蹤一條開等值線
void CContourTracer::TracingOneNonClosedContour()
{
CCurve* pCtrLine = new CCurve;
m_pCurveList->AddTail(pCtrLine);
m_currentCurveLine = pCtrLine;
//記錄下線頭所在邊的i,j,橫縱邊標(biāo)識
int startPt_i = CurrentPoint.i;
int startPt_j = CurrentPoint.j;
BOOL startPt_bHoriz = CurrentPoint.bHorV;
//驗(yàn)證線頭在邊界上
ASSERT( startPt_i == 0 || /*線頭在底邊界上*/
startPt_i == m_gridDataInfo.rows-1 || /*線頭在上邊界上*/
startPt_j == 0 || /*線頭在左邊界上*/
startPt_j == m_gridDataInfo.cols-1 /*線頭在右邊界上*/
);
CalcAndSaveOnePointCoord(startPt_i,startPt_j,startPt_bHoriz,CurrentPoint.x,CurrentPoint.y); //計算出線頭的坐標(biāo)并保存
if( startPt_bHoriz )
{
xSide[startPt_i][startPt_j] = -2.0f;
}
else
{
ySide[startPt_i][startPt_j] = -2.0f;
}
TracingNextPoint(); //追蹤出NextPoint
PreviousPoint = CurrentPoint;
CurrentPoint = NextPoint;
int cols = m_gridDataInfo.cols;
int rows = m_gridDataInfo.rows;
//遇到網(wǎng)格邊界就結(jié)束追蹤
//------2004/03/09修改------------------
//為了不讓浮點(diǎn)數(shù)計算的誤差引起追蹤結(jié)束條件的判斷失誤,
//我們不能用『CurrentPoint.y <= yMin』來判斷是否遇到底邊框,
// 也不能用『CurrentPoint.x <= xMin』來判斷是否遇到左邊框
BOOL bIsFinish = (CurrentPoint.i == 0 && CurrentPoint.bHorV == TRUE ) || /*遇到底邊界,(注:不能僅僅用CurrentPoint.i == 0判斷)*/
(CurrentPoint.i == rows-1) || /*遇到上邊界*/
(CurrentPoint.j == 0 && CurrentPoint.bHorV == FALSE ) || /*遇到左邊界,(注:不能僅僅用CurrentPoint.j == 0判斷)*/
(CurrentPoint.j == cols-1) ; /*遇到右邊界*/
while( !bIsFinish )
{
TracingNextPoint();
PreviousPoint = CurrentPoint;
CurrentPoint = NextPoint;
bIsFinish = (CurrentPoint.i == 0 && CurrentPoint.bHorV == TRUE ) ||
(CurrentPoint.i == rows-1) ||
(CurrentPoint.j == 0 && CurrentPoint.bHorV == FALSE ) ||
(CurrentPoint.j == cols-1) ;
}
}
//追蹤開曲線
void CContourTracer::TracingNonClosedContour()
{//該函數(shù)的關(guān)鍵是找出開曲線的線頭,并設(shè)置好追蹤前進(jìn)的方向的條件
int i,j;
int cols = m_gridDataInfo.cols;
int rows = m_gridDataInfo.rows;
//1.搜索底邊框
for(j=0; j<cols-1; j++)
{
if( IsHavingPoint(xSide[0][j]) )
{
/*按自下向上的前進(jìn)方向虛設(shè)前一點(diǎn)的i,j*/
PreviousPoint.i = -1; // 假設(shè)前一點(diǎn)在-1行,這樣下一點(diǎn)到當(dāng)前點(diǎn)的前進(jìn)方向就是自下向上的
PreviousPoint.j = j;
PreviousPoint.bHorV = TRUE;
CurrentPoint.i = 0; //底邊的行號為0,所以設(shè)置線頭的i為0
CurrentPoint.j = j;
CurrentPoint.bHorV = TRUE; //底邊是橫邊
TracingOneNonClosedContour();
}
}
//2.搜索左邊框(左邊框在第0列)
for(i=0; i<rows-1; i++)
{
if( IsHavingPoint(ySide[i][0]) )
{
/*按由左向右的前進(jìn)方向虛設(shè)前一點(diǎn)的i,j*/
PreviousPoint.i = i;
PreviousPoint.j = -1; //假設(shè)前一點(diǎn)在-1列,使其滿足左-->右的前進(jìn)方向
PreviousPoint.bHorV = FALSE;
CurrentPoint.i = i;
CurrentPoint.j = 0; //左邊框在第0列,所以設(shè)置線頭的j為0
CurrentPoint.bHorV = FALSE;
TracingOneNonClosedContour();
}
}
//3.搜索上邊框
float deltX = ( m_gridDataInfo.xMax-m_gridDataInfo.xMin ) / ( m_gridDataInfo.cols-1 );
float curPt_Col_X = m_gridDataInfo.xMin + CurrentPoint.j * deltX; //當(dāng)前等值點(diǎn)所在邊(i,j)的所標(biāo)識的j列的X坐標(biāo)
for(j=0; j<cols-1; j++)
{
if( IsHavingPoint(xSide[rows-1][j]) )
{
/*虛設(shè)出由上向下追蹤的條件
由上向下追蹤的條件如下:
1. Not( CurrentPoint.i > PreviousPoint.i )
2. Not( CurrentPoint.j > PreviousPoint.j )
3. CurrentPoint.x > m_gridDataInfo.xMin + CurrentPoint.j * deltX; 即:要求在橫邊上
*/
PreviousPoint.i = rows-1;
PreviousPoint.j = j;
PreviousPoint.bHorV = TRUE;
CurrentPoint.i = rows-1; //上邊框的行號為rows-1
CurrentPoint.j = j;
CurrentPoint.bHorV = TRUE; //使其符合第三個條件
//第三個條件條件不用虛設(shè),只要邊上存在就會滿足第三個條件,因?yàn)樯线吙蚴菣M邊
// if( CurrentPoint.x < curPt_Col_X )
// {
// CurrentPoint.x = curPt_Col_X + 1; //為了保證讓其滿足第3個條件
// }
TracingOneNonClosedContour();
}
}
//4.搜索右邊框(在第cols-1列,注意列號是從0開始計數(shù)的)
for(i=0; i<rows-1; i++)
{
if( IsHavingPoint(ySide[i][cols-1]) )
{
/*虛設(shè)出由右向左追蹤的條件
由右向左追蹤的條件如下:
1. Not( CurrentPoint.i > PreviousPoint.i )
2. Not( CurrentPoint.j > PreviousPoint.j )
3. Not( CurrentPoint.x > m_gridDataInfo.xMin + CurrentPoint.j * deltX ); 要求在縱邊上
*/
PreviousPoint.i = i;
PreviousPoint.j = cols-1;
PreviousPoint.bHorV = FALSE;
CurrentPoint.i = i;
CurrentPoint.j = cols-1; //右邊框在第cols-1列
CurrentPoint.bHorV = FALSE; //使其符合第三個條件
// //虛設(shè)出第三個條件
// CurrentPoint.x = curPt_Col_X - 1;//減去1,使之比curPt_Col_X小
TracingOneNonClosedContour();
}
}
}
void CContourTracer::TracingClosedContour()
{
int cols = m_gridDataInfo.cols;
int rows = m_gridDataInfo.rows;
//搜索所有的除了邊框外的縱邊,從左到右搜索每一列上的縱邊,對于一列,從下到上搜索
for(int j=1; j<cols-1; j++) //j從1開始
for(int i=0; i<rows-1; i++) //i從0開始
{
if( IsHavingPoint(ySide[i][j]))
{
TracingOneClosedContour(i,j);
}
}
}
//從縱邊開始追蹤一條封閉等值線(注:是從縱邊開始搜索)
void CContourTracer::TracingOneClosedContour(int startPt_i, int startPt_j)
{//參數(shù)i,j是該閉曲線的第一個等值點(diǎn)的i,j
CCurve* pCtrLine = new CCurve;
m_pCurveList->AddTail(pCtrLine);
m_currentCurveLine = pCtrLine;
//虛設(shè)前一等值點(diǎn)的i,j,讓其滿足從左向右追蹤的條件
PreviousPoint.i = startPt_i;
PreviousPoint.j = 0;
PreviousPoint.bHorV = FALSE;
CurrentPoint.i = startPt_i;
CurrentPoint.j = startPt_j;
CurrentPoint.bHorV = FALSE; //是FALSE,因?yàn)槭窃诳v邊上
// float startPt_x;
// float startPt_y;
CalcAndSaveOnePointCoord(startPt_i,startPt_j,FALSE/*線頭在縱邊上*/,CurrentPoint.x,CurrentPoint.y);
TracingNextPoint();
PreviousPoint = CurrentPoint;
CurrentPoint = NextPoint;
BOOL bColsed = FALSE;
while(!bColsed)
{
TracingNextPoint();
PreviousPoint = CurrentPoint;
CurrentPoint = NextPoint;
//------2004/03/09修改------------------
//用等值點(diǎn)所在邊的標(biāo)識i,j來判斷曲線是否封閉,不用x、y坐標(biāo)來比較,因?yàn)楦↑c(diǎn)數(shù)計算會出現(xiàn)誤差
// bColsed = (CurrentPoint.x == startPt_x) && (CurrentPoint.y == startPt_y);
bColsed = ( CurrentPoint.i == startPt_i ) &&
( CurrentPoint.j == startPt_j ) &&
( CurrentPoint.bHorV == FALSE );
}
ySide[startPt_i][startPt_j] = -2.0f; //已經(jīng)追蹤過
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -