旋转矩阵 - C++

题目描述

任意输入两个9阶以下矩阵,要求判断第二个是否是第一个的旋转矩阵,如果是,输出旋转角度(0、90、180、270),如果不是,输出-1。 要求先输入矩阵阶数,然后输入两个矩阵,每行两个数之间可以用任意个空格分隔。行之间用回车分隔,两个矩阵间用任意的回车分隔。

输入描述:

输入有多组数据。
每组数据第一行输入n(1<=n<=9),从第二行开始输入两个n阶矩阵。

输出描述:

判断第二个是否是第一个的旋转矩阵,如果是,输出旋转角度(0、90、180、270),如果不是,输出-1。
如果旋转角度的结果有多个,则输出最小的那个。

示例1

输入

3
1 2 3
4 5 6
7 8 9
7 4 1
8 5 2
9 6 3

输出

90

分析

不要看到旋转矩阵就懵了,它没有那么复杂的求任意角度的旋转矩阵,只是0 90 180 270 四种,方方正正的矩阵旋转方方正正的角度而已。这样就只是找旋转前后坐标间的关系,就非常简单了,这题没说清楚是按顺时针旋转,否则的话应该不存在270这一答案

代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<cmath>

using namespace std;
int mat1[11][11], mat2[11][11];

int main()
{
    int n;
    while (cin>>n)
    {
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                scanf("%d", &mat1[i][j]);
        bool flag = true;
        int angle = -1;
        // if 0
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
            {
                scanf("%d", &mat2[i][j]);
                if (mat2[i][j] != mat1[i][j])flag = false;
            }
        if (flag == true)angle = 0;
        else {
        //if 90
            flag = true;
            for(int i = 0;i<n;i++)
                for (int j = 0; j < n; j++)
                {
                    if (mat1[i][j] != mat2[j][n - 1 - i]) { flag = false; break; }
                }
            if (flag == true) angle = 90;
            else {
            //if 270 
                flag = true;
                for (int i = 0; i<n; i++)
                    for (int j = 0; j < n; j++)
                    {
                        if (mat1[i][j] != mat2[n-1-j][i]) { flag = false; break; }
                    }
                if (flag == true)angle = 270;
                else {
                //if 180 
                    flag = true;
                    for (int i = 0; i<n; i++)
                        for (int j = 0; j < n; j++)
                        {
                            if (mat1[i][j] != mat2[n - 1 - i][n-1-j]) { flag = false; break; }
                        }
                    if (flag == true)angle = 180;
                    else {
                        angle = -1;
                    }
                }
            }
        }

        printf("%d\n", angle);

    }
}
### 三维旋转的构建原理 在三维空间中,旋转可以通过欧拉角来描述,通常表示为绕X轴、Y轴和Z轴的旋转角度。这些角度分别记为 $\theta_x$、$\theta_y$ 和 $\theta_z$。每个轴的旋转都可以用一个对应的旋转矩阵表示,最终的旋转矩阵可以通过这些基本矩阵的乘积得到。 绕X轴旋转矩阵 $R_x$ 为: $$ R_x(\theta_x) = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos(\theta_x) & -\sin(\theta_x) \\ 0 & \sin(\theta_x) & \cos(\theta_x) \end{bmatrix} $$ 绕Y轴旋转矩阵 $R_y$ 为: $$ R_y(\theta_y) = \begin{bmatrix} \cos(\theta_y) & 0 & \sin(\theta_y) \\ 0 & 1 & 0 \\ -\sin(\theta_y) & 0 & \cos(\theta_y) \end{bmatrix} $$ 绕Z轴旋转矩阵 $R_z$ 为: $$ R_z(\theta_z) = \begin{bmatrix} \cos(\theta_z) & -\sin(\theta_z) & 0 \\ \sin(\theta_z) & \cos(\theta_z) & 0 \\ 0 & 0 & 1 \end{bmatrix} $$ 最终的旋转矩阵 $R$ 可以通过矩阵乘法得到,通常顺序为 $R = R_z \cdot R_y \cdot R_x$。这种顺序对应于先绕X轴旋转,然后绕Y轴,最后绕Z轴[^2]。 ### C++实现 在C++中,可以使用 `Eigen` 库来处理矩阵运算。以下是一个基于欧拉角构建旋转矩阵的实现示例: ```cpp #include <Eigen/Dense> #include <cmath> #include <iostream> Eigen::Matrix3d eulerAnglesToRotationMatrix(const Eigen::Vector3d& angles) { double theta_x = angles(0); double theta_y = angles(1); double theta_z = angles(2); // 构建绕X轴的旋转矩阵 Eigen::Matrix3d R_x; R_x << 1, 0, 0, 0, std::cos(theta_x), -std::sin(theta_x), 0, std::sin(theta_x), std::cos(theta_x); // 构建绕Y轴的旋转矩阵 Eigen::Matrix3d R_y; R_y << std::cos(theta_y), 0, std::sin(theta_y), 0, 1, 0, -std::sin(theta_y), 0, std::cos(theta_y); // 构建绕Z轴的旋转矩阵 Eigen::Matrix3d R_z; R_z << std::cos(theta_z), -std::sin(theta_z), 0, std::sin(theta_z), std::cos(theta_z), 0, 0, 0, 1; // 计算最终的旋转矩阵 Eigen::Matrix3d R = R_z * R_y * R_x; return R; } int main() { // 输入欧拉角(以弧度为单位) Eigen::Vector3d angles(M_PI / 4, M_PI / 6, M_PI / 3); // 例如:45度, 30度, 60度 // 计算旋转矩阵 Eigen::Matrix3d rotationMatrix = eulerAnglesToRotationMatrix(angles); // 输出旋转矩阵 std::cout << "Rotation Matrix:\n" << rotationMatrix << std::endl; return 0; } ``` ### 代码说明 - **输入**:一个包含三个角度的向量,分别表示绕X轴、Y轴和Z轴的旋转角度(以弧度为单位)。 - **输出**:一个 $3 \times 3$ 的旋转矩阵- **实现**:代码中分别构建了绕X轴、Y轴和Z轴的旋转矩阵,并通过矩阵乘法得到最终的旋转矩阵。 ### 注意事项 - **旋转顺序**:上述代码假设旋转顺序为Z-Y-X,即先绕X轴旋转,然后绕Y轴,最后绕Z轴。不同的旋转顺序会导致不同的旋转矩阵[^2]。 - **角度单位**:输入的角度应为弧度。如果使用角度,需要将其转换为弧度。 - **Eigen库**:代码中使用了 `Eigen` 库进行矩阵运算,确保在编译时链接了 `Eigen` 库。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值