MFC鼠标绘制直线段并使用编码裁剪算法
聰明的你通過本文可以學會在MFC中
- 初始化時繪制自定義矩形框
- 使用鼠標來實時繪制你想要的直線段
- 實現編碼裁剪算法裁去直線段在自定義矩形框以外的部分
完成效果如下
- 進入運行界面
- 鼠標繪制直線
- 編碼算法裁剪
接下來讓我們共同打敗這三個boss吧!難度也是和闖關類游戲一樣依次遞增呢!一步一步的跟著做哦,很容易就學會了
這篇博客主要講思路,所以要求你已經基本會使用MFC建立項目了,如果還不會的話,沒關系,我已經為你寫好了一篇MFC入門教程手把手教你建立繪制圓形的MFC項目,你保準一學就會,如果具備基本條件了,那還等什么,快開始吧
首先建立【MFC AppWizard (exe)】項目,我將其命名為【LineCut】
其次,將項目調成【Release】版本,這個很重要,否則該項目運行不了 具體步驟在向上數三行的鏈接中可以找到
1. 初始化時繪制自定義矩形框
- 達到的效果:初次運行程序,每次更新或重繪屏幕都會顯示該矩形框
2.鼠標實時繪制直線段
- 預期效果:在客戶區內鼠標左鍵單擊觸發直線繪制,單擊點成為直線段起點=》按住鼠標左鍵同時移動光標=》移動過程中光標實際位置與起點總是有線段相連=》松開鼠標左鍵=》直線段固定=》繪制完成
- 步驟分析:根據效果可知,在此鼠標有三個狀態/動作,左鍵按下,光標移動,左鍵彈起,所以接下來要給這三個動作添加響應函數,也就是消息函數,此三種消息函數在MFC ClassWizard 中的Messages中以存在,接下來為具體步驟:選擇【Class name:】下的【CLineCutView】=》單擊【Messages:】下的【WM_RBUTTONDOWN】=》單擊右上方的【Edit Code】=》進入【CLineCutView.cpp】編輯該響應函數。
- 變量準備,直線至少需要兩個頂點,并添加一些鼠標左鍵按下的標志
- 在【LineCutView.h】中添加變量
- 在構造函數中初始化變量
1. 鼠標左鍵按下的綁定函數OnLButtonDown
void CLineCutView::OnLButtonDown(UINT nFlags, CPoint point) {// TODO: Add your message handler code here and/or call default//以下4行是自己添加的,其他均為自動生成CClientDC dc(this);m_Draw=TRUE;//標記鼠標左鍵按下x0=point.x;//記錄下起點的 y0=point.y;CView::OnLButtonDown(nFlags, point); }2.鼠標移動的綁定函數OnMouseMove
//鼠標移動:實時更新當前位置到鼠標左鍵單擊位置的直線,動態效果,便于用戶判斷直線段位置與長短 //反復使用兩點確定直線繪制法+不斷更新的動畫制作原理=》從而產生動態效果 void CLineCutView::OnMouseMove(UINT nFlags, CPoint point) {// TODO: Add your message handler code here and/or call defaultCClientDC dc(this); x1=point.x;//記錄當前光標位置y1=point.y;if(m_Draw==TRUE)//若是沒這句,松開鼠標左鍵后直線就消失RedrawWindow();//重新調用OnDraw函數繪制直線,具體步驟稍后補上CView::OnMouseMove(nFlags, point); }3. 鼠標左鍵彈起綁定函數
void CLineCutView::OnLButtonUp(UINT nFlags, CPoint point) {// TODO: Add your message handler code here and/or call defaultm_Draw=FALSE;//標記鼠標左鍵彈起RedrawWindow();CView::OnLButtonUp(nFlags, point); }4. 想OnDraw函數添加直線繪制代碼
在操作前先在【LineCutView.cpp】中添加四舍五入宏定義
#define ROUND(a) (int)(a+0.5) //編碼宏定義后面千萬別帶分號,不然代入式會把分號一同帶入,造成語法錯誤 //設置直線畫筆CPen pen2(PS_SOLID,1,RGB(0,0,225));dc.SelectObject(&pen2);//將繪制直線封裝到Draw中,這樣每次更新即可重新繪制直線,便于其他部分使用//鼠標左鍵點擊后才開始傳遞鼠標移動信息if(m_Draw==TRUE){ dc.MoveTo(ROUND(x0),ROUND(y0));dc.LineTo(ROUND(x1),ROUND(y1));}5. 檢驗時刻: 完成了前四步,運行項目試試,若有如下效果,那么,恭喜你,成功地闖過第二關,你離目標只有1/3了,若沒有如下效果,則請回頭檢查
編碼裁剪算法實現
- 編碼函數
先添加四條邊界的宏定義
具體實現
unsigned int CLineCutView::enCode(float xx,float yy ) {RC=0;//初始化if(xx<wxl)//當前點在左邊界以左RC=RC|LEFT;//利用或運算將相應位置的數置為1if(xx>wxr)RC=RC|RIGHT;if(yy<wyb)RC=RC|BOTTOM;if(yy>wyt)RC=RC|TOP;return RC; }- cohen()裁剪函數
一路破關斬將的你是不是很輕松地到了這里,那么,接下來,有個博主尚未搞清原因的問題,等著聰明的你解答
問題描述:
【LineCutView】類中的變量x0,y0,x1,y1中的x1,y1在為對其進行任何運算時在鼠標動作綁定的函數與在其他函數中的值竟然不同,而x0,y0,卻沒有這個問題。
初步猜測:
x1,y1是已經被使用的變量名,于是我將二者換為ttx,tty,問題依舊。
解決方案:
定義變量ttx,tty,先把終點坐標記錄下來,在使用x1,y1時再賦給二者
避坑指南
- 線段頂點的類型不一致或者是線段頂點的類型均為int,那么計算斜率k則需強制轉換
- 二進制運算符【|】優先級<【=】,所以用作條件判斷時【|】兩側必須加括號,如if((a|b)==0)
- 編碼的宏定義要認真,別把自己搞糊涂
- 最后一個則是我之前提到的問題,目前還不知道原因,期待你的發現
在學習計算機圖形學時遇到了許多困難,花了許多時間才解決,所以希望該文能夠給你帶來幫助,節約時間,知識的意義在于分享,歡迎廣大朋友互相交流,qq:1140132928
總結
以上是生活随笔為你收集整理的MFC鼠标绘制直线段并使用编码裁剪算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 修改qq快捷键
- 下一篇: 百度2017春招笔试真题编程题集合 [编