【計算機圖形學課程】一.MFC基本繪圖函式使用方法

Eastmount發表於2016-11-16

        這是最近我《計算機圖形學》課程實踐程式設計課介紹的相關知識,主要是想通過MFC C++繪圖,讓學生體會下圖形學相關的程式設計及簡單的圖形繪製,同時非常佩服學生的想象力,他們做得真的不錯。希望這篇基礎文章對你有所幫助吧!尤其是有這門課程的學生或程式設計愛好者,如果文章存在錯誤或不足之處,還請海涵。
        參考書籍:孔令德·《計算機圖形學基礎教程(Visual C++版)》
        學生繪製的圖形還是非常有創新的,表示很滿意,哈哈哈~

   


一. MFC繪圖基礎知識 CDC類

        PS:這部分主要引入孔令德老師的知識,這篇文章以後面的程式設計為主。

        VC++具有強大的繪圖功能,雖然基於對話方塊的應用我推薦大家使用C# Winform程式,但是計算機圖形和影象的基礎知識,還是強烈推薦使用VC++ MFC實現。這有助於讓你深入的理解圖形變換、影象處理等知識。
        在Windows平臺下,GDI(Graphics Device Interface)圖形裝置介面被抽象為上下文CDC類(Device Context,DC)。Windows平臺直接接收圖形資料資訊的不是顯示器和印表機等硬體裝置,而是CDC物件。MFC中,CDC類定義裝置上下文物件的基類,封裝了所需的成員函式,呼叫CDC類的成員函式,繪製和列印圖形及文字。

        CDC類派生出CClientDC類、CMetaFileDC類、CPaintDC類和CWindowDC類,請讀者自行學習,同時推薦閱讀原書。
        MFC常用CPoint、CRect、CSize等資料型別。
        (1) CPoint類:存放點座標(x,y);
        (2) CRect類:存放矩形左上頂點和右下角頂點的座標(top、left、right、bottom),其中(top,left)為矩形的左上角點,(right,bottom)為矩形的右下角點;
        (3) CSzie類:存放矩形的寬度和高度的座標(cx,cy),其中cx為矩形的寬度,cy為矩形的高度。

        
        MFC繪圖工具類包括CGdiObject、CBitmap、CBrush、CFont、CPallette、CPen和CRgn等。常用的包括:
        (1) CBitmap:封裝了一個GDI點陣圖,提供點陣圖操作的介面;
        (2) CFont:封裝了GDI字型,可以選作裝置上下文中的當前字型;
        (3) CBrush:封裝了GDI畫刷,選作裝置上下文的當前畫刷,畫刷用於填充圖形內部;
        (4) CPen:封裝了GDI畫筆,選作裝置上下文的當前畫筆,畫筆用於繪製圖形邊界線;
        (5) CPallette:封裝了GDI調色盤,提供應用程式和顯示器之間的顏色介面;
        (6) CGdiObject:GDI繪圖工具的基類,一般不能直接使用。


二. MFC單文件程式設計介紹

        首先建立MFC專案,選擇"MFC AppWizard"工程,命名為"test01"。


        然後選擇"單文件"格式,其中"基於對話方塊"是Dialog對話方塊工程。



        建立完工程,在工作區間主要包括:ClassView(類檢視)、ResourceView(資源檢視)和FileView(檔案檢視)。其中類檢視主要包含各個類,檔案檢視包括原始檔.cpp和標頭檔案.h。

  

        開啟資源ResourceView檢視如下所示:


       MFC寫程式碼通常在xxxView.cpp檔案下,在"test01View.cpp"中找到OnDraw()函式,用於繪圖:
/////////////////////////////////////////////////////////////////////////////
// CTest01View drawing

void CTest01View::OnDraw(CDC* pDC)
{
	CTest01Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
}
       下面將詳細介紹MFC基礎繪圖函式。



三. MFC繪圖函式及擴充套件


1.MFC繪圖函式

        (1)繪製直線
        CDC::MoveTo(int x, int y)

        將畫筆移動到當前位置,即座標(x, y)處,並沒有畫線。
        CDC::LineTo(int x, int y)
        畫筆從當前位置繪製一條子線到(x, y)點,但不包含(x, y)點。

