当前位置: 首页 > news >正文

2.13 转换矩阵

转换矩阵引用了库nalgebra,使用时研究具体实现。

use std::ops;use nalgebra::Perspective3;use crate::Scalar;use super::{Aabb, LineSegment, Point, Triangle, Vector};/// An affine transform
#[repr(C)]
#[derive(Debug, Clone, Copy, Default)]
pub struct Transform(nalgebra::Transform<f64, nalgebra::TAffine, 3>);impl Transform {/// Construct an identity transformpub fn identity() -> Self {Self(nalgebra::Transform::identity())}/// Construct a translationpub fn translation(offset: impl Into<Vector<3>>) -> Self {let offset = offset.into();Self(nalgebra::Transform::from_matrix_unchecked(nalgebra::OMatrix::new_translation(&offset.to_na()),))}/// Construct a rotation////// The direction of the vector defines the rotation axis. Its length/// defines the angle of the rotation.pub fn rotation(axis_angle: impl Into<Vector<3>>) -> Self {let axis_angle = axis_angle.into();Self(nalgebra::Transform::from_matrix_unchecked(nalgebra::OMatrix::<_, nalgebra::Const<4>, _>::new_rotation(axis_angle.to_na(),),))}/// Construct a scalingpub fn scale(scaling_factor: f64) -> Self {Self(nalgebra::Transform::from_matrix_unchecked(nalgebra::OMatrix::new_scaling(scaling_factor),))}/// # Extract the "right" vector from the rotational componentpub fn right(&self) -> Vector<3> {let d = self.data();Vector::from([d[0], d[1], d[2]])}/// # Extract the "up" vector from the rotational componentpub fn up(&self) -> Vector<3> {let d = self.data();Vector::from([d[4], d[5], d[6]])}/// Transform the given pointpub fn transform_point(&self, point: &Point<3>) -> Point<3> {Point::from(self.0.transform_point(&point.to_na()))}/// Inverse transform given pointpub fn inverse_transform_point(&self, point: &Point<3>) -> Point<3> {Point::from(self.0.inverse_transform_point(&point.to_na()))}/// Transform the given vectorpub fn transform_vector(&self, vector: &Vector<3>) -> Vector<3> {Vector::from(self.0.transform_vector(&vector.to_na()))}/// Transform the given segmentpub fn transform_segment(&self,segment: &LineSegment<3>,) -> LineSegment<3> {let [a, b] = &segment.points;LineSegment::from([self.transform_point(a), self.transform_point(b)])}/// Transform the given trianglepub fn transform_triangle(&self, triangle: &Triangle<3>) -> Triangle<3> {let [a, b, c] = &triangle.points;Triangle::from([self.transform_point(a),self.transform_point(b),self.transform_point(c),])}/// Inverse transformpub fn inverse(&self) -> Self {Self(self.0.inverse())}/// Transpose transformpub fn transpose(&self) -> Self {Self(nalgebra::Transform::from_matrix_unchecked(self.0.to_homogeneous().transpose(),))}/// Project transform according to camera specification, return data as an array./// Used primarily for graphics code.pub fn project_to_array(&self,aspect_ratio: f64,fovy: f64,znear: f64,zfar: f64,) -> [Scalar; 16] {let projection = Perspective3::new(aspect_ratio, fovy, znear, zfar);let mut array = [0.; 16];array.copy_from_slice((projection.to_projective() * self.0).matrix().as_slice(),);array.map(Scalar::from)}/// Return a copy of the inner nalgebra transformpub fn get_inner(&self) -> nalgebra::Transform<f64, nalgebra::TAffine, 3> {self.0}/// Transform the given axis-aligned bounding boxpub fn transform_aabb(&self, aabb: &Aabb<3>) -> Aabb<3> {Aabb {min: self.transform_point(&aabb.min),max: self.transform_point(&aabb.max),}}/// Exposes the data of this Transform as a slice of f64.pub fn data(&self) -> &[f64] {self.0.matrix().data.as_slice()}/// Extract the rotation component of this transformpub fn extract_rotation(&self) -> Self {Self(nalgebra::Transform::from_matrix_unchecked(self.0.matrix().fixed_resize::<3, 3>(0.).to_homogeneous(),))}/// Extract the translation component of this transformpub fn extract_translation(&self) -> Self {*self * self.extract_rotation().inverse()}
}impl ops::Mul<Self> for Transform {type Output = Self;fn mul(self, rhs: Self) -> Self::Output {Self(self.0.mul(rhs.0))}
}#[cfg(test)]
mod tests {use approx::assert_abs_diff_eq;use crate::{Scalar, Vector};use super::Transform;#[test]fn extract_rotation_translation() {let rotation =Transform::rotation(Vector::unit_z() * (Scalar::PI / 2.));let translation = Transform::translation([1., 2., 3.]);assert_abs_diff_eq!((translation * rotation).extract_rotation().data(),rotation.data(),epsilon = 1e-8,);assert_abs_diff_eq!((translation * rotation).extract_translation().data(),translation.data(),epsilon = 1e-8,);assert_abs_diff_eq!((rotation * translation).extract_rotation().data(),rotation.data(),epsilon = 1e-8,);assert_abs_diff_eq!((rotation * translation).extract_translation().data(),Transform::translation([-2., 1., 3.]).data(),epsilon = 1e-8,);}
}

