现在给定目标为在视图窗口中实现直线的距离和角度量测的功能。具体要求为鼠标左键点击图像某一位置后,出现某一测量线,再次点击后确定直线,点击鼠标右键将计算该直线的像素长度以及与水平面的夹角。该直线量测的功能关键至于要实现橡皮筋技术,即直线随着鼠标的移动而移动。
下面将在MFC建立的工程中具体实现这一功能:
1. 首先在工具栏上加入 直尺测量标记
2. 在Doc类中响应直尺测量函数
//直线测量距离及角度
void CCalibDoc::OnBtnLinedis()
{
m_nTool = 3;
m_bBtnLineDis = !m_bBtnLineDis;
}
void CCalibDoc::OnUpdateBtnLinedis(CCmdUI* pCmdUI)
{
pCmdUI->Enable( m_pDocImg != NULL );
pCmdUI->SetCheck( m_bBtnLineDis );
}
其中,m_nTool和m_bBtnLineDis为消息识别变量和点击控制变量
3. 在View类中加入OnLButtonDown、OnMouseMove和OnRButtonDown三个函数
4. 在View头文件中加入以下的类成员
//直线测量的起始点
CPoint m_ptLineBegin;
//直线测量的终点
CPoint m_ptLineEnd;
//是否在绘制橡皮筋
bool m_bEraDrawing;
//直线测量时改变光标
HCURSOR m_hCursor;
//记录鼠标按下的次数
int m_nPressDown;
5. 在View构造函数中初始化相关成员
6. 在OnLButtonDown函数中加入以下代码
//直线测量工具
if( m_pDoc->m_nTool == 3 )
{
m_hCursor = AfxGetApp()->LoadStandardCursor( IDC_CROSS );
::SetCursor( m_hCursor );
//如果是第一次点击
if( m_nPressDown == 0 )
{
m_bEraDrawing = true;
m_ptLineBegin = point;
m_ptLineEnd = point;
m_nPressDown++;
SetCapture();
}
else if( m_nPressDown == 1 )
{
m_nPressDown = 0;
ReleaseCapture();
}
}
7. 在OnMouseMove函数中加入以下代码
//直线测量
if( pDoc->m_nTool == 3 && m_nPressDown > 0 )
{
if( !m_bEraDrawing )
return;
CClientDC dc( this );
OnPrepareDC( &dc );
dc.DPtoLP( &point );
CPen pen, *pOldPen;
pen.CreatePen( PS_SOLID, 1, RGB(255,0,0) );
dc.SetROP2( R2_NOT );
if( m_ptLineEnd != point )
{
dc.MoveTo( m_ptLineBegin );
dc.LineTo( m_ptLineEnd );
dc.MoveTo( m_ptLineBegin );
dc.LineTo( point );
m_ptLineEnd = point;
}
pOldPen = dc.SelectObject( &pen );
}
8. 在OnRButtonDown函数中加入以下代码
if( pDoc->m_nTool == 3 && m_nPressDown == 0 )
{
if( !m_bEraDrawing )
return;
CClientDC dc( this );
OnPrepareDC( &dc );
CPen pen, *pOldPen;
pen.CreatePen( PS_SOLID, 1, RGB(255,0,0) );
dc.DPtoLP( &point );
//距离计算
double dbTemp1 = m_ptLineBegin.x - m_ptLineEnd.x;
dbTemp1 = dbTemp1 > 0? dbTemp1: -dbTemp1;
CString strLineDis;
strLineDis.Format( "%.1lf", dbTemp1 );
strLineDis += "pixels";
dc.TextOut( m_ptLineEnd.x, m_ptLineEnd.y, strLineDis );
//角度计算
double dbTemp2 = m_ptLineBegin.y - m_ptLineEnd.y;
dbTemp2 = dbTemp2 > 0? dbTemp2: -dbTemp2;
double dbTemp3 = dbTemp2 / dbTemp1;
//弧度
dbTemp3 = atan( dbTemp3 );
//转化为角度
dbTemp3 *= 180.0 / 3.14;
CString strLineAngle;
strLineAngle.Format( "%.2lf", dbTemp3 );
strLineAngle += "°";
dc.TextOut( m_ptLineEnd.x, m_ptLineEnd.y+20, strLineAngle );
pOldPen = dc.SelectObject( &pen );
}
9. 编译运行程序,截图如下: