【学写LibreCAD】Rust Vector2D 实现与 C++ RS_Vector 的对应关系及优势分析

一、整体架构对比

1.1 C++ 原始设计

cpp 复制代码
// C++ 单一结构体设计
class RS_Vector {
    double x, y, z;  // 3D坐标,z在2D CAD中多为0
    bool valid;      // 手动有效性管理
    // 所有方法都包含valid检查
};

问题分析:

  • 类型混合:2D/3D不分离
  • 冗余存储:z坐标在2D中浪费内存
  • 错误处理:通过特殊值和布尔标志

1.2 Rust 改进设计

rust 复制代码
// Rust 分离结构体设计
pub struct Vector2D { x: f64, y: f64 }           // 纯2D
pub struct Vector3D { x: f64, y: f64, z: f64 }    // 纯3D
pub type RsVector = Option<Vector2D>;            // 有效性通过类型系统保证

二、关键功能对应关系

2.1 构造函数的对应

C++ 构造函数 Rust 对应实现 优势分析
RS_Vector(double x, double y, double z=0) Vector2D::new(x, y) 类型明确:避免z坐标误用
RS_Vector(double angle) Vector2D::from_angle(angle) 功能专注:只创建2D单位向量
RS_Vector(bool valid) RsVector::invalid() 类型安全:Option自然表示无效
RS_Vector(const QPointF& point) impl From<(f64, f64)> 通用性:支持多种输入类型

2.2 几何计算的对应

距离计算
cpp 复制代码
// C++ 版本
double RS_Vector::distanceTo(const RS_Vector& v) const {
    if (!valid || !v.valid) return RS_MAXDOUBLE;  // 手动检查
    return (*this - v).magnitude();
}
rust 复制代码
// Rust 版本
impl Vector2D {
    pub fn distance_to(&self, other: &Self) -> f64 {
        ((self.x - other.x).powi(2) + (self.y - other.y).powi(2)).sqrt()
    }
}

impl RsVector {
    pub fn distance_to(&self, other: &Self) -> Option<f64> {
        match (self, other) {
            (Some(v1), Some(v2)) => Some(v1.distance_to(v2)),
            _ => None,  // 编译时强制处理
        }
    }
}

优势对比:

方面 C++ Rust 优势
错误处理 返回魔法数值 返回Option 无魔法值,类型安全
有效性检查 运行时手动检查 编译时类型保证 性能更好,无运行时开销
使用安全 可能忽略检查 必须处理None 防止未定义行为
角度计算
cpp 复制代码
// C++ 版本
double RS_Vector::angle() const {
    return RS_Math::correctAngle(std::atan2(y,x));
}
rust 复制代码
// Rust 版本
impl Vector2D {
    pub fn angle(&self) -> f64 {
        self.y.atan2(self.x).rem_euclid(2.0 * PI)  // 自动规范化
    }
}

改进点:

  1. 数学库优化 :使用标准库rem_euclid代替自定义correctAngle
  2. 无状态依赖 :不依赖外部RS_Math
  3. 常量使用 :直接使用PI常量

2.3 变换操作的对应

旋转操作
cpp 复制代码
// C++ 版本
RS_Vector& RS_Vector::rotate(double ang) {
    double x0 = x * cos(ang) - y * sin(ang);
    y = x * sin(ang) + y * cos(ang);
    x = x0;
    return *this;
}
rust 复制代码
// Rust 版本
impl Vector2D {
    pub fn rotate(mut self, angle: f64) -> Self {
        let cos_angle = angle.cos();
        let sin_angle = angle.sin();
        let new_x = self.x * cos_angle - self.y * sin_angle;
        let new_y = self.x * sin_angle + self.y * cos_angle;
        self.x = new_x;
        self.y = new_y;
        self
    }
    
    pub fn rotated(&self, angle: f64) -> Self {  // 新增:不可变版本
        let cos_angle = angle.cos();
        let sin_angle = angle.sin();
        Self::new(
            self.x * cos_angle - self.y * sin_angle,
            self.x * sin_angle + self.y * cos_angle,
        )
    }
}

新增优势:

  1. 双版本APIrotate(修改自身)和rotated(返回新实例)
  2. 函数式风格:支持链式调用
  3. 所有权明确:Rust所有权系统防止意外修改
镜像操作
cpp 复制代码
// C++ 版本
RS_Vector& RS_Vector::mirror(const RS_Vector& axisPoint1, 
                             const RS_Vector& axisPoint2) {
    // 复杂的投影计算,需要检查有效性
    if (!valid || !axisPoint1.valid || !axisPoint2.valid) return *this;
    // ... 计算逻辑
}
rust 复制代码
// Rust 版本
impl Vector2D {
    pub fn mirror(self, axis_point1: &Self, axis_point2: &Self) -> Self {
        let direction = *axis_point2 - *axis_point1;
        let a = direction.squared();
        
        if a < TOLERANCE_SQUARED {
            panic!("Mirror axis too short");  // 明确失败
        }
        
        let projection = *axis_point1 + direction * 
            self.dot_product(&(self - *axis_point1)) / a;
        projection * 2.0 - self
    }
}

错误处理改进:

  • C++:静默返回无效向量
  • Rust:明确panic或返回Result(实际应改为Result类型)

2.4 运算符重载对比

运算符 C++ 实现 Rust 实现 Rust 优势
+ 成员函数 trait实现 统一接口,可与其他类型互操作
- 需要检查valid 类型保证有效 无运行时检查
* 标量和向量乘法混合 分开实现Mul<f64>Mul 类型明确,避免混淆
/ 需要容差检查 trait实现中检查 错误处理集中

2.5 有效性处理的范式转变

C++ 模式(手动管理)
cpp 复制代码
// 到处都是valid检查
bool RS_Vector::operator==(const RS_Vector& v) const {
    return valid && v.valid && x==v.x && y==v.y && z==v.z;
}

double RS_Vector::magnitude() const {
    if (!valid) return 0.0;
    return sqrt(x*x + y*y + z*z);
}
Rust 模式(类型系统保证)
rust 复制代码
// Vector2D总是有效的
impl Vector2D {
    pub fn magnitude(&self) -> f64 {
        (self.x.powi(2) + self.y.powi(2)).sqrt()
    }
}

// 有效性在RsVector层面处理
impl RsVector {
    pub fn magnitude(&self) -> Option<f64> {
        self.as_ref().map(|v| v.magnitude())
    }
}

优势总结:

  1. 关注点分离:计算逻辑与有效性检查分离
  2. 性能优化:有效向量操作无额外检查
  3. 代码清晰:无效状态在类型层面明确

三、内存布局优化

3.1 内存占用对比

类型 C++ RS_Vector Rust Vector2D 节省
大小 32字节 (3×f64 + bool + 对齐) 16字节 (2×f64) 50%
缓存友好性 较差(有未使用字段) 优秀(紧凑) 缓存命中率更高

3.2 对齐优化

rust 复制代码
// Rust 自动最优对齐
assert_eq!(std::mem::size_of::<Vector2D>(), 16);  // 与[f64; 2]相同
assert_eq!(std::mem::align_of::<Vector2D>(), 8);   // f64对齐

四、API 设计改进

4.1 更清晰的接口分离

2D专用操作
rust 复制代码
impl Vector2D {
    // 这些是纯2D操作
    pub fn cross_product_2d(&self, other: &Self) -> f64;  // 返回标量
    pub fn flip_xy(&self) -> Self;  // 交换坐标
    pub fn angle(&self) -> f64;     // 2D角度
}
3D专用操作
rust 复制代码
impl Vector3D {
    // 这些是纯3D操作
    pub fn cross_product(&self, other: &Self) -> Self;  // 返回向量
    pub fn dot_product(&self, other: &Self) -> f64;     // 3D点积
}

4.2 丰富的转换支持

rust 复制代码
// 自动转换,避免手动构造
impl From<Vector2D> for Vector3D {
    fn from(v: Vector2D) -> Self {
        Self::new(v.x, v.y, 0.0)  // 自动填充z=0
    }
}

impl From<(f64, f64)> for Vector2D {
    fn from((x, y): (f64, f64)) -> Self {
        Self::new(x, y)  // 从元组自动创建
    }
}

// 使用示例
let point: Vector2D = (10.0, 20.0).into();
let point_3d: Vector3D = point.into();  // 自动转换

五、错误处理的现代化

5.1 从特殊值到类型安全

错误类型 C++ 处理 Rust 处理 优势
无效向量 RS_MAXDOUBLE Option::None 编译时检查
除零错误 容差检查 panic!Result 明确失败点
无效参数 返回无效向量 返回Option或panic 强制错误处理

5.2 推荐的实际错误处理

rust 复制代码
// 生产代码应该使用Result
impl Vector2D {
    pub fn try_div(self, scalar: f64) -> Result<Self, MathError> {
        if scalar.abs() < TOLERANCE {
            Err(MathError::DivisionByZero)
        } else {
            Ok(Self::new(self.x / scalar, self.y / scalar))
        }
    }
}

// 使用模式匹配处理错误
match vector.try_div(0.0) {
    Ok(result) => use_vector(result),
    Err(MathError::DivisionByZero) => handle_error(),
    _ => unreachable!(),
}

六、性能优势分析

6.1 编译时优化

Rust的优势:

  1. 内联优化:编译器可自由内联小型函数
  2. 常量传播TOLERANCE等常量在编译时传播
  3. 零成本抽象:Option在编译后无额外开销

6.2 运行时优势

操作 C++ 开销 Rust 开销 改进
向量创建 初始化z和valid 只初始化x,y 减少33%内存写入
距离计算 检查valid + 3D计算 纯2D计算 减少33%平方运算
角度计算 调用外部correctAngle 内置rem_euclid 减少函数调用

6.3 向量化可能性

