我有一个三维点和一些三维点,我将它三角测量并输入到AABB树中,这样我就可以找到光线与网格的交点。 现在我还想知道光线相交的三角形的法线向量。
我将点投影到x-y平面并应用Delaunay网格划分。然后我将3D点提供给AABBtree结构。理想情况下,我不想改变这一部分。
查找与first_intersection()的交集非常简单 如何找到相交三角形的法线?
编辑:问题是,boost::get<KernelSCD::Point_3>(&(intersection->first))
只给出了实际的交叉点。为了找到相交三角形的法向量,我需要相交三角形的手柄。我怎么得到这个?
这是我的代码:
// CGAL includes for AABB tree for intersection detection
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/AABB_triangle_primitive.h>
#include <CGAL/Simple_cartesian.h>
// CGAL includes for Delaunay triangulation
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
#include <CGAL/Polygon_mesh_processing/compute_normal.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/AABB_face_graph_triangle_primitive.h>
#include <CGAL/Polygon_mesh_processing/compute_normal.h>
#include <CGAL/Polygon_mesh_processing/orientation.h>
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
int main (int argc, char *argv[])
{
typedef CGAL::Simple_cartesian<double> KernelSCD;
typedef KernelSCD::Triangle_3 Triangle_3;
typedef std::list<Triangle_3>::iterator IteratorTriangle;
typedef CGAL::AABB_triangle_primitive<KernelSCD, IteratorTriangle> Primitive;
typedef CGAL::AABB_traits<KernelSCD, Primitive> AABB_triangle_traits;
typedef CGAL::AABB_tree<AABB_triangle_traits> Tree;
typedef CGAL::Simple_cartesian<double> K;
typedef CGAL::Triangulation_vertex_base_with_info_2<unsigned, K> Vb;
typedef CGAL::Triangulation_data_structure_2<Vb> Tds;
typedef CGAL::Delaunay_triangulation_2<K, Tds> Delaunay;
typedef Delaunay::Point PointD;
typedef Delaunay::Vertex_handle Vertex_handle;
typedef KernelSCD::Point_3 Point_3;
typedef KernelSCD::Vector_3 Vector_3;
typedef KernelSCD::Ray_3 Ray_3;
typedef boost::optional<Tree::Intersection_and_primitive_id<Ray_3>::Type> Ray_intersection;
typedef Tree::Primitive_id AABB_primitive_id;
Delaunay dt;
std::vector< std::pair<PointD, unsigned> > points_2d;
std::vector<Point_3> points_3d;
Tree tree_3d_map_;
std::list<Triangle_3> triangles_;
std::vector<double> verts = { 0, 0, 100,
0, 1, 101,
1, 0, 102,
1, 1, 103,
10, 0, 104,
0, 10, 105,
10, 10, 106};
// Filling Delaunay triangulation
for (int i = 0; i+2 < verts.size(); i += 3) {
points_2d.push_back(std::make_pair(PointD(verts.at(i), verts.at(i + 1)), i / 3));
points_3d.push_back(Point_3(verts.at(i), verts.at(i + 1), verts.at(i + 2)));
}
dt.insert(points_2d.begin(), points_2d.end());
// Filling AABB tree
int v0, v1, v2;
for (Delaunay::Finite_faces_iterator it = dt.finite_faces_begin(); it != dt.finite_faces_end(); it++){
v0 = it->vertex(0)->info();
v1 = it->vertex(1)->info();
v2 = it->vertex(2)->info();
triangles_.push_back(Triangle_3(points_3d.at(v0), points_3d.at(v1), points_3d.at(v2)));
}
tree_3d_map_.insert(triangles_.begin(), triangles_.end());
Point_3 p1(.4, .5, 0.1);
Vector_3 v(0, 0, 1);
Ray_3 ray(p1, v);
// Find point where the ray intersects the mesh for the first time
Ray_intersection intersection = tree_3d_map_.first_intersection(ray);
if (intersection){
if (boost::get<KernelSCD::Point_3>(&(intersection->first))){
const KernelSCD::Point_3* p = boost::get<KernelSCD::Point_3>(&(intersection->first));
std::cout << "First intersection: " << p->x() << ", " << p->y() << ", " << p->z() << std::endl;
AABB_primitive_id primitive_id = intersection->second;
// Fails:
// | | | |
// v v v v
//KernelSCD::Vector_3 v = CGAL::Polygon_mesh_processing::compute_face_normal(primitive_id,points_3d);
//std::cout << "v: " << v.x() << ", " << v.y() << ", " << v.z() << std::endl;
}
}
/* If I use a Surface_mesh, it works:
typedef CGAL::Surface_mesh<Point_3> Mesh;
typedef CGAL::AABB_face_graph_triangle_primitive<Mesh> PrimitiveM;
typedef CGAL::AABB_traits<KernelSCD, PrimitiveM> Traits;
typedef CGAL::AABB_tree<Traits> TreeM;
typedef boost::optional<TreeM::Intersection_and_primitive_id<Ray_3>::Type> Ray_intersectionM;
typedef TreeM::Primitive_id AABB_primitive_idM;
std::ifstream input("tetrahedron.off");
Mesh mesh;
input >> mesh;
TreeM tree;
tree.insert(faces(mesh).first, faces(mesh).second, mesh);
Ray_intersectionM intersection2 = tree.first_intersection(ray);
if (intersection2){
if (boost::get<Point_3>(&(intersection2->first))){
const Point_3* p = boost::get<Point_3>(&(intersection2->first));
std::cout << "First intersection: " << *p << std::endl;
AABB_primitive_idM primitive_id = intersection2->second;
// Works:
Vector_3 v = CGAL::Polygon_mesh_processing::compute_face_normal(primitive_id,mesh);
std::cout << "v: " << v.x() << ", " << v.y() << ", " << v.z() << std::endl;
}
}*/
std::cout << "done" << std::endl;
std::cin.get();
return 0;
}
答案 0 :(得分:0)
也许我错过了什么,但是不是简单矢量数学的应用吗?如果您知道三角形的3个点,则可以创建从点[0]到点[1]以及从点[0]到点[2]的矢量并执行叉积。结果将是一个向量垂直的向量<(三角形正常)。