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

应用场景

  现有三维模型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);
    

参考资源

  矩阵旋转的公式详细推导

    原文作者:X_Imagine
    原文地址: https://blog.csdn.net/kxh123456/article/details/114303265
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