rust 复制代码
// Rust更容易向量化
pub fn process_batch(points: &[Vector2D]) -> Vec<f64> {
    points.iter()
        .map(|p| p.magnitude())
        .collect()
}

// 编译器可能自动向量化为SIMD指令
// 因为Vector2D布局与[f64; 2]相同

七、测试和维护优势

7.1 单元测试更简单

rust 复制代码
#[test]
fn test_vector_operations() {
    let v1 = Vector2D::new(1.0, 2.0);
    let v2 = Vector2D::new(3.0, 4.0);
    
    // 无需担心valid标志
    assert_eq!(v1 + v2, Vector2D::new(4.0, 6.0));
    assert!((v1.distance_to(&v2) - 2.828).abs() < 0.001);
}

7.2 文档更清晰

rust 复制代码
/// 计算两个2D向量的点积
/// 
/// # 示例
/// ```
/// let v1 = Vector2D::new(1.0, 2.0);
/// let v2 = Vector2D::new(3.0, 4.0);
/// assert_eq!(v1.dot_product(&v2), 11.0);
/// ```
pub fn dot_product(&self, other: &Self) -> f64 {
    self.x * other.x + self.y * other.y
}

八、与C++的兼容性考虑

8.1 FFI接口设计

如果需要与现有C++代码交互:

rust 复制代码
// C兼容接口
#[repr(C)]
pub struct CVector2D {
    x: f64,
    y: f64,
}

// 转换函数
impl From<Vector2D> for CVector2D {
    fn from(v: Vector2D) -> Self {
        CVector2D { x: v.x, y: v.y }
    }
}

// C++可安全调用的函数
#[no_mangle]
pub extern "C" fn vector_distance(a: CVector2D, b: CVector2D) -> f64 {
    let va = Vector2D::new(a.x, a.y);
    let vb = Vector2D::new(b.x, b.y);
    va.distance_to(&vb)
}

九、总结:Rust实现的核心优势

9.1 安全性提升

  • 内存安全:无悬垂指针、缓冲区溢出
  • 类型安全:编译时检查所有边界情况
  • 线程安全:所有权系统天然防止数据竞争

9.2 性能优化

  • 内存效率:减少50%内存占用
  • 计算效率:消除冗余的valid检查
  • 缓存友好:紧凑的内存布局

9.3 代码质量

  • 清晰度:2D/3D明确分离
  • 可维护性:强类型减少错误
  • 可测试性:纯函数便于单元测试

9.4 现代化特性

  • 模式匹配:优雅的错误处理
  • trait系统:灵活的运算符重载
  • 零成本抽象:高级特性无运行时开销

这个Rust实现不仅完整对应了C++版本的所有功能,更通过现代化的语言特性提供了更高的安全性、更好的性能和更清晰的代码结构。特别适合CAD这种对精度和性能要求极高的应用场景。

附vector.rs源码:

rust 复制代码
// lib.rs
use std::f64::consts::PI;
use std::ops::{Add, Sub, Mul, Div, Neg, AddAssign, SubAssign, MulAssign, DivAssign};
use std::fmt;
use serde::{Serialize, Deserialize};

/// 容差常量
const TOLERANCE: f64 = 1e-9;
const TOLERANCE_SQUARED: f64 = 1e-18;
const MAX_DOUBLE: f64 = f64::MAX;

/// 2D 向量结构体 - 专为 2D CAD 设计
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct Vector2D {
    pub x: f64,
    pub y: f64,
}

/// 3D 向量结构体 - 用于需要 z 坐标的操作
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct Vector3D {
    pub x: f64,
    pub y: f64,
    pub z: f64,
}

/// 向量类型别名,使用 Option 表示有效性
pub type RsVector = Option<Vector2D>;
pub type RsVector3D = Option<Vector3D>;

/// 向量集合,使用 Option 表示有效解
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RsVectorSolutions {
    vectors: Vec<RsVector>,
    tangent: bool,
}

impl Vector2D {
    /// 创建新向量
    pub fn new(x: f64, y: f64) -> Self {
        Self { x, y }
    }
    
    /// 从极坐标创建向量
    pub fn from_angle(angle: f64) -> Self {
        Self::new(angle.cos(), angle.sin())
    }
    
    /// 从极坐标创建(半径,角度)
    pub fn polar(radius: f64, angle: f64) -> Self {
        Self::new(radius * angle.cos(), radius * angle.sin())
    }
    
    /// 设置向量值
    pub fn set(&mut self, x: f64, y: f64) {
        self.x = x;
        self.y = y;
    }
    
    /// 设置极坐标
    pub fn set_polar(&mut self, radius: f64, angle: f64) {
        self.x = radius * angle.cos();
        self.y = radius * angle.sin();
    }
    
    /// 计算距离
    pub fn distance_to(&self, other: &Self) -> f64 {
        ((self.x - other.x).powi(2) + (self.y - other.y).powi(2)).sqrt()
    }
    
