文档:
https://doc.cgal.org/latest/AABB_tree/index.html
文档中关于距离计算的实现:
Distance
. An AABB tree computes the closest point from a given point query to the input primitives through the function
AABB_tree::closest_point()
. In addition, it can compute the id of the closest primitive from a given point query through the function
AABB_tree::closest_point_and_primitive()
, i.e., the id of the primitive which realizes the minimum distance from the point query. The AABB tree uses a secondary search structure to speed up the distance queries. The construction of this secondary structure should be requested by the user by a call to
AABB_tree::accelerate_distance_queries()
before the first the distance computation. This data structure is not generated by default because it is used only for distance computations.
操作方式如下:
输入:
一个
点
query
,一个
obj网格
M
Mesh M;
Point query(0.0, 0.0, 3.0);
①
读取
obj模
型
M
,
并构造一棵
AABB树
tree
//load obj
load_obj(M, "mesh/sheetSquare60.obj");
std::vector<Triangle> triangles;//mesh.faces
for (int i = 0; i < M.faces.size(); i++)
Point p1(M.faces[i]->v[0]->x[0], M.faces[i]->v[0]->x[1], M.faces[i]->v[0]->x[2]);
Point p2(M.faces[i]->v[1]->x[0], M.faces[i]->v[1]->x[1], M.faces[i]->v[1]->x[2]);
Point p3(M.faces[i]->v[2]->x[0], M.faces[i]->v[2]->x[1], M.faces[i]->v[2]->x[2]);
triangles.push_back(Triangle(p1, p2, p3));
Tree tree(triangles.begin(), triangles.end());
②
AABB_tree::accelerate_distance_queries()
使用辅助搜索结构来加快距离查询,这个函数要在刚创建AABB Tree之后,计算距离之前进行调用
tree.accelerate_distance_queries();
③
调用函数进行距离查询,返回距离的平方
这个函数内部实现如下:
(1)对
tree
中所有面进行投影,计算出与
query
距离最近的投影点
point
,并返回这个点;
(2)计算点
query
到这个点
point
的距离;
// computes squared distance from query
FT sqd = tree.squared_distance(query);
std::cout << "squared distance: " << sqd << std::endl;
完整的main.cpp:
#include <iostream>
#include "mesh.h"
#include "io.h"
#include <CGAL/Simple_cartesian.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/AABB_triangle_primitive.h>
#include <CGAL/AABB_face_graph_triangle_primitive.h>
typedef CGAL::Simple_cartesian<double> K;
typedef K::FT FT;
typedef K::Point_3 Point;
typedef K::Triangle_3 Triangle;//Triangle
typedef K::Segment_3 Segment;
typedef std::vector<Triangle>::iterator Iterator;
typedef CGAL::AABB_triangle_primitive<K, Iterator> Primitive;
typedef CGAL::AABB_traits<K, Primitive> Traits;
typedef CGAL::AABB_tree<Traits> Tree;
int main()
Mesh M;
Point query(0.0, 0.0, 3.0);
//load obj
load_obj(M, "mesh/sheetSquare60.obj");
std::vector<Triangle> triangles;//mesh.faces
for (int i = 0; i < M.faces.size(); i++)
Point p1(M.faces[i]->v[0]->x[0], M.faces[i]->v[0]->x[1], M.faces[i]->v[0]->x[2]);
Point p2(M.faces[i]->v[1]->x[0], M.faces[i]->v[1]->x[1], M.faces[i]->v[1]->x[2]);
Point p3(M.faces[i]->v[2]->x[0], M.faces[i]->v[2]->x[1], M.faces[i]->v[2]->x[2]);
triangles.push_back(Triangle(p1, p2, p3));
Tree tree(triangles.begin(), triangles.end());
tree.accelerate_distance_queries();
// computes squared distance from query
FT sqd = tree.squared_distance(query);
std::cout << "squared distance: " << sqd << std::endl;
// computes closest point
Point closest = tree.closest_point(query);
std::cout << "closest point: " << closest << std::endl;
return EXIT_SUCCESS;
注:其中mesh.h提供了Mesh结构体,io.h提供了读入obj模型的函数;
obj模型读入之后存在Mesh结构体中,Mesh结构体中包含Face结构。Face结构通过M.faces[i]来遍历,存储了obj模型每个面的顶点们M.faces[i]->v,如果是三角形面,这三个顶点就是M.faces[i]->v[0],M.faces[i]->v[1],M.faces[i]->v[2],代码中p1,p2,p3获取的就是Face结构体中每个面三个顶点的坐标值。
………………………………………………………………………………………………………………………………………………
查询obj网格M中与点query距离最近的投影点有两种方式:
①第一种:直接调用closest_point
Point closest = tree.closest_point(query);
std::cout << "closest point: " << closest << std::endl;
②第二种:调用closest_point_and_primitive
typedef Tree::Point_and_primitive_id Point_and_primitive_id;
Point_and_primitive_id pp = tree.closest_point_and_primitive(query);
Point closest_point = pp.first;
std::cout << "closest point: " << closest_point << std::endl;
closest_point_and_primitive返回的第二个参数里面有投影面的信息
上述代码中pp.first是最近投影点的坐标;
pp.second[0]存的是投影面三个顶点的坐标,9个数值;
AABB Tree简介
「AABB Tree」AABB树组件提供了静态数据结构和算法,以支持对有限的3D对象集执行相交和距离查询。可以查询存储在数据结构中的一组几何对象,以进行相交检测、相交计算和距离计算。
如果在traits类中实现了相应的相交谓词和构造函数,则相交查询可以支持任何类型
距离查询仅限于点查询
「官方提供的例子」
相交查询:针对三角形集的线对象(射线、线、线.
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Polyhedron_3.h>
#include <iostream>
#include <string>
typedef CGAL::Simple_cartesian<double> ...
# ----- 查找
string.find(str, beg=0, end=len(string) ) #[0, len)中是否有str,有返回索引值,无返回-1
string.index(str, beg=0, end=len(string) ) #与f...
CGAL带岛多边形三角化,并输出(*.ply)格式的模型
模型输出的关键是节点和索引
#include <CGAL/Triangulation_vertex_base_with_id_2.h>#include <CGAL/Triangulation_face_base_with_info_2.h>
因此注意这两个泛型,对比不带信息的
#include <CGA...
#include
#include
//stdlib.h里面定义了五种类型、一些宏和通用工具函数。类型例如size_t、wchar_t、div_t、ldiv_t和lldiv_t;宏例如EXIT_FAILURE、EXIT_SUCCESS、RAND_MAX和MB_CUR_MAX等等;常用的函数如malloc()、calloc()、re