// Computes the intersection C+uV of the planes M*x+D=0 and N*x+E=0. // Returns -1 if there are no intersections (parallel), 0 for a line // intersection and 1 for co-planarity. // precondition: A, B are normalized (hessian form) int plane_plane_intersection(const Vector_3& M, const double D, const Vector_3& N, const double E, Point_3& C, Vector_3& V) { typedef CGAL::Cartesian<double> K; typedef CGAL::Plane_3<K> Plane_3; typedef CGAL::Line_3<K> Line_3; Plane_3 P1(M.x(), M.y(), M.z(), D); Plane_3 P2(N.x(), N.y(), N.z(), E); CGAL::Object result = CGAL::intersection(P1, P2); if (const Line_3 *iline = CGAL::object_cast<Line_3>(&result)) { CGAL::Point_3<K> p = iline->point(0); CGAL::Vector_3<K> v = iline->to_vector(); C = Point_3(p.x(), p.y(), p.z()); V = Vector_3(v.x(), v.y(), v.z()); return 0; } else if (const Plane_3 *iplane = CGAL::object_cast<Plane_3>(&result)) { return 1; } else { return -1; } }
std::size_t hash_value(const CGAL::Point_3<Kernel>& point) { std::size_t seed = 0; boost::hash_combine(seed, to_double(point.x())); boost::hash_combine(seed, to_double(point.y())); boost::hash_combine(seed, to_double(point.z())); return seed; }
bool MeshEx::findClosestIntersection( const math::Vec3f &position, const math::Vec3f &p1, const math::Vec3f &p2, math::Vec3f &intersection, math::Vec3f &normal, Triangle *&t ) { int count = 0; struct IntersectionHelper { IntersectionHelper( math::Vec3f intersection, Triangle *triangle, float sqDistance ) : m_intersection(intersection), m_triangle(triangle), m_sqDistance(sqDistance) { } // used for sorting bool operator<( const IntersectionHelper &rhs ) { return m_sqDistance < rhs.m_sqDistance; } math::Vec3f m_intersection; // point of intersection Triangle *m_triangle; // triangle in which the intersection point lies float m_sqDistance; // distance to the near point }; std::vector<IntersectionHelper> intersections; // test every triangle (TODO: do some spatial subdivision) for( std::vector<Triangle *>::iterator it = m_triangles.begin(); it != m_triangles.end(); ++it ) { Triangle *tri = *it; Triangle_3 cgalTri( Point_3(tri->v0->position), Point_3(tri->v1->position), Point_3(tri->v2->position) ); Segment_3 seg( Point_3(p1), Point_3(p2) ); if( CGAL::do_intersect( cgalTri, seg ) ) { CGAL::Point_3<K> tempIntersection; CGAL::Object o = CGAL::intersection(CGAL::Plane_3<K>( Point_3(tri->v0->position), Point_3(tri->v1->position), Point_3(tri->v2->position) ), seg); if( CGAL::assign(tempIntersection, o) ) { float sd = CGAL::squared_distance( Point_3(position), tempIntersection ); // intersection results in a point intersections.push_back( IntersectionHelper( math::Vec3f(tempIntersection.x(), tempIntersection.y(), tempIntersection.z()), tri, sd ) ); }else { // segment! printf( "error : intersection during vertex movement is a line\n" ); } //printf( "intersection\n" ); } } // if we have found any intersection if( intersections.size() ) { std::sort( intersections.begin(), intersections.end() ); // find the closest one intersection = intersections[0].m_intersection; t = intersections[0].m_triangle; normal = t->normal; // and indicate success return true; } return false; }