void CTest01View::OnDraw(CDC* pDC)
{
	CTest01Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	pDC->MoveTo(100,150);
	pDC->LineTo(300,400);

	// TODO: add draw code for native data here
}
        繪製圖形如下所示,座標(100, 150)表示距離左邊100,距離頂部150。


        注意:繪製圖形主要呼叫CDC* pDC方法實現,MFC可以補充提示函式。



        (2) 設定畫筆
        通常可以設定繪製圖形的顏色及線條屬性,函式為:
        CPen::CreatePen(int nPenStyle, int nWidth, COLORREF color)
       其中第一個引數為畫筆的風格,實現、虛線等,第二個引數為畫筆粗細,第三個引數使畫筆的顏色,採用RGB(255, 255, 255)賦值。



        CPen::SelectObject(Cpen *pen)
        呼叫CPen選中畫筆物件指標,即將畫筆指向新畫筆,同時指向指標。

void CTest01View::OnDraw(CDC* pDC)
{
	CTest01Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	//繪製直線
	pDC->MoveTo(100,150);
	pDC->LineTo(300,400);

	//定義畫筆繪製直線
	CPen pen(PS_DASH, 4, RGB(255,0,0)); //虛線 粗4 紅色
	pDC->SelectObject(&pen);
	pDC->MoveTo(100,150);
	pDC->LineTo(400,300);

	//方法二 CreatePen定義畫筆
	CPen pen2;   
	pen2.CreatePen(PS_DASHDOTDOT, 1, RGB(0,255,0)); //雙點畫線 粗2 綠色
	pDC->SelectObject(&pen2);
	pDC->MoveTo(100,150);
	pDC->LineTo(500,200);

}
        執行結果如下圖所示,注意定義畫筆後需要選擇畫筆SelectObject(),才能使用。



        (3) 繪製矩形
        CDC::Rectangle(int x1, int y1, int x2, int y2)

        引數x1、y1表示矩形左上角座標,引數x2、y2表示矩形右下角座標。

void CTest01View::OnDraw(CDC* pDC)
{
	CTest01Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	//定義畫筆繪製矩形
	CPen pen(PS_DASH, 2, RGB(0,0,255)); //虛線 粗2 藍色
	pDC->SelectObject(&pen);

	//定義座標點
	CPoint point1(100,150);
	CPoint point2(400,300);
	
	//繪製矩形
	pDC->Rectangle(point1.x, point1.y, point2.x, point2.y);

}
        執行結果如下圖所示,同時定義點是CPoint,可以呼叫point.x和point.y獲取座標。


        (4) 設定畫刷填顏色
        CBrush::CreateSolidBrush(COLORREF crColor) 

        引數為畫刷顏色,主要用於填充圖形。
        CBrush::SelectObject(CBrush* pBrush)
        選擇畫刷,填充顏色,引數pBrush為選中CBrush物件的指標。
        CGdiObject::DelectObject()
        把已成自由狀態的畫刷從系統記憶體中清除,此函式同刪除畫筆函式。

void CTest01View::OnDraw(CDC* pDC)
{
	CTest01Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	//定義畫筆繪製矩形
	CPen pen(PS_DASH, 2, RGB(0,0,255)); //虛線 粗2 藍色
	pDC->SelectObject(&pen);
	CBrush bush;
	bush.CreateSolidBrush(RGB(255,0,0));
	pDC->SelectObject(bush);

	//定義座標點
	CPoint point1(100,150);
	CPoint point2(400,300);
	
	//繪製矩形
	pDC->Rectangle(point1.x, point1.y, point2.x, point2.y);

}
        選擇畫刷填充如下圖所示:



        (5) 清除畫筆及畫刷
        真實操作中,通常會在畫筆和畫刷使用完畢時,把已成為自由狀態的畫筆和畫刷從系統記憶體中刪除。

