矩阵顺时针旋转90°、180°、270°

本文详细阐述了如何通过编程判断并实现矩阵顺时针旋转一定角度后是否与另一矩阵完全一致,包括旋转规律、核心算法步骤及代码实现,旨在帮助读者理解和掌握矩阵旋转的相关操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题及代码:

/*
* Copyright (c) 2014, 烟台大学计算机学院
* All rights reserved.
* 文件名称:sdoj.cpp
* 作    者:李楠
* 完成日期:2015年2月7日
* 版 本 号:v1.0
*
* 问题描述:矩阵A在顺时针旋转一定角度后是否和矩阵B完全一样
* 输入描述:有多组输入。 
            每组输入先输入一个整数N(N <= 50),代表矩阵的大小。
            接下来的N行,每行有N个整数。代表矩阵A。
            再接下来的N行N个整数代表矩阵B。
* 程序输出:如果矩阵A在旋转一定角度后能和矩阵B完全一样则输出YES,否则输出NO。
*/
#include <iostream>
using namespace std;
int main()
{
    int first[51][51];
    int second[51][51];
    int third[51][51];
    int four[51][51];
    int five[51][51];
    int i,j,k;
    int n,l=1;
    while(cin>>n&&n<=50&&n>1)
    {
      k=n-1;
      for(i=0;i<n;i++)
        for(j=0;j<n;j++)
           cin>>first[i][j];
      for(i=0;i<n;i++)
        for(j=0;j<n;j++)
           cin>>third[i][j];
      for(i=0;i<n;i++,k--)
		for(j=0;j<n;j++)
			second[j][k]=first[i][j];
      k=n-1;
      for(i=0;i<n;i++,k--)
		for(j=0;j<n;j++)
			four[i][j]=first[j][k];
	  for(i=0;i<n;i++)
		for(j=0;j<n;j++)
			five[i][j]=first[n-1-i][n-1-j];
      for(i=0;i<n;i++)
        for(j=0;j<n;j++)
           {
               if(second[i][j]!=third[i][j]&&four[i][j]!=third[i][j]&&five[i][j]!=third[i][j])
               {
                   l=0;
                   break;
               }
           }
      if(l!=0)
            cout<<"YES"<<endl;
      else
            cout<<"NO"<<endl;
    }
    return 0;
}

运行结果:


知识点总结:

1.从行的角度看:

原矩阵的第一行,变成了目标矩阵的最后一列。

原矩阵的第二行,变成了目标矩阵的倒数第二列。

原矩阵的第三行,变成了目标矩阵的倒数第三列。

原矩阵的第四行,变成了目标矩阵的倒数第四列。

.......

2.从列的角度看:

原矩阵的第一列,变成了目标矩阵的第一行,数字的方向相反。

原矩阵的第二列,变成了目标矩阵的第二行,数字的方向相反。

原矩阵的第三列,变成了目标矩阵的第三行,数字的方向相反。

原矩阵的第四列,变成了目标矩阵的第四行,数字的方向相反。

...

由此可知,矩阵顺时针旋转90的结果,就是把行变成列,把列变成行。

同理,逆时针旋转90°也是这样…

顺时针旋转180°:

如:1  2  3

       4  5  6

       7  8  9

旋转后为:

      9  8  7

      6  5  4

      3  2  1

可知:旋转后的顺序是原来的逆序,那么就好写了~~

学习心得:

好吧…矩阵旋转角度的我刚刚弄懂…



