文档: 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 TreeAABB树组件提供了静态数据结构和算法,以支持对有限的3D对象集执行相交和距离查询。可以查询存储在数据结构中的一组几何对象,以进行相交检测、相交计算距离计算。 如果在traits类中实现了相应的相交谓词和构造函数,则相交查询可以支持任何类型 距离查询仅限于点查询 「官方提供的例子」 相交查询:针对三角形集的线对象(射线、线、线. #include &lt;CGAL/Simple_cartesian.h&gt; #include &lt;CGAL/Polyhedron_3.h&gt; #include &lt;iostream&gt; #include &lt;string&gt; typedef CGAL::Simple_cartesian&lt;double&gt; ... # ----- 查找 string.find(str, beg=0, end=len(string) ) #[0, len)中是否有str,有返回索引值,无返回-1 string.index(str, beg=0, end=len(string) ) #与f... CGAL带岛多边形三角化,并输出(*.ply)格式的模型 模型输出的关键是节点和索引 #include &lt;CGAL/Triangulation_vertex_base_with_id_2.h&gt;#include &lt;CGAL/Triangulation_face_base_with_info_2.h&gt; 因此注意这两个泛型,对比不带信息的 #include &lt;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