绕任一向量旋转矩阵计算思考与实现

article/2025/10/10 13:42:38

欢迎关注更多精彩
关注我,学习常用算法与数据结构,一题多解,降维打击。

问题提出

请添加图片描述

如图所示,在空间中有一向量A,问点O绕A方向逆时针旋转角度α的矩阵如何表示。

问题分析

问题化规

直接去构造一个矩阵是比较困难的。
我们知道绕X,Y,Z三个方向的旋转矩阵是可以直接给出的。分别如下。
角度根据右手定则绕各轴逆时针旋转θ

绕 X 轴表示为: X ( θ ) = [ 1 0 0 0 c o s θ − s i n θ 0 s i n θ c o s θ ] 绕X轴表示为:X(\theta)=\begin{bmatrix}1&0&0\\0&cos\theta&-sin\theta\\0&sin\theta&cos\theta\end{bmatrix} X轴表示为:X(θ)= 1000cosθsinθ0sinθcosθ

绕 Y 轴表示为: Y ( θ ) = [ c o s θ 0 s i n θ 0 1 0 - s i n θ 0 c o s θ ] 绕Y轴表示为:Y(\theta)=\begin{bmatrix}cos\theta&0&sin\theta\\0&1&0\\-sin\theta&0&cos\theta\end{bmatrix} Y轴表示为:Y(θ)= cosθ0sinθ010sinθ0cosθ

绕 Z 轴表示为: Z ( θ ) = [ c o s θ − s i n θ 0 s i n θ c o s θ 0 0 0 1 ] 绕Z轴表示为:Z(\theta)=\begin{bmatrix}cos\theta&-sin\theta&0\\sin\theta&cos\theta&0\\0&0&1\end{bmatrix} Z轴表示为:Z(θ)= cosθsinθ0sinθcosθ0001

一个直观的想法就是先把向量A转到与X轴相同的方向。
也就是沿着A与X叉乘方向旋转β,如图所示。

请添加图片描述

图中向量M分别与向量A,向量X垂直,可知向量M处于平面YOZ中。

设上述旋转为RM

那么O点最终结果可以表示如下

O ′ = R M − 1 ⋅ X ( α ) ⋅ R M ⋅ O O'=RM^{-1}\cdot X(\alpha) \cdot RM\cdot O O=RM1X(α)RMO

由于向量M并不与X,Y,Z轴中任意一轴平行,所以还是不好直接给出RM表达式。

但是向量M处于平面YOZ,可以行将向量M旋转到与Y轴平行,再按照上述同理操作。设旋转到Y轴矩阵为RY。

R M = R Y − 1 ⋅ Y ( − β ) ⋅ R Y RM=RY^{-1}\cdot Y(-\beta)\cdot RY RM=RY1Y(β)RY

= X ( − γ ) − 1 ⋅ Y ( − β ) ⋅ X ( − γ ) =X(- \gamma)^{-1}\cdot Y(-\beta)\cdot X(- \gamma) =X(γ)1Y(β)X(γ)

致此,所有旋转都转化成和X轴,Y轴相关的旋转。

求解过程

RY计算。

RY的作用是把M转到与Y轴相同位置。

M可以由A与X叉乘得到

设 M = ( 0 , M y , M z ) , 由于 M 处于 Y O Z 平面,可知 M x = 0 设M=(0, My, Mz), 由于M处于YOZ平面,可知Mx=0 M(0,My,Mz),由于M处于YOZ平面,可知Mx=0

请添加图片描述
由上图可以知

R Y = X ( − γ ) = X ( γ ) T RY=X(-\gamma)=X(\gamma)^T RY=X(γ)=X(γ)T

= [ 1 0 0 0 c o s γ − s i n γ 0 s i n γ c o s γ ] T =\begin{bmatrix}1&0&0\\0&cos\gamma&-sin\gamma\\0&sin\gamma&cos\gamma\end{bmatrix}^T = 1000cosγsinγ0sinγcosγ T

= [ 1 0 0 0 c o s γ s i n γ 0 - s i n γ c o s γ ] =\begin{bmatrix}1&0&0\\0&cos\gamma&sin\gamma\\0&-sin\gamma&cos\gamma\end{bmatrix} = 1000cosγsinγ0sinγcosγ

