ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

MFC之学习交互式绘图技术、三角形交互式实时绘制

2021-08-03 17:32:06  阅读:264  来源: 互联网

标签:MFC 鼠标 point void CPoint 绘图 交互式 顶点 pDC


1.笔记

1.1回显技术

回显是对图形的操作,用某种方式表达出来的技术。例如,在窗口客户区使用鼠标移动顶点时,希望能实时显示顶点坐标,这就是一种回显技术。

1.2引力域技术

绘图过程中,常常需要使用鼠标光标选择某一顶点。要准确定位光标很难,这时可以采用引力域技术。

引力域是指以某一点为中心所建立的一个矩形区域,当光标处于矩形区域之内时,就被“引力”吸引到该点上来。需要注意的是引力域大小要选择适当,太小了没有引力,太大了容易出现错误连接。

1.3橡皮筋技术

橡皮筋技术是鼠标绘图的过程连续、动态地表现出来,直到产生用户满意的结果为止的技术。例如,使用鼠标移动多边形的一个顶点,随着鼠标的移动,多边形的形状在不断变化,就像由橡皮筋构成。橡皮筋技术一般需要双缓冲机制

双缓冲机制是通过增加一个内存缓冲区,在缓冲区将图画好再一次性拷贝到显示设备上,以解决频繁擦除屏幕所导致的屏幕闪烁问题。

2.使用练习

2.1使鼠标能够移动三角形的顶点,回显顶点坐标,用橡皮筋技术动态显示移动过程。

首先在工程的视图类中定义三角形顶点及相关变量。添加消息处理函数的方法之前已经学习过,故略。

// 在Example_1View.h文件中编辑

class CExample1View : public CView{
...
protected:
	CPoint p[3];//三角形三个顶点
	BOOL bLBDown;//左键按下状态
	int nCount;//顶点计数器
public:
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);//处理左键按下消息
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);//处理左键弹起消息
	void DoubleBuffer(CDC* pDC);//双缓冲函数
	void DrawTriangle(CDC* pDC);//绘制三角形
	afx_msg void onm ouseMove(UINT nFlags, CPoint point);//处理光标移动消息
};

然后给工程的视图类进行相应的初始化。

//在Example_1View.cpp文件中编辑

CExample1View::CExample1View() noexcept
{
	// TODO: 在此处添加构造代码
	p[0] = CPoint(100, 100);//三角形三个顶点初始化
	p[1] = CPoint(300, 200);
	p[2] = CPoint(50, 300);
	bLBDown = false;//左键按下状态初始化
	nCount = 0;//顶点计数器初始化
}

重写界面绘图函数。

//在Example_1View.cpp文件中编辑

void CExample1View::OnDraw(CDC* pDC)
{
	CExample1Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TODO: 在此处为本机数据添加绘制代码
	DoubleBuffer(pDC);
}

实现双缓冲函数。

//在Example_1View.cpp文件中编辑

void CExample1View::DoubleBuffer(CDC* pDC) {
	CRect rect;//获取客户区
	GetClientRect(&rect);

	CDC memDC;//缓冲区设备上下文要与显示设备上下文兼容
	memDC.CreateCompatibleDC(pDC);

	CBitmap newBitmap, * pOldBitmap;//准备好缓冲区
        //创建和显示设备上下文客户区一致的位图,用于绘图
	newBitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
	pOldBitmap = memDC.SelectObject(&newBitmap);//将位图选入缓冲区
	memDC.FillSolidRect(rect, pDC->GetBkColor());//填充缓冲区背景

	DrawTriangle(&memDC);//画三角形,缓冲区绘制完后将图像拷贝回显示设备上下文
	pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(),
		&memDC, 0, 0, SRCCOPY);

	memDC.SelectObject(pOldBitmap);//恢复缓冲区设备上下文
	newBitmap.DeleteObject();//释放用毕资源
	memDC.DeleteDC();
}

实现绘制三角形函数。

//在Example_1View.cpp文件中编辑

void CExample1View::DrawTriangle(CDC* pDC) {
	pDC->SelectStockObject(GRAY_BRUSH);//选灰色画刷

	for (int i = 0; i < 3; ++i) {//3个顶点依次处理
		CString str;
		str.Format(CString("x=%d,y=%d"), p[i].x, p[i].y);
		pDC->SetTextColor(RGB(255, 0, 0));
		pDC->TextOutW(p[i].x, p[i].y, str);//输出顶点实时坐标
                
                //绘制顶点的引力域
		pDC->Rectangle(p[i].x - 5, p[i].y - 5, p[i].x + 5, p[i].y + 5);
                
                //连线,画三角形
		if (i == 0)pDC->MoveTo(p[i]);
		else pDC->LineTo(p[i]);
	}

	pDC->LineTo(p[0]);//连最后一条边
}

用鼠标拖动顶点的过程中,三角形的形状在不断变化,即要不断更新三角形的顶点信息,擦除画板重新绘制三角形。实现鼠标移动消息的处理函数。注意此处的GetDC和ReleaseDC配对出现是行规,否则容易出现内存泄漏问题。

//在Example_1View.cpp文件中编辑

void CExample1View::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	CDC* pDC = GetDC();//申请画图资源

	for(int i=0;i<3;++i)//寻找光标所在的顶点
		if (point.x<p[i].x + 5 && point.x > p[i].x - 5 &&
			point.y < p[i].y + 5 && point.y > p[i].y - 5)
		{
			//将光标形状设置为手形
                        SetCursor(LoadCursor(NULL, IDC_HAND));
			nCount = i;//标记光标所在的顶点
		}
	
	//如果鼠标左键按下,将光标当前位置的坐标赋值给顶点
	if (bLBDown)p[nCount] = point;

	ReleaseDC(pDC);//释放资源
	Invalidate(FALSE);//不擦除背景直接画,因为缓冲区是准备好背景才开始画三角形
        //Invalidate(TRUE)是擦除背景再画

	CView::OnMouseMove(nFlags, point);
}

 鼠标坐标按下、抬起的消息处理则非常简单。

//在Example_1View.cpp文件中编辑

void CExample1View::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	bLBDown = true;//鼠标左键按下,记为真

	CView::OnLButtonDown(nFlags, point);
}


void CExample1View::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	bLBDown = false;//鼠标左键抬起,记为假

	CView::OnLButtonUp(nFlags, point);
}

该案例所有需要自行编写代码如上所示,鼠标移动消息处理函数中申请绘图设备做何用,又为什么释放设备才去触发界面重绘事件,暂时还未明白,先记录之。

实现效果:

<iframe allowfullscreen="true" data-mediaembed="bilibili" id="pr7XFDvp-1627982308679" src="https://player.bilibili.com/player.html?aid=717060408"></iframe>

交互式实时绘制三角形

标签:MFC,鼠标,point,void,CPoint,绘图,交互式,顶点,pDC
来源: https://blog.csdn.net/qq_44643644/article/details/119351435

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有