void CTest01View::OnDraw(CDC* pDC)
{
	CTest01Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	//定義畫筆繪製矩形
	CPen MyPen, *OldPen; 
	MyPen.CreatePen(PS_DASH, 2, RGB(0,0,255)); //虛線 粗2 藍色
	OldPen = pDC->SelectObject(&MyPen);        //舊畫筆賦值

	//畫刷
	CBrush MyBrush, *OldBrush;
	MyBrush.CreateSolidBrush(RGB(255,0,0));
	OldBrush = pDC->SelectObject(&MyBrush);

	//定義座標點
	CPoint point1(100,150);
	CPoint point2(400,300);
	
	//繪製矩形
	pDC->Rectangle(point1.x, point1.y, point2.x, point2.y);

	//清除
	pDC->SelectObject(OldPen);
	MyPen.DeleteObject();
	pDC->SelectObject(OldBrush);
	MyBrush.DeleteObject();

}

        (6) 繪製橢圓函式
        CDC::Ellipse(int x1, int y1, int x2, int y2)

        引數x1、y1是繪製橢圓外接矩形左上角的座標,x2、y2是外接矩形的右下角座標。當繪製的外接矩形長和寬相同,即繪製的是圓。

void CTest01View::OnDraw(CDC* pDC)
{
	CTest01Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	//定義畫筆
	CPen MyPen, *OldPen; 
	MyPen.CreatePen(PS_DASH, 2, RGB(0,0,255)); //虛線 粗2 藍色
	OldPen = pDC->SelectObject(&MyPen);        //舊畫筆賦值

	//畫刷
	CBrush MyBrush, *OldBrush;
	MyBrush.CreateSolidBrush(RGB(255,0,0));
	OldBrush = pDC->SelectObject(&MyBrush);

	//定義座標點
	CPoint point1(100,150);
	CPoint point2(400,300);
	
	//繪製橢圓
	pDC->Ellipse(point1.x, point1.y, point2.x, point2.y);

	//繪製圓
	pDC->Ellipse(0, 0, 100, 100);

	//清除
	pDC->SelectObject(OldPen);
	MyPen.DeleteObject();
	pDC->SelectObject(OldBrush);
	MyBrush.DeleteObject();

}
        輸出如下圖所示:


        注意:還有些方法,包括繪製圓弧、繪製多邊形,方法類似,只是注意下引數即可。

        (7) 繪製文字
        CDC::TextOut(int x, int y, const CString & str)

        引數x、y是文字的起點座標,引數str是CString物件,文字內容。同時可以結合Format格式控制字串輸出變數。

void CTest01View::OnDraw(CDC* pDC)
{
	CTest01Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	//定義畫筆
	CPen MyPen, *OldPen; 
	MyPen.CreatePen(PS_DASH, 2, RGB(0,0,255)); //虛線 粗2 藍色
	OldPen = pDC->SelectObject(&MyPen);        //舊畫筆賦值

	//畫刷
	CBrush MyBrush, *OldBrush;
	MyBrush.CreateSolidBrush(RGB(255,0,0));
	OldBrush = pDC->SelectObject(&MyBrush);

	//定義座標點
	CPoint point1(100,150);
	CPoint point2(400,300);
	
	//繪製橢圓
	pDC->Ellipse(point1.x, point1.y, point2.x, point2.y);
	pDC->TextOut(405,305,_T("繪製橢圓"));

	//繪製圓
	pDC->Ellipse(0, 0, 100, 100);
	//使用Format寫文字
	CString str1 = "繪製圓 半徑=";
	int r = 50;
	CString data;
	data.Format("%s %d", str1,r);
	pDC->TextOut(105,105,data);

	//清除
	pDC->SelectObject(OldPen);
	MyPen.DeleteObject();
	pDC->SelectObject(OldBrush);
	MyBrush.DeleteObject();

}
        輸出如下圖所示:



2.擴充套件知識

        第一個擴充套件是,繪製直線過程中,如果圍繞一個圓心進行迴圈繪製,可以得到很好看的圓形直線。

#include <math.h>

