Show HN: Rust Vector and Quaternion Lib
该项目发布了一个基于 Rust 的向量、四元数和矩阵运算库,主要用于通用目的和计算机图形领域。该库支持 f32 和 f64 类型,并提供了 `no_std`、`computer_graphics` 和 `encode` 等特性。它包含向量、四元数和矩阵的数据结构及相关运算,适用于计算机图形、生物力学、机器人等多种科学和工程应用。代码示例展示了基本的向量和四元数操作,以及在计算机图形中的应用。
Show HN: Rust Vector 和 Quaternion 库
该库提供了矩阵、向量和四元数运算功能。
Operations on matrices, vectors, and quaternions
License
用于通用目的和计算机图形的向量、四元数和矩阵
该库提供向量、矩阵和四元数数据结构和运算。使用基于 f32 或 f64 的类型。
适用场景:
- 计算机图形
- 生物力学
- 机器人和无人机
- 结构化学和生物化学
- 宇宙学建模
- 各种科学和工程应用
- 飞机姿态系统和自动驾驶仪
Vector
和 Quaternion
类型是 _copy_
的。
为了与 no_std
targets 兼容(例如嵌入式系统),请使用 no_std
特性。此特性会省略 std::fmt::Display
的实现。
对于计算机图形功能(例如特殊矩阵构造函数,以及用于在 GPU 之间传递的字节数组的序列化/反序列化),请使用 computer_graphics
特性。
对于 bincode 二进制编码和解码,请使用 encode
特性。
请不要在此代码库上运行 cargo fmt
;用于防止 f32
和 f64
模块之间代码重复的宏会导致不希望的行为。
有关实际四元数运算的信息:Quaternions: A practical guide。
对于大多数类型,From
trait 已经实现,用于在使用 into()
语法在 f32
和 f64
变体之间进行转换。
详情请参阅官方文档(上面已链接)。以下是一个简短而不实用的语法概述:
use core::f32::consts::TAU;
use lin_alg::f32::{Vec3, Quaternion};
fn main() {
let _ = Vec3::new_zero();
let a = Vec3::new(1., 1., 1.);
let b = Vec3::new(0., -1., 10.);
let c = a + b;
let mut d = a.dot(b);
d.normalize();
let e = c.to_normalized();
a.magnitude();
let f = a.cross(b);
let g = Quaternion::from_unit_vecs(d, e);
let h = g.inverse();
let k = Quaternion::new_identity();
let l = k.rotate_vec(c);
l.magnitude();
let m = Quaternion::from_axis_angle(Vec3::new(1., 0., 0.), TAU / 16.);
}
如果用于计算机图形,以下功能可能会有所帮助:
let a = Vec3::new(1., 1., 1.);
let bytes = a.to_bytes(); // Send this to the GPU
let model_mat = Mat4::new_translation(self.position)
* self.orientation.to_matrix()
* Mat4::new_scaler_partial(self.scale);
let proj_mat = Mat4::new_perspective_lh(self.fov_y, self.aspect, self.near, self.far);
let view_mat = self.orientation.inverse().to_matrix() * Mat4::new_translation(self.position * -1.);
// Example of rolling a camera around the forward axis:
let fwd = orientation.rotate_vec(FWD_VEC);
let rotation = Quaternion::from_axis_angle(fwd, -rotate_key_amt);
orientation = rotation * orientation;
/// Calculate the dihedral angle between 4 positions (3 bonds).
/// The `bonds` are one atom's position, substracted from the next. Order matters.
pub fn calc_dihedral_angle(bond_middle: Vec3, bond_adjacent1: Vec3, bond_adjacent2: Vec3) -> f64 {
// Project the next and previous bonds onto the plane that has this bond as its normal.
// Re-normalize after projecting.
let bond1_on_plane = bond_adjacent1.project_to_plane(bond_middle).to_normalized();
let bond2_on_plane = bond_adjacent2.project_to_plane(bond_middle).to_normalized();
// Not sure why we need to offset by 𝜏/2 here, but it seems to be the case
let result = bond1_on_plane.dot(bond2_on_plane).acos() + TAU / 2.;
// The dot product approach to angles between vectors only covers half of possible
// rotations; use a determinant of the 3 vectors as matrix columns to determine if what we
// need to modify is on the second half.
let det = det_from_cols(bond1_on_plane, bond2_on_plane, bond_middle);
if det < 0. { result } else { TAU - result }
}
关于
Operations on matrices, vectors, and quaternions