计算机图形学学习总结 联系客服

发布时间 : 星期一 文章计算机图形学学习总结更新完毕开始阅读72c6aed149649b6648d74741

void CDDAMouseLineView::DDAMouseLine(CDC *pDC, int x0, int y0, int x1, int y1, COLORREF color) {

int length,i; float x,y,dx,dy; length=abs(x1-x0); if (abs(y1-y0)>length) length=abs(y1-y0);

dx=(float)(x1-x0)/length; dy=(float)(y1-y0)/length; x=x0+0.5;y=y0+0.5; for (i=1;i<=length;i++) {

pDC->SetPixel((int)x,(int)y,color); x=x+dx;y=y+dy; }

//pDC->MoveTo(x0,y0); //pDC->LineTo(x1,y1); }

第八步:编译运行程序,验证运行结果。

程序改进,添加橡皮筋绘图技术,实现交互式画直线。

向视图类中添加鼠标OnMouseMove ()函数消息响应函数,并输入鼠标处理程序代码。 void CDDAMouseLineView::OnMouseMove(UINT nFlags, CPoint point) {

// TODO: Add your message handler code here and/or call default CDC *pDC=GetDC();

int nDrawmode=pDC->SetROP2(R2_NOT); //设置异或绘图模式,并保存原来绘图模式 pDC->SelectStockObject(NULL_BRUSH); if(m_ist==1){

CPoint prePnt,curPnt;

prePnt=m_p2; //获得鼠标所在的前一位置 curPnt=point; //绘制橡皮筋线

DDAMouseLine(pDC,m_p1.x,m_p1.y,prePnt.x,prePnt.y,RGB(255,0,0)); //DrawCircle(pDC,m_bO,prePnt); //用异或模式重复画圆,擦出所画的圆 DDAMouseLine(pDC,m_p1.x,m_p1.y,curPnt.x,curPnt.y,RGB(255,0,0)); //DrawCircle(pDC,m_bO,curPnt); //用当前位置作为圆周上的点画圆 m_p2=point; }

pDC->SetROP2(nDrawmode); //恢复原绘图模式 ReleaseDC(pDC); //释放设备环境 CView::OnMouseMove(nFlags, point); }

实验三

一、实验目的

编写圆和椭圆的扫描转换算法程序,验证算法的正确性。 二、实验任务

1. 编写中点画圆法的扫描转换程序,考虑原点在(x0,y0)处程序的改动; 2. 添加鼠标程序,实现交互式画圆; 3. 编写中点画椭圆法的扫描转换程序;

13

4. 添加鼠标程序,实现交互式画椭圆;

三、实验内容

任务一:中点画圆法的扫描转换算法

程序实现步骤:

(1) 建立MidPointCircle工程文件;

(2) 右击CMidPointCircleView类,建立成员函数

void MidpointCircle(CDC *pDC,int x0, int y0, int r, COLORREF color) int CirPot(CDC *pDC,int x0, int y0, int x, int y, COLORREF color) (3) 编写成员函数代码,程序如下:

void CMidPointCircleView::MidpointCircle(CDC *pDC,int x0, int y0, int r, COLORREF color) {

int x,y; float d;

x=0;y=r;d=1.25-r;

CirPot(pDC,x0,y0,x,y,color); while (x<=y) {

if(d<0) {

d+=2*x+3; x++; } else {

d+=2*(x-y)+5; x++; y--; }

CirPot(pDC,x0,y0,x,y,color); } /* while*/ }

int CMidPointCircleView::CirPot(CDC *pDC,int x0, int y0, int x, int y, COLORREF color) {

pDC->SetPixel((x0+x),(y0+y),color); pDC->SetPixel((x0+y),(y0+x),color); pDC->SetPixel((x0+y),(y0-x),color); pDC->SetPixel((x0+x),(y0-y),color); pDC->SetPixel((x0-x),(y0-y),color); pDC->SetPixel((x0-y),(y0-x),color); pDC->SetPixel((x0-y),(y0+x),color); pDC->SetPixel((x0-x),(y0+y),color); return 0; }

(4)编写OnDraw(CDC* pDC)函数,程序如下: void CMidPointCircleView::OnDraw(CDC* pDC) {

CMidPointCircleDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc);

// TODO: add draw code for native data here

MidpointCircle(pDC,100, 100, 10, RGB(255,0,0)); MidpointCircle(pDC,500, 300, 60, RGB(255,255,0)); }

(6) 编译、运行程序,查看结果。

14

任务二:添加鼠标程序,实现交互式画圆

在任务1的基础上,完成下列步骤: (1)向视图类中添加自定义的成员变量

用鼠标右键单击视图类,选择“Add Member Variable…”,添加下面三个成员变量。 proctected : int m_r; // 半径

CPoint m_bO; // 圆心 CPoint m_bR; //圆上的点

int m_ist; //圆心与圆周上点的区别,m_ist=0,表示鼠标左击点为圆心, //m_ist=1,表示鼠标左击点为圆周上的点

(2)在视图类CPP文件的构造函数中初始化成员变量 CMidPointCircleMouseView::CMidPointCircleMouseView() {

// TODO: add construction code here m_bO.x=0; m_bO.y=0; //圆心 m_bR.x=0; m_bR.y=0; //圆上的点 m_ist=0; //圆心与圆上的点区别 m_r=0; //圆的半径 }

(3)向视图类中添加自定义的成员函数原型: public:

int ComputeRadius(CPoint cenp,CPoint ardp); 添加成员函数的程序代码:

int CMouseSpringView::ComputeRadius(CPoint cenp, CPoint ardp) {

int dx=cenp.x-ardp.x; int dy=cenp.y-ardp.y;

//sqrt()函数的调用,在头文件中加入#include \ return (int)sqrt(dx*dx+dy*dy); }

(4)向视图类中添加两个鼠标消息响应函数,并输入鼠标处理程序代码。

具体操作方法与鼠标示例1方法相同。一个是OnLButtonDown()函数,另一个是OnMouseMove()函数。程序如下:

void CMidPointCircleMouseView::OnLButtonDown(UINT nFlags, CPoint point) {

// TODO: Add your message handler code here and/or call default CDC *pDC=GetDC();

pDC->SelectStockObject(NULL_BRUSH); if (!m_ist) //绘制圆 {

m_bO=m_bR=point; //纪录第一次单击鼠标位置,定圆心 m_ist++; } else {

m_bR=point; //记录第二次单击鼠标的位置,定圆周上的点 m_ist--; // 为新绘图作准备

m_r=ComputeRadius(m_bO,m_bR);

MidpointCircle(pDC,m_bO.x,m_bO.y,m_r,RGB(255,0,0)); }

ReleaseDC(pDC); //释放设备环境

CView::OnLButtonDown(nFlags, point); }

15

void CMidPointCircleMouseView::OnMouseMove(UINT nFlags, CPoint point) {

// TODO: Add your message handler code here and/or call default CDC *pDC=GetDC();

int nDrawmode=pDC->SetROP2(R2_NOT); //设置异或绘图模式,并保存原来绘图模式 pDC->SelectStockObject(NULL_BRUSH); if(m_ist==1) {

CPoint prePnt,curPnt;

prePnt=m_bR; //获得鼠标所在的前一位置 curPnt=point; //绘制橡皮筋线

m_r=ComputeRadius(m_bO,prePnt);

MidpointCircle(pDC,m_bO.x,m_bO.y,m_r,RGB(255,0,0));//用异或模式重复画圆,擦出所画的圆 // DrawCircle(pDC,m_bO,prePnt); m_r=ComputeRadius(m_bO,curPnt);

MidpointCircle(pDC,m_bO.x,m_bO.y,m_r,RGB(255,0,0)); //用当前位置作为圆周上的点画圆 m_bR=point; }

pDC->SetROP2(nDrawmode); //恢复原绘图模式 ReleaseDC(pDC); //释放设备环境 CView::OnMouseMove(nFlags, point); }

任务三:编写中点画椭圆法的扫描转换程序

程序实现步骤:

(1) 建立MidPointEllise工程文件;

(2)右击CMidPointElliseView类,建立成员函数

void MidpointEllise(CDC *pDC, int x0, int y0, int a, int b, COLORREF color) (3) 编写成员函数代码,程序如下:

void CMidPointEllipseView::MidpointEllise(CDC *pDC, int x0, int y0, int a, int b, COLORREF color) { } // 上半部分 int x,y; d2=(b*(x+0.5))*(b*(x+0.5))+(a*(y-1))*(a*(y-1))-(float d1,d2; a*b)*(a*b); x=0;y=b; while (y>0) d1=b*b+a*a*(-b+0.25); { pDC->SetPixel(x+x0,y+y0,color); if (d2<0) while (b*b*(x+1)SetPixel(x0+x,y0+y,color); x++; y--; pDC->SetPixel(x0+x,y0-y,color); } pDC->SetPixel(x0-x,y0+y,color); pDC->SetPixel(x0+x,y0+y,color); pDC->SetPixel(x0-x,y0-y,color); pDC->SetPixel(x0+x,y0-y,color); } //下半部分 pDC->SetPixel(x0-x,y0+y,color); } pDC->SetPixel(x0-x,y0-y,color); (4) 编写OnDraw()函数

16