    /// 计算向量角度
    pub fn angle(&self) -> f64 {
        self.y.atan2(self.x).rem_euclid(2.0 * PI)
    }
    
    /// 计算到另一个向量的角度
    pub fn angle_to(&self, other: &Self) -> f64 {
        (*other - *self).angle()
    }
    
    /// 计算三个点之间的角度
    pub fn angle_between(&self, v1: &Self, v2: &Self) -> f64 {
        let v_start = *v1 - *self;
        let v_end = *v2 - *self;
        
        let cross = v_start.x * v_end.y - v_start.y * v_end.x;
        let dot = v_start.x * v_end.x + v_start.y * v_end.y;
        
        cross.atan2(dot).rem_euclid(2.0 * PI)
    }
    
    /// 计算向量长度
    pub fn magnitude(&self) -> f64 {
        (self.x.powi(2) + self.y.powi(2)).sqrt()
    }
    
    /// 计算向量长度的平方
    pub fn squared(&self) -> f64 {
        self.x.powi(2) + self.y.powi(2)
    }
    
    /// 计算到另一个向量距离的平方
    pub fn squared_to(&self, other: &Self) -> f64 {
        (*self - *other).squared()
    }
    
    /// 线性插值
    pub fn lerp(&self, other: &Self, t: f64) -> Self {
        Self::new(
            self.x + (other.x - self.x) * t,
            self.y + (other.y - self.y) * t,
        )
    }
    
    /// 检查点是否在窗口内
    pub fn is_in_window(&self, corner1: &Self, corner2: &Self) -> bool {
        let min_x = corner1.x.min(corner2.x);
        let max_x = corner1.x.max(corner2.x);
        let min_y = corner1.y.min(corner2.y);
        let max_y = corner1.y.max(corner2.y);
        
        self.x >= min_x && self.x <= max_x && 
        self.y >= min_y && self.y <= max_y
    }
    
    /// 检查点是否在有序窗口内
    pub fn is_in_window_ordered(&self, low: &Self, high: &Self) -> bool {
        self.x >= low.x && self.x <= high.x && 
        self.y >= low.y && self.y <= high.y
    }
    
    /// 移动到最近的整数点
    pub fn to_integer(mut self) -> Self {
        self.x = self.x.round();
        self.y = self.y.round();
        self
    }
    
    /// 平移
    pub fn translate(mut self, offset: &Self) -> Self {
        self.x += offset.x;
        self.y += offset.y;
        self
    }
    
    /// 旋转(绕原点)
    pub fn rotate(mut self, angle: f64) -> Self {
        let cos_angle = angle.cos();
        let sin_angle = angle.sin();
        let new_x = self.x * cos_angle - self.y * sin_angle;
        let new_y = self.x * sin_angle + self.y * cos_angle;
        self.x = new_x;
        self.y = new_y;
        self
    }
    
    /// 旋转(返回新向量)
    pub fn rotated(&self, angle: f64) -> Self {
        let cos_angle = angle.cos();
        let sin_angle = angle.sin();
        Self::new(
            self.x * cos_angle - self.y * sin_angle,
            self.x * sin_angle + self.y * cos_angle,
        )
    }
    
    /// 绕指定点旋转
    pub fn rotate_around(self, center: &Self, angle: f64) -> Self {
        let offset = self - center;
        let rotated = offset.rotated(angle);
        center + rotated
    }
    
    /// 缩放
    pub fn scale(mut self, factor: f64) -> Self {
        self.x *= factor;
        self.y *= factor;
        self
    }
    
    /// 各分量缩放
    pub fn scale_components(mut self, factor: &Self) -> Self {
        self.x *= factor.x;
        self.y *= factor.y;
        self
    }
    
    /// 绕指定点缩放
    pub fn scale_around(self, center: &Self, factor: &Self) -> Self {
        *center + (self - *center).scale_components(factor)
    }
    
    /// 镜像
    pub fn mirror(self, axis_point1: &Self, axis_point2: &Self) -> Self {
        let direction = *axis_point2 - *axis_point1;
        let a = direction.squared();
        
        if a < TOLERANCE_SQUARED {
            panic!("Mirror axis too short");
        }
        
        let projection = *axis_point1 + direction * 
            self.dot_product(&(self - *axis_point1)) / a;
        projection * 2.0 - self
    }
    
    /// 相对坐标
    pub fn relative(&self, distance: f64, angle: f64) -> Self {
        Self::new(
            self.x + distance * angle.cos(),
            self.y + distance * angle.sin(),
        )
    }
    
    /// 剪切变换
    pub fn shear(mut self, k: f64) -> Self {
        self.x += k * self.y;
        self
    }
    
    /// 点积
    pub fn dot_product(&self, other: &Self) -> f64 {
        self.x * other.x + self.y * other.y
    }
    
    /// 2D 叉积(返回标量)
    pub fn cross_product_2d(&self, other: &Self) -> f64 {
        self.x * other.y - self.y * other.x
    }
    