= [ 1 0 0 0 M y M z 0 - M z M y ] =\begin{bmatrix}1&0&0\\0&My&Mz\\0&-Mz&My\end{bmatrix} = 1000MyMz0MzMy

R Y − 1 = R Y T RY^{-1}=RY^T RY1=RYT

有了RY后,可以先将A乘上RY。这样A就会被旋转到平面ZOX上来。

A ′ = R Y ⋅ A = ( A x ′ , 0 , A z ′ ) A' = RY\cdot A = (Ax',0, Az') A=RYA=(Ax,0,Az)

同理,

R X = Y ( − β ) = Y ( β ) T RX=Y(-\beta) = Y(\beta)^T RX=Y(β)=Y(β)T

= [ c o s β 0 − s i n β 0 1 0 s i n β 0 c o s β ] = \begin{bmatrix}cos\beta&0&-sin\beta\\0&1&0\\sin\beta&0&cos\beta\end{bmatrix} = cosβ0sinβ010sinβ0cosβ

= [ A x ′ 0 A z ′ 0 1 0 - A z ′ 0 A x ′ ] = \begin{bmatrix}Ax'&0&Az'\\0&1&0\\-Az'&0&Ax'\end{bmatrix} = Ax0Az010Az0Ax

旋转后的P’

P ′ = R Y − 1 ⋅ R X − 1 ⋅ X ( α ) ⋅ R X ⋅ R Y ⋅ P P'=RY^{-1}\cdot RX^{-1}\cdot X(\alpha)\cdot RX\cdot RY\cdot P P=RY1RX1X(α)RXRYP

代码实现

  • 代码链接点击前往
  • 代码链接点击前往
  • 代码链接点击前往