void CTest01View::OnDraw(CDC* pDC)
{
	CTest01Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	//定義畫筆並選擇
	CPen pen(PS_SOLID,4,RGB(120,32,240));
	pDC->SelectObject(&pen);

	//定義點繪製一條豎直直線
	CPoint p0(300,300);
	CPoint p1(300,550);
	pDC->MoveTo(p0);
	pDC->LineTo(p1);

	//半徑和PI
	int R = 250;
	float pi = 3.14f;

	//定義150個點 迴圈按照圓形繪製
	CPoint p[100];
	for(int i=0;i<100;i++)
	{
		p[i].x = int(p0.x+R*sin((pi+i+1)/20));  //x座標 sin涉及數學知識
		p[i].y = int(p0.y+R*cos((pi+i+1)/20));  //y座標

		//先移動到圓形p0(300,300) 再繪製直線
		pDC->MoveTo(p0);
		pDC->LineTo(p[i]);
	}

}
輸出如下圖所示:


        該內容就是常見的圖形旋轉知識,核心內容:計算新座標,通過sin和cos數學知識,同時圓形不變,每次迴圈先MoveTo(p0)即可。
        第二段程式碼涉及圖形平移,就是繪製矩形圖形平移操作。

void CTest01View::OnDraw(CDC* pDC)
{
	CTest01Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	//定義畫筆並選擇
	CPen pen(PS_SOLID,4,RGB(120,32,240));
	pDC->SelectObject(&pen);

	CBrush brush(RGB(250,12,30));
	pDC->SelectObject(&brush);

	//迴圈繪製矩形
	int x1=100,y1=100,x2=300,y2=400;
	for(int j=0; j<100; j=j+3)
	{
		pDC->Rectangle(x1+j, y1+j, x2+j, y2+j);
	}

}
        輸出如下所示:


四. 學生成果及創新

        下面的程式碼是做得比較好的同學的,感覺還是不錯的。
        夏KH同學:

#include <math.h>

void CTest01View::OnDraw(CDC* pDC)
{
	CTest01Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here

	int d,k,x1,x2,y1,y2;
	float pi,a,e;
	CPen pen;
	pen.CreatePen(PS_SOLID,1,RGB(155,0,0));
	CPen *pOldPen = pDC->SelectObject(&pen);
	pi = 3.1415926f;
	d = 80;
	for (a = 0; a<=2 * pi; a+= pi/360)
	{
		e = d * (1+0.25*sin(4*a));
		e = e * (1 + sin(8*a));
		x1 = int(320+e*cos(a));
		x2 = int(320+e*cos(a + pi/8));
		y1 = int(200+e*sin(a));
		y2 = int(200+e*sin(a + pi/8));
		pDC->MoveTo(x1,y1);
		pDC->LineTo(x2,y2);
	}

}
        輸出如下所示:

        李N同學:
void CTest01View::OnDraw(CDC* pDC)
{
	CTest01Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here

	//定義畫筆
	CPen pen(PS_SOLID,2,RGB(0,255,0));
	pDC->SelectObject(&pen);

	CPoint p0(400,200);
	int R=200;
	CPoint p1(400,600);

	pDC->MoveTo(p0);
	pDC->LineTo(p1);

	float pi=3.14f;

	CPoint p[126];
	for(int i=0;i<126;i++)
	{
		p[i].x=int(p0.x + R*sin((pi+i+1)/20));
		p[i].y=int(p0.y + R*cos((pi+i+1)/20));

		pDC->MoveTo(p0);
		pDC->LineTo(p[i]);
	}

	CBrush bush(RGB(255,255,0));
	pDC->SelectObject(&bush);

	int x1=700,y1=100,x2=900,y2=400;
	for(int j=0;j<50;j++)
	{
		pDC->Rectangle(x1+j,y1+j, x2+j, y2+j);
	}
}
        輸出如下所示:


        楊J同學:
