# FastChart3D **Repository Path**: thdmi/fast-chart3-d ## Basic Information - **Project Name**: FastChart3D - **Description**: No description available - **Primary Language**: C++ - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-03 - **Last Updated**: 2026-07-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Chart3D - 高性能三维数据可视化组件 基于 Qt 6 + OpenGL 的高性能 3D 散点数据可视化组件,专为实时大规模三维数据展示而设计。 ## 目录 - [模块用途](#模块用途) - [使用示例](#使用示例) - [调用方法](#调用方法) - [核心接口](#核心接口) - [注意事项](#注意事项) - [可选项](#可选项) - [构建与运行](#构建与运行) --- ## 模块用途 ### 核心功能 Chart3D 是一个基于 Qt 6 和 OpenGL 的三维散点数据可视化组件,提供以下核心能力: - **高性能实时渲染**:基于 OpenGL 的 GPU 加速渲染,支持每秒 10,000 个数据点的插入速度 - **大规模数据支持**:内置降采样算法,累计支持最高 1,000,000 个数据点的可视化 - **三维交互操作**:支持鼠标拖拽旋转视角、滚轮缩放、空格键重置视图 - **多坐标系支持**:支持基准点偏移、Z轴压缩显示、Y/Z轴交换等坐标变换 - **自动适配视图**:根据数据范围自动调整缩放比例,确保数据始终在可视范围内 ### 设计目的 - **线程分离**:数据处理与 UI 渲染解耦,避免长时间计算阻塞界面 - **内存优化**:降采样机制保证渲染性能,避免 GPU 过载 - **模块化设计**:清晰的类职责划分,易于集成和扩展 ### 适用场景 - 实时传感器数据三维可视化 - 经纬度与高度数据的空间展示 - 时间序列三维轨迹展示 - 大规模点云数据预览 - 科学计算数据三维呈现 --- ## 使用示例 ### 基础使用:插入数据点 ```cpp #include "scatter3dvisualizer.h" #include #include int main(int argc, char* argv[]) { QApplication app(argc, argv); Scatter3DVisualizer visualizer; visualizer.resize(1000, 800); visualizer.show(); // 单个点插入 QVector3D point{10.0f, 20.0f, 30.0f}; visualizer.InsertData(point); // 批量点插入(性能更优) QVector points{}; for (int i = 0; i < 1000; ++i) { float x = static_cast(i); float y = static_cast(i * i) / 100.0f; float z = static_cast(sin(i * 0.1)) * 50.0f; points.append(QVector3D{x, y, z}); } visualizer.InsertData(points); return app.exec(); } ``` ### 使用基准点 ```cpp // 设置基准点(经纬度+高度示例) QVector3D reference_point{90.0f, 90.0f, 500000.0f}; visualizer.SetReferencePoint(reference_point); // 后续插入的所有点都会以基准点为原点进行偏移显示 QVector3D data_point{95.0f, 92.0f, 510000.0f}; visualizer.InsertData(data_point); // 实际显示为 (5, 2, 10000) // 清除基准点 visualizer.ClearReferencePoint(); ``` ### 使用 Z 轴压缩 ```cpp // 设置 Z 轴压缩比例(适用于经纬度与高度数据范围差异大的场景) visualizer.SetAxisCompression(0.00001f); // 原始数据 Z 范围 0~1,000,000 压缩后显示为 0~10 ``` ### 使用缓冲插入(推荐用于高频数据场景) ```cpp // 设置缓冲区容量(可选,默认1024) visualizer.SetBufferCapacity(2048); // 高频插入数据(数据会先存入缓冲区,满后自动批量写入) for (int i = 0; i < 10000; ++i) { float x = static_cast(sin(i * 0.1)); float y = static_cast(cos(i * 0.1)); float z = static_cast(i * 0.5); visualizer.BufferedInsert(QVector3D{x, y, z}); } // 手动刷新缓冲区(在数据生成结束后调用,确保所有数据都已写入) visualizer.FlushBuffer(); ``` ### 完整界面集成示例 ```cpp #include "mainwindow.h" #include int main(int argc, char* argv[]) { QApplication app(argc, argv); MainWindow window; window.show(); return app.exec(); } ``` --- ## 调用方法 ### 前置条件 | 依赖项 | 版本要求 | 说明 | |--------|---------|------| | Qt | 6.x 及以上 | 使用 Qt6::Core, Qt6::Widgets, Qt6::OpenGL, Qt6::OpenGLWidgets | | CMake | 3.16 及以上 | 构建系统 | | C++ 编译器 | 支持 C++17 | MSVC 2022、GCC 9+、Clang 10+ | | OpenGL | 3.3 及以上 | 图形驱动支持 | ### 集成步骤 1. **添加头文件** ```cpp #include "scatter3dvisualizer.h" ``` 2. **创建可视化组件** ```cpp Scatter3DVisualizer* visualizer = new Scatter3DVisualizer(parent_widget); ``` 3. **设置可选配置** ```cpp visualizer->SetAutoFit(true); // 启用自动适配 visualizer->SetAxisCompression(0.001f); // 设置Z轴压缩比例 visualizer->SetReferencePoint(ref); // 设置基准点 ``` 4. **插入数据** ```cpp visualizer->InsertData(data_points); ``` 5. **显示组件** ```cpp visualizer->show(); ``` ### 交互操作 | 操作 | 功能 | |------|------| | 鼠标左键拖拽 | 旋转三维视角 | | 鼠标中键拖拽 | 上下左右平移视角 | | 鼠标右键 | 重置视图 | | 鼠标滚轮 | 缩放视图 | | F 键 | 切换自动适配开关 | --- ## 核心接口 ### Scatter3DVisualizer 类 #### 数据操作接口 | 接口名称 | 功能描述 | |----------|---------| | `InsertData(points_)` | 批量插入三维数据点(立即写入) | | `InsertData(point_)` | 插入单个三维数据点(立即写入) | | `BufferedInsert(point_)` | 缓冲插入单个数据点(暂存至缓冲区,满后批量写入) | | `FlushBuffer()` | 手动刷新缓冲区,将剩余数据立即写入 | | `ClearData()` | 清空所有数据并重置视图 | **参数说明:** | 参数名称 | 类型 | 必填性 | 默认值 | 说明 | |---------|------|--------|--------|------| | `points_` | `const QVector&` | 是 | - | 批量插入的点集合 | | `point_` | `const QVector3D&` | 是 | - | 单个插入的数据点 | #### 缓冲区配置接口 | 接口名称 | 功能描述 | |----------|---------| | `SetBufferCapacity(capacity_)` | 设置缓冲区容量(默认1024) | | `GetBufferCapacity()` | 获取当前缓冲区容量 | **参数说明:** | 参数名称 | 类型 | 必填性 | 默认值 | 说明 | |---------|------|--------|--------|------| | `capacity_` | `int` | 是 | - | 缓冲区容量,必须大于0 | #### 视图控制接口 | 接口名称 | 功能描述 | |----------|---------| | `ResetView()` | 重置视图到默认状态 | | `SetAutoFit(enabled_)` | 设置是否启用自动适配 | **参数说明:** | 参数名称 | 类型 | 必填性 | 默认值 | 说明 | |---------|------|--------|--------|------| | `enabled_` | `bool` | 是 | - | true 启用自动适配,false 禁用 | #### 基准点接口 | 接口名称 | 功能描述 | |----------|---------| | `SetReferencePoint(point_)` | 设置基准参考点 | | `GetReferencePoint()` | 获取当前基准点 | | `ClearReferencePoint()` | 清除基准点 | **参数说明:** | 参数名称 | 类型 | 必填性 | 默认值 | 说明 | |---------|------|--------|--------|------| | `point_` | `const QVector3D&` | 是 | - | 作为坐标原点的基准点坐标 | #### 坐标轴压缩接口 | 接口名称 | 功能描述 | |----------|---------| | `SetAxisCompression(z_compression_ratio_)` | 设置 Z 轴压缩比例 | | `GetAxisCompression()` | 获取当前 Z 轴压缩比例 | **参数说明:** | 参数名称 | 类型 | 必填性 | 默认值 | 说明 | |---------|------|--------|--------|------| | `z_compression_ratio_` | `float` | 是 | - | Z轴压缩比例,1.0 表示不压缩 | #### 坐标轴样式接口 | 接口名称 | 功能描述 | |----------|---------| | `SetAxisLabels(x_label_, y_label_, z_label_)` | 设置三个轴的标签文字 | | `SetAxisColors(x_color_, y_color_, z_color_)` | 设置三个轴的颜色 | **参数说明:** | 参数名称 | 类型 | 必填性 | 默认值 | 说明 | |---------|------|--------|--------|------| | `x_label_` | `const QString&` | 是 | - | X 轴标签文字 | | `y_label_` | `const QString&` | 是 | - | Y 轴标签文字 | | `z_label_` | `const QString&` | 是 | - | Z 轴标签文字 | | `x_color_` | `const QColor&` | 是 | - | X 轴颜色 | | `y_color_` | `const QColor&` | 是 | - | Y 轴颜色 | | `z_color_` | `const QColor&` | 是 | - | Z 轴颜色 | #### 状态查询接口 | 接口名称 | 返回类型 | 功能描述 | |----------|---------|---------| | `TotalPoints()` | `qint64` | 获取累计插入的数据点总数 | ### DataGenerator 类(测试/演示用) | 接口名称 | 功能描述 | |----------|---------| | `Start(interval_ms_)` | 启动数据生成器 | | `Stop()` | 停止数据生成器 | | `ResetTime()` | 重置时间计数器 | | `IsRunning()` | 查询是否正在运行 | **信号:** | 信号名称 | 说明 | |---------|------| | `DataGenerated(points_)` | 每次生成数据时发出,携带生成的点集合 | --- ## 注意事项 ### 1. 线程安全 - **OpenGL 操作必须在 GUI 线程执行**:不要在工作线程中调用任何与渲染相关的方法 - **数据插入是线程安全的**:`InsertData` 内部使用互斥锁保护,可以跨线程调用 - **信号槽连接建议使用 `Qt::QueuedConnection`**:跨线程传递数据时确保线程安全 ### 2. 性能注意事项 - **高频数据场景推荐使用缓冲插入**:`BufferedInsert(point_)` 将数据暂存至缓冲区,满后自动批量写入,避免频繁的 OpenGL 操作 - **优先使用批量插入**:`InsertData(QVector)` 比循环调用单点插入性能高得多 - **最大显示点数限制**:内置降采样算法限制最大显示 100,000 个点,超出会自动均匀采样 - **避免频繁调用 ClearData**:清空会重置所有状态,如需部分更新请使用批量插入 ### 3. 坐标系统 - **默认坐标系**:X 轴向右,Y 轴向上,Z 轴向屏幕外(右手坐标系) - **基准点只影响显示**:原始数据不会被修改,仅在可视化时进行偏移计算 - **Z 轴压缩只影响显示**:不改变原始数据精度,仅用于视觉呈现优化 ### 4. 内存管理 - Scatter3DVisualizer 作为 QWidget 子类,遵循 Qt 的父子对象内存管理机制 - 内部 OpenGL 资源(着色器、缓冲区)在析构时自动释放 - 大数据量下建议定期检查内存使用情况 ### 5. Qt 信号槽注意 - DataGenerator 必须在无父对象的情况下创建,才能成功 moveToThread - 工作线程中创建的 QTimer 必须在该线程的事件循环中运行 - 析构时需正确停止线程,避免资源泄漏 --- ## 可选项 ### 自动适配(Auto Fit) | 选项 | 取值范围 | 默认值 | 效果 | |------|---------|--------|------| | `SetAutoFit(enabled_)` | `true` / `false` | `true` | 开启后自动根据数据范围调整视图缩放,使得所有数据可见 | **说明**: - 开启时,每次新数据到达都会重新计算最佳缩放比例 - 用户手动旋转或缩放后会自动关闭此功能 - 按空格键重置视图会重新启用 ### Z 轴压缩比例 | 选项 | 取值范围 | 默认值 | 效果 | |------|---------|--------|------| | `SetAxisCompression(ratio_)` | `0.0` ~ `1.0` | `1.0` | 对 Z 轴坐标值乘以压缩比例,仅影响视觉显示 | **建议取值:** - 经纬度+高度数据:`0.00001` ~ `0.001`(将几十万的高度值压缩到可观测范围) - 等比例数据:`1.0`(不压缩) - 数据范围差异 100 倍:`0.01` ### 坐标轴标签 | 选项 | 类型 | 默认值 | 说明 | |------|------|--------|------| | X 轴标签 | `QString` | `"X"` | X 轴末端显示的文字 | | Y 轴标签 | `QString` | `"Z"` | Y 轴末端显示的文字(Y/Z 交换后) | | Z 轴标签 | `QString` | `"Y"` | Z 轴末端显示的文字(Y/Z 交换后) | ### 坐标轴颜色 | 选项 | 类型 | 默认值 | 说明 | |------|------|--------|------| | X 轴颜色 | `QColor` | 红色 (`Qt::red`) | X 坐标轴线条及标签颜色 | | Y 轴颜色 | `QColor` | 黄色 (`Qt::yellow`) | Y 坐标轴线条及标签颜色 | | Z 轴颜色 | `QColor` | 绿色 (`Qt::green`) | Z 坐标轴线条及标签颜色 | ### 最大显示点数 | 常量 | 值 | 说明 | |------|---|------| | `MAX_DISPLAY_POINTS` | 100,000 | 超过此数量的数据会自动降采样 | 如需修改,在 [scatter3dvisualizer.h](scatter3dvisualizer.h) 中调整该常量值。 --- ## 构建与运行 ### Windows 环境 ```powershell # 配置 cmake -S . -B build -G "Visual Studio 17 2022" -A x64 -DCMAKE_PREFIX_PATH="C:/Qt/6.7.3/msvc2022_64" # 构建 cmake --build build --config Release # 运行 ./build/Release/Chart3D.exe ``` ### Linux / macOS 环境 ```bash # 配置 cmake -S . -B build -DCMAKE_PREFIX_PATH="/path/to/qt6" # 构建 cmake --build build -j$(nproc) # 运行 ./build/Chart3D ``` ### 自动测试模式 程序启动时默认进入自动测试模式: - 自动生成基准点 `(90, 90, 500000)` - 自动设置 Z 轴压缩比例 `0.00001` - 自动开始数据生成 - 5 秒后自动停止并退出 如需关闭测试模式,在 [mainwindow.cpp](mainwindow.cpp) 中将 `m_is_auto_test_mode` 初始值改为 `false`。 --- ## 项目结构 ``` Chart3D/ ├── CMakeLists.txt # CMake 构建配置 ├── README.md # 项目文档 ├── CHANGELOG.md # 版本变更记录 ├── main.cpp # 程序入口 ├── mainwindow.h/cpp # 主窗口(UI 布局、按钮控制) ├── scatter3dvisualizer.h/cpp # 3D 可视化核心组件 ├── datagenerator.h/cpp # 数据生成器(测试用,独立线程) ├── datastructures.h # 数据结构定义 └── test_buffered_insert.cpp # 缓冲区接口单元测试 ``` --- ## License 本项目可自由使用和修改。