1、用VC+在屏幕上绘图,计算机图形学实验,如何建立一个VC+应用程序框架文件:,一.MFC绘图函数:,1.1 生成设备环境对象设备环境是一个对窗口的绘图表面的属性保持跟踪的数据结构。这些属性包括用于在屏幕上绘图的当前所使用的画笔和画刷。与可以同时使用很多画刷和画笔的艺术家不同,设备环境每次只能用一种画笔和一种画刷。而设备环境对象就是设备环境类的一个实例,它设置了绘图工具,并提供了绘制点,线等简单图形的绘图函数。所有的绘图工作都要通过设备环境对象来实现。,例如,如果想用一个能够画粗线条的画笔,就必须创建一个新画笔,然后用它取代设备环境中原有的画笔。类似的,如果想用红色的画刷填充一个图形,必须创建一
2、个画刷,并将它选进设备环境,这就是Windows程序员在设备环境中取代工具的方式。,下面简单介绍几种设备环境:,.CDC 设备环境对象类,是其它设备环境的基类。一般情况下,应用程序都要在View(视图)类中来进行绘图,视图窗口绘制或者重绘,应用程序框架都要调用视图类的OnDraw成员函数。 void CMyDrawView:OnDraw(CDC* pDC) / TODO: add draw code for native data here ,.CPaintDC 构造函数调用BeginPaint ,析构函数调用EndPaint。有时在视图窗口以外的窗口(如对话框)中绘制图形,需要调用窗口类的W
3、M_PAINT的消息处理函数 OnPaint来绘制或者重绘窗口,OnPaint函数必须生成由 CPaintDC类派生的设备环境对象,如下所示: void CMyDialog:OnPaint() CPaintDC dc(this); (*),CPaintDC dc(this);创建一个名为dc的设备环境对象,而this指向当前的对话框。这样就可以在对话框画图了。,注意:由于视图类窗口也是窗口的一类,所以视图窗口要绘制时也收到WM_PAINT 的消息,但是Cview提供一个OnPaint函数,生成和准备设备环境对象,然后将对象传入OnDraw函数。只有不从视图类派生的窗口类才需要提供自己的OnPa
4、int函数做各种窗口绘图工作。,.CClientDC 这个设备环境对象仅仅代表了当前窗口区域。它的构造函数调用GetDC函数,它的析构函数调用ReleaseDC 函数。 对于在OnDraw和OnPaint处理器之外的函数中显示图形,必须生成CClientDC类成员的设备环境对象。 CMyFunction:Function() CClientDC ClientDC(this); / TODO: Add your message handler code here,1.2 选择绘图工具,画笔,画刷,字体等等。 系统默认的画笔和画刷: 默认的画笔画出的线为宽度为1像素的黑色实线。默认的画刷是白色的,
5、己用默认的画刷填充图形时,图形的内部填充成白色。,121 选用库存的绘图工具,CDC:SelectStockObject(int nIndex);void CMyView:OnDraw(CDC*pDC) pDC- SelectStockObject(WHITE_PEN); pDC- SelectStockObject(GRAY_BRUSH); ,122 生成自定义的绘图工具,生成自定义画笔和画刷的基本步骤:(1)生成画笔(CPen类)和画刷(CBrush)类的实例;(2)调用CPen类和CBrush类的成员函数来初始化画笔和画刷;(3)将生成的画笔和画刷选入设备环境对象中,并将设备环境对象的原
6、有的画笔和画刷保存在指针中;(4)调用相应的绘图函数进行绘图;(5)将原来的画笔和画刷重新选入设备环境对象中,(1)生成笔(CPen类)和刷(CBrush)类的实例; CPen pen; CBrush brush;(2)调用CPen类和CBrush类的成员函数来初始化笔和刷;画笔的初始化CPen:CreatePen,BOOL CreatePen(int nPenStyle,int nWidth,COLORREF crColor);nPenStyle : PS_SOLIDPS_DOT PS_DASH PS_DASHDOT PS_DASHDOTDOT nWidth : 线的宽度(线宽1均产生实线)
7、,crColor参数指定线的颜色,类型为COLORREF RGB(BYTE bRed ,BYTE bGreen, BYTE bBlue);0bRed ,bGreen, bBlue255RGB宏功能定义了16种纯颜色。,RGB(0,0,0);黑色RGB(255,255,255);白色 RGB(128,0,0);深红RGB(255,0,0);淡红 RGB(0, 128,0);深绿RGB(0, 255,0);淡绿 RGB(0,0,128);深蓝RGB(0,0.255);淡蓝 RGB(128,128,0);深黄 RGB(255,255,0);淡黄 RGB(0,128,128);深青 RGB(0,255
8、,255);淡青 等。,画刷的初始化:BOOL CreateSolidBrush(COLORREF crColor);BOOL CreateHatchBrush(int nIndex,COLORREF crColor);BOOL CreatePatternBrush(Cbitmap *pBitmap);,nIndex指定格子的形式。HS_CROSS 水平垂直交叉阴影HS_HORIZONAL 水平阴影线HS_VERTICAL 竖直阴影线HS_DIAGCROSS 45度交叉阴影对角线HS_BDIAGONL 以45度角从左上到右下倾斜的阴影HS_FDIAGONL 以45度角从左下到右上倾斜的阴影,(
9、3)将生成的笔和刷选入设备环境对象中,并将设备环境对象的原有的笔和刷保存在指针中; CDC:SelectObject CPen * SelectObject (CPen *pPen); CBrush*SelectObject(Cbrush*pBrush); 注意:该函数返回的是原来的设备环境对象的指针,1.3 设置绘图属性,(1) 背景色GetBkColor()返回当前的背景色。SetBkColor(COLORREF crColor)函数是将当前的背景色设置成参数crColor所代表的颜色值。,(2)背景方式GetBkMode()SetBkMode(int nBkMode)nBkMode: O
10、PAQUETRANSPARENT这两个函数主要影响Chord ,Ellipse和Pie等闭合图形绘图函数。,(3)绘图方式 GetROP2( ); int SetROP2( int nDrawMode ); 绘图方式(nDrawMode) 组合后像素的颜色 R2_BLACK 总为黑色 R2_WHITE 总为白色 R2_NOT 颜色与屏幕颜色相反 R2_COPYPEN 具有画笔的颜色 R2_NOTCOPYPEN 具有与画笔相反的颜色,1.4 几种常用的绘图函数,1.画线函数(1) 成员函数MoveTo:将当前的绘图位置移到point 指定的坐标处 CPoint MoveTo(int x,int
11、y);CPoint MoveTo(POINT point);(2) 成员函数LineTo在当前的绘图位置上与一个新坐标点之间画一条直线,这个新的坐标点将变成当前位置。BOOL LineTo (int x,int y);BOOL LineTo (POINT);,(3)成员函数Arc画一个椭圆形的弧线,它是一个指定边界矩形内一个内切椭圆的一段。BOOL Arc(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4); (4)成员函数PolylBezierBOOL PolyBezier(const POINT *lpPoints,int nC
12、ount);绘制由几个控制点所决定的多条Bezier曲线 一般给定的点为所画样条函数的3倍加1,void CMyDrawView:OnDraw(CDC *pDC) CPen Pen; CPen *OldPen; Pen.CreatePen(PS_SOLID,4,RGB(0,0,0); OldPen=pDC-SelectObject(,points0.x=100; points0.y=100; points1.x=200; points1.y=200; points2.x=300; points2.y=200; points3.x=400; points3.y=300; points4.x=50
13、0; points4.y=400; points5.x=300; points5.y=400; points6.x=200; points6.y=400; pDC-PolyBezier(points,7); pDC- SelectObject(OldPen);,2.画简单的闭合图形,(1) RectangleBOOL Rectangle(int x1,int y1,int x2,int y2);(2) EllipseBOOL Ellipse(int x1,int y1,int x2,int y2);,(3) Chord(一个椭圆和一条直线相交的图形)BOOL Chord(int x1,int
14、y1,int x2,int y2,int x3,int y3,int x4,int y4);(4) PolygonBOOL Polygon( LPPOINT lpPoints, int nCount );LpPoints是一个指向CPoint实例的POINT数组的指针 其中 nCount2,void CMyTestView:OnDraw(CDC *pDC) CPen Pen; CPen *OldPen;CBrush Brush;CBrush *OldBrush;Pen.CreatePen(PS_SOLID,5,RGB(0,0,0);Brush.CreateSolidBrush(RGB(0,25
15、5,0);OldPen=pDC-SelectObject(,void CMyTestView:OnDraw(CDC *pDC) CPen Pen;CPen *OldPen; Pen.CreatePen(PS_SOLID,2,RGB(255,255,0); CBrush Brush; CBrush *OldBrush; Brush.CreateHatchBrush(4,RGB(0,200,200); OldPen= pDC-SelectObject(,二实例,pDC-RoundRect(100,100,300,300,30,60); pDC-SetBkColor(RGB(255,255,0);
16、pDC-SetBkMode(OPAQUE); pDC-Ellipse(300,100,500,200); pDC-Pie(300,100,600,400,300,400,600,400); pDC-SelectObject(OldPen); pDC-SelectObject(OldBrush); ,三.鼠标消息函数的应用:,void CMyLineView:OnLButtonDown(UINT nFlags, CPoint point) m_Oldpoint=point;/保存光标的当前位置 m_Newpoint=point;/存放画线的起始位置 SetCapture(); /捕捉鼠标 m_p
17、LMouseDown=TRUE;/表示鼠标为按下的状态 CRect rect; GetClientRect(/获得并保存用户区坐标,MyLine应用程序(鼠标消息的应用),ClientToScreen( ,void CMyLineView:OnMouseMove(UINT nFlags, CPoint point) SetCursor(m_HCursor); /设置自定义光标 if(m_pLMouseDown) CClientDC dc(this);dc.SetROP2(R2_NOT); /设置绘图模式,以屏幕颜色的相反色绘图,/以重绘的方式擦除前一个OnMouseMove绘制的直线dc.Mo
18、veTo(m_Newpoint);dc.LineTo(m_Oldpoint);dc.MoveTo(m_Newpoint); /重新位置到当前位置画一条直线dc.LineTo(point);m_Oldpoint=point; /存放当前鼠标位置 CView:OnMouseMove(nFlags, point);,void CMyLineView:OnLButtonUp(UINT nFlags, CPoint point) if(m_pLMouseDown)m_pLMouseDown=FALSE;/标志鼠标释放ReleaseCapture();/释放鼠标捕捉ClipCursor(NULL);/使光标可以随意移动 CView:OnLButtonUp(nFlags, point);,