void CTest01View::OnDraw(CDC* pDC)
{
	CTest01Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here

	CPen pen(PS_SOLID,1,RGB(255,0,0));
	pDC->SelectObject(&pen);
   
	CPoint p0(400,300);
	int R=200;
	CPoint p1;
	p1.x=p0.x;
	p1.y=p0.y+R;
 
	pDC->MoveTo(p0);
	pDC->LineTo(p1);

	CPoint p2;
	float pi=3.14f;
	p2.x=int(p0.x+R*sin(pi/20));
	p2.y=int(p0.y+R*cos(pi/20));
	pDC->MoveTo(p0);
	pDC->LineTo(p2);

	CPoint p[1000];
	for(int i=0;i<1000;i++){
		p[i].x=int(p0.x+R*sin((pi+i+1)/20));
		p[i].y=int(p0.y+R*cos((pi+i+1)/20));

		pDC->MoveTo(p0);
		pDC->LineTo(p[i]);
	}

	CBrush bush(RGB(0,255,255));
	pDC->SelectObject(&bush);
	for(int j=0;j<200;j=j+3)
	{
		pDC->Rectangle(600+j,100+j,800+j,400+j);
	}

}
        輸出如下圖所示:
        張J同學:
#include <math.h>

void CTest01View::OnDraw(CDC* pDC)
{
	CTest01Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here

	CPen pen(PS_SOLID,1,RGB(255,80,0));
	pDC->SelectObject(&pen);
	CPoint p0(200,200);
	CPoint p1;
	int R=200,P=100;
	p1.x=p0.x;
	p1.y=p0.y+R;
	pDC->MoveTo(p0);
	pDC->LineTo(p1);
	float pi=3.14;
	CPoint p[200];
	for(int i=0,h=1;i<200,i<200;i=i+2,h=h+2)
	{
		p[i].x=int(R*sin((pi+i)/20)+p0.x);
		p[i].y=int(R*cos((pi+i)/20)+p0.y);
        p[h].x=int(P*sin((pi+h)/20)+p0.x);
		p[h].y=int(P*cos((pi+h)/20)+p0.y);
		pDC->MoveTo(p0);
		pDC->LineTo(p[i]);
		pDC->MoveTo(p0);
		pDC->LineTo(p[h]);
	}

	CBrush bush(RGB(255,190,0));
	pDC->SelectObject(&bush);
	int x1=500,y1=100,x2=600,y2=300;
	for(int j=0;j<100;j++)
	{
		pDC->Rectangle(500-j,100+j,600+j,300-j);
	}
    int x3=700,y3=100,x4=800,y4=300;
	for(int k=0;k<100;k++)
	{
		pDC->Ellipse(700-k,100+k,800+k,300-k);
	}
	int x5=900,y5=100,x6=1000,y6=300;
	for(int l=0;l<100;l++)
	{
		pDC->Rectangle(900+l,100+l,1000+l,300+l);
	}

}
        輸出如下圖所示:

        鄭DD同學:

#include <math.h>

void CTest01View::OnDraw(CDC* pDC)
{
	CTest01Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here

	CPen pen(PS_SOLID,1,RGB(0,255,0,));
	pDC->SelectObject(&pen);
	CPoint p1,p2;
	int R=200;
	p1.x=200;
	p1.y=300;
	p2.x=100;
	p2.y=p1.y+R;
	pDC->MoveTo(p1);
	pDC->MoveTo(p2);

	float pi=3.14f;

	CPoint p[400];

	for(int i=0;i<400;i++)
	{
		p[i].x = int(R*sin((pi+i+1)/3)+p1.x);
		p[i].y = int(R*cos((pi+i+1)/6)+p1.y);
		pDC->MoveTo(p1);
		pDC->LineTo(p[i]);
	}
	pDC->TextOut(190,280,_T("wow")),RGB(255,0,0);

	float ph=3.14f;
    for(int h=0;h<400;h++)
	{
		p[h].x = int(R*sin((ph+h+1)/6)+p1.x);
		p[h].y = int(R*cos((ph+h+1)/3)+p1.y);
		pDC->MoveTo(p1);
		pDC->LineTo(p[i]);
	}

}
        輸出如下圖所示:




        趙BL同學:

#include <math.h>