    /// 归一化
    pub fn normalize(mut self) -> Self {
        let mag = self.magnitude();
        if mag > TOLERANCE {
            let inv_mag = 1.0 / mag;
            self.x *= inv_mag;
            self.y *= inv_mag;
        }
        self
    }
    
    /// 返回归一化向量
    pub fn normalized(&self) -> Self {
        let mag = self.magnitude();
        if mag > TOLERANCE {
            let inv_mag = 1.0 / mag;
            Self::new(
                self.x * inv_mag,
                self.y * inv_mag,
            )
        } else {
            *self
        }
    }
    
    /// 交换x和y坐标
    pub fn flip_xy(&self) -> Self {
        Self::new(self.y, self.x)
    }
    
    /// 转换为 Vector3D(z=0)
    pub fn to_3d(&self) -> Vector3D {
        Vector3D::new(self.x, self.y, 0.0)
    }
}

impl Vector3D {
    /// 创建新 3D 向量
    pub fn new(x: f64, y: f64, z: f64) -> Self {
        Self { x, y, z }
    }
    
    /// 从 Vector2D 创建(z=0)
    pub fn from_2d(v2d: &Vector2D) -> Self {
        Self::new(v2d.x, v2d.y, 0.0)
    }
    
    /// 计算 3D 距离
    pub fn distance_to(&self, other: &Self) -> f64 {
        ((self.x - other.x).powi(2) + 
         (self.y - other.y).powi(2) + 
         (self.z - other.z).powi(2)).sqrt()
    }
    
    /// 计算向量长度
    pub fn magnitude(&self) -> f64 {
        (self.x.powi(2) + self.y.powi(2) + self.z.powi(2)).sqrt()
    }
    
    /// 计算向量长度的平方
    pub fn squared(&self) -> f64 {
        self.x.powi(2) + self.y.powi(2) + self.z.powi(2)
    }
    
    /// 线性插值
    pub fn lerp(&self, other: &Self, t: f64) -> Self {
        Self::new(
            self.x + (other.x - self.x) * t,
            self.y + (other.y - self.y) * t,
            self.z + (other.z - self.z) * t,
        )
    }
    
    /// 3D 点积
    pub fn dot_product(&self, other: &Self) -> f64 {
        self.x * other.x + self.y * other.y + self.z * other.z
    }
    
    /// 3D 叉积
    pub fn cross_product(&self, other: &Self) -> Self {
        Self::new(
            self.y * other.z - self.z * other.y,
            self.z * other.x - self.x * other.z,
            self.x * other.y - self.y * other.x,
        )
    }
    
    /// 归一化
    pub fn normalize(mut self) -> Self {
        let mag = self.magnitude();
        if mag > TOLERANCE {
            let inv_mag = 1.0 / mag;
            self.x *= inv_mag;
            self.y *= inv_mag;
            self.z *= inv_mag;
        }
        self
    }
    
    /// 返回归一化向量
    pub fn normalized(&self) -> Self {
        let mag = self.magnitude();
        if mag > TOLERANCE {
            let inv_mag = 1.0 / mag;
            Self::new(
                self.x * inv_mag,
                self.y * inv_mag,
                self.z * inv_mag,
            )
        } else {
            *self
        }
    }
    
    /// 转换为 Vector2D(丢弃 z 坐标)
    pub fn to_2d(&self) -> Vector2D {
        Vector2D::new(self.x, self.y)
    }
}

// 为 Vector2D 实现运算符重载
impl Add for Vector2D {
    type Output = Self;
    
    fn add(self, other: Self) -> Self {
        Self::new(self.x + other.x, self.y + other.y)
    }
}

impl Sub for Vector2D {
    type Output = Self;
    
    fn sub(self, other: Self) -> Self {
        Self::new(self.x - other.x, self.y - other.y)
    }
}

impl Mul<f64> for Vector2D {
    type Output = Self;
    
    fn mul(self, scalar: f64) -> Self {
        Self::new(self.x * scalar, self.y * scalar)
    }
}

impl Mul for Vector2D {
    type Output = Self;
    
    fn mul(self, other: Self) -> Self {
        Self::new(self.x * other.x, self.y * other.y)
    }
}

impl Div<f64> for Vector2D {
    type Output = Self;
    
    fn div(self, scalar: f64) -> Self {
        if scalar.abs() < TOLERANCE {
            panic!("Division by zero");
        }
        Self::new(self.x / scalar, self.y / scalar)
    }
}

impl Div for Vector2D {
    type Output = Self;
    
    fn div(self, other: Self) -> Self {
        if other.x.abs() < TOLERANCE || other.y.abs() < TOLERANCE {
            panic!("Division by near-zero component");
        }
        Self::new(self.x / other.x, self.y / other.y)
    }
}

impl Neg for Vector2D {
    type Output = Self;
    
    fn neg(self) -> Self {
        Self::new(-self.x, -self.y)
    }
}

// 为 Vector3D 实现运算符重载
impl Add for Vector3D {
    type Output = Self;
    
