Show HN: Rust Vector 和 Quaternion 库

该库提供了矩阵、向量和四元数运算功能。

Operations on matrices, vectors, and quaternions

License

MIT license 38 stars 1 fork

用于通用目的和计算机图形的向量、四元数和矩阵

Crate Docs

该库提供向量、矩阵和四元数数据结构和运算。使用基于 f32 或 f64 的类型。

适用场景:

VectorQuaternion 类型是 _copy_ 的。

为了与 no_std targets 兼容(例如嵌入式系统),请使用 no_std 特性。此特性会省略 std::fmt::Display 的实现。

对于计算机图形功能(例如特殊矩阵构造函数,以及用于在 GPU 之间传递的字节数组的序列化/反序列化),请使用 computer_graphics 特性。

对于 bincode 二进制编码和解码,请使用 encode 特性。

请不要在此代码库上运行 cargo fmt;用于防止 f32f64 模块之间代码重复的宏会导致不希望的行为。

有关实际四元数运算的信息:Quaternions: A practical guide

对于大多数类型,From trait 已经实现,用于在使用 into() 语法在 f32f64 变体之间进行转换。

详情请参阅官方文档(上面已链接)。以下是一个简短而不实用的语法概述:

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

资源

Readme

许可协议

MIT license

Activity

Stars

38 stars

Watchers

3 watching

Forks

1 fork