当前位置:首页 > 计算机图形学学习总结
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
共分享92篇相关文档