    fn add(self, other: Self) -> Self {
        Self::new(self.x + other.x, self.y + other.y, self.z + other.z)
    }
}

impl Sub for Vector3D {
    type Output = Self;
    
    fn sub(self, other: Self) -> Self {
        Self::new(self.x - other.x, self.y - other.y, self.z - other.z)
    }
}

impl Mul<f64> for Vector3D {
    type Output = Self;
    
    fn mul(self, scalar: f64) -> Self {
        Self::new(self.x * scalar, self.y * scalar, self.z * scalar)
    }
}

impl Neg for Vector3D {
    type Output = Self;
    
    fn neg(self) -> Self {
        Self::new(-self.x, -self.y, -self.z)
    }
}

impl fmt::Display for Vector2D {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}/{}", self.x, self.y)
    }
}

impl fmt::Display for Vector3D {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}/{}/{}", self.x, self.y, self.z)
    }
}

// 转换 trait 实现
impl From<Vector2D> for Vector3D {
    fn from(v: Vector2D) -> Self {
        Self::new(v.x, v.y, 0.0)
    }
}

impl From<Vector3D> for Vector2D {
    fn from(v: Vector3D) -> Self {
        Self::new(v.x, v.y)
    }
}

impl From<(f64, f64)> for Vector2D {
    fn from((x, y): (f64, f64)) -> Self {
        Self::new(x, y)
    }
}

impl From<(f64, f64, f64)> for Vector3D {
    fn from((x, y, z): (f64, f64, f64)) -> Self {
        Self::new(x, y, z)
    }
}

// 为 RsVector (Option<Vector2D>) 提供便利方法
impl RsVector {
    /// 安全的创建方法
    pub fn valid(x: f64, y: f64) -> Self {
        Some(Vector2D::new(x, y))
    }
    
    /// 无效向量
    pub fn invalid() -> Self {
        None
    }
    
    /// 检查是否有效
    pub fn is_valid(&self) -> bool {
        self.is_some()
    }
    
    /// 解包向量,如果无效则返回默认值
    pub fn unwrap_or_default(&self) -> Vector2D {
        self.unwrap_or(Vector2D::new(0.0, 0.0))
    }
    
    /// 应用函数到向量(如果有)
    pub fn map<F>(self, f: F) -> Self 
    where
        F: FnOnce(Vector2D) -> Vector2D,
    {
        self.map(f)
    }
    
    /// 应用可能失败的函数
    pub fn and_then<F>(self, f: F) -> Self 
    where
        F: FnOnce(Vector2D) -> Self,
    {
        self.and_then(f)
    }
    
    /// 计算距离,如果任一向量无效则返回 None
    pub fn distance_to(&self, other: &Self) -> Option<f64> {
        match (self, other) {
            (Some(v1), Some(v2)) => Some(v1.distance_to(v2)),
            _ => None,
        }
    }
    
    /// 计算角度,如果向量无效则返回 None
    pub fn angle(&self) -> Option<f64> {
        self.as_ref().map(|v| v.angle())
    }
    
    /// 计算到另一个向量的角度
    pub fn angle_to(&self, other: &Self) -> Option<f64> {
        match (self, other) {
            (Some(v1), Some(v2)) => Some(v1.angle_to(v2)),
            _ => None,
        }
    }
    
    /// 平移向量
    pub fn translate(self, offset: &Self) -> Self {
        match (self, offset) {
            (Some(v), Some(off)) => Some(v.translate(off)),
            _ => None,
        }
    }
    
    /// 旋转向量
    pub fn rotate(self, angle: f64) -> Self {
        self.map(|v| v.rotate(angle))
    }
    
    /// 缩放向量
    pub fn scale(self, factor: f64) -> Self {
        self.map(|v| v.scale(factor))
    }
    
    /// 归一化
    pub fn normalize(self) -> Self {
        self.map(|v| v.normalize())
    }
}

// 静态方法实现
impl Vector2D {
    /// 静态方法:点积
    pub fn dot(v1: &Self, v2: &Self) -> f64 {
        v1.dot_product(v2)
    }
    
    /// 静态方法:2D 叉积(标量)
    pub fn cross_2d(v1: &Self, v2: &Self) -> f64 {
        v1.cross_product_2d(v2)
    }
    
    /// 静态方法:最小值
    pub fn min(v1: &Self, v2: &Self) -> Self {
        Self::new(
            v1.x.min(v2.x),
            v1.y.min(v2.y),
        )
    }
    
    /// 静态方法:最大值
    pub fn max(v1: &Self, v2: &Self) -> Self {
        Self::new(
            v1.x.max(v2.x),
            v1.y.max(v2.y),
        )
    }
    
    /// 计算在线段上的位置参数
    pub fn position_on_line(start: &Self, end: &Self, point: &Self) -> f64 {
        let dir_end = *end - *start;
        let dir_point = *point - *start;
        let len_squared = dir_end.squared();
        
        if len_squared < TOLERANCE_SQUARED {
            return start.distance_to(point);
        }
        
        dir_point.dot_product(&dir_end) / len_squared
    }
}