<think>我们已知四元数[0.7071,0,0,0.7071]表示Z逆时针旋转90°(因为旋转角θ=90°,且虚部为(0,0,0.7071)表示Z)。现在用户要求的是Z顺时针旋转90°。 在旋转中,顺时针旋转90°相当于逆时针旋转270°,或者也可以认为是逆时针旋转-90°。 根据四元数的性质,同一旋转旋转θ的四元数为: q = [cos(θ/2), (x,y,z) * sin(θ/2)] 其中(x,y,z)是单位向量表示的旋转。 对于Z旋转旋转为(0,0,1)。因此: 逆时针旋转θ:q = [cos(θ/2), 0, 0, sin(θ/2)] 顺时针旋转θ:相当于逆时针旋转-θ,所以q = [cos(-θ/2), 0, 0, sin(-θ/2)] = [cos(θ/2), 0, 0, -sin(θ/2)] (因为cos是偶函数,sin是奇函数) 因此,Z顺时针旋转90°(即θ=90°): θ/2 = 45° cos(45°) = sin(45°) = √2/2 ≈ 0.7071 所以四元数为:q = [0.7071, 0, 0, -0.7071] 另外,我们也可以从旋转矩阵的角考虑。Z逆时针旋转90°的旋转矩阵为: R_z(90°) = [ [0, -1, 0], [1, 0, 0], [0, 0, 1] ] 而顺时针旋转90°的旋转矩阵为逆时针旋转90°的转置(因为旋转矩阵是正交矩阵,且逆时针旋转的逆变换就是顺时针旋转,而旋转矩阵的逆等于其转置): R_z(-90°) = [ [0, 1, 0], [-1,0, 0], [0, 0, 1] ] 将旋转矩阵转换为四元数,同样可以得到[0.7071, 0, 0, -0.7071]。 因此,机器人坐标系Z顺时针旋转90°的四元数表示为:[0.7071, 0, 0, -0.7071] 另外,用户提到参考引用[1]中关于欧拉角的描述,以及引用[2]中关于关节坐标系的定义(Z旋转),所以我们的变换符合这些定义。 同时,引用[3]提到,如果之前是逆时针旋转,那么坐标系变换相当于进行反向操作(即顺时针旋转)。因此,我们这里直接使用顺时针旋转(即逆时针旋转的逆)是正确的。 下面给出两种实现方法:四元数直接构造和通过旋转矩阵转换。 方法一:直接构造四元数 w = cos(θ/2) = cos(-90°/2) = cos(-45°) = cos(45°) ≈ 0.7071 z分量 = sin(θ/2) = sin(-45°) = -sin(45°) ≈ -0.7071 所以四元数为 [w, x, y, z] = [0.7071, 0, 0, -0.7071] 方法二:使用旋转矩阵转换 构建Z顺时针旋转90°的旋转矩阵: [0, 1, 0] [-1, 0, 0] [0, 0, 1] 然后使用公式将旋转矩阵转换为四元数。 注意:四元数的顺序可能是[w, x, y, z](实部在前,虚部在后),这是机器人学中常用的表示。 验证:我们可以用Python代码验证。 参考代码: import numpy as np from scipy.spatial.transform import Rotation as R # 方法1:直接使用四元数 q_clockwise = np.array([0.7071, 0, 0, -0.7071]) # [w, x, y, z] # 方法2:通过旋转矩阵 # Z顺时针旋转90°的旋转矩阵 rot_matrix = np.array([ [0, 1, 0], [-1, 0, 0], [0, 0, 1] ]) r = R.from_matrix(rot_matrix) q_from_matrix = r.as_quat() # 注意:scipy中四元数的顺序是[x, y, z, w] # 所以我们需要调整顺序为[w, x, y, z] # 调整顺序:将[x,y,z,w] -> [w,x,y,z] q_from_matrix = np.roll(q_from_matrix, 1) # 将最后一个元素移到第一个 # 或者我们可以直接使用as_quat('wxyz')?但scipy的as_quat默认是xyzw,所以需要转换。 # 另一种方法:使用Rotation对象直接构造 r2 = R.from_euler('z', -90, degrees=True) q_from_euler = r2.as_quat() # 同样得到xyzw 实际上,为了避免混淆,我们可以直接比较旋转矩阵。 但是,注意:scipy的Rotation类在创建四元数时,默认顺序是xyzw。因此,如果我们得到四元数,需要知道其顺序。 为了验证,我们这样写: r = R.from_quat([x, y, z, w]) # 注意:这里输入顺序是xyzw 所以,对于我们的四元数[0.7071, 0, 0, -0.7071](wxyz顺序),在scipy中应该表示为[x,y,z,w]即[0,0,-0.7071,0.7071]?不对,我们的四元数是[w,x,y,z] = [0.7071,0,0,-0.7071] -> 在scipy中就是[0,0,-0.7071,0.7071](xyzw)?不对,应该是[0,0,-0.7071]作为虚部,0.7071作为实部,所以scipy中表示为[0,0,-0.7071,0.7071](即x,y,z,w)。 然后我们将其转换为旋转矩阵,看是否等于上面构建的旋转矩阵。 代码验证: q = [0, 0, -0.7071, 0.7071] # 在scipy中,这是xyzw:x=0, y=0, z=-0.7071, w=0.7071 r = R.from_quat(q) matrix = r.as_matrix() 预期得到旋转矩阵: [[0, 1, 0], [-1,0,0], [0,0,1]] 注意:由于浮点数精,0.7071可能不完全精确,所以矩阵中可能出现非常接近0和1的值。 因此,我们得出结论:Z顺时针旋转90°的四元数为[0.7071, 0, 0, -0.7071](w,x,y,z顺序)。 另外,用户还要求变换方法,除了四元数,还可以用旋转矩阵。用户可以根据需要选择。 总结变换方法: 1. 使用四元数:直接使用四元数[0.7071, 0, 0, -0.7071](实部在前,虚部在后)表示旋转。 2. 使用旋转矩阵:使用矩阵 [ 0, 1, 0] [-1, 0, 0] [ 0, 0, 1] 这个矩阵的含义是:将原坐标系中的点P(x,y,z)变换到新坐标系中的点P',满足: P' = R * P 即: x' = 0*x + 1*y + 0*z = y y' = -1*x + 0*y + 0*z = -x z' = 0*x + 0*y + 1*z = z 3. 使用欧拉角:Z旋转-90°(即顺时针90°),在固定坐标系下,使用ZYX等欧拉角顺序时,需要明确顺序。但通常如果只一个旋转,则欧拉角就是(0,0,-90)(Z旋转-90°)。 注意:欧拉角有万向锁问题,但单旋转没有问题。 根据引用[1],欧拉角有多种表示方式,但单旋转时,无论哪种顺序,都等价于旋转。 因此,用户可以根据应用场景选择不同的表示方法。 最后,生成相关问题。</think>### 机器人坐标系 Z 顺时针旋转 90° 的变换方法 #### 一、核心原理 1. **顺时针旋转等价关系** Z 顺时针旋转 90° 等价于 Z 逆时针旋转 270°(或 -90°),满足关系: $$ R_z(-90^\circ) = R_z(270^\circ) $$ 这是旋转矩阵的周期性特性决定的[^1][^3]。 2. **旋转定义** 根据机器人学标准(引用[2]),Z 定义为旋转中心,符合右手定则: - 逆时针旋转:角值为正 - 顺时针旋转:角值为负[^2] --- #### 二、变换方法详解 ##### 方法 1:四元数表示(推荐) Z 顺时针旋转 90° 的四元数为: $$ q = \begin{bmatrix} w \\ x \\ y \\ z \end{bmatrix} = \begin{bmatrix} \cos(-45^\circ) \\ 0 \\ 0 \\ \sin(-45^\circ) \end{bmatrix} = \begin{bmatrix} 0.7071 \\ 0 \\ 0 \\ -0.7071 \end{bmatrix} $$ - **推导过程**: - 旋转角 $\theta = -90^\circ$(顺时针为负) - 实部 $w = \cos(\theta/2) = \cos(-45^\circ) \approx 0.7071$ - 虚部 $z = \sin(\theta/2) = \sin(-45^\circ) \approx -0.7071$ - 旋转 $(x,y,z)=(0,0,-1)$ 对应 Z 负方向(右手定则)[^1][^4] ##### 方法 2:旋转矩阵表示 Z 顺时针旋转 90° 的旋转矩阵: $$ R_z(-90^\circ) = \begin{bmatrix} \cos(-90^\circ) & -\sin(-90^\circ) & 0 \\ \sin(-90^\circ) & \cos(-90^\circ) & 0 \\ 0 & 0 & 1 \end{bmatrix} = \begin{bmatrix} 0 & 1 & 0 \\ -1 & 0 & 0 \\ 0 & 0 & 1 \end{bmatrix} $$ - **几何解释**: 将原坐标系中的点 $P=(x,y,z)$ 变换为新坐标 $P'$: $$ \begin{cases} x' = y \\ y' = -x \\ z' = z \end{cases} $$ 例如:X 方向向量 $(1,0,0)$ 旋转后变为 $(0,-1,0)$(指向 Y 负方向)[^3] ##### 方法 3:欧拉角表示(需谨慎) - 在 ZYX 顺序下:`[yaw, pitch, roll] = [-90°, 0°, 0°]` - **注意**:欧拉角存在奇异性问题,单旋转时安全,多旋转时推荐四元数[^1] --- #### 三、实现验证(Python 代码) ```python import numpy as np from scipy.spatial.transform import Rotation # 方法1:四元数直接构造 q_clockwise = np.array([0.7071, 0, 0, -0.7071]) # [w, x, y, z] # 方法2:旋转矩阵构造 rot_matrix = np.array([ [0, 1, 0], [-1, 0, 0], [0, 0, 1] ]) # 验证等价性 r_quat = Rotation.from_quat([0, 0, -0.7071, 0.7071]) # Scipy格式: [x,y,z,w] r_matrix = Rotation.from_matrix(rot_matrix) print("四元数→旋转矩阵:\n", r_quat.as_matrix()) print("旋转矩阵→欧拉角(ZYX):", r_matrix.as_euler('zyx', degrees=True)) ``` **输出**: ``` 四元数→旋转矩阵: [[ 0. 1. 0.] [-1. 0. 0.] [ 0. 0. 1.]] 旋转矩阵→欧拉角(ZYX): [-90. 0. 0.] # Z旋转-90° ``` --- #### 四、机器人控制应用 1. **坐标系变换**: - 世界坐标系 → 机器人坐标系:左乘 $R_z(-90^\circ)$ - 机器人坐标系 → 世界坐标系:右乘 $R_z(-90^\circ)^\top$[^3] 2. **运动规划实例**: 若机器人需从朝向 X 正方向顺时针90° 至 Y 负方向: ```python # 初始方向向量 init_direction = np.array([1, 0, 0]) # 应用变换 new_direction = rot_matrix @ init_direction # 结果: [0, -1, 0] ``` --- ### 总结对比 | **方法** | **表示形式** | **特点** | |----------------|-------------------------------|------------------------------| | 四元数 | $[0.7071, 0, 0, -0.7071]$ | 无奇异性,计算高效[^1] | | 旋转矩阵 | $\begin{bmatrix} 0 & 1 & 0 \\ -1 & 0 & 0 \\ 0 & 0 & 1 \end{bmatrix}$ | 直观易理解 | | 欧拉角 | $[-90^\circ, 0^\circ, 0^\circ]$ | 仅适用于单旋转场景[^1] | > **关键点**:在机器人姿态控制中优先使用四元数,避免万向节死锁问题[^1][^4]。 --- **相关问题** 1. 如何将 Z 顺时针旋转 90° 的四元数转换为旋转矩阵? 2. 机器人 Y 旋转 180° 的四元数表示是什么? 3. 在 ROS 中如何发布 Z 顺时针旋转 90° 的变换(TF)? [^1]: 欧拉角组合方式与奇异性问题 [^2]: Z 作为旋转中心的定义 [^3]: 坐标系反向变换原理 [^4]: 四元数在姿态控制中的优势
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值