数学应用 —— 三维模型绕坐标轴旋转

应用场景

  现有三维模型Model(vtx),坐标系中任意朝向。需要将该模型进行绕轴旋转,使得该模型能够基本摆正。

理论介绍

  相关旋转的数学理论,可以参考下面链接:[https://www.cnblogs.com/zhoug2020/p/7842808.html].(https://www.cnblogs.com/zhoug2020/p/7842808.html)

示例代码

  1. 函数void get_M()是生成相应的旋转矩阵

    void get_M(float degree, cv::Point3f axis, cv::Mat roate_matrix)
    {
    	float x = axis.x, y = axis.y, z = axis.z;
    	degree = degree * 3.1492657 / 180;
    	float c = cos(degree);
    	float s = sin(degree);
    
    	cv::Point3f col;
    	roate_matrix.at<float>(0, 0) = x * x * (1 - c) + c;
    	roate_matrix.at<float>(0, 1) = x * y * (1 - c) - z * s;
    	roate_matrix.at<float>(0, 2) = x * z * (1 - c) + y * s;
    
    	roate_matrix.at<float>(1, 0) = x * y * (1 - c) + z * s;
    	roate_matrix.at<float>(1, 1) = y * y * (1 - c) + c;
    	roate_matrix.at<float>(1, 2) = y * z * (1 - c) - x * s;
    
    	roate_matrix.at<float>(2, 0) = x * z * (1 - c) - y * s;
    	roate_matrix.at<float>(2, 1) = y * z * (1 - c) + x * s;
    	roate_matrix.at<float>(2, 2) = z * z * (1 - c) + c;
    	cout << "get_M计算: " << roate_matrix << endl;
    	return;
    }	
    
  2. 根据上面的计算矩阵,下面的代码进行模型的旋转:

    /**
    * @brief 对三维模型进行绕坐标轴进行连续旋转
    * @param angle 待旋转的角度和对应的坐标轴
    * @param vtx   待旋转的三维模型
    *
    * @return 返回旋转后的模型
    *         -NULL
    */
    void Measure::rotate_ALL(vector<pair<int, cv::Point3f>> angle, vector<Pnt3> &vtx)
    {
    	cv::Mat M = cv::Mat::eye(3, 3, CV_32FC1);
    	for (int i = 0; i < angle.size(); i++)
    	{
    		cv::Mat roate_matrix = cv::Mat::eye(3, 3, CV_32FC1);
    		cout << roate_matrix << endl;
    		get_M(angle[i].first, angle[i].second, roate_matrix);  // 形参的rotate_matrix改变,实参的也改变,它们的内存地址是一样的
    		cout << roate_matrix << endl;
    		M = roate_matrix*M;
    	}
    
    	// 输出旋转矩阵
    	//ofstream mm("mm_test12.txt");
    	//for (int i = 0; i < 3; i++)
    	//{
    	//	for (int j = 0; j < 3; j++)
    	//	{
    	//		mm << M.at<float>(i,j) << " ";
    	//	}
    	//	mm << "\n";
    	//}
    	//mm << M << endl;
    
    	float scale = 1.0;
    	for (int i = 0; i < vtx.size(); i++)
    	{
    		cv::Mat V = cv::Mat::ones(3, 1, CV_32FC1);
    		V.at<float>(0, 0) = vtx[i][0] * scale;  // 将模型缩放
    		V.at<float>(1, 0) = vtx[i][1] * scale;
    		V.at<float>(2, 0) = vtx[i][2] * scale;
    
    		//V.at<float>(0, 0) = vtx[i][0];  // 将模型缩放
    		//V.at<float>(1, 0) = vtx[i][1];
    		//V.at<float>(2, 0) = vtx[i][2];
    
    		V = M*V;
    		vtx[i][0] = V.at<float>(0, 0);
    		vtx[i][1] = V.at<float>(1, 0);
    		vtx[i][2] = V.at<float>(2, 0);
    	}
    }
    
  3. 函数调用:

    // 给出旋转角度和相应的旋转轴
    angle.push_back(make_pair(110, cv::Point3f(1, 0, 0)));
    angle.push_back(make_pair(45, cv::Point3f(0, 0, 1)));
    	
    // vtx:三维模型的顶点坐标
    rotate_ALL(angle, vtx);
    

参考资源

  矩阵旋转的公式详细推导

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值