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,);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/887442.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL进阶:如何跳过多个NULL值取第一个非NULL值?

NULL 一、问题描述二、ORACLE<一>、last_value () over ()<二>、lag () over()<三>、相关子查询 三、MYSQL<一>、全局变量<二>、coalesce() lag() over()<三>、相关子查询<四>、 recursive<五>、lag() over() min() over() …

wordpress获取文章总数、分类总数、tag总数等

在制作wordpress模板的时候会要调用网站的文章总数分类总数tag总数等这个数值&#xff0c;如果直接用count查询数据库那就太过分了。好在wordpress内置了一些标签可以直接获取到这些数值&#xff0c;本文整理了一些常用的wordpress网站总数标签。 文章总数 <?php $count_…

人工智能|计算机视觉——微表情识别(Micro expression recognition)的研究现状

一、简述 微表情是一种特殊的面部表情,与普通的表情相比,微表情主要有以下特点: 持续时间短,通常只有1/25s~1/3s;动作强度低,难以察觉;在无意识状态下产生,通常难以掩饰或伪装;对微表情的分析通常需要在视频中,而普通表情在图像中就可以分析。由于微表情在无意识状态…

玩转合宙Luat教程 基础篇④——程序基础(库、线程、定时器和订阅/发布)

文章目录 一、前言二、库三、线程四、定时器五、订阅/发布5.1 回调函数5.2 堵塞等待一、前言 教程目录大纲请查阅:玩转合宙Luat教程——导读 写一写Lua程序基础的东西。 包括如何调用库,如何创建线程、如何创建定时器,如何使用订阅/发布事件。 二、库 程序从main.lua开始通…

嵌入式系统与OpenCV

目录 一、OpenCV 简介 二、嵌入式 OpenCV 的安装方法 1. Ubuntu 系统下的安装 2. 嵌入式 ARM 系统中的安装 3. Windows10 和树莓派系统下的安装 三、嵌入式 OpenCV 的性能优化 1. 介绍嵌入式平台上对 OpenCV 进行优化的必要性。 2. 利用嵌入式开发工具&#xff0c;如优…

CentOS环境上离线安装python3及相关包

0. 准备操作系统及安装包 准备操作系统环境&#xff1a; 首先安装依赖包&#xff0c;安装相应的编译工具 [rootbigdatahost bin]# yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-d…

在 Ubuntu 上安装 MinIO 并设置密码

在 Ubuntu 上安装 MinIO 并设置密码 1. 更新系统2. 设置时区为中国大陆3. 安装 MinIO3.1 下载 MinIO3.2 赋予执行权限3.3 移动 MinIO 到系统路径 4. 创建 MinIO 用户和数据目录4.1 创建用户4.2 创建数据目录4.3 设置权限 5. 配置 MinIO5.1 创建配置文件 6. 创建 Systemd 服务文…

数学建模_基于对数和傅里叶变换的多通道图像增强模型(处理模糊)Matlab代码包教会使用,直接替换数据即可

图像增强模型&#xff1a;基于对数和傅里叶变换的多通道增强 模型简介 本博客介绍一种基于对数变换&#xff08;Logarithmic Transformation&#xff09;和傅里叶变换&#xff08;FFT&#xff09;的图像增强方法。该方法结合多尺度高斯滤波器和拉普拉斯模糊度分布评估&#xf…

Qt交叉编译x86和arm心得

最近一直在Linux上开发qt程序&#xff0c;主要工作是在x86的Ubuntu上开发编译调试程序&#xff0c;确定没有问题后交叉编译到arm的linux系统上运行 1.环境 Qt的交叉编译环境厂家已经提供了&#xff0c;嵌入式的同事帮我安装调试的&#xff0c;具体就是装了厂家给的gcc编译套件…

LeetCode739. 每日温度(2024冬季每日一题 15)

给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于第 i 天&#xff0c;下一个更高温度出现在几天后。如果气温在这之后都不会升高&#xff0c;请在该位置用 0 来代替。 示例 1: 输入: temperatu…

React(五)——useContecxt/Reducer/useCallback/useRef/React.memo/useMemo

