【LibreCAD】 rs_vector.cpp 文件详解

这是rs_vector.cpp文件,实现了rs_vector.h中声明的RS_VectorRS_VectorSolutions类的所有成员函数。以下是详细的实现分析:

文件概述

  • 实现内容:提供向量和向量集合的完整实现
  • 数学依赖:使用标准C++数学库和Qt的QPointF
  • 精度处理 :包含各种容差检查(RS_TOLERANCE

RS_Vector 类实现详解

1. 构造函数实现

cpp 复制代码
RS_Vector::RS_Vector(double vx, double vy, double vz):
    x(vx), y(vy), z(vz), valid(true) {}
  • 坐标构造:设置x,y,z并标记为有效
cpp 复制代码
RS_Vector::RS_Vector(double angle):
    x(std::cos(angle)), y(std::sin(angle)), valid(true) {}
  • 角度构造:创建单位方向向量
cpp 复制代码
RS_Vector::RS_Vector(bool valid): valid(valid) {}
  • 有效性构造:仅设置有效性标志

2. 基本设置方法

cpp 复制代码
void RS_Vector::set(double vx, double vy, double vz) {
    x = vx; y = vy; z = vz; valid = true;
}
  • 直接设置坐标值
cpp 复制代码
void RS_Vector::setPolar(double radius, double angle) {
    x = radius * std::cos(angle);
    y = radius * std::sin(angle);
    z = 0.0;
    valid = true;
}
  • 极坐标设置: x = r ⋅ cos ⁡ ( θ ) x = r \cdot \cos(\theta) x=r⋅cos(θ), y = r ⋅ sin ⁡ ( θ ) y = r \cdot \sin(\theta) y=r⋅sin(θ)

3. 几何计算实现

向量长度计算
cpp 复制代码
double RS_Vector::magnitude() const {
    if (valid)
        return std::hypot(std::hypot(x, y), z);
    return 0.0;
}
  • 使用std::hypot避免数值溢出
角度计算
cpp 复制代码
double RS_Vector::angle() const {
    return RS_Math::correctAngle(std::atan2(y,x));
}

double RS_Vector::angleTo(const RS_Vector& v) const {
    return (v-(*this)).angle();
}
  • atan2计算方位角,经过角度修正
  • angleTo计算两点连线与X轴夹角
三点夹角计算
cpp 复制代码
double RS_Vector::angleBetween(const RS_Vector& v1, const RS_Vector& v2) const {
    RS_Vector const vStart(v1 - (*this));
    RS_Vector const vEnd(v2 - (*this));
    return RS_Math::correctAngle(
        std::atan2(vStart.x * vEnd.y - vStart.y * vEnd.x,
                   vStart.x * vEnd.x + vStart.y * vEnd.y));
}
  • 使用向量叉积和点积公式: θ = atan2 ( v 1 × v 2 , v 1 ⋅ v 2 ) \theta = \text{atan2}(v_1 \times v_2, v_1 \cdot v_2) θ=atan2(v1×v2,v1⋅v2)

4. 几何变换实现

旋转实现
cpp 复制代码
RS_Vector& RS_Vector::rotate(const RS_Vector& angleVector) {
    double x0 = x * angleVector.x - y * angleVector.y;
    y = x * angleVector.y + y * angleVector.x;
    x = x0;
    return *this;
}
  • 使用旋转矩阵: [ cos ⁡ θ − sin ⁡ θ sin ⁡ θ cos ⁡ θ ] \begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{bmatrix} [cosθsinθ−sinθcosθ]
  • 如果angleVector是单位向量,表示旋转角度
镜像实现
cpp 复制代码
RS_Vector& RS_Vector::mirror(const RS_Vector& axisPoint1, 
                             const RS_Vector& axisPoint2) {
    RS_Vector direction(axisPoint2-axisPoint1);
    double a= direction.squared();
    if(a<RS_TOLERANCE2) return *this; // 轴太短
    
    RS_Vector ret= axisPoint1 + direction* dotP(*this - axisPoint1,direction)/a;
    *this = ret + ret - *this;
    return *this;
}
  • 计算点在线上的投影
  • 镜像公式: P ′ = 2 × proj − P P' = 2 \times \text{proj} - P P′=2×proj−P
剪切变换
cpp 复制代码
RS_Vector& RS_Vector::shear(double k) {
    x += k * y;
    return *this;
}
  • x坐标受y坐标影响: x ′ = x + k ⋅ y x' = x + k \cdot y x′=x+k⋅y

5. 运算符重载实现

算术运算
cpp 复制代码
RS_Vector RS_Vector::operator * (const RS_Vector& v) const {
    return {x * v.x, y * v.y, z * v.z};
}

RS_Vector RS_Vector::operator / (const RS_Vector& v) const {
    if(fabs(v.x)> RS_TOLERANCE && fabs(v.y)>RS_TOLERANCE)
        return {x / v.x, y / v.y, z / v.z};
    return *this; // 防止除以零
}
  • 逐分量运算
  • 除法有容差检查
比较运算
cpp 复制代码
bool RS_Vector::operator == (const RS_Vector& v) const {
    return valid && v.valid
           && RS_Math::equal(x, v.x)
           && RS_Math::equal(y, v.y)
           && RS_Math::equal(z, v.z);
}
  • 严格相等,考虑有效性和容差

6. 静态方法实现

最小/最大值向量
cpp 复制代码
RS_Vector RS_Vector::minimum(const RS_Vector& v1, const RS_Vector& v2) {
    if (!v2) return v1;
    if (!v1) return v2;
    return {std::min(v1.x, v2.x),
            std::min(v1.y, v2.y),
            std::min(v1.z, v2.z)};
}
  • 对每个分量取最小值
叉积计算
cpp 复制代码
RS_Vector RS_Vector::crossP(const RS_Vector& v1, const RS_Vector& v2) {
    return {v1.y*v2.z - v1.z*v2.y,
            v1.z*v2.x - v1.x*v2.z,
            v1.x*v2.y - v1.y*v2.x};
}
  • 标准3D向量叉积公式

RS_VectorSolutions 类实现详解

1. 存储管理

cpp 复制代码
void RS_VectorSolutions::alloc(size_t num) {
    if(num <= vector.size()){
        vector.resize(num);
    } else {
        vector.insert(vector.end(), num - vector.size(), RS_Vector(false));
    }
}
  • 动态调整向量数组大小

2. 安全访问

cpp 复制代码
RS_Vector RS_VectorSolutions::get(size_t i) const {
    if(i < vector.size())
        return vector.at(i);
    return {}; // 返回无效向量
}
  • 带边界检查的访问方法

3. 最近点搜索

cpp 复制代码
RS_Vector RS_VectorSolutions::getClosest(const RS_Vector &coord,
                                         double* dist, size_t* index) const {
    double curDist{0.};
    double minDist = RS_MAXDOUBLE;
    RS_Vector closestPoint{false};
    int pos(0);

    for (size_t i=0; i<vector.size(); i++) {
        if (vector[i].valid) {
            curDist = (coord - vector[i]).squared(); // 用平方距离避免开方
            if (curDist < minDist) {
                closestPoint = vector[i];
                minDist = curDist;
                pos = i;
            }
        }
    }
    if (dist) *dist = std::sqrt(minDist);
    if (index) *index = pos;
    return closestPoint;
}
  • 平方距离优化性能
  • 返回最近点、距离和索引

4. 批量变换

cpp 复制代码
void RS_VectorSolutions::rotate(const RS_Vector& center, double ang) {
    const RS_Vector angleVector(ang);
    for (auto& vp: vector) {
        if (vp.valid) {
            vp.rotate(center, angleVector);
        }
    }
}
  • 对集合中所有有效向量应用相同变换

关键算法和技术细节

1. 数值稳定性处理

cpp 复制代码
if(fabs(v.x)> RS_TOLERANCE && fabs(v.y)>RS_TOLERANCE)
  • 所有除法操作都检查除数是否足够大

2. 性能优化

  • 使用平方距离比较避免开方运算
  • 使用std::hypot避免数值溢出
  • 移动语义减少复制

3. 错误处理

cpp 复制代码
if(a<RS_TOLERANCE2) {
    ret = RS_Vector{false};
    return ret;
}
  • 对无效几何条件返回无效向量

4. 数学精度

  • 使用RS_Math::equal进行浮点数比较
  • 使用RS_Math::correctAngle进行角度规范化

使用注意事项

  1. 有效性检查:始终检查向量是否有效
  2. 容差处理:几何计算包含容差处理
  3. 性能考虑 :批量操作时使用RS_VectorSolutions
  4. 坐标系统:Z坐标通常为0(2D CAD)

这个实现文件提供了完整、健壮且高效的向量运算功能,是LibreCAD几何计算的核心。

相关推荐
DongLi012 天前
rustlings 学习笔记 -- exercises/05_vecs
rust
番茄灭世神2 天前
Rust学习笔记第2篇
rust·编程语言
shimly1234563 天前
(done) 速通 rustlings(20) 错误处理1 --- 不涉及Traits
rust
shimly1234563 天前
(done) 速通 rustlings(19) Option
rust
@atweiwei3 天前
rust所有权机制详解
开发语言·数据结构·后端·rust·内存·所有权
shimly1234563 天前
(done) 速通 rustlings(24) 错误处理2 --- 涉及Traits
rust
shimly1234563 天前
(done) 速通 rustlings(23) 特性 Traits
rust
shimly1234563 天前
(done) 速通 rustlings(17) 哈希表
rust
shimly1234563 天前
(done) 速通 rustlings(15) 字符串
rust
shimly1234563 天前
(done) 速通 rustlings(22) 泛型
rust