replace furthest intersection test by first_intersection

This commit is contained in:
Pierre Alliez 2008-07-28 18:16:38 +00:00
parent 93cae6500f
commit bc8e6fd1e2
3 changed files with 53 additions and 102 deletions

View File

@ -217,45 +217,36 @@ private:
public:
// -----------------------------------------------------------//
// --------------------LISTING QUERIES------------------------//
// -----------------------------------------------------------//
// puts the intersection points with the query q in the container result.
// This function will work for any type QueryType such that the following
// two oracles are defined:
// static bool intersection(const QueryType& q, const typename Input& f, Container::value_type& p)
// static bool do_intersect(const QueryType& q, const Iso_cuboid& bbox)
// [do NOT use a template parameter for the QueryType when defining such oracles]
// compute the first intersection encountered.
// nb_primitives = number of primitives contained in this node.
template<class QueryType, class Container>
void list_intersections(const QueryType& q,
Container& result,
template<class QueryType, class ResultType>
void first_intersection(const QueryType& q,
ResultType& result,
int nb_primitives)
{
traversal<Listing_traits<QueryType, Container> >(q, result, nb_primitives);
traversal<First_intersection_traits<QueryType, ResultType> >(q, result, nb_primitives);
}
template<class QueryType, class Container>
class Listing_traits
template<class QueryType, class ResultType>
class First_intersection_traits
{
typedef typename Container::value_type Pt;
private:
Container& r;
ResultType& r;
public:
bool go_further()
{
return true;
return !r.first;
}
Listing_traits(Container& result) : r(result) {}
First_intersection_traits(ResultType& result) : r(result) {}
bool intersection(const QueryType& q, const Input& i)
{
Pt p;
if(Node::intersection(q, i, p))
ResultType result;
if(Node::intersection(q, i, result.second))
{
r.push_back(p);
r.first = true;
r.second = result.second;
return true;
}
return false;
@ -266,10 +257,6 @@ public:
}
};
// -----------------------------------------------------------//
// -----------------------LINE ORACLES-------------------------//
// -----------------------------------------------------------//
@ -417,7 +404,6 @@ public:
// general traversal query, the traits class allows to use it for the various
// traversal methods we need: listing, counting, detecting intersections, drawing the boxes.
// TODO: document the traits class requirements...
template<class Traits, class QueryType, class ResultType>
void traversal(const QueryType& query,
ResultType& result,
@ -427,18 +413,18 @@ public:
bool left_test;
switch(nb_primitives)
{
case 2: // comment
case 2:
left_test = traits.intersection(query, *static_cast<Input*>(m_left_child));
if((! left_test) || (traits.go_further()))
traits.intersection(query, *static_cast<Input*>(m_right_child));
break;
case 3: // comment
case 3:
left_test = traits.intersection(query, *static_cast<Input*>(m_left_child));
if((! left_test) || (traits.go_further()))
if(traits.do_intersect(query, *static_cast<Node*>(m_right_child)))
static_cast<Node*>(m_right_child)->traversal<Traits>(query, result, 2);
break;
default: // comment
default:
if(traits.do_intersect(query, *static_cast<Node*>(m_left_child)))
{
static_cast<Node*>(m_left_child)->traversal<Traits>(query, result, nb_primitives/2);

View File

@ -64,8 +64,7 @@ public:
Object operator()(const Surface_3& surface, const Segment_3& segment) const
{
Point_with_facet_handle pwh;
if(surface.tree()->furthest_intersection(segment,CGAL::ORIGIN,pwh))
// ^^^^^^^^^^^^ to fix
if(surface.tree()->first_intersection(segment,pwh))
return make_object(pwh.first);
else
return Object();
@ -74,8 +73,7 @@ public:
Object operator()(const Surface_3& surface, const Ray_3& ray) const
{
Point_with_facet_handle pwh;
if(surface.tree()->furthest_intersection(ray,CGAL::ORIGIN,pwh))
// ^^^^^^^^^^^^ to fix
if(surface.tree()->first_intersection(ray,pwh))
return make_object(pwh.first);
else
return Object();
@ -84,8 +82,7 @@ public:
Object operator()(const Surface_3& surface, const Line_3& line) const
{
Point_with_facet_handle pwh;
if(surface.tree()->furthest_intersection(line,CGAL::ORIGIN,pwh))
// ^^^^^^^^^^^^ to fix
if(surface.tree()->first_intersection(line,pwh))
return make_object(pwh.first);
else
return Object();

View File

@ -91,76 +91,44 @@ public:
return m_data.size() < 2; // TODO: change this requirement to < 1
}
bool furthest_intersection(const Ray& ray,
const Point& from,
Point_with_input& furthest)
bool first_intersection(const Ray& ray,
Point_with_input& pwh)
{
std::vector<Point_with_input> ps;
m_root->list_intersections(ray, ps, m_data.size());
if(ps.size() == 0)
return false;
furthest = furthest_point_from(ps,from);
return true;
}
bool furthest_intersection(const Segment& seg,
const Point& from,
Point_with_input& furthest)
{
std::vector<Point_with_input> ps;
m_root->list_intersections(seg, ps, m_data.size());
if(ps.size() == 0)
return false;
furthest = furthest_point_from(ps,from);
return true;
}
bool furthest_intersection(const Line& line,
const Point& from,
Point_with_input& closest)
{
std::vector<Point_with_input> ps;
m_root->list_intersections(line, ps, m_data.size());
if(ps.size() == 0)
return false;
closest = furthest_point_from(ps,from);
return true;
}
// -------------- Any query ----------------------//
template<class PointInputContainer, class Pt>
Point_with_input furthest_point_from(const PointInputContainer& intersections,
const Pt& from)
{
typename PointInputContainer::const_iterator it = intersections.begin();
Point_with_input furthest_point = *it;
FT max_sqd = CGAL::squared_distance(from,furthest_point.first);
it++;
for(;it != intersections.end();it++)
std::pair<bool,Point_with_input> result;
m_root->first_intersection(ray, result, m_data.size());
if(result.first)
{
FT sqd = CGAL::squared_distance(from,(*it).first);
if(sqd > max_sqd)
{
furthest_point = *it;
max_sqd = sqd;
}
pwh = result.second;
return true;
}
return furthest_point;
return false;
}
bool first_intersection(const Segment& seg,
Point_with_input& pwh)
{
std::pair<bool,Point_with_input> result;
m_root->first_intersection(seg, result, m_data.size());
if(result.first)
{
pwh = result.second;
return true;
}
return false;
}
bool first_intersection(const Line& line,
Point_with_input& pwh)
{
std::pair<bool,Point_with_input> result;
m_root->first_intersection(line, result, m_data.size());
if(result.first)
{
pwh = result.second;
return true;
}
return false;
}
};
CGAL_END_NAMESPACE