C++橡皮筋技术实现像方坐标量测

 

现在给定目标为在视图窗口中实现直线的距离和角度量测的功能。具体要求为鼠标左键点击图像某一位置后,出现某一测量线,再次点击后确定直线,点击鼠标右键将计算该直线的像素长度以及与水平面的夹角。该直线量测的功能关键至于要实现橡皮筋技术,即直线随着鼠标的移动而移动。

下面将在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_nToolm_bBtnLineDis为消息识别变量和点击控制变量

3.       View类中加入OnLButtonDownOnMouseMoveOnRButtonDown三个函数

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.       编译运行程序,截图如下:

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值