文章目录 项目地址十六、useContecxt十七、useReducer十八、React.memo以及产生的问题18.1组件嵌套的渲染规律18.2 React.memo18.3 引出问题 十九、useCallback和useMemo19.1 useCallback对函数进行缓存19.2 useMemo19.2.1 基本的使用19.2.2 缓存属性数据 19.2.3 对于更新的理解…

STM32设计学生宿舍监测控制系统-分享

目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 电路图采用Altium Designer进行设计&#xff1a; 三、实物设计图 四、程序源代码设计 五、获取资料内容 前言 本项目旨在利用STM32单片机为核心&#xff0c;结合传感器技术、无线通信技…

华为无线AC+AP组网实际应用小结

之前公司都是使用的H3C的交换机、防火墙以及无线AC和AP的&#xff0c;最近优化下无线网络&#xff0c;说新的设备用华为的&#xff0c;然后我是直到要部署的当天才知道用华为设备的&#xff0c;就很无语了&#xff0c;一点准备没有&#xff0c;以下为这次的实际操作记录吧&…

Java学习,继承(1)

Java继承是面向对象的编程特性&#xff0c;允许一个类&#xff08;称为子类或派生类&#xff09;继承另一个类&#xff08;称为父类或基类&#xff09;的字段和方法。通过继承&#xff0c;子类可以获得父类的所有公共&#xff08;public&#xff09;和保护&#xff08;protecte…

二刷代码随想录第13天

二叉树的递归遍历 递归三部曲1.确定递归函数的参数和返回值 2.确定终止条件 3.确定单层的递归逻辑前中后序遍历只需要改一下位置即可 class Solution { public:vector<int> inorderTraversal(TreeNode* root) {vector<int> vec;traversal(root, vec);return vec;…

Linux麦克风录音实战

在 Linux 上使用麦克风进行录音可以通过多种方式实现&#xff0c;包括使用命令行工具、图形界面应用程序以及编程接口。下面我将介绍几种常见的方法&#xff0c;从简单的命令行工具到使用 PortAudio 库进行编程。 一. 使用arecord命令行工具 arecord 是 ALSA&#xff08;Adva…

虚拟苹果系统MacOS中新建自定义C++Dylib并用C++测试程序测试

前言 苹果系统中Dylib的建立和使用是一个非常基础的功能。本博客使用苹果虚拟机MacOS Ventura 13.6.7&#xff0c;XCode15.2&#xff0c;来复现这个过程。供参考。 1、Dylib框架的建立 2、增加一个函数 注意&#xff0c;向导自动生成的Helloworld函数中嵌套了一个函数Helloworl…

Windows系统电脑安装TightVNC服务端结合内网穿透实现异地远程桌面

文章目录 前言1. 安装TightVNC服务端2. 局域网VNC远程测试3. Win安装Cpolar工具4. 配置VNC远程地址5. VNC远程桌面连接6. 固定VNC远程地址7. 固定VNC地址测试 前言 在追求高效、便捷的数字化办公与生活的今天&#xff0c;远程桌面服务成为了连接不同地点、不同设备之间的重要桥…

树莓派2装FreeBSD14.1 Raspberry Pi2 install FreeBSD14.1 00000121:error:0A000086:SSL

树莓派2代的Model B采用Broadcom BCM2836 900MHz的四核SoC&#xff0c;1GB内存&#xff0c;是新一代开拓者&#xff0c;兼容1代B。相比之下&#xff0c;树莓派2的性能比1代提升6倍&#xff0c;内存翻了一番。Raspberry Pi 2不仅能跑全系列ARM GNU/Linux发行版&#xff0c;而且支…

ThingsBoard规则链节点:Azure IoT Hub 节点详解

目录 引言 1. Azure IoT Hub 节点简介 2. 节点配置 2.1 基本配置示例 3. 使用场景 3.1 数据传输 3.2 数据分析 3.3 设备管理 4. 实际项目中的应用 4.1 项目背景 4.2 项目需求 4.3 实现步骤 5. 总结 引言 ThingsBoard 是一个开源的物联网平台&#xff0c;提供了设备…