arcball 鼠标 相机转动

利用arcball原理来是相机在某个半径旋转,而且相机的目标方向永远指向最初的目标方向,就是类似于相机在球面上旋转并且始终指向球心。
直接上程序流图和代码。

arcball原理还有相关的旋转矩阵在上一篇文章有介绍:这里
程序流图:

在这里插入图片描述

主函数:
    /*
    arcBallRotate 函数说明:
    给定单位化后,鼠标在屏幕上的偏移量,计算在arcball原理下,相机实际位置的变换,并改变相机的实际位置

    参数说明:
    double x : x方向偏移量
    double y : y方向便宜量
    */
void Camera::arcBallRotate(double x, double y)
{
   
	//创建在相机坐标系下的旋转轴和旋转角度
	arma::vec3 axisVec;
	double theta;
	arcball(x, y, axisVec, theta);

	//计算世界坐标系下的旋转轴
	arma::vec3 worldAxis = cameraToWorldCoord(axisVec);
	
	//构建世界坐标系的坐标系
	Axis axis;
	axis.position = target;
	axis.direction = worldAxis;

	//在世界坐标系下旋转theta角,并得到新的相机位置
	this->position = this->axisRotateTheta(axis, theta, position);
}
/* 
    arcball 函数说明:
    在单位化下,计算屏幕中鼠标移动的偏移量,在单位球上产生的位置变换,并且用旋转轴和旋转角表示
    
    参数说明:
    double x 范围输入0.0 - 1.0;表示在相机坐标系下x方向偏移量
    double y 范围输入0.0 - 1.0;表示在相机坐标系下y方向的偏移量
    arma::vec3 &axisVec 经过计算后返回的旋转轴方向向量,如果计算失败返回的就是输入值
    double &thete 经过计算后旋转的角度,若计算失败返回输入值
    
    函数返回值说明:
    如果返回true,则表示计算成功,否则表示计算失败
    */
bool Camera::arcball(double x, double y, arma::vec3& axisVec, double& theta)
{
      //检查x的范围是否符合要求
	if ((x > 1.0) || (x < -1.0))
	{
   
		return false;
	}
	
	//检查y的范围是否符合要求
	if ((y > 1.0) || (y < -1.0))
	{
   
		return false;
	}

	double z = sqrt((1 - x * x - y * y));//arcball原理计算Z

	arma::vec3 startPoint({
    0.0,0.0,1.0 });//相机在相机坐标系下鼠标移动前的位置
	arma::vec3 endPoint({
   x,y,z});//相机在相机坐标系下鼠标移动后的位置

	axisVec = arma::normalise(arma::cross(startPoint, endPoint));//得到归一化的叉乘向量,也即旋转轴向量

	theta = acos(arma::norm_dot(startPoint, endPoint
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值