从某一点出发沿任意一方向旋转矩阵计算思考与实现

article/2025/10/10 13:40:22

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

上期讲到
绕任一向量旋转矩阵计算思考与实现
点击前往
点击前往

问题提出

之前讲到绕任一向量旋转矩阵实现,原来的向量都是从原点出发,现在把出发点改变成任意一点。

请添加图片描述

除了需要计算旋转矩阵,还可以支持2个旋转矩阵的乘法操作。就是2个旋转矩阵依次作用以后的一个综合结果。

问题分析

从某点出发沿某一方向旋转实现

从原点出发的旋转是已经实现的,我的思路是把坐标系统一平移一个(-x0, -y0,-z0),然后作用旋转矩阵,最后再平移回去。

用公式表示, RT1表示旋转矩阵,O1表示出发点。

P ′ = R T 1 ⋅ ( P − O 1 ) + O 1 ( 1 ) P' = RT1\cdot(P-O1)+O1 (1) P=RT1(PO1)+O11

既我们只要用一个旋转矩阵RT加一个出发点O就可以表示这个旋转动作。那么如果是2个旋转动作叠加怎么去用一个旋转动作来表示呢。

旋转相乘

有一种方法是用奇次矩阵来表示一个平移和旋转的组合,然后矩阵可以相乘,但是这种方式需要用到4*4的矩阵效率上没有3*3的矩阵来得高。

我这边通过公式推导得到一种新的表示方法。

首先对式子(1)进行展开再合并同类项得到

P ′ = R T 1 ⋅ P + ( I − R T 1 ) ⋅ O 1 P'=RT1\cdot P+(I-RT1)\cdot O1 P=RT1P+(IRT1)O1

( I − R T 1 ) ⋅ O 1 是一个常量, (I-RT1)\cdot O1 是一个常量, (IRT1)O1是一个常量,

即只要一个表示形如 R T ⋅ P + Q ( Q 是一个常量 ) 的形式, 即只要一个表示形如 RT\cdot P+Q(Q是一个常量)的形式, 即只要一个表示形如RTP+Q(Q是一个常量)的形式,

就可用一个矩阵加一个出发点的形式来表示。 就可用一个矩阵加一个出发点的形式来表示。 就可用一个矩阵加一个出发点的形式来表示。

出发点 O = ( I − R T ) − 1 Q 出发点O=(I-RT)^{-1}Q 出发点O=(IRT)1Q

现在有第二个旋转RT2,O2作用于P’ 得到

P ′ ′ = R T 2 ⋅ P ′ + ( I − R T 2 ) ⋅ O 2 P''=RT2\cdot P' + (I-RT2)\cdot O2 P′′=RT2P+(IRT2)O2

= R T 2 ⋅ R T 1 ⋅ P + R T 2 ⋅ ( I − R T 1 ) ⋅ O 1 + ( I − R T 2 ) ⋅ O 2 =RT2\cdot RT1 \cdot P + RT2\cdot (I-RT1)\cdot O1 + (I-RT2)\cdot O2 =RT2RT1P+RT2(IRT1)O1+(IRT2)O2

上式中 , R T = R T 2 ⋅ R T 1 上式中, RT = RT2\cdot RT1 上式中,RT=RT2RT1

O = ( I − R T ) − 1 ⋅ [ R T 2 ⋅ ( I − R T 1 ) ⋅ O 1 + ( I − R T 2 ) ⋅ O 2 ] O = (I-RT)^{-1}\cdot [RT2\cdot (I-RT1)\cdot O1 + (I-RT2)\cdot O2] O=(IRT)1[RT2(IRT1)O1+(IRT2)O2]

这样,我们就得了两个刚体变换的综合变换。

但是上面的方法有一个问题,当(I-RT)不可逆时,那么该公式失效。
我的理解是,当(I-RT)不可逆时,O并不是没有解,而是有很多个解。

那么我们要另选他法。

再观察(1)式,其实我们并不需要求出O,只要求出Q就可以了。

R T = R T 2 ⋅ R T 1 , Q = R T 2 ⋅ Q 1 + Q 2 RT = RT2\cdot RT1, Q=RT2\cdot Q_1 + Q_2 RT=RT2RT1,Q=RT2Q1+Q2

这个方法与奇次矩阵相比,计算量小很多。

代码实现

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

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;trans = (Eigen::Matrix3d::Identity() - mat) * start; // 存储总体位移}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 + trans;}friend static RigidRTMatrix operator*(RigidRTMatrix& a, RigidRTMatrix& b) {RigidRTMatrix multi;multi.mat = a.mat * b.mat;multi.trans = a.mat * b.trans + a.trans;return multi;}};
}

代码测试


可以看出一个点依次作用与用一次综合矩阵的效果是一样的。


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

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


http://chatgpt.dhexx.cn/article/P40rnCFo.shtml

相关文章

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

欢迎关注更多精彩 关注我&#xff0c;学习常用算法与数据结构&#xff0c;一题多解&#xff0c;降维打击。 问题提出 如图所示&#xff0c;在空间中有一向量A&#xff0c;问点O绕A方向逆时针旋转角度α的矩阵如何表示。 问题分析 问题化规 直接去构造一个矩阵是比较困难的。…

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;…