Visual C++ MFC编程 绘制直线、圆、自行车

1.建立工程
右方空白处输入工程名称,然后点击确定
在这里插入图片描述
选中基本对话框,点击完成
在这里插入图片描述
将右边控件中的图像控件拖到这上面去,然后点击右键,改成位图类型
在这里插入图片描述
2.界面设计
布局各自随意,这里用到了静态文本,编辑框,组框,按钮。
(当然你写的时候可以布局一部分,然后编写该部分的代码并且测试)
在这里插入图片描述
3.按钮事件响应
布局完成后,双击其中一个按钮会自动设置好函数,你只需要进行编写就行。
(1)绘制直线
这里我们使用的是DDA法绘制直线,当然Bresenham方法也可以,后面设置线宽时用的便是这个算法。

void CExperiment1Dlg::OnOK() 
{
	float s1,s2,s6,s7;	//起始点坐标
	int s3,s4,s5;		//RGB
	CString str1,str2,str3,str4,str5,str6,str7;
	//IDC_EDIT1这是编辑框的id,右键该控件就可以看见
	GetDlgItemText(IDC_EDIT1,str1);
	GetDlgItemText(IDC_EDIT2,str2);
	GetDlgItemText(IDC_EDIT3,str3);
	GetDlgItemText(IDC_EDIT4,str4);
	GetDlgItemText(IDC_EDIT5,str5);
	GetDlgItemText(IDC_EDIT6,str6);
	GetDlgItemText(IDC_EDIT7,str7);
	s1=atof(str1);//将字符串转化成float型
	s2=atof(str2);
	s6=atof(str6);
	s7=atof(str7);
	s3=atoi(str3);//那当然atoi就是将字符串转换成整型
	s4=atoi(str4);
	s5=atoi(str5);
	CDC *pDC=GetDlgItem(IDC_STATIC)->GetDC();
	Line1(pDC,s1,s6,s2,s7,s3,s4,s5);
}
void Line1(CDC *pDC,int xs,int ys,int xe,int ye,int R,int G,int B)
{
	int dx,dy,t; float k,x,y; 
	if(xs>xe) 
	{
		t=xe,xe=xs,xs=t; 
		t=ye,ye=ys,ys=t; 
	} 
	dx=xe-xs,dy=ye-ys; k=(float)dy/dx; 
	if(abs(dx)>=abs(dy)) 
	{ 
		y=ys; 
		for(x=xs;x<=xe;x++) 
			pDC->SetPixel((int)x,(int)y,RGB(R,G,B)),y=y+k; 
	} 
	else 
	{ 
		if(ye>ys) 
		{
			x=xs; 
			for(y=ys;y<=ye;y++) 
				pDC->SetPixel((int)x,(int)y,RGB(R,G,B)),x=x+1/k; 
		} 
		else 
		{
			x=xs; 
			for(y=ys;y>=ye;y--) 
				pDC->SetPixel((int)x,(int)y,RGB(R,G,B)),x=x-1/k; 
		} 
	} 
}

(2)绘制圆
Bresenham方法,这种方法画出来的圆更加圆滑

void CExperiment1Dlg::OnOk2() 
{
	float s8,s9,s10;
	int s3,s4,s5;
	CString str3,str4,str5,str8,str9,str10;
	GetDlgItemText(IDC_EDIT3,str3);
	GetDlgItemText(IDC_EDIT4,str4);
	GetDlgItemText(IDC_EDIT5,str5);
	GetDlgItemText(IDC_EDIT8,str8);
	GetDlgItemText(IDC_EDIT9,str9);
	GetDlgItemText(IDC_EDIT10,str10);
	s3=atoi(str3);
	s4=atoi(str4);
	s5=atoi(str5);
	s8=atof(str8);
	s9=atof(str9);
	s10=atof(str10);
	CDC *pDC=GetDlgItem(IDC_STATIC)->GetDC();
	Circle3(pDC,s8,s9,s10,s3,s4,s5); 
}
void Circle3(CDC *pDC,int x0,int y0,int r,int R,int G,int B) 
{
	int d=3-2*r,x=0,y=r; 
	while(y>=x) 
	{ 
		pDC->SetPixel (x+x0,y+y0,RGB(R,G,B)); 
		pDC->SetPixel (-x+x0,y+y0,RGB(R,G,B)); 
		pDC->SetPixel (-x+x0,-y+y0,RGB(R,G,B)); 
		pDC->SetPixel (x+x0,-y+y0,RGB(R,G,B)); 
		pDC->SetPixel (y+x0,x+y0,RGB(R,G,B)); 
		pDC->SetPixel (-y+x0,x+y0,RGB(R,G,B)); 
		pDC->SetPixel (-y+x0,-x+y0,RGB(R,G,B)); 
		pDC->SetPixel (y+x0,-x+y0,RGB(R,G,B)); 
		if(d<0) 
			d=d+4*x+6; 
		else 
			d=d+4*x-4*y+10, y=y--; 
		x++; 
	} 
}

