【发布时间】:2016-03-15 10:53:01
【问题描述】:
我正在研究防水网格,我正在尝试在网格表面上获得从网格中的每个顶点到网格中的每个其他顶点的最短路径。
例如当网格中有 100 个顶点时,我会得到 100X100 的距离,我想将它们存储在 100x100 距离矩阵中。
我使用 CGAL(因此也使用 BOOST),但我几乎没有这两个方面的经验。
这是我目前所拥有的:
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <iterator>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Random.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Polyhedron_items_with_id_3.h>
#include <CGAL/IO/Polyhedron_iostream.h>
#include <CGAL/Surface_mesh_shortest_path.h>
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
#include <CGAL/boost/graph/iterator.h>
#include "boost/multi_array.hpp"
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef CGAL::Polyhedron_3<Kernel, CGAL::Polyhedron_items_with_id_3> Polyhedron_3;
typedef CGAL::Surface_mesh_shortest_path_traits<Kernel, Polyhedron_3> Traits;
typedef CGAL::Surface_mesh_shortest_path<Traits> Surface_mesh_shortest_path;
typedef Surface_mesh_shortest_path::Shortest_path_result Shortest_path_result;
typedef boost::graph_traits<Polyhedron_3> Graph_traits;
typedef Graph_traits::vertex_iterator vertex_iterator;
typedef Graph_traits::vertex_descriptor vertex_desc;
typedef Graph_traits::face_iterator face_iterator;
typedef boost::multi_array<double, 2> distArray;
typedef distArray::index distArrayIndex;
class DistanceMeasure {
public:
static distArray getDistances(Polyhedron_3 p);
};
作为我的头文件和:
#include "DistanceMeasure.h"
distArray DistanceMeasure::getDistances(Polyhedron_3 p) {
distArray dists(boost::extents[p.size_of_vertices()][p.size_of_vertices()]);
// pick up a random face
CGAL::set_halfedgeds_items_id(p);
vertex_iterator pit = vertices(p).first;
// construct a shortest path query object and add a source point
Surface_mesh_shortest_path shortest_paths(p);
//add all points from p to the source points
for ( pit = vertices(p).first; pit != vertices(p).end(); pit++)
shortest_paths.add_source_point(*pit);
//for all points in p get distance to all the other points
vertex_iterator vit, vit_end;
for ( boost::tie(vit, vit_end) = vertices(p);
vit != vit_end; ++vit)
{
//get distances
Shortest_path_result res = shortest_paths.shortest_distance_to_source_points(*vit);
//iterate over all query results
Surface_mesh_shortest_path::Source_point_iterator spit;
int count = 0;
for(spit = res.second; spit != shortest_paths.source_points_end(); spit++) {
count++;
}
}
return dists;
}
我的源文件。
在我的理解中,我会在 res 中获取到所有其他点的距离,并可以在其中迭代它们
for(spit = res.second; spit != shortest_paths.source_points_end(); spit++) {
count++;
}
因此我有两个问题: 第一的: 我做对了吗?我有所有的距离吗? 第二: 如何在我的结果(以及从 spit 中)中获取顶点的 id 和与它们的距离,以便能够识别它们并将它们的距离存储在 dists 数组中。
到目前为止我的想法是,也许顺序是我将点放入源点的顺序。
当我运行它时,例如100 个顶点并使用 count 来计算我将得到的 res 中的顶点数。
100 99 98 97 96 95 .. 2 1
我认为这可能是因为 CGAL 不会两次计算距离。 我仍然不确定索引。
感谢您的回答 史蒂芬
【问题讨论】:
-
我们在这里讨论的是什么类型的网格?如果我们谈论的是可映射的 TIN(三角地形模型),您可以通过切割 TIN 的一个部分并计算三角形切割边缘之间的 3d 距离来获得表面距离。这不一定是最短距离,例如绕过陡峭的山丘可能比翻越它所覆盖的距离更短。如果它是不可映射的 TIN(例如复杂管网的三角剖分),则查找任意两个顶点之间的任意路径并非易事,并且找到最短路径可能非常复杂。
-
鉴于您对多面体的引用,我猜该表面是多面体网格的外表面,这再次变得复杂,因为网格不是凸面的。对于这类内容,Joe O'Rourke 的 Computational Geometry in C 值得一读,Edelsbrunner 的 Geometry and Topology for mesh generation 也值得一读。
-
我正在使用来自 .off 文件的混搭。所以基本上我得到的只是捣碎表面,我需要顶点的测地线距离。
-
非常感谢您的回答(当我读到它时,我一直在开车...)现在在考虑您的回答后,我认为我的想法是错误的...实际上我没有t要的是最短路径!我想要边缘切割之间的路径!您知道使用 CGAL 是否可以轻松实现这一点,还是建议您自己编写代码?
-
嗯,你帮助了你的其他 cmets,谢谢!我会试试看的!