MFC基本图形的绘制

实验一 基本图形绘制

一、实验目的和要求
通过本次实验,掌握Behamsen或DDA方法绘制直线、圆或椭圆算法原理,加深对算法的理解,并采用Vc++提供的绘图函数实现多义线、矩形、多边形的绘制。了解区域填充的实现过程。
二、实验环境
1.硬件环境:PC机
2.软件环境: Windows 环境、Vc++编程
三、实验内容
1.实现Bresenham直线生成算法或DDA方法绘制直线、圆或椭圆算法
2.实现多义线、矩形、多边形的绘制
四、实验要求
(1)认真分析实验内容和要求,复习相关的理论知识,选择适当的解决方案;
(2)编写上机实验过程,作好上机前的准备工作;
(3)编写Bresenham直线生成算法或DDA绘制直线的函数
(4)编写Bresenham绘制园、椭圆函数
(5)了解并实现多义线、矩形、多边形的绘制方法。
(6)上机实践,记录实验结果(包括必要的中间结果);
(7)分析实验结果,并提供系统屏幕抓屏。
五、算法原理
1.DDA算法:直接利用计算x轴上的增量 x或y轴的增量 y的线段扫描转换算法。
若线段的斜率m的绝对值小于等于1,则在单位x间隔( x=1)取样,计算每个y的值,即 。
.若线段的斜率m的绝对值大于1,则在单位y间隔( y=1)取样,计算每个x的值,即
2.Bresenham直线生成算法:用线段上的点和上下相邻像素点间距离的对比来选择合适的像素点。
定义线段上的某一点到下像素点的距离为的d1,到上像素点的距离为d2,定义 d=d1-d2, ,并求出 的值。
根据相应的 的值来选取点。即 的值大于0,则取上像素点,且 ;若 的值小于0,则取下像素点,且 ;
3.Bresenham绘制园、椭圆:
算法内容:输入椭圆的长短轴来绘制
注释:这些代码的绘制全是基于MFC的onDrawview()里面进行的
如果老师要求要加上坐标轴代码如下

CRect rc;
	GetClientRect(&rc);
	pDC->SetMapMode(4);
	pDC->SetViewportOrg(rc.right/2,rc.bottom/2);
	pDC->MoveTo(-rc.right,0);
	pDC->LineTo(rc.right,0);
	pDC->MoveTo(0,rc.bottom);
	pDC->LineTo(0,-rc.bottom);

	pDC->TextOut(450,250,"第一象限");
	pDC->TextOut(-450,250,"第二象限");
	pDC->TextOut(-450,-250,"第三象限");
	pDC->TextOut(450,-250,"第四象限");
	pDC->TextOut(520,0,"X轴");
	pDC->TextOut(0,260,"Y轴");
  1. DDA算法绘制直线
DDA(int x1, int y1, int x2, int y2, CDC *pDC)
{	int dx, dy ,epsl,k;
	float x,y,xIncre,yIncre;
 	dx=x2-x1; 	dy=y2-y1;
x=x1; 		y=y1;
if (abs(dx)>abs(dy))
	epsl=abs(dx);
else
epsl=abs(dy);
	       xIncre=(float)dx/(float)epsl
	       yIncre=(float)dy/(float)epsl;
	CPoint P;
for(k=0;k<=epsl;k++)
	{
		P.x=int (x+0.5); P.y=int (y+0.5);
 pDC->SetPixel(P.x,P.y,RGB(255,0,0));
	x+=xIncre;
		y+=yIncre;
	}
}
DDA算法的调用:DDA(0,0,300,300,pDC);
DDA(0,0,-100,300,pDC);
	          DDA(0,0,-100,-300,pDC);
	                DDA(0,0,100,-300,pDC);

2.中点Bresenham算法绘制直线

中点Bresenham算法函数:
MidBresenham(int x1, int y1, int x2, int y2, CDC *pDC)
{
	int dx,int dy,d ,UpIncre,DownIncre,x,y;
	if (x1>x2){
		x=x2;
		x2=x1;
		x1=x;
	}
	x=x1;
	y=y1;
	dx=x2-x1;
	dy=y2-y1;
	d=dx-2*dy;
	UpIncre=2*dx-2*dy;
	DownIncre=-2*dy;
	
	while(x<=x2)
	{
		pDC->SetPixel(x,y,RGB(225,0,0));
		x++;
		if(d<0){
			y++;
			d+=UpIncre;
		}
		else
		{
			d+=DownIncre;
		}
	}


}
函数调用:
MidBresenham(0,0,300,300,pDC);
	MidBresenham(-10,-10,-300,-300,pDC);
	MidBresenham(0,0,-300,300,pDC);
	MidBresenham(10,-10,300,-300,pDC);

3.Bresenham算法绘制直线

Bresenham算法函数:
Bresenham(int x0, int y0, int x1, int y1, CDC *pDC)
{
	int x,y,dx,dy,e;
	dx=x1-x0;
	dy=y1-y0;
	e=-dx;
	x=x0;
	y=y0;
	while(x<=x1)
	{
		pDC->SetPixel(x,y,RGB(0,225,0));
		x++;
		e=e+2*dy;
		if(e>0)
		{
			y++;
			e=e-2*dx;
		}
	}

}
函数调用:	Bresenham(-50,-100,200,300,pDC);

