几何尺寸与公差论坛

 找回密码
 注册
12
返回列表 发新帖
楼主: huangyhg

布局管道pipe,如果解决2管道自相交问题

[复制链接]
 楼主| 发表于 2025-3-18 14:58:14 | 显示全部楼层
继续,结合 VTK 或 Open3D 进行3D Mesh和路径可视化,用c++或c#编写
 楼主| 发表于 2025-3-18 14:58:28 | 显示全部楼层
要将 3D 网格路径规划与 VTK 或 Open3D 结合,实现 3D Mesh 和路径可视化,我们可以从以下几个部分展开:
📌 目标

    3D Mesh 建模和碰撞检测:生成障碍物和管道的 3D Mesh。
    路径规划与弯头调整:结合 A* 算法避障规划路径。
    可视化展示:
        使用 VTK 或 Open3D 实现 3D Mesh 的渲染与路径展示。
        支持 C++ 和 C# 实现。

🔧 方案选择

    VTK(Visualization Toolkit)
        更适合 C++ 环境,功能丰富,广泛应用于 CAD、医学、BIM 等领域。
    Open3D
        更适合 Python 和 C#,轻量易用,支持点云、网格的可视化。

📌 方案 1: 使用 VTK 进行 3D Mesh 和路径可视化(C++ 实现)
1. 环境配置

安装 VTK 库:

sudo apt-get install libvtk7-dev

或者在 Windows 上使用 VTK 官方安装包。

CMakeLists.txt 配置:

cmake_minimum_required(VERSION 3.10)
project(BIM_Path_Planning)

find_package(VTK REQUIRED)
include(${VTK_USE_FILE})

add_executable(BIM_Path_Planning main.cpp)
target_link_libraries(BIM_Path_Planning ${VTK_LIBRARIES})

2. 代码实现

main.cpp:包括 3D 网格、A* 路径规划和 VTK 可视化。

#include <vtkSmartPointer.h>
#include <vtkActor.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSphereSource.h>
#include <vtkCubeSource.h>
#include <vtkLineSource.h>
#include <vtkNamedColors.h>
#include <vtkPoints.h>
#include <vtkCellArray.h>
#include <vtkProperty.h>
#include <iostream>
#include <vector>
#include <queue>
#include <cmath>
#include <tuple>
#include <unordered_map>

// 3D 网格路径规划 (A* 实现)
struct Node {
    int x, y, z;
    double cost, heuristic;
    Node *parent;

    Node(int _x, int _y, int _z, double _cost, double _heuristic, Node *_parent = nullptr)
        : x(_x), y(_y), z(_z), cost(_cost), heuristic(_heuristic), parent(_parent) {}

    bool operator<(const Node &other) const {
        return (cost + heuristic) > (other.cost + other.heuristic); // 小顶堆
    }
};

// 启发式函数(欧氏距离)
double heuristic(int x, int y, int z, int tx, int ty, int tz) {
    return std::sqrt(std::pow(tx - x, 2) + std::pow(ty - y, 2) + std::pow(tz - z, 2));
}

// A* 规划路径
std::vector<std::tuple<int, int, int>> a_star_3d(const std::vector<std::vector<std::vector<int>>> &grid,
                                                 int sx, int sy, int sz, int gx, int gy, int gz) {
    int nx = grid.size(), ny = grid[0].size(), nz = grid[0][0].size();
    std::priority_queue<Node> pq;
    std::unordered_map<int, Node *> visited;

    pq.push(Node(sx, sy, sz, 0, heuristic(sx, sy, sz, gx, gy, gz)));
    std::vector<std::tuple<int, int, int>> directions = {
        {1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0},
        {0, 0, 1}, {0, 0, -1}};

    while (!pq.empty()) {
        Node current = pq.top();
        pq.pop();

        if (current.x == gx && current.y == gy && current.z == gz) {
            std::vector<std::tuple<int, int, int>> path;
            Node *node = ¤t;
            while (node) {
                path.emplace_back(node->x, node->y, node->z);
                node = node->parent;
            }
            std::reverse(path.begin(), path.end());
            return path;
        }

        int index = current.x * ny * nz + current.y * nz + current.z;
        visited[index] = new Node(current);

        for (const auto &[dx, dy, dz] : directions) {
            int nx = current.x + dx;
            int ny = current.y + dy;
            int nz = current.z + dz;

            if (nx < 0 || nx >= grid.size() || ny < 0 || ny >= grid[0].size() ||
                nz < 0 || nz >= grid[0][0].size() || grid[nx][ny][nz] == 1)
                continue;

            double new_cost = current.cost + 1;
            double h = heuristic(nx, ny, nz, gx, gy, gz);

            if (!visited.count(nx * ny * nz + ny * nz + nz)) {
                pq.push(Node(nx, ny, nz, new_cost, h, new Node(current)));
            }
        }
    }

    return {};
}

int main() {
    vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
    vtkSmartPointer<vtkRenderWindow> window = vtkSmartPointer<vtkRenderWindow>::New();
    window->AddRenderer(renderer);
    vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    interactor->SetRenderWindow(window);

    int nx = 10, ny = 10, nz = 10;
    std::vector<std::vector<std::vector<int>>> grid(nx, std::vector<std::vector<int>>(ny, std::vector<int>(nz, 0)));
    for (int i = 3; i < 7; ++i)
        for (int j = 3; j < 7; ++j)
            for (int k = 3; k < 7; ++k)
                grid[j][k] = 1;

    auto path = a_star_3d(grid, 0, 0, 0, 9, 9, 9);

    for (const auto &[x, y, z] : path) {
        vtkSmartPointer<vtkSphereSource> sphere = vtkSmartPointer<vtkSphereSource>::New();
        sphere->SetCenter(x, y, z);
        sphere->SetRadius(0.1);
        
        vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
        mapper->SetInputConnection(sphere->GetOutputPort());

        vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
        actor->SetMapper(mapper);
        actor->GetProperty()->SetColor(0, 1, 0);

        renderer->AddActor(actor);
    }

    renderer->SetBackground(0.1, 0.1, 0.1);
    window->Render();
    interactor->Start();

    return 0;
}

&#128204; 效果展示

    绿色小球表示路径点,避开中心障碍。
    可调节障碍物大小、起点和终点,实现复杂路径规划。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|Archiver|小黑屋|几何尺寸与公差论坛

GMT+8, 2025-4-2 05:41 , Processed in 0.030474 second(s), 13 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表