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

19 角度操作模块(angle.rs)

angle.rs代码定义了一个泛型结构体 Angle,用于表示一个角度,其中角度以弧度为单位存储。这个结构体提供了许多特性,包括复制、克隆、默认实现、调试输出、部分相等性比较、哈希等。此外,它还根据编译时的特性(features)提供了序列化/反序列化、零值安全和纯数据(Plain Old Data, POD)支持。下面是这段代码的详细解读。

一、angle.rs源码

use crate::approxeq::ApproxEq;
use crate::trig::Trig;use core::cmp::{Eq, PartialEq};
use core::hash::Hash;
use core::iter::Sum;
use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, Sub, SubAssign};#[cfg(feature = "bytemuck")]
use bytemuck::{Pod, Zeroable};
use num_traits::real::Real;
use num_traits::{Float, FloatConst, NumCast, One, Zero};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};/// An angle in radians
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Angle<T> {pub radians: T,
}#[cfg(feature = "bytemuck")]
unsafe impl<T: Zeroable> Zeroable for Angle<T> {}#[cfg(feature = "bytemuck")]
unsafe impl<T: Pod> Pod for Angle<T> {}#[cfg(feature = "arbitrary")]
impl<'a, T> arbitrary::Arbitrary<'a> for Angle<T>
whereT: arbitrary::Arbitrary<'a>,
{// This implementation could be derived, but the derive would require an `extern crate std`.fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {Ok(Angle {radians: arbitrary::Arbitrary::arbitrary(u)?,})}fn size_hint(depth: usize) -> (usize, Option<usize>) {<T as arbitrary::Arbitrary>::size_hint(depth)}
}impl<T> Angle<T> {#[inline]pub fn radians(radians: T) -> Self {Angle { radians }}#[inline]pub fn get(self) -> T {self.radians}
}impl<T> Angle<T>
whereT: Trig,
{#[inline]pub fn degrees(deg: T) -> Self {Angle {radians: T::degrees_to_radians(deg),}}#[inline]pub fn to_degrees(self) -> T {T::radians_to_degrees(self.radians)}
}impl<T> Angle<T>
whereT: Rem<Output = T> + Sub<Output = T> + Add<Output = T> + Zero + FloatConst + PartialOrd + Copy,
{/// Returns this angle in the [0..2*PI[ range.pub fn positive(&self) -> Self {let two_pi = T::PI() + T::PI();let mut a = self.radians % two_pi;if a < T::zero() {a = a + two_pi;}Angle::radians(a)}/// Returns this angle in the ]-PI..PI] range.pub fn signed(&self) -> Self {Angle::pi() - (Angle::pi() - *self).positive()}
}impl<T> Angle<T>
whereT: Rem<Output = T>+ Mul<Output = T>+ Sub<Output = T>+ Add<Output = T>+ One+ FloatConst+ Copy,
{/// Returns the shortest signed angle between two angles.////// Takes wrapping and signs into account.pub fn angle_to(&self, to: Self) -> Self {let two = T::one() + T::one();let max = T::PI() * two;let d = (to.radians - self.radians) % max;Angle::radians(two * d % max - d)}/// Linear interpolation between two angles, using the shortest path.pub fn lerp(&self, other: Self, t: T) -> Self {*self + self.angle_to(other) * t}
}impl<T> Angle<T>
whereT: Float,
{/// Returns `true` if the angle is a finite number.#[inline]pub fn is_finite(self) -> bool {self.radians.is_finite()}
}impl<T> Angle<T>
whereT: Real,
{/// Returns `(sin(self), cos(self))`.pub fn sin_cos(self) -> (T, T) {self.radians.sin_cos()}
}impl<T> Angle<T>
whereT: Zero,
{pub fn zero() -> Self {Angle::radians(T::zero())}
}impl<T> Angle<T>
whereT: FloatConst + Add<Output = T>,
{pub fn pi() -> Self {Angle::radians(T::PI())}pub fn two_pi() -> Self {Angle::radians(T::PI() + T::PI())}pub fn frac_pi_2() -> Self {Angle::radians(T::FRAC_PI_2())}pub fn frac_pi_3() -> Self {Angle::radians(T::FRAC_PI_3())}pub fn frac_pi_4() -> Self {Angle::radians(T::FRAC_PI_4())}
}impl<T> Angle<T>
whereT: NumCast + Copy,
{/// Cast from one numeric representation to another.#[inline]pub fn cast<NewT: NumCast>(&self) -> Angle<NewT> {self.try_cast().unwrap()}/// Fallible cast from one numeric representation to another.pub fn try_cast<NewT: NumCast>(&self) -> Option<Angle<NewT>> {NumCast::from(self.radians).map(|radians| Angle { radians })}// Convenience functions for common casts./// Cast angle to `f32`.#[inline]pub fn to_f32(&self) -> Angle<f32> {self.cast()}/// Cast angle `f64`.#[inline]pub fn to_f64(&self) -> Angle<f64> {self.cast()}
}impl<T: Add<T, Output = T>> Add for Angle<T> {type Output = Self;fn add(self, other: Self) -> Self {Self::radians(self.radians + other.radians)}
}impl<T: Copy + Add<T, Output = T>> Add<&Self> for Angle<T> {type Output = Self;fn add(self, other: &Self) -> Self {Self::radians(self.radians + other.radians)}
}impl<T: Add + Zero> Sum for Angle<T> {fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {iter.fold(Self::zero(), Add::add)}
}impl<'a, T: 'a + Add + Copy + Zero> Sum<&'a Self> for Angle<T> {fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {iter.fold(Self::zero(), Add::add)}
}impl<T: AddAssign<T>> AddAssign for Angle<T> {fn add_assign(&mut self, other: Angle<T>) {self.radians += other.radians;}
}impl<T: Sub<T, Output = T>> Sub<Angle<T>> for Angle<T> {type Output = Angle<T>;fn sub(self, other: Angle<T>) -> <Self as Sub>::Output {Angle::radians(self.radians - other.radians)}
}impl<T: SubAssign<T>> SubAssign for Angle<T> {fn sub_assign(&mut self, other: Angle<T>) {self.radians -= other.radians;}
}impl<T: Div<T, Output = T>> Div<Angle<T>> for Angle<T> {type Output = T;#[inline]fn div(self, other: Angle<T>) -> T {self.radians / other.radians}
}impl<T: Div<T, Output = T>> Div<T> for Angle<T> {type Output = Angle<T>;#[inline]fn div(self, factor: T) -> Angle<T> {Angle::radians(self.radians / factor)}
}impl<T: DivAssign<T>> DivAssign<T> for Angle<T> {fn div_assign(&mut self, factor: T) {self.radians /= factor;}
}impl<T: Mul<T, Output = T>> Mul<T> for Angle<T> {type Output = Angle<T>;#[inline]fn mul(self, factor: T) -> Angle<T> {Angle::radians(self.radians * factor)}
}impl<T: MulAssign<T>> MulAssign<T> for Angle<T> {fn mul_assign(&mut self, factor: T) {self.radians *= factor;}
}impl<T: Neg<Output = T>> Neg for Angle<T> {type Output = Self;fn neg(self) -> Self {Angle::radians(-self.radians)}
}impl<T: ApproxEq<T>> ApproxEq<T> for Angle<T> {#[inline]fn approx_epsilon() -> T {T::approx_epsilon()}#[inline]fn approx_eq_eps(&self, other: &Angle<T>, approx_epsilon: &T) -> bool {self.radians.approx_eq_eps(&other.radians, approx_epsilon)}
}#[test]
fn wrap_angles() {use core::f32::consts::{FRAC_PI_2, PI};assert!(Angle::radians(0.0).positive().approx_eq(&Angle::zero()));assert!(Angle::radians(FRAC_PI_2).positive().approx_eq(&Angle::frac_pi_2()));assert!(Angle::radians(-FRAC_PI_2).positive().approx_eq(&Angle::radians(3.0 * FRAC_PI_2)));assert!(Angle::radians(3.0 * FRAC_PI_2).positive().approx_eq(&Angle::radians(3.0 * FRAC_PI_2)));assert!(Angle::radians(5.0 * FRAC_PI_2).positive().approx_eq(&Angle::frac_pi_2()));assert!(Angle::radians(2.0 * PI).positive().approx_eq(&Angle::zero()));assert!(Angle::radians(-2.0 * PI).positive().approx_eq(&Angle::zero()));assert!(Angle::radians(PI).positive().approx_eq(&Angle::pi()));assert!(Angle::radians(-PI).positive().approx_eq(&Angle::pi()));assert!(Angle::radians(FRAC_PI_2).signed().approx_eq(&Angle::frac_pi_2()));assert!(Angle::radians(3.0 * FRAC_PI_2).signed().approx_eq(&-Angle::frac_pi_2()));assert!(Angle::radians(5.0 * FRAC_PI_2).signed().approx_eq(&Angle::frac_pi_2()));assert!(Angle::radians(2.0 * PI).signed().approx_eq(&Angle::zero()));assert!(Angle::radians(-2.0 * PI).signed().approx_eq(&Angle::zero()));assert!(Angle::radians(-PI).signed().approx_eq(&Angle::pi()));assert!(Angle::radians(PI).signed().approx_eq(&Angle::pi()));
}#[test]
fn lerp() {type A = Angle<f32>;let a = A::radians(1.0);let b = A::radians(2.0);assert!(a.lerp(b, 0.25).approx_eq(&Angle::radians(1.25)));assert!(a.lerp(b, 0.5).approx_eq(&Angle::radians(1.5)));assert!(a.lerp(b, 0.75).approx_eq(&Angle::radians(1.75)));assert!(a.lerp(b + A::two_pi(), 0.75).approx_eq(&Angle::radians(1.75)));assert!(a.lerp(b - A::two_pi(), 0.75).approx_eq(&Angle::radians(1.75)));assert!(a.lerp(b + A::two_pi() * 5.0, 0.75).approx_eq(&Angle::radians(1.75)));
}#[test]
fn sum() {type A = Angle<f32>;let angles = [A::radians(1.0), A::radians(2.0), A::radians(3.0)];let sum = A::radians(6.0);assert_eq!(angles.iter().sum::<A>(), sum);
}

