应用场景
现有三维模型Model(vtx),坐标系中任意朝向。需要将该模型进行绕轴旋转,使得该模型能够基本摆正。
理论介绍
相关旋转的数学理论,可以参考下面链接:[https://www.cnblogs.com/zhoug2020/p/7842808.html].(https://www.cnblogs.com/zhoug2020/p/7842808.html)
示例代码
函数
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; }
根据上面的计算矩阵,下面的代码进行模型的旋转:
/** * @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); } }
函数调用:
// 给出旋转角度和相应的旋转轴 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);