【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几何计算的核心。

相关推荐
江公望2 小时前
Tauri框架是什么,它能做什么?
rust·tauri·流媒体
星释2 小时前
Rust 练习册 108:深入探索过程宏的奥秘
开发语言·后端·rust
百锦再3 小时前
.NET到Java的终极迁移指南:最快转型路线图
android·java·开发语言·python·rust·go·.net
wadesir17 小时前
深入理解Rust静态生命周期(从零开始掌握‘static的奥秘)
开发语言·后端·rust
脑极体21 小时前
蓝河入海:Rust先行者vivo的开源之志
开发语言·后端·rust·开源
badmonster01 天前
实时代码库索引:用 CocoIndex 构建智能代码搜索的终极方案
python·rust
黛色正浓1 天前
【React】极客园案例实践-项目搭建和登录模块
前端·react.js·rust
思密吗喽1 天前
npm install 报错,解决 node-sass@4.14.1 安装失败问题
rust·npm·node.js·毕业设计·sass·课程设计
青云交1 天前
深度实战:Rust交叉编译适配OpenHarmony PC——ansi_term完整适配案例
rust·交叉编译·命令行工具·openharmony pc·ansi_term·适配案例·终端颜色