colmap 0.1.2

A comprehensive Rust library for COLMAP-style computer vision and 3D reconstruction
Documentation
//! 数学工具模块
//!
//! 这个模块提供了 COLMAP 中使用的各种数学工具和算法,包括:
//! - 矩阵运算
//! - 几何变换
//! - 优化算法
//! - 统计工具

// TODO: 实现这些模块
// pub mod matrix;
// pub mod geometry;
// pub mod optimization;
// pub mod statistics;
// pub mod random;

// 重新导出主要类型
// pub use matrix::*;
// pub use geometry::*;
// pub use optimization::*;
// pub use statistics::*;
// pub use random::*;

use nalgebra::{Matrix3, Vector3, Point3, Isometry3};

/// 3D 变换类型别名
pub type Transform3d = Isometry3<f64>;

/// 旋转矩阵类型别名
pub type RotationMatrix = Matrix3<f64>;

/// 平移向量类型别名
pub type TranslationVector = Vector3<f64>;

/// 3D 点类型别名
pub type Point3d = Point3<f64>;

/// 3D 向量类型别名
pub type Vector3d = Vector3<f64>;

/// 数学常量
pub mod constants {
    /// π
    pub const PI: f64 = std::f64::consts::PI;
    
    ///    pub const TAU: f64 = 2.0 * PI;
    
    /// π/2
    pub const HALF_PI: f64 = PI / 2.0;
    
    /// 角度到弧度的转换因子
    pub const DEG_TO_RAD: f64 = PI / 180.0;
    
    /// 弧度到角度的转换因子
    pub const RAD_TO_DEG: f64 = 180.0 / PI;
    
    /// 浮点数比较的默认容差
    pub const EPS: f64 = 1e-10;
}

/// 角度转弧度
pub fn deg_to_rad(degrees: f64) -> f64 {
    degrees * constants::DEG_TO_RAD
}

/// 弧度转角度
pub fn rad_to_deg(radians: f64) -> f64 {
    radians * constants::RAD_TO_DEG
}

/// 检查浮点数是否近似相等
pub fn approx_equal(a: f64, b: f64, eps: f64) -> bool {
    (a - b).abs() < eps
}

/// 将角度规范化到 [-π, π] 范围
pub fn normalize_angle(angle: f64) -> f64 {
    let mut normalized = angle % constants::TAU;
    if normalized > constants::PI {
        normalized -= constants::TAU;
    } else if normalized < -constants::PI {
        normalized += constants::TAU;
    }
    // 处理边界情况:π 映射到 -π,-π 映射到 π
    if (normalized - constants::PI).abs() < constants::EPS {
        normalized = -constants::PI;
    } else if (normalized + constants::PI).abs() < constants::EPS {
        normalized = constants::PI;
    }
    normalized
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_angle_conversion() {
        let degrees = 90.0;
        let radians = deg_to_rad(degrees);
        assert!(approx_equal(radians, constants::HALF_PI, constants::EPS));
        
        let back_to_degrees = rad_to_deg(radians);
        assert!(approx_equal(back_to_degrees, degrees, constants::EPS));
    }

    #[test]
    fn test_normalize_angle() {
        assert!(approx_equal(normalize_angle(3.0 * constants::PI), -constants::PI, constants::EPS));
        assert!(approx_equal(normalize_angle(-3.0 * constants::PI), constants::PI, constants::EPS));
        assert!(approx_equal(normalize_angle(constants::PI / 2.0), constants::PI / 2.0, constants::EPS));
    }

    #[test]
    fn test_approx_equal() {
        assert!(approx_equal(1.0, 1.0 + constants::EPS / 2.0, constants::EPS));
        assert!(!approx_equal(1.0, 1.0 + constants::EPS * 2.0, constants::EPS));
    }
}