4.系统函数直接绘制直线`

②代码:for(int i=0;i<300;i++)
		pDC->SetPixel(1*i,50,RGB(225,0,0));
	for(int j=0;j<400;j++)
		pDC->SetPixel(2*j,100,((COLORREF)0x0000FF00));
	pDC->MoveTo(-100,40);
	pDC->LineTo(-300,-400);

5.八分画画圆

CirclePoint(int x, int y, CDC *pDC)
{
	pDC->SetPixel(x,y,RGB(255,0,0));
	pDC->SetPixel(y,x,RGB(255,0,0));
	pDC->SetPixel(-y,x,RGB(255,0,0));
	pDC->SetPixel(-x,y,RGB(255,0,0));
	pDC->SetPixel(-x,-y,RGB(255,0,0));
	pDC->SetPixel(-y,-x,RGB(255,0,0));
	pDC->SetPixel(y,-x,RGB(255,0,0));
	pDC->SetPixel(x,-y,RGB(255,0,0));

}
函数调用:
	CirclePoint(10, 50, pDC);

6.中点Bresenham绘制圆

中点Bresenham算法函数:
MidBresenhamCircle(int r, CDC *pDC)
{
	int x,y,d;
	x=0;
	x=r;
	d=1-r;
	while(x<=y)
	{
			pDC->SetPixel(x,y,RGB(255,0,0));
	pDC->SetPixel(y,x,RGB(255,0,0));
	pDC->SetPixel(-y,x,RGB(255,0,0));
	pDC->SetPixel(-x,y,RGB(255,0,0));
	pDC->SetPixel(-x,-y,RGB(255,0,0));
	pDC->SetPixel(-y,-x,RGB(255,0,0));
	pDC->SetPixel(y,-x,RGB(255,0,0));
pDC->SetPixel(x,-y,RGB(255,0,0));
	if(d<0)
		d+=2*x+3;
	else
		d+=2*(x-y)+5;
	y--;
	}
	x++;

}
函数调用:
MidBresenhamCircle(100, pDC);

7.系统函数调用直接绘制圆

②	代码:pDC->SetViewportOrg(rc.right*3/4,rc.bottom/4);
	pDC->Ellipse(-100,-100,100,100);

8,.中点Bresenham算法绘制椭圆

中点Bresenham算法函数:
MidBresenhamEllipse(int a, int b, CDC *pDC)
{
	int x,y;
	float d1,d2;
	x=0;
	y=b;
	d1=b*b+a*a*(-b+0.25);
	pDC->SetPixel(x,y,RGB(255,10,255));
	pDC->SetPixel(-x,-y,RGB(255,10,255));
	pDC->SetPixel(-x,y,RGB(255,10,255));
	pDC->SetPixel(x,-y,RGB(255,10,255));
	while (b*b*(x+1)<a*a*(y-0.5)){
		if(d1<=0)
		{
			d1+=b*b*(2*x+3);
			x++;
		}
		else
		{
			d1+=b*b*(2*x+3)+a*a*(-2*y+2);
			x++;
			y--;
		}
		pDC->SetPixel(x,y,RGB(255,10,255));
		pDC->SetPixel(-x,-y,RGB(255,10,255));
		pDC->SetPixel(-x,y,RGB(255,10,255));
		pDC->SetPixel(x,-y,RGB(255,10,255));
	}
	d2=b*b*(x+0.5)*(x+0.5)+a*a*(y-1)*(y-1)-a*a*b*b;
	while(y>0)
	{
		if(d2<=0)
		{
			d2+=b*b*(2*x+2)+a*a*(-2*y+3);
			x++;
			y--;
		}
		else
		{
			d2+=a*a*(-2*y+3);
			y--;
		}
		pDC->SetPixel(x,y,RGB(255,10,255));
		pDC->SetPixel(-x,-y,RGB(255,10,255));
		pDC->SetPixel(-x,y,RGB(255,10,255));
		pDC->SetPixel(x,-y,RGB(255,10,255));
	}

}
函数调用:MidBresenhamEllipse(200, 50, pDC);

9.系统直接调用绘制椭圆

pDC->SetViewportOrg(rc.right/4,rc.bottom/4);
pDC->Ellipse(-200,-50,200,50);	

10.多义曲线的绘制

pDC->SetViewportOrg(rc.right*3/4,rc.bottom*3/4);
	CPoint pt[7];
	pt[0].x=-150;pt[0].y=0;
	pt[1].x=-100;pt[1].y=-75;
	pt[2].x=-50; pt[2].y=-75;
	pt[3].x=0; pt[3].y=0;
	pt[4].x=50;pt[4].y=75;
	pt[5].x=100; pt[5].y=75;
	pt[6].x=150; pt[6].y=0;//使用现成的CDC类成员函数,绘制Bezier曲线;
	pDC->PolyBezier(pt,7);

11.矩形的绘制

pDC->Rectangle(10,20,300,200);//绘制矩形
	pDC->Rectangle(10,10,200,200);//绘制正方形

12.多边形的绘制

pDC->SetViewportOrg(rc.right*3/4,rc.bottom*3/4);
	CPoint pt[7];
	pt[0].x=-150;pt[0].y=0;
	pt[1].x=-100;pt[1].y=-75;
	pt[2].x=-50; pt[2].y=-75;
	pt[3].x=0; pt[3].y=0;
	pt[4].x=50;pt[4].y=75;
	pt[5].x=100; pt[5].y=75;
	pt[6].x=150; pt[6].y=0;//使用现成的CDC类成员函数,绘制Bezier曲线;
	pDC->Polygon(pt,7);//绘制多边型

13.扇形的绘制

②	代码:	pDC->Pie(-100,-100,100,100,-100,-100,100,150);

14.圆弧的绘制

	pDC->SetViewportOrg(rc.right/4,rc.bottom*3/4);
	pDC->Arc(-100,-100,100,100,-100,0,100,0);

  • 4
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值