二、结构体定义

pub struct Angle<T> {pub radians: T,
}

这个结构体非常简单,包含一个泛型类型 T 的字段 radians,用于存储角度的弧度值。

三、条件编译特性

  • Serde 序列化/反序列化:当启用了 serde 特征时,为 Angle 结构体实现了 Serialize 和 Deserialize 特性。
  • Bytemuck 的 Zeroable 和 Pod:当启用了 bytemuck 特征时,为实现了 Zeroable 和 Pod 特性的 T 类型,为 Angle 也实现了这些特性。
  • Arbitrary 支持:当启用了 arbitrary 特征时,为 Angle 实现了 Arbitrary 特性,这主要用于属性测试(property testing)。

四、方法实现

  • 构造函数:提供了 radians 方法作为构造函数。
  • gefrom 方法:这里似乎有一个错误,gefrom 方法名可能是一个打字错误,而且方法的实现部分也不完整。如果目的是提供一个从某种转换来创建 Angle 的方法,应该重新考虑方法名和实现。
  • 类型转换方法:提供了 to_f32 和 to_f64 方法,用于将角度转换为 f32 或 f64 类型的弧度。这里假设有一个 cast 方法被调用,但代码中并未显示其定义。

五、运算符重载

  1. 加法:为 Angle 实现了加法运算符重载,支持两个 Angle 之间的相加,以及一个 Angle 和一个 &Angle 之间的相加,也实现了两个 Angle 加法赋值。此外,还实现了 Sum 特性,允许对 Angle 的迭代器进行求和操作。
  2. 减法:允许两个 Angle 实例进行减法操作;允许对 Angle 实例进行减法赋值操作。
  3. 除法:两个 Angle 实例相除,及Angle 实例与一个 T 类型值相除。也对 Angle 实例进行除法赋值操作

