旋转矩阵 - 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);

    }
}
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
欧拉角分解旋转矩阵是将旋转矩阵分解为三个绕不同轴向旋转的角度的过程。在C++中,可以使用以下代码实现: ```c++ #include <iostream> #include <cmath> using namespace std; // 定义旋转矩阵 typedef double Matrix[3][3]; // 定义欧拉角 typedef double Euler[3]; // 将欧拉角转换为旋转矩阵 void euler2matrix(const Euler &euler, Matrix &matrix) { double cx = cos(euler[0]); double sx = sin(euler[0]); double cy = cos(euler[1]); double sy = sin(euler[1]); double cz = cos(euler[2]); double sz = sin(euler[2]); matrix[0][0] = cz * cy; matrix[0][1] = sz * cy; matrix[0][2] = -sy; matrix[1][0] = cz * sy * sx - sz * cx; matrix[1][1] = sz * sy * sx + cz * cx; matrix[1][2] = cy * sx; matrix[2][0] = cz * sy * cx + sz * sx; matrix[2][1] = sz * sy * cx - cz * sx; matrix[2][2] = cy * cx; } // 将旋转矩阵分解为欧拉角 void matrix2euler(const Matrix &matrix, Euler &euler) { euler[1] = asin(-matrix[0][2]); double cy = cos(euler[1]); if (fabs(cy) > 1e-6) { euler[0] = atan2(matrix[1][2] / cy, matrix[2][2] / cy); euler[2] = atan2(matrix[0][1] / cy, matrix[0][0] / cy); } else { euler[0] = atan2(-matrix[2][1], matrix[1][1]); euler[2] = 0; } } // 输出欧拉角 void print_euler(const Euler &euler) { cout << "Yaw: " << euler[0] << " Pitch: " << euler[1] << " Roll: " << euler[2] << endl; } int main() { Matrix matrix; Euler euler = {0, 0, 0}; // 将欧拉角转换为旋转矩阵 euler2matrix(euler, matrix); // 输出旋转矩阵 cout << "Rotation matrix:" << endl; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { cout << matrix[i][j] << " "; } cout << endl; } // 将旋转矩阵分解为欧拉角 matrix2euler(matrix, euler); // 输出欧拉角 cout << "Euler angles:" << endl; print_euler(euler); return 0; } ``` 此代码将欧拉角和旋转矩阵定义为结构体,并提供了将欧拉角转换为旋转矩阵和将旋转矩阵分解为欧拉角的函数。主函数中将欧拉角初始化为0,并输出生成的旋转矩阵和分解出的欧拉角。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值