在MFC中,运用轨迹球算法实现鼠标旋转物体

本文介绍如何在MFC应用中利用轨迹球算法,通过鼠标操作实现物体的旋转。参照nehe教程第48课,设置轨迹球边界,并定义鼠标事件响应函数OnLButtonUp, OnLButtonDown, OnMouseMove,以处理鼠标拖动时的旋转矩阵计算。" 78650985,7243279,目标函数优化:从随机梯度下降到Adam算法,"['数据结构与算法', '机器学习', '深度学习']

参考资料:nehe教程第48课《轨迹球实现的鼠标旋转》

1、在头文件中为Arcball添加变量

	//为Arcball添加变量用来获取当前鼠标点
	Point2fT    MousePt;// NEW: Current Mouse Point	

2、在源文件中对轨迹球参数初始化

transform是我们获得的最终的变换矩阵
lastRot是上一次鼠标拖动得到的旋转矩阵
thisRot为这次鼠标拖动得到的旋转矩阵。

//*******************轨迹球参数初始化********************
ArcBallT ArcBall(640.0f, 480.0f);
Matrix4fT Transform={1.0f,0.0f,0.0f,0.0f,// NEW: Final Transform
0.0f,1.0f,0.0f,0.0f,
0.0f,0.0f,1.0f,0.0f,
0.0f,0.0f,0.0f,1.0f};
Matrix3fT LastRot  ={1.0f,0.0f,0.0f,	// NEW: Last Rotation
0.0f,1.0f,0.0f,
0.0f,0.0f,1.0f};
Matrix3fT ThisRot  ={1.0f,0.0f,0.0f,	// NEW: This Rotation
0.0f,1.0f,0.0f,
0.0f,0.0f,1.0f};



3、在onsize()函数中设置轨迹球的边界

注意:onsize()函数中,添加if()判断,设置轨迹球的函数ArcBall.SetBounds()才不会出现assert错误,这跟轨迹球的头文件有关。

if(cy>0)
{
ArcBall.setBounds((GLfloat)cx, (GLfloat)cy); 
}

函数全:

void CtestviewView::OnSize(UINT nType, int cx, int cy) 
{
	CView::OnSize(nType, cx, cy);
	// TODO: Add your message handler code here
	//////////////////////////////////////////////////////////////////////////////
if (cy>0)
{
	glViewport (0, 0, (GLsizei)(cx), (GLsizei)(cy));				    // 设置窗口可见区为窗口大小
	glMatrixMode (GL_PROJECTION);										// 设置投影矩阵
	glLoadIdentity ();													// 重置它
	gluPerspective (45.0f, (GLfloat)(cx)/(GLfloat)(cy),1.0f, 100.0f);	// 设置可视冷苔体
	//glMatrixMode (GL_MODELVIEW);										// 设置为模型变换矩阵
	glLoadIdentity ();													// 重置它
	/***********************************新添的代码***********************************************************************************/

	//设置轨迹球的边界
	ArcBall.setBounds((GLfloat)cx, (GLfloat)cy); 

	//在后缓冲中绘制图形
	//glDrawBuffer (GL_BACK);
	/********************************************************************************************************************************/
}
	
}


4、添加鼠标消息响应函数

//鼠标的消息响应函数
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);

//鼠标左键down
void CtestviewView::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	//Arcball rotate control
	LastRot=ThisRot;// Set Last Static Rotation To Last Dynamic One
	MousePt.s.X=point.x;
	MousePt.s.Y=point.y;
	ArcBall.click(&MousePt);// Update Start Vector And Prepare For Dragging
	LButtonSta=TRUE;
	//mouseX=point.x;
	//mouseY=point.y;
	CView::OnLButtonDown(nFlags, point);
}

//鼠标左键up
void CtestviewView::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	LButtonSta=FALSE;
	CView::OnLButtonUp(nFlags, point);
}

//鼠标move
void CtestviewView::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (LButtonSta==TRUE)
	{
	Quat4fT ThisQuat;
	MousePt.s.X=point.x;
	MousePt.s.Y=point.y;
	ArcBall.drag(&MousePt,&ThisQuat);// 更新轨迹球的变量
	Matrix3fSetRotationFromQuat4f(&ThisRot, &ThisQuat);// Convert Quaternion Into Matrix3fT
	Matrix3fMulMatrix3f(&ThisRot, &LastRot);// Accumulate Last Rotation Into This One
	Matrix4fSetRotationFromMatrix3f(&Transform, &ThisRot);
	}
	CView::OnMouseMove(nFlags, point);
}

5、在RenderScene() 函数中,在绘制前,把我们得到的矩阵乘以当前的模型变换矩阵。

         //为arcball添加的旋转矩阵,用以乘以当前的模型变换矩阵
	  glMultMatrixf(Transform.M);//旋转





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值