(3)垂直线刷子增加线宽
适用于直线斜率在[-1, 1]之间。把线刷子放置成垂直方向,刷子中点对准直线一端点,然后让刷子中心往直线的另一端移动,即可“刷出”具有一定宽度的线段。垂直线刷子其实也就是多画了一些像素点,在点的左右两边各多画了一个点。这里使用的便是Bresenham方法,当然还有方刷子水平线刷子增加线宽的方法。

void CExperiment1Dlg::OnOk3() 
{
	float s1,s2,s6,s7;	//起始点坐标
	int s3,s4,s5;		//RGB
	CString str1,str2,str3,str4,str5,str6,str7;
	GetDlgItemText(IDC_EDIT1,str1);
	GetDlgItemText(IDC_EDIT2,str2);
	GetDlgItemText(IDC_EDIT3,str3);
	GetDlgItemText(IDC_EDIT4,str4);
	GetDlgItemText(IDC_EDIT5,str5);
	GetDlgItemText(IDC_EDIT6,str6);
	GetDlgItemText(IDC_EDIT7,str7);
	s1=atof(str1);
	s2=atof(str2);
	s6=atof(str6);
	s7=atof(str7);
	s3=atoi(str3);
	s4=atoi(str4);
	s5=atoi(str5);
	CDC *pDC=GetDlgItem(IDC_STATIC)->GetDC();
	Line2(pDC,s1,s6,s2,s7,s3,s4,s5);	
}
void Line2(CDC *pDC,int xs,int ys,int xe,int ye,int R,int G,int B)
{ 
	float dx=xe-xs; 
	float dy=ye-ys; //( xs,ys),(xe,ye)为直线段的两个端点坐标
	float e=-dx; 
	float y=ys; 
	float dxx=dx+dx;
	float dyy=dy+dy; 
	float x;
	for( x=xs;x<=xe;x++) 
	{ 
		pDC->SetPixel(x,y,RGB(R,G,B)); 
		//垂直线刷子
		pDC->SetPixel(x-1,y,RGB(R,G,B)); 
		pDC->SetPixel(x+1,y,RGB(R,G,B));
		if(e>=0) 
		y=y++, e=e-dxx; 
		e=e+dyy; 
	}
}

(4)绘制自行车
这个其实就是对上面直线和圆的应用了,比较麻烦的是你需要自己设置坐标。

void CExperiment1Dlg::OnOk4() 
{
	CDC *pDC=GetDlgItem(IDC_STATIC)->GetDC();
	Circle3(pDC,40,250,40,0,0,0); 
	Circle3(pDC,95,250,15,0,0,0); 
	Circle3(pDC,220,250,40,0,0,0); 
	Line1(pDC,40,210,180,170,0,255,0);
	Line1(pDC,180,170,220,250,0,255,0);
	Line1(pDC,95,250,180,170,0,255,0);
	Line1(pDC,80,180,95,250,0,255,0);
	Line1(pDC,160,160,200,180,0,255,0);
	Line2(pDC,70,180,90,180,0,0,255);
}

4.实验结果

在这里插入图片描述
可能有的同学会问了,这个默认值是怎么设置的呢(咳咳,当然你不一定能想到这个问题)
在代码中会有这个函数 BOOL CExperiment1Dlg::OnInitDialog()
你找一下然后可以在这里面初始化一些参数,比如编辑框的默认值

	GetDlgItem(IDC_EDIT1)->SetWindowText("10");
	GetDlgItem(IDC_EDIT2)->SetWindowText("80");
	GetDlgItem(IDC_EDIT3)->SetWindowText("255");
	GetDlgItem(IDC_EDIT4)->SetWindowText("0");
	GetDlgItem(IDC_EDIT5)->SetWindowText("0");
	GetDlgItem(IDC_EDIT6)->SetWindowText("5");
	GetDlgItem(IDC_EDIT7)->SetWindowText("30");
	GetDlgItem(IDC_EDIT8)->SetWindowText("80");
	GetDlgItem(IDC_EDIT9)->SetWindowText("80");
	GetDlgItem(IDC_EDIT10)->SetWindowText("50");

5.代码下载
压缩包下载
ps:
其实这是我们计算机图形学的实验,希望我的“自行车”别被同专业同学直接拿去交作业了嘿嘿,改一下参数嘛很简单的。我也是才刚学,很多都不会,如有不对请加以指正,谢谢!

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值