impl Vector3D {
    /// 静态方法:3D 叉积
    pub fn cross(v1: &Self, v2: &Self) -> Self {
        v1.cross_product(v2)
    }
    
    /// 静态方法:3D 点积
    pub fn dot(v1: &Self, v2: &Self) -> f64 {
        v1.dot_product(v2)
    }
    
    /// 静态方法:最小值
    pub fn min(v1: &Self, v2: &Self) -> Self {
        Self::new(
            v1.x.min(v2.x),
            v1.y.min(v2.y),
            v1.z.min(v2.z),
        )
    }
    
    /// 静态方法:最大值
    pub fn max(v1: &Self, v2: &Self) -> Self {
        Self::new(
            v1.x.max(v2.x),
            v1.y.max(v2.y),
            v1.z.max(v2.z),
        )
    }
}

// RsVectorSolutions 实现
impl RsVectorSolutions {
    /// 创建空集合
    pub fn new() -> Self {
        Self {
            vectors: Vec::new(),
            tangent: false,
        }
    }
    
    /// 从向量切片创建
    pub fn from_vectors(vectors: Vec<RsVector>) -> Self {
        Self {
            vectors,
            tangent: false,
        }
    }
    
    /// 从基础向量切片创建
    pub fn from_vector2ds(vectors: Vec<Vector2D>) -> Self {
        Self {
            vectors: vectors.into_iter().map(Some).collect(),
            tangent: false,
        }
    }
    
    /// 从迭代器创建
    pub fn from_iter<I: IntoIterator<Item = RsVector>>(iter: I) -> Self {
        Self {
            vectors: iter.into_iter().collect(),
            tangent: false,
        }
    }
    
    /// 获取向量数量
    pub fn len(&self) -> usize {
        self.vectors.len()
    }
    
    /// 检查是否为空
    pub fn is_empty(&self) -> bool {
        self.vectors.is_empty()
    }
    
    /// 获取向量引用
    pub fn get(&self, index: usize) -> Option<&RsVector> {
        self.vectors.get(index)
    }
    
    /// 获取向量可变引用
    pub fn get_mut(&mut self, index: usize) -> Option<&mut RsVector> {
        self.vectors.get_mut(index)
    }
    
    /// 添加向量
    pub fn push(&mut self, vector: RsVector) {
        self.vectors.push(vector);
    }
    
    /// 添加基础向量
    pub fn push_vector2d(&mut self, vector: Vector2D) {
        self.vectors.push(Some(vector));
    }
    
    /// 移除指定位置的向量
    pub fn remove(&mut self, index: usize) -> RsVector {
        self.vectors.remove(index)
    }
    
    /// 清空集合
    pub fn clear(&mut self) {
        self.vectors.clear();
        self.tangent = false;
    }
    
    /// 调整大小
    pub fn resize(&mut self, new_len: usize, value: RsVector) {
        self.vectors.resize(new_len, value);
    }
    
    /// 检查是否有有效向量
    pub fn has_valid(&self) -> bool {
        self.vectors.iter().any(|v| v.is_some())
    }
    
    /// 获取所有有效向量的迭代器
    pub fn valid_vectors(&self) -> impl Iterator<Item = &Vector2D> {
        self.vectors.iter().filter_map(|v| v.as_ref())
    }
    
    /// 获取所有有效向量的可变迭代器
    pub fn valid_vectors_mut(&mut self) -> impl Iterator<Item = &mut Vector2D> {
        self.vectors.iter_mut().filter_map(|v| v.as_mut())
    }
    
    /// 设置切线标志
    pub fn set_tangent(&mut self, tangent: bool) {
        self.tangent = tangent;
    }
    
    /// 检查是否为切线解
    pub fn is_tangent(&self) -> bool {
        self.tangent
    }
    
    /// 获取最接近的向量
    pub fn get_closest(&self, coord: &Vector2D) -> Option<(Vector2D, f64, usize)> {
        let mut result = None;
        let mut min_distance = f64::MAX;
        let mut index = 0;
        
        for (i, vector) in self.vectors.iter().enumerate() {
            if let Some(vector) = vector {
                let distance = vector.distance_to(coord);
                if distance < min_distance {
                    min_distance = distance;
                    result = Some((*vector, distance, i));
                }
            }
        }
        
        result
    }
    
    /// 批量旋转
    pub fn rotate(&mut self, angle: f64) {
        for vector in self.valid_vectors_mut() {
            *vector = vector.rotated(angle);
        }
    }
    
    /// 批量平移
    pub fn translate(&mut self, offset: &Vector2D) {
        for vector in self.valid_vectors_mut() {
            *vector = *vector + *offset;
        }
    }
    
    /// 批量缩放
    pub fn scale(&mut self, factor: &Vector2D) {
        for vector in self.valid_vectors_mut() {
            *vector = vector.scale_components(factor);
        }
    }
    