相关文章:

2.13 转换矩阵

转换矩阵引用了库nalgebra&#xff0c;使用时研究具体实现。 use std::ops;use nalgebra::Perspective3;use crate::Scalar;use super::{Aabb, LineSegment, Point, Triangle, Vector};/// An affine transform #[repr(C)] #[derive(Debug, Clone, Copy, Default)] pub struct…...

【C语言】遗传算法matlab程序

遗传算法matlab程序 遗传算法是一种模拟自然选择过程的优化技术&#xff0c;用于解决复杂问题。在MATLAB中编写遗传算法程序&#xff0c;通常包括以下几个步骤&#xff1a; 初始化种群&#xff1a;创建一个初始解集&#xff08;种群&#xff09;&#xff0c;每个解代表一个问题…...

Java LinkedList 详解

LinkedList 是 Java 集合框架中常用的数据结构之一&#xff0c;位于 java.util 包中。它实现了 List、Deque 和 Queue 接口&#xff0c;是一个双向链表结构&#xff0c;适合频繁的插入和删除操作。 1. LinkedList 的特点 数据结构&#xff1a;基于双向链表实现&#xff0c;每个…...

mac-mini的时间机器,数据备份到alist 中的网盘

苹果的时间机器不能直接将备份存储在 alist 上的网盘&#xff0c;但可以通过一些中间步骤来实现类似的效果&#xff0c;以下是具体介绍&#xff1a; 方法原理 通过将支持 WebDAV 协议的网络存储挂载到本地&#xff0c;再将其设置为时间机器的备份磁盘&#xff0c;从而间接实现…...

【HarmonyOS】鸿蒙应用加载读取csv文件

【HarmonyOS】鸿蒙应用加载读取csv文件 一、问题背景&#xff1a; 1. csv文件是什么&#xff1f; csv是一种文本文件格式&#xff0c;与json类似。会存储一些文本内容&#xff0c;应用需要读取该文件&#xff0c;进行UI内容得填充等。 文件中的数据是以纯文本形式存储的&…...

Java retainAll() 详解

在 Java 中&#xff0c;retainAll() 是 Collection 接口&#xff08;List、Set 等集合类实现该接口&#xff09;的一种方法&#xff0c;用于保留集合中与指定集合交集的元素&#xff0c;删除其他所有元素。 以下是对 retainAll() 方法的详细讲解。 1. 方法定义 方法签名 boo…...

Redis的基本数据类型

初识Redis缓存 Redis缓存&#xff1a; 实际开发中经常使用Redis作为缓存数据库&#xff0c;从而提高数据存取效率&#xff0c;减轻后端数据库的压力。 可以将经常被查询的数据缓存起来&#xff0c;比如热点数据&#xff0c;这样当用户来访问的时候&#xff0c;就不需要到MyS…...

通过vite+vue3+pinia从0到1搭建一个uniapp应用