void CTest01View::OnDraw(CDC* pDC)
{
	CTest01Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here

	//定義畫筆
	CPen pen(PS_SOLID,2,RGB(255,32,150));
    pDC->SelectObject(&pen);

	//定義點
	CPoint p0(300,400);
	CPoint p1(300,600);

	pDC->MoveTo(p0);
	pDC->LineTo(p1);

	float pi=3.14f;
	int R=200;

	CPoint p[249];
	for(int i=0; i<249; i++){

		p[i].x = int(p0.x + R*cos((pi+i+1)/20));
		p[i].y = int(p0.y + R*tan((pi+i+1)/20));

		pDC->MoveTo(p0);
		pDC->LineTo(p[i]);
	}


	CBrush bush(RGB(255,166,123));
	pDC->SelectObject(bush);
	int x=600,y=100;
	int x2=900,y2=300;
	pDC->Rectangle(x,y,x2,y2);

	for(int j=0;j<100;j=j+4){
	
		pDC->Rectangle(x+j,y+j,x2+j,y2+j);
	}
}
        輸出如下圖所示:

        陳Y同學:
void CTest01View::OnDraw(CDC* pDC)
{
	CTest01Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here

	CPen pen(PS_SOLID,8,RGB(132,255,255));
	pDC->SelectObject(&pen);

	CPoint p0(220,300);
	int R=200;
	CPoint p1;
	p1.x=p0.x;
	p1.y=p0.y+R;

	pDC->MoveTo(p0);
	pDC->LineTo(p1);

	CPoint p2;
	float pie=3.14f;

	CPoint p[45];
	for(int i=0;i<60;i++) {
	 
		p2.x=int(p0.x+R*sin((pie-i)/10));
		p2.y=int(p0.y+R*tan((pie-i)/10));
	
		pDC->MoveTo(p0);
		 pDC->LineTo(p2);

	}
}
        輸出如下圖所示:



        文FB同學程式碼:
#include <math.h>

void CTest01View::OnDraw(CDC* pDC)
{
	CTest01Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here

	CPen pen(PS_SOLID, 3, RGB(0, 0, 255));
	pDC->SelectObject(&pen);
	CPoint p0(350, 200);
	int r = 200;
	CPoint p1(350, 300 + r);

	pDC->MoveTo(p0);
	pDC->LineTo(p1);

	CPoint p2;
	float PI = 3.14f;

	p2.x = int(p0.x + r*sin(PI / 10));
	p2.y = int(p0.y + r*cos(PI / 10));
	pDC->MoveTo(p0);
	pDC->LineTo(p2);

	CPoint p[1000];
	for (int i = 0; i <300; i++)
	{
		
		p[i].x = int(p0.x + r*sin((PI + i + 1) / 10));
		p[i].y = int(p0.y + r*cos((PI + i + 1) / 10));
		r--;
		pDC->MoveTo(p0);
		pDC->LineTo(p[i]);
	}
}
        輸出如下圖所示:


        劉JL同學程式碼如下:

void CTest01View::OnDraw(CDC* pDC)
{
	CTest01Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here

	CPen pen(PS_SOLID,2,RGB(255,0,0));
	pDC->SelectObject(&pen);
	CPoint p0(300,200);
	int R=170;
	CPoint p1(350,400);
	pDC->MoveTo(p0);
	pDC->LineTo(p1);
	
	
	float pi=3.14f;
	CPoint p[45];
	for(int i=0;i<45;i++)
	{
		p[i].x=int(p0.x*sin((pi+i)/20));
		p[i].y=int(p0.y*cos((pi+i)/20)+R);
		pDC->MoveTo(p0);
		pDC->LineTo(p[i]);
	}
}
        輸出如下圖所示:


        希望文章對你有所幫助,上課內容還需要繼續探索,這篇文章主要講述MFC繪製圖形的基礎知識,再結合計算機圖形學的旋轉和平移應用進行擴充套件。原來課程可以這麼上,挺有意思的,同時學生的想象力真實厲害,而且也很優秀。下週專家就來了,真的很忙,但是再忙,寫部落格的時候自己都是最放鬆最享受的時候,上課也是一樣。加油~

        (By:Eastmount 2016-11-16 半夜4點半 http://blog.csdn.net/eastmount/ )

相關文章