    /// 交换x,y坐标
    pub fn flip_xy(&self) -> Self {
        let vectors = self.vectors.iter()
            .map(|v| v.map(|v| v.flip_xy()))
            .collect();
        Self {
            vectors,
            tangent: self.tangent,
        }
    }
    
    /// 获取迭代器
    pub fn iter(&self) -> impl Iterator<Item = &RsVector> {
        self.vectors.iter()
    }
    
    /// 获取可变迭代器
    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut RsVector> {
        self.vectors.iter_mut()
    }
}

impl fmt::Display for RsVectorSolutions {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        writeln!(f, "VectorSolutions:")?;
        for (i, vector) in self.vectors.iter().enumerate() {
            match vector {
                Some(v) => writeln!(f, "  [{}]: {}", i, v)?,
                None => writeln!(f, "  [{}]: invalid", i)?,
            }
        }
        write!(f, "  tangent: {}", self.tangent)
    }
}

impl Default for RsVectorSolutions {
    fn default() -> Self {
        Self::new()
    }
}

// 单元测试
#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_vector2d_creation() {
        let v1 = Vector2D::new(1.0, 2.0);
        assert_eq!(v1.x, 1.0);
        assert_eq!(v1.y, 2.0);
        
        let v2 = Vector2D::polar(5.0, 0.0);
        assert!((v2.x - 5.0).abs() < 1e-10);
        assert!((v2.y - 0.0).abs() < 1e-10);
    }
    
    #[test]
    fn test_vector3d_creation() {
        let v3d = Vector3D::new(1.0, 2.0, 3.0);
        assert_eq!(v3d.z, 3.0);
        
        let v2d = Vector2D::new(4.0, 5.0);
        let v3d_from_2d = Vector3D::from_2d(&v2d);
        assert_eq!(v3d_from_2d.x, 4.0);
        assert_eq!(v3d_from_2d.z, 0.0);
    }
    
    #[test]
    fn test_conversion_between_2d_and_3d() {
        let v2d = Vector2D::new(1.0, 2.0);
        let v3d: Vector3D = v2d.into();
        assert_eq!(v3d.x, 1.0);
        assert_eq!(v3d.y, 2.0);
        assert_eq!(v3d.z, 0.0);
        
        let v3d_2 = Vector3D::new(3.0, 4.0, 5.0);
        let v2d_2: Vector2D = v3d_2.into();
        assert_eq!(v2d_2.x, 3.0);
        assert_eq!(v2d_2.y, 4.0);
    }
    
    #[test]
    fn test_cross_products() {
        let v1 = Vector2D::new(1.0, 0.0);
        let v2 = Vector2D::new(0.0, 1.0);
        let cross_2d = Vector2D::cross_2d(&v1, &v2);
        assert!((cross_2d - 1.0).abs() < 1e-10);
        
        let v3d1 = Vector3D::new(1.0, 0.0, 0.0);
        let v3d2 = Vector3D::new(0.0, 1.0, 0.0);
        let cross_3d = Vector3D::cross(&v3d1, &v3d2);
        assert_eq!(cross_3d.z, 1.0);
    }
    
    #[test]
    fn test_memory_size() {
        use std::mem::size_of;
        assert_eq!(size_of::<Vector2D>(), 16); // 2 * f64
        assert_eq!(size_of::<Vector3D>(), 24); // 3 * f64
    }
    
    #[test]
    fn test_angle_calculations() {
        let v = Vector2D::new(1.0, 0.0);
        assert!((v.angle() - 0.0).abs() < 1e-10);
        
        let v = Vector2D::new(0.0, 1.0);
        assert!((v.angle() - PI/2.0).abs() < 1e-10);
    }
}
相关推荐
Hello.Reader1 小时前
Rocket 0.5 快速上手3 分钟跑起第一个 Rust Web 服务
开发语言·前端·rust
蚂蚁取经1 小时前
Qt C++ 小部件 QCustomPlot 的使用
c++·qt·信息可视化
爱装代码的小瓶子1 小时前
【c++知识铺子】最后一块拼图-多态
java·开发语言·c++
Source.Liu1 小时前
【LibreCAD】RS2 模块完整解析
qt·cad
无限进步_1 小时前
C语言文件操作函数解析
c语言·开发语言·数据库·c++·后端·visual studio
FreeBuf_2 小时前
恶意 Rust 包瞄准 Web3 开发者窃取加密货币
开发语言·rust·web3
_OP_CHEN2 小时前
【算法基础篇】(二十六)数据结构封神!Trie 树从入门到爆杀算法题:拼音输入法、单词统计都靠它
数据结构·c++·算法·蓝桥杯·trie树·算法竞赛·acm/icpc
ULTRA??2 小时前
C++类型和容器在Rust中的对应关系
c++·rust
Source.Liu2 小时前
【学写LibreCAD】单位转换系统 Rust 实现
qt·rust·cad