最近项目上要做一个app&#xff0c;选择了用uniapp作为开发框架&#xff1b;我大概看了一下uniapp的文档&#xff0c;根据文档从0到1搭了一个uniapp应用供大家参考。 因为本人习惯使用了WebStorm编译器&#xff0c;但是uniapp官方推荐使用HBuilder搭建&#xff0c;如果和我一样…...

Linux的桌面

Linux的桌面是可以卸载的 的确&#xff0c;Linux并不像Windows&#xff0c;Linux本身是一个基于命令行的操作系统&#xff0c;在内核眼中&#xff0c;桌面只不过是个普通的应用程序&#xff0c;所以&#xff0c;在Linux的桌面中可以完成的事情&#xff0c;命令行中也基本可以完…...

Easyexcel(5-自定义列宽)

相关文章链接 Easyexcel&#xff08;1-注解使用&#xff09;Easyexcel&#xff08;2-文件读取&#xff09;Easyexcel&#xff08;3-文件导出&#xff09;Easyexcel&#xff08;4-模板文件&#xff09;Easyexcel&#xff08;5-自定义列宽&#xff09; 注解 ColumnWidth Data…...

操作系统实验 C++实现死锁检测算法

实验目的 模拟实现死锁检测算法 实验内容 1、 输入&#xff1a; “资源分配表”文件&#xff0c;每一行包含资源编号、进程编号两项&#xff08;均用整数表示&#xff0c;并用空格分隔开&#xff09;&#xff0c;记录资源分配给了哪个进程。 “进程等待表”文件&…...

小鹏汽车智慧材料数据库系统项目总成数据同步

1、定时任务处理 2、提供了接口 小鹏方面提供的推送的数据表结构&#xff1a; 这几个表总数为100多万&#xff0c;经过条件筛选过滤后大概2万多条数据 小鹏的人给的示例图&#xff1a; 界面&#xff1a; SQL: -- 查询车型 select bmm.md_material_id, bmm.material_num, bm…...

1、HCIP之RSTP协议与STP相关安全配置

目录 RSTP—快速生成树协议 STP STP的缺点&#xff1a; STP的选举&#xff08;Listening状态中&#xff09;&#xff1a; RSTP P/A&#xff08;提议/同意&#xff09;机制 同步机制&#xff1a; 边缘端口的配置&#xff1a; RSTP的端口角色划分&#xff1a; ensp模拟…...

Linux云服务器docker使用教程

诸神缄默不语-个人CSDN博文目录 我用的是腾讯云服务器&#xff0c;操作系统是OpenCloudOS 9&#xff0c;基本上可以当特色版CentOS用。 docker安装跟各个系统关系太大了&#xff0c;我就不写了。OpenCloudOS 9安装docker见这篇博文&#xff1a;腾讯云服务器使用教程 文章目录 …...

如何从android的webview 取得页面上的数据

要从Android的WebView中获取页面上的数据&#xff0c;通常有几种常见的方法&#xff1a; JavaScript Interface&#xff1a;通过JavaScript和Android Interface进行通信。这种方法允许你在JavaScript中调用Android的方法&#xff0c;反之亦然。 Evaluate JavaScript&#xff…...

VTK知识学习(12)- 读取PNG图像

