mirror of https://github.com/CGAL/cgal
324 lines
11 KiB
C++
324 lines
11 KiB
C++
// Copyright (c) 2005 Tel-Aviv University (Israel).
|
|
// All rights reserved.
|
|
//
|
|
// This file is part of CGAL (www.cgal.org); you may redistribute it under
|
|
// the terms of the Q Public License version 1.0.
|
|
// See the file LICENSE.QPL distributed with CGAL.
|
|
//
|
|
// Licensees holding a valid commercial license may use this file in
|
|
// accordance with the commercial license agreement provided with the software.
|
|
//
|
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
//
|
|
// $URL$
|
|
// $Id$
|
|
//
|
|
//
|
|
// Author(s) : Kapelushnik Lior <liorkape@post.tau.ac.il>
|
|
|
|
/*! \file
|
|
* spherical arrangements of none intersecting arcs of great circles on a sphere
|
|
*/
|
|
|
|
#ifndef CGAL_SPHERE_POINT_LOCATION_H_
|
|
#define CGAL_SPHERE_POINT_LOCATION_H_
|
|
|
|
#include "CGAL/Spherical_map.h"
|
|
#include <CGAL/Object.h>
|
|
#include <CGAL/Arr_naive_point_location.h>
|
|
#include <CGAL/Arr_walk_along_line_point_location.h>
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
/*
|
|
generic class for point location, can be templated with the required
|
|
cgm arrangement point location
|
|
|
|
_Spherical_map - the spherical map to point locate over
|
|
_PointLocation - the type of point location in a cgm face
|
|
*/
|
|
template<class _Spherical_map,
|
|
#ifndef CGAL_CFG_NO_TMPL_IN_TMPL_PARAM
|
|
template <class _T>
|
|
#endif
|
|
class _PointLocation >
|
|
class Sphere_base_point_location {
|
|
public:
|
|
// public definitions
|
|
typedef _Spherical_map Spherical_map;
|
|
typedef typename Spherical_map::CGM CGM;
|
|
typedef typename Spherical_map::Vertex_const_handle Vertrx_const_handle;
|
|
typedef typename Spherical_map::Vertex_handle Vertrx_handle;
|
|
typedef typename Spherical_map::Halfedge_const_handle Halfedge_const_handle;
|
|
typedef typename Spherical_map::Halfedge_handle Halfedge_handle;
|
|
typedef typename Spherical_map::Face_const_handle Face_const_handle;
|
|
typedef typename Spherical_map::Face_handle Face_handle;
|
|
typedef typename Spherical_map::Direction_3 Direction_3;
|
|
typedef typename Spherical_map::Point_3 Point_3;
|
|
typedef typename CGM::Arrangement Int_arr;
|
|
// the templated point location
|
|
typedef _PointLocation<Int_arr> Point_location;
|
|
|
|
/*
|
|
constructor, based uppon a spherical map
|
|
|
|
sphere - the spherical map to point locate
|
|
*/
|
|
Sphere_base_point_location(Spherical_map *sphere):
|
|
m_sphere(sphere) {}
|
|
|
|
/*
|
|
empty constructor
|
|
*/
|
|
Sphere_base_point_location(): m_sphere(0) {}
|
|
|
|
/*
|
|
set the spherical object to point locate over
|
|
|
|
sphere - the spherical map to point locate
|
|
*/
|
|
void init(Spherical_map * sphere) {
|
|
m_sphere = sphere;
|
|
}
|
|
|
|
/*
|
|
locate the object at a sphere direction
|
|
|
|
d - direction on the sphere to locate it's object
|
|
|
|
return value - an object stating the element at direction d,
|
|
the element may be a sphere Vertex_handle, Halfedge_handle or Face_handle
|
|
*/
|
|
CGAL::Object locate(const Direction_3 &d) {
|
|
m_sphere->update(); // make sure the search sphere has updated data
|
|
Projected_normal pn; // projected normal with direction d
|
|
pn.compute_projection(d.vector());
|
|
|
|
// find a cubical arrangement id which holds a direction point on the cube
|
|
// with the direction d
|
|
unsigned int faces_mask = pn.get_faces_mask();
|
|
unsigned int face_id;
|
|
for (face_id = 0; face_id < CGM::NUM_FACES; ++face_id) {
|
|
if (faces_mask & CGM::get_mask(face_id)) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
// find the 2d point on the cubical face
|
|
const Point_3 &point3d = pn.get_projected_normal();
|
|
Point_2 point = (m_sphere->get_cgm())->construct_point(point3d, face_id);
|
|
|
|
// locate on the cubical map
|
|
Point_location pl((m_sphere->get_cgm())->arrangement(face_id));
|
|
CGAL::Object obj = pl.locate(point);
|
|
|
|
// handle possible cubical elements cases
|
|
if (const Int_vertex_const_handle *const_ver_ptr =
|
|
CGAL::object_cast<Int_vertex_const_handle>(&obj)) {
|
|
// in case the direction points to a cubical vertex
|
|
|
|
Int_vertex_const_handle ver = *const_ver_ptr;
|
|
if (ver->getReal()) {
|
|
// a real vertex, return it
|
|
while (!ver->is_rep()) {
|
|
// get the representative vertex in degenerate cases
|
|
void *tmp = ver->get_adjacent_vertex();
|
|
ver = *((Int_vertex_const_handle *)(&tmp));
|
|
}
|
|
} else {
|
|
// not a real vertex, either a corner or part of an arc
|
|
if (ver->degree() == 2) {
|
|
// a corner has degree 2, all other unreal vertices are
|
|
// located on a cubic edge and have another incoming halfedge
|
|
// that caused their creation so they have degree > 2
|
|
Int_halfedge_around_vertex_const_circulator icirc;
|
|
icirc = ver->incident_halfedges();
|
|
int ind;
|
|
// check if a corner that is part of a real halfedge
|
|
for (ind = 0; ind < 2; ++ind) {
|
|
if (icirc->is_real()) {
|
|
break;
|
|
}
|
|
++icirc;
|
|
}
|
|
|
|
if (!icirc->is_real()) {
|
|
// corner, not part of a sphere edge
|
|
|
|
// find an edge near the corner vertex
|
|
Int_halfedge_const_handle ihedge;
|
|
ihedge = ver->incident_halfedges();
|
|
if ((ihedge->face())->is_unbounded()) {
|
|
ihedge = ihedge->twin();
|
|
}
|
|
// return the face of adjacent halfedge
|
|
return CGAL::make_object
|
|
(*((Face_handle *)((ihedge->face())->getSphereFace())));
|
|
} else {
|
|
// corner, part of a sphere edge
|
|
if ((icirc->face())->is_unbounded()) {
|
|
icirc = icirc->twin();
|
|
}
|
|
while (!icirc->target()->getReal()) {
|
|
// find the last halfedge of the spherical halfedge that
|
|
// holds the cubical halfedge
|
|
icirc = icirc->next();
|
|
while (!icirc->is_real()) {
|
|
icirc = m_sphere->get_cgm()->get_adjacent_halfedge_handle(icirc);
|
|
icirc = icirc->next();
|
|
}
|
|
}
|
|
return CGAL::
|
|
make_object(*((Halfedge_handle *)(icirc->getSphereEdge())));
|
|
}
|
|
} else {
|
|
// unreal vertex, not a corner, part of a sphere halfedge
|
|
Int_halfedge_around_vertex_const_circulator icirc;
|
|
icirc = ver->incident_halfedges();
|
|
// locate a real cgm halfedge around the vertex (part of sphere halfedge)
|
|
while (!icirc->is_real()) {
|
|
++icirc;
|
|
}
|
|
if ((icirc->face())->is_unbounded()) {
|
|
icirc = icirc->twin();
|
|
}
|
|
// find the last halfedge of the spherical halfedge that
|
|
// holds the cubical halfedge
|
|
while (!icirc->target()->getReal()) {
|
|
icirc = icirc->next();
|
|
while (!icirc->is_real()) {
|
|
icirc = m_sphere->get_cgm()->get_adjacent_halfedge_handle(icirc);
|
|
icirc = icirc->next();
|
|
}
|
|
}
|
|
return CGAL::
|
|
make_object(*((Halfedge_handle *)(icirc->getSphereEdge())));
|
|
}
|
|
}
|
|
// a real vertex, return the spherical vertex
|
|
return CGAL::
|
|
make_object(*((Vertrx_handle *)(ver->getSphereVertex())));
|
|
}
|
|
|
|
|
|
if (const Int_halfedge_const_handle *const_hed_ptr =
|
|
CGAL::object_cast<Int_halfedge_const_handle>(&obj)) {
|
|
|
|
// in case the direction points to a cubical halfedge
|
|
Int_halfedge_const_handle ihedge = *const_hed_ptr;
|
|
|
|
if (ihedge->is_real()) {
|
|
// part of a real sphere halfedge
|
|
if ((ihedge->face())->is_unbounded()) {
|
|
ihedge = ihedge->twin();
|
|
}
|
|
// find the last cgm halfedge of the spherical halfedge
|
|
while (!ihedge->target()->getReal()) {
|
|
ihedge = ihedge->next();
|
|
while (!ihedge->is_real()) {
|
|
ihedge = m_sphere->get_cgm()->get_adjacent_halfedge_handle(ihedge);
|
|
ihedge = ihedge->next();
|
|
}
|
|
}
|
|
return CGAL::
|
|
make_object(*((Halfedge_handle *)(ihedge->getSphereEdge())));
|
|
} else {
|
|
// part of cube unreal halfedge, return a face near halfedge
|
|
if ((ihedge->face())->is_unbounded()) {
|
|
ihedge = ihedge->twin();
|
|
}
|
|
return CGAL::
|
|
make_object
|
|
(*((Face_handle *)((ihedge->face())->getSphereFace())));
|
|
}
|
|
}
|
|
|
|
if (const Int_face_const_handle *const_face_ptr =
|
|
CGAL::object_cast<Int_face_const_handle>(&obj)) {
|
|
// found a cubical face, return it's spherical face handle
|
|
|
|
Int_face_const_handle iface = *const_face_ptr;
|
|
return CGAL::make_object
|
|
(*((Face_handle *)(iface->getSphereFace())));
|
|
}
|
|
|
|
// getting here means that in the cubical gaussian map the located element
|
|
// was not a face, halfedge or vertex, should not get here
|
|
std::cerr << "internal error locating direction on cgm" << std::endl;
|
|
CGAL_assertion(false);
|
|
return CGAL::make_object(0);
|
|
}
|
|
|
|
private:
|
|
// private definitions
|
|
typedef typename CGM::Projected_normal Projected_normal;
|
|
typedef typename CGM::Kernel::Point_2 Point_2;
|
|
typedef typename CGM::Arr_vertex_const_handle Int_vertex_const_handle;
|
|
typedef typename CGM::Arr_halfedge_const_handle Int_halfedge_const_handle;
|
|
typedef typename CGM::Arr_face_const_handle Int_face_const_handle;
|
|
// typedef typename CGM::Arr_ccb_halfedge_circulator Int_halfedge_circulator;
|
|
typedef typename CGM::Arr_halfedge_around_vertex_const_circulator Int_halfedge_around_vertex_const_circulator;
|
|
|
|
Spherical_map *m_sphere; // the spherical map to point locate over
|
|
};
|
|
|
|
/*
|
|
a spherical point location class that does the cgm point location using
|
|
the naive point location method
|
|
inherits from the general point location templated with naive point location
|
|
|
|
_Spherical_map - the spherical map to point locate over
|
|
*/
|
|
template <class _Spherical_map>
|
|
class Sphere_naive_point_location :
|
|
public Sphere_base_point_location<_Spherical_map, CGAL::Arr_naive_point_location>
|
|
{
|
|
public:
|
|
|
|
/*
|
|
constructor, based uppon a spherical map
|
|
|
|
sphere - the spherical map to point locate
|
|
*/
|
|
Sphere_naive_point_location(_Spherical_map *sphere):
|
|
Sphere_base_point_location<_Spherical_map, CGAL::Arr_naive_point_location>::
|
|
Sphere_base_point_location(sphere) {}
|
|
|
|
/*
|
|
empty constructor
|
|
*/
|
|
Sphere_naive_point_location() {}
|
|
};
|
|
|
|
/*
|
|
a spherical point location class that does the cgm point location using
|
|
the walk along line point location method
|
|
inherits from the general point location templated with walk along line point location
|
|
|
|
_Spherical_map - the spherical map to point locate over
|
|
*/
|
|
template <class _Spherical_map>
|
|
class Sphere_walk_along_line_point_location :
|
|
public Sphere_base_point_location<_Spherical_map, CGAL::Arr_walk_along_line_point_location>
|
|
{
|
|
public:
|
|
/*
|
|
constructor, based uppon a spherical map
|
|
|
|
sphere - the spherical map to point locate
|
|
*/
|
|
Sphere_walk_along_line_point_location(_Spherical_map *sphere):
|
|
Sphere_base_point_location<_Spherical_map, CGAL::Arr_walk_along_line_point_location>::
|
|
Sphere_base_point_location(sphere) {}
|
|
|
|
/*
|
|
empty constructor
|
|
*/
|
|
Sphere_walk_along_line_point_location() {}
|
|
};
|
|
|
|
CGAL_END_NAMESPACE
|
|
|
|
#endif
|