相关文章:

19 角度操作模块(angle.rs)

angle.rs代码定义了一个泛型结构体 Angle&#xff0c;用于表示一个角度&#xff0c;其中角度以弧度为单位存储。这个结构体提供了许多特性&#xff0c;包括复制、克隆、默认实现、调试输出、部分相等性比较、哈希等。此外&#xff0c;它还根据编译时的特性&#xff08;features…...

前端高级面试题及其答案

以下是一些前端高级面试题及其答案&#xff1a; 一、JavaScript相关 事件循环&#xff08;Event Loop&#xff09;机制 答案&#xff1a; JavaScript的事件循环负责执行代码、收集和处理事件以及执行队列中的子任务。它包含宏任务&#xff08;macrotask&#xff09;队列&…...

【ORACLE】这个‘‘和null不等价的场景,deepseek你怎么看?

【ORACLE】一处’和null不等价的场景–to_char(number,varchar2) 背景 最近在做一个国产数据库替代项目&#xff0c;要求将ORACLE迁移到一个openGauss系数据库&#xff0c;迁移后&#xff0c;执行一个存储过程时&#xff0c;发现国产库的执行结果和ORACLE不一致&#xff0c; …...

使用Python实现PDF与SVG相互转换

目录 使用工具 使用Python将SVG转换为PDF 使用Python将SVG添加到现有PDF中 使用Python将PDF转换为SVG 使用Python将PDF的特定页面转换为SVG SVG&#xff08;可缩放矢量图形&#xff09;和PDF&#xff08;便携式文档格式&#xff09;是两种常见且广泛使用的文件格式。SVG是…...