1、代码 private void ShowPngImage(){vtkPNGReader pngReader vtkPNGReader.New();pngReader.SetFileName("D:\\图像\\boxes\\cardboard_boxes_01.png");pngReader.Update();vtkImageActor imageActor vtkImageActor.New();imageActor.SetInputData(pngReader.Get…...

Springboot项目搭建(3)-更改用户信息与文件上传

1.概要 前一章节完成了用户信息的注册、登录、详细信息查询&#xff0c;以及线程池与拦截器技术。 这一章完善了用户信息更新/更改功能&#xff0c;包括昵称、邮箱、头像、密码等... 而后接触到了本地上传和云上传&#xff0c;其二者区别&#xff1a; 选择本地上传还是云上…...

Docker1:认识docker、在Linux中安装docker

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…...

python成绩分级 2024年6月python二级真题 青少年编程电子学会编程等级考试python二级真题解析

目录 python成绩分级 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序代码 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python成绩分级 2024年6月 python编程等级考试二级编程题 一、题目要求 …...

android 如何获取当前 Activity 的类名和包名

其一&#xff1a;getClass().getSimpleName() public static String getTopActivity(Context context){ ActivityManager am (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE); ComponentName cn am.getRunningTasks(1).get(0).topAct…...

Spring Boot 项目 myblog 整理

myblog 项目是一个典型的 Spring Boot 项目&#xff0c;主要包括用户注册、登录、文章管理&#xff08;创建、查询、更新、删除&#xff09;等功能。 1. 项目结构与依赖设置 项目初始化与依赖 使用 Spring Initializr 创建项目。引入必要的依赖包&#xff1a; Spring Boot W…...

uniapp 城市选择插件

uniapp城市选择插件 如上图 地址 完整demo <template><view><city-selectcityClick"cityClick":formatName"formatName":activeCity"activeCity":hotCity"hotCity":obtainCitys"obtainCitys":isSearch&quo…...

测试工程师如何在面试中脱颖而出

目录 1.平时工作中是怎么去测的&#xff1f; 2.B/S架构和C/S架构区别 3.B/S架构的系统从哪些点去测&#xff1f; 4.你为什么能够做测试这一行&#xff1f;&#xff08;根据个人情况分析理解&#xff09; 5.你认为测试的目的是什么&#xff1f; 6.软件测试的流程&#xff…...

Mesh路由组网

Mesh无线网格网络&#xff0c;多跳&#xff08;multi-hop&#xff09;网络&#xff0c;为解决全屋覆盖信号&#xff0c;一般用于家庭网络和小型企业 原理 网关路由器&#xff08;主路由&#xff0c;连接光猫&#xff09;&#xff0c;Mesh路由器&#xff08;子路由&#xff0c;…...

LeetCode131:分割回文串

题目链接&#xff1a;131. 分割回文串 - 力扣&#xff08;LeetCode&#xff09; 代码如下&#xff1a; class Solution { private:vector<vector<string>> result;vector<string> path; // 放已经回文的子串void backtracking (const string& s, int s…...

详细解析 devmem 命令:在 Linux 系统中直接访问内存的利器

目录 什么是 devmem&#xff1f;为什么需要 devmem&#xff1f;devmem 命令的基本语法devmem 在硬件调试中的应用安全性与风险devmem 的常见应用示例结论 在嵌入式系统开发和硬件调试中&#xff0c;开发者经常需要直接与硬件打交道&#xff0c;访问和修改内存中某些特定区域的内…...

[Docker-显示所有容器IP] 显示docker-compose.yml中所有容器IP的方法

本文由Markdown语法编辑器编辑完成。 1. 需求背景: 最近在启动一个服务时&#xff0c;突然发现它的一个接口&#xff0c;被另一个服务ip频繁的请求。 按理说&#xff0c;之前设置的是&#xff0c;每隔1分钟请求一次接口。但从日志来看&#xff0c;则是1秒钟请求一次&#xff…...

【前端知识】nodejs项目配置package.json深入解读

package.json详细解读 文件解读一、文件结构二、字段详解三、使用场景四、注意事项 组件版本匹配规则 文件解读 package.json 文件是 Node.js 项目中的一个核心配置文件&#xff0c;它位于项目的根目录下&#xff0c;并包含项目的基本信息、依赖关系、脚本、版本等内容。以下是…...

XGBOOST算法Python实现(保姆级)

摘要 XGBoost算法&#xff08;eXtreme Gradient Boosting&#xff09;在目前的Kaggle、数学建模和大数据应用等竞赛中非常流行。本文将会从XGBOOST算法原理、Python实现、敏感性分析和实际应用进行详细说明。 目录 0 绪论 一、材料准备 二、算法原理 三、算法Python实现 3…...

JDK、MAVEN与IDEA的安装与配置

1.认识JDK、MAVEN与IDEA JDK 提供了编译和运行Java程序的基本环境。Maven 帮助管理项目的构建和依赖。IDEA 提供了一个强大的开发环境&#xff0c;使得编写、调试和运行Java程序更加高效。 2. 安装与环境配置 2.1 官网地址 选择你需要的版本下载&#xff1a; MAVEN下载传送…...