namespace acamcad {const double pi = acos(-1);using Point = Eigen::Vector3d;class RigidRTMatrix {private:Eigen::Matrix3d mat;Eigen::Vector3d trans;public:RigidRTMatrix(Point start, Point end, double theta) {cout << "generate RigidRTMatrix 2" << endl;Eigen::Vector3d v = end - start;cout << "v:" << v << endl;cout << "angle:" << theta << endl;assert(!v.isZero());// Point::Zero();v.normalize();Eigen::Vector3d X(1,0,0);Eigen::Vector3d m = v.cross(X);// todo m=0时特殊处理if (m.isZero()) {if (v.dot(X) > 0) m = { 0,1,0 }; // 直接等于Y轴else m = { 0,-1,0 }; // 等于Y轴的反轴}auto RY = GetRY(m);// 将v 旋转至ZOX 平面。auto vZOX = RY * v;auto RX = GetRX(vZOX);auto Xrotate = GetXRotate(theta);mat = RY.transpose() * RX.transpose() * Xrotate * RX * RY;cout << "mat create :" << mat << endl;}RigidRTMatrix() {}// 给定YOX平面上的单位M向量,将其旋转到Y轴上。Eigen::Matrix3d GetRY(Eigen::Vector3d m) {assert(!m.isZero());m.normalize();Eigen::Matrix3d RY;RY.setIdentity();RY(1, 1) = m.y();RY(1, 2) = m.z();RY(2, 1) = -m.z();RY(2, 2) = m.y();return RY;}// 给定ZOX平面上的单位M向量,将其旋转到X轴上。Eigen::Matrix3d GetRX(Eigen::Vector3d m) {assert(!m.isZero());m.normalize();Eigen::Matrix3d RX;RX.setIdentity();RX(0, 0) = m.x();RX(0, 2) = m.z();RX(2, 0) = -m.z();RX(2, 2) = m.x();return RX;}// 给定ZOX平面上的单位M向量,将其旋转到X轴上。Eigen::Matrix3d GetXRotate(double theta) {double rad = theta / 180 * pi;Eigen::Matrix3d X;X.setIdentity();X(1, 1) = cos(rad);X(1, 2) = -sin(rad);X(2, 1) = sin(rad);X(2, 2) = cos(rad);return X;}double angleMod(double theta) {while (theta < -180)theta += 360;while (theta > 180)theta -= 360;return theta;}Point Trans(Point &a) {return mat * a;}friend static RigidRTMatrix operator*(RigidRTMatrix& a, RigidRTMatrix& b) {RigidRTMatrix multi;multi.mat = a.mat * b.mat;return multi;}};
}

数据测试

测试代码链接点击前往

测试代码链接点击前往

测试代码链接点击前往

效果展示


往外的三条线分别是X,Y,Z中间那么是向量(1,1,1),红点是(0.5,0,0.5)
绿点是红点沿(1,1,1)逆时针转90度结果。


本人码农,希望通过自己的分享,让大家更容易学懂计算机知识。

欢迎添加我的公众号,进群交流。


http://chatgpt.dhexx.cn/article/81jxH2ta.shtml

相关文章

echarts 象形柱状图+标注图形

代码&#xff1a; let myChart echarts.init(this.$refs.myChart);let option {graphic: [ // echarts整体的背景图{type: image, // 图形元素类型id: logo, // 更新或删除图形元素时指定更新哪个图形元素&#xff0c;如果不需要用可以忽略。right: center, // 根据父元素进…

【JEECG技术文档】JEECG平台对外接口JWT应用文档V3.7.2

一、 接口方式 接口调用采用http协议&#xff0c;rest请求方式&#xff1b; 二、 接口安全 接口安全采用Json web token (JWT)机制&#xff0c;基于token的鉴权机制. 1. 机制说明 基于token的鉴权机制类似于http协议也是无状态的&#xff0c;它不需要在服务端去保留用户的认证…

轻量级前端MVVM框架avalon - 整体架构

官网提供架构图 单看这个图呢,还木有说明,感觉有点蛋疼,作者的抽象度太高了,还好在前面已经大概分析过了执行流程 如图 左边是View视图,我们就理解html结构,换句话就是说用户能看到的界面,渲染页面&#xff0c;绑定事件&#xff0c;切换类名&#xff0c;什么脏活都揽右边是View…

下载kaggle数据集出现的一系列问题

下载kaggle数据集出现了如下情况 按照下面的帖子安装kaggle库 https://www.cnblogs.com/shuaishuaidefeizhu/p/15170305.html 1.windowsR 打开命令提示符cmd&#xff0c;输入pip install kaggle --user 2.在C:\Users\&#xff08;用户名&#xff09;文件下会生成一个.kaggle文…

CT图像重建算法------射线驱动投影模型

在模拟CT扫描过程中被测物体保持静止不动&#xff0c;射线源与探测器绕Z轴做逆时针旋转&#xff0c;每隔一定角度进行一次投影数据的计算&#xff0c;而计算方法则取决于采用什么样的投影算法。本文主要介绍了投影算法的分类&#xff0c;并详细描述了射线驱动算法中的joseph算法…

尤雨溪告诉你为什么Vue比yox优秀

2019年6月8日来自全球各地的开发者齐聚上海交通大学文治堂&#xff0c;VueConf 2019 在上海成功举办。 VUE 3.0 最新进展 更快 使用 Object.defineProperty -> Proxy 速度 提升了1倍 VUE3.0 将 Virtual DOM 重构 速度 提升 6 倍 牛逼吧 &#xff01;&#xff01;&…

kubernetes的初认识

1.先谈容器。 一个“容器”&#xff0c;实践上是一个由Linux Namespace、Linux Cgroups 和 rootfs 三种技术构建出来的进程的隔离环境。 一个正在运行的linux容器&#xff0c;其实可以被“一分为二”地看待&#xff1a; 一组联合挂载在/var/lib/docker/overlay2下的rootfs&a…

KubeSphere简介,功能介绍,优势,架构说明及应用场景

目录 一、KuberSphere简介 1.1 功能介绍 1.2 Kubernetes 资源管理 1.3 微服务治理 1.4 多租户管理 1.5 DevOps 工程 1.6 Source to Image 1.7 多维度监控 1.8 自研多租户告警系统 1.9 日志查询与收集 1.10 应用管理与编排 1.11 基础设施管理 1.12 多存储类型支持…

云原生钻石课程 | 第4课:Kubernetes存储架构原理深度剖析(上)

点击上方“程序猿技术大咖”&#xff0c;关注并选择“设为星标” 回复“加群”获取入群讨论资格&#xff01; 本篇文章来自《华为云云原生王者之路训练营》钻石系列课程第4课&#xff0c;由云原生存储解决方案Everest2.0的架构设计专家Jabin主讲&#xff0c;详细介绍云原生存储…

1.k8s基本使用(测试加分)

测试为什么要学习容器技术及k8s k8s不是运维的专属技术 随着互联网技术的发展&#xff0c;架构也已经从单体架构发展到容器云( “微服务 k8s” 完美结合) 很多人认为&#xff0c;k8s只是运维需要掌握的技术&#xff0c;讲真&#xff0c;测试和运维、开发都有技术交集 所以&…

Kubernetes 持久化存储(Pod Volumes,PV和PVC)

一、Volumes 介绍 Pod Volumes 首先来看一下 Pod Volumes 的使用场景&#xff1a; 场景一&#xff1a;如果 pod 中的某一个容器在运行时异常退出&#xff0c;被 kubelet 重新拉起之后&#xff0c;如何保证之前容器产生的重要数据没有丢失&#xff1f;场景二&#xff1a;如果…

面试题引出的知识点整理

1、自旋锁&可重复锁&公平锁&共享锁&分段锁你都知道吗? 2、无锁&偏向锁&轻量级锁&重量级锁如何膨胀升级? 3、Lock底层AQS实现与Synchronized底层实现异同&#xff1f; 4、LongAdder的分段CAS优化机制如何设计的&#xff1f; 5、Java多线程内存模型…

云集成,给超大规模K8s运维带来的丝滑体验

根据IDC统计&#xff0c;未来五年容器基础架构软件市场将以超过40%的复合增长率爆发式增长&#xff0c;行业也从互联网向更多的传统行业渗透&#xff0c;比如金融、政府、电信&#xff0c;制造和能源等行业。 近年来&#xff0c;随着云技术的日益普及&#xff0c;越来越多的企…

Spring

目录 1.spring介绍 spring中的两个核心概念 1.1 IoC 1.2 AoP 1.3 Spring的优点 1.4 Spring工程构建 1.4.1 Maven Spring 依赖 1.4.2 Spring核心配置文件编写 1.4.2.1 完成控制反转以及依赖注入 1.4.2.2 测试 1.4.2.3 Spring中的IOC 产生的对象是否是单例模式 1.5 B…

动静分离 与 热点缓存

动静分离 让系统“快”起来&#xff1a;1、提高单次请求的效率2、减少没必要的请求 “动静分离”就是瞄着这个大方向去的。所谓“动静分离”&#xff0c;其实就是把用户请求的数据&#xff08;如HTML页面&#xff09;划分为“动态数据”和“静态数据”。简单来说&#xff0c;“…

天猫浏览型应用的CDN静态化架构演变

转载自&#xff1a;http://zhu-zhiguo.iteye.com/blog/2145496 在天猫双11活动中&#xff0c;商品详情、店铺等浏览型系统&#xff0c;通常会承受超出日常数倍甚至数十倍的流量冲击。随着历年来双11流量的大幅增加&#xff0c; 每年这些浏览型系统都要面临容量评估、硬件扩容、…

java 确保线程安全_确保不安全感

java 确保线程安全 33岁的克雷格斯宾塞&#xff08;Craig Spencer&#xff09;在治疗埃博拉病毒患者后于10月17日从非洲返回美国。 几天后&#xff0c;他的埃博拉病毒呈阳性React。 每个人&#xff08;尤其是周围的人&#xff09;和纽约人都感到关切。 纽约市市长走到媒体前&am…

经验:一个秒杀系统的设计思考

前言 秒杀大家都不陌生。自2011年首次出现以来&#xff0c;无论是双十一购物还是 12306 抢票&#xff0c;秒杀场景已随处可见。简单来说&#xff0c;秒杀就是在同一时刻大量请求争抢购买同一商品并完成交易的过程。 从架构视角来看&#xff0c;秒杀系统本质是一个高性能、高一…

Java调用C++/C

Java调用C/C有3中方式&#xff1a;JNI、JNA、JNative。 注&#xff1a;1、个人觉得还是JNA的方式最好。 2、Java和C/C交互的难点在于数据结构的对应 3、java不可以直接调用C#代码&#xff0c;C#代码需要托管 JNI &#xff08;Android调用&#xff0c;普通java类似&#xff09;…

kubernetes 静态存储与动态存储

静态存储 Kubernetes 同样将操作系统和 Docker 的 Volume 概念延续了下来&#xff0c;并且对其进一步细化。Kubernetes 将 Volume 分为持久化的 PersistentVolume 和非持久化的普通 Volume 两类。为了不与前面定义的 Volume 这个概念产生混淆&#xff0c;后面特指 Kubernetes …