ComfyUI 安装教程:macOS 和 Linux 统一步骤

本教程将详细介绍如何在 macOS 和 Linux 上安装 ComfyUI。我们将从 安装 Anaconda 开始&#xff0c;到安装 PyTorch 和 ComfyUI&#xff0c;最后提供一些常见问题的解决方法。 macOS和linux安装步骤很相似 可以按照1️⃣安装anaconda2️⃣安装python3️⃣torch4️⃣comfyui Co…...

360手机刷机 360手机解Bootloader 360手机ROOT

360手机刷机 360手机解Bootloader 360手机ROOT 问&#xff1a;360手机已停产&#xff0c;现在和以后&#xff0c;能刷机吗&#xff1f; 答&#xff1a;360手机&#xff0c;是肯定能刷机的 360手机资源下载网站 360手机-360手机刷机RootTwrp 360os.top 360rom.github.io 一、…...

t113-qt

修改QT配置: # # qmake configuration for building with arm-linux-gnueabi-g ## MAKEFILE_GENERATOR UNIX # CONFIG incremental # QMAKE_INCREMENTAL_STYLE sublib# include(../common/linux.conf) # include(../common/gcc-base-unix.conf) # inc…...

【真一键部署脚本】——一键部署deepseek

目录 deepseek一键部署脚本说明 0 必要前提 1 使用方法 1.1 使用默认安装配置 1.1 .1 使用其它ds模型 1.2 使用自定义安装 2 附录&#xff1a;deepseek模型手动下载 3 脚本下载地址 deepseek一键部署脚本说明 0 必要前提 linux环境 python>3.10 1 使用方法 1.1 …...

【AI 语音】实时语音交互优化全解析:从 RTC 技术到双讲处理

网罗开发 &#xff08;小红书、快手、视频号同名&#xff09; 大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等…...

pytest-xdist 进行多进程并发测试

在自动化测试中&#xff0c;运行时间过长往往是令人头疼的问题。你是否遇到过执行 Pytest 测试用例时&#xff0c;整个测试流程缓慢得让人抓狂&#xff1f;别担心&#xff0c;pytest-xdist 正是解决这一问题的利器&#xff01;它支持多进程并发执行&#xff0c;能够显著加快测试…...

【Android】版本和API对应关系表

目录 版本和API对应关系表 不积跬步&#xff0c;无以至千里&#xff1b;不积小流&#xff0c;无以成江海。要沉下心来&#xff0c;诗和远方的路费真的很贵&#xff01; 版本和API对应关系表 版本名版本号名称APIAndroid 1616.0W36Android 1515.0V35Android 1414.0U34Android 1…...

通过acme生成与续签ssl证书,并部署到nginx

通过acme生成与续签ssl证书&#xff0c;并部署到nginx 介绍 官方介绍&#xff1a; acme.sh 实现了 acme 协议&#xff0c;可以从 ZeroSSL&#xff0c;Lets Encrypt 等 CA 生成免费的证书。 安装 acme.sh 1. curl方式 curl https://get.acme.sh | sh -s emailmyexample.com…...

mysql系统库介绍,数据字典(介绍,存储方式,常见表,访问权限),系统表(介绍,不同功能的表)

目录 mysql系统库 介绍 数据字典 介绍 不同版本下的存储方式 常见的数据字典表 访问权限 系统表 介绍 权限授予系统表 对象信息系统表 服务器端帮助系统表 时区系统表 mysql系统库 介绍 MySQL 默认创建 的特殊数据库&#xff0c;主要用于存储服务器运行时所需的信…...

spring 学习(工厂方式 实例化对象(静态工厂,实例化工厂,实现factorybean 规范))

目录 前言 第一种&#xff1a;静态工厂方式实例化对象 静态工厂的特点 demo(案例&#xff09; 第二种&#xff1a;实例工厂的方式 实例工厂和静态工厂的区别 demo(案例&#xff09; 第三种&#xff1a;实现FactoryBean规范的方式 demo(案例&#xff09; 前言 spring 实…...

MarkupLM:用于视觉丰富文档理解的文本和标记语言预训练

摘要 结合文本、布局和图像的多模态预训练在视觉丰富文档理解&#xff08;VRDU&#xff09;领域取得了显著进展&#xff0c;尤其是对于固定布局文档&#xff08;如扫描文档图像&#xff09;。然而&#xff0c;仍然有大量的数字文档&#xff0c;其布局信息不是固定的&#xff0…...

讯飞智作 AI 配音技术浅析(三):自然语言处理

自然语言处理&#xff08;NLP&#xff09;是讯飞智作 AI 配音技术的重要组成部分&#xff0c;负责将输入的文本转换为机器可理解的格式&#xff0c;并提取出文本的语义和情感信息&#xff0c;以便生成自然、富有表现力的语音。 一、基本原理 讯飞智作 AI 配音的 NLP 技术主要包…...

kafka服务端之日志存储

文章目录 日志布局日志索引日志清理日志删除基于时间基千日志大小基于日志起始偏移量 日志压缩总结 日志布局 Ka饮a 中的消息是以主题为基本单位进行归类的&#xff0c; 各个主题在逻辑 上相互独立。 每个主题又可以分为一个或多个分区&#xff0c; 分区的数量可以在主题创建的…...

软件工程的熵减:AI如何降低系统复杂度

软件开发的世界&#xff0c;如同一个不断膨胀的宇宙。随着功能的增加和时间的推移&#xff0c;代码库越来越庞大&#xff0c;系统复杂度也随之水涨船高。代码膨胀、维护困难、开发效率低下等问题困扰着无数开发者。这不禁让人联想到物理学中的“熵增”原理——一个孤立系统的熵…...

模拟开发小鹅通首页网站练习

HTML代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>小鹅通-首页</title><!-- 引入页…...

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_strerror 函数

声明 ngx_strerror 函数声明在 ngx_errno.h 中&#xff1a; u_char *ngx_strerror(ngx_err_t err, u_char *errstr, size_t size); 实现 在 ngx_errno.c 中&#xff1a; u_char * ngx_strerror(ngx_err_t err, u_char *errstr, size_t size) {size_t len;const char *ms…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录&#xff0c;不允许匿名访问&#xff0c;kefu只能访问/data/kefu目录&#xff0c;不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

解读《网络安全法》最新修订,把握网络安全新趋势

《网络安全法》自2017年施行以来&#xff0c;在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂&#xff0c;网络攻击、数据泄露等事件频发&#xff0c;现行法律已难以完全适应新的风险挑战。 2025年3月28日&#xff0c;国家网信办会同相关部门起草了《网络安全…...

DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态

前言 在人工智能技术飞速发展的今天&#xff0c;深度学习与大模型技术已成为推动行业变革的核心驱动力&#xff0c;而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心&#xff0c;系统性地呈现了两部深度技术著作的精华&#xff1a;…...

Python网页自动化Selenium中文文档

1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API&#xff0c;让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API&#xff0c;你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...

从物理机到云原生:全面解析计算虚拟化技术的演进与应用

前言&#xff1a;我的虚拟化技术探索之旅 我最早接触"虚拟机"的概念是从Java开始的——JVM&#xff08;Java Virtual Machine&#xff09;让"一次编写&#xff0c;到处运行"成为可能。这个软件层面的虚拟化让我着迷&#xff0c;但直到后来接触VMware和Doc…...

Matlab实现任意伪彩色图像可视化显示

Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中&#xff0c;如何展示好看的实验结果图像非常重要&#xff01;&#xff01;&#xff01; 1、灰度原始图像 灰度图像每个像素点只有一个数值&#xff0c;代表该点的​​亮度&#xff08;或…...

算法刷题-回溯

今天给大家分享的还是一道关于dfs回溯的问题&#xff0c;对于这类问题大家还是要多刷和总结&#xff0c;总体难度还是偏大。 对于回溯问题有几个关键点&#xff1a; 1.首先对于这类回溯可以节点可以随机选择的问题&#xff0c;要做mian函数中循环调用dfs&#xff08;i&#x…...