corrections for public release...

This commit is contained in:
Tran Kai Frank Da 1999-11-15 13:23:54 +00:00
parent f6987ab722
commit 8a8e00aaa2
9 changed files with 1011 additions and 615 deletions

View File

@ -68,7 +68,9 @@ clean:
$(Package).tar.gz:
tar -zcvf $(Package).tar.gz \
--exclude=CVS --exclude=wrapper.tex \
--exclude=CVS \
--exclude=wrapper.tex --exclude=weight.tex \
--exclude=Weighted_alpha_shape_2.h \
--exclude=Makefile* --exclude=*5000* --exclude=*.o \
--exclude=*.obj --exclude=*.exe --exclude=*~ \
version description.txt changes.txt \

View File

@ -1,16 +1,38 @@
// ======================================================================
//
// Copyright (c) 1997 The CGAL Consortium
// Copyright (c) 1999 The GALIA Consortium
//
// This software and related documentation is part of an INTERNAL release
// of the Computational Geometry Algorithms Library (CGAL). It is not
// intended for general use.
// This software and related documentation is part of the
// Computational Geometry Algorithms Library (CGAL).
//
// Every use of CGAL requires a license. Licenses come in three kinds:
//
// - For academic research and teaching purposes, permission to use and
// copy the software and its documentation is hereby granted free of
// charge, provided that
// (1) it is not a component of a commercial product, and
// (2) this notice appears in all copies of the software and
// related documentation.
// - Development licenses grant access to the source code of the library
// to develop programs. These programs may be sold to other parties as
// executable code. To obtain a development license, please contact
// the GALIA Consortium (at cgal@cs.uu.nl).
// - Commercialization licenses grant access to the source code and the
// right to sell development licenses. To obtain a commercialization
// license, please contact the GALIA Consortium (at cgal@cs.uu.nl).
//
// This software and documentation is provided "as-is" and without
// warranty of any kind. In no event shall the CGAL Consortium be
// liable for any damage of any kind.
//
// The GALIA Consortium consists of Utrecht University (The Netherlands),
// ETH Zurich (Switzerland), Free University of Berlin (Germany),
// INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg
// (Germany), Max-Planck-Institute Saarbrucken (Germany),
// and Tel-Aviv University (Israel).
//
// ----------------------------------------------------------------------
//
// release : $CGAL_Revision: CGAL-2.0-I-20 $
// release_date : $CGAL_Date: 1999/06/02 $
//
// file : demo/Alpha_shapes_2/demo_alpha.C
// package : Alpha_shapes_2(1.0)
// source : $RCSfile$

View File

@ -1,16 +1,38 @@
// ======================================================================
//
// Copyright (c) 1997 The CGAL Consortium
// Copyright (c) 1999 The GALIA Consortium
//
// This software and related documentation is part of an INTERNAL release
// of the Computational Geometry Algorithms Library (CGAL). It is not
// intended for general use.
// This software and related documentation is part of the
// Computational Geometry Algorithms Library (CGAL).
//
// Every use of CGAL requires a license. Licenses come in three kinds:
//
// - For academic research and teaching purposes, permission to use and
// copy the software and its documentation is hereby granted free of
// charge, provided that
// (1) it is not a component of a commercial product, and
// (2) this notice appears in all copies of the software and
// related documentation.
// - Development licenses grant access to the source code of the library
// to develop programs. These programs may be sold to other parties as
// executable code. To obtain a development license, please contact
// the GALIA Consortium (at cgal@cs.uu.nl).
// - Commercialization licenses grant access to the source code and the
// right to sell development licenses. To obtain a commercialization
// license, please contact the GALIA Consortium (at cgal@cs.uu.nl).
//
// This software and documentation is provided "as-is" and without
// warranty of any kind. In no event shall the CGAL Consortium be
// liable for any damage of any kind.
//
// The GALIA Consortium consists of Utrecht University (The Netherlands),
// ETH Zurich (Switzerland), Free University of Berlin (Germany),
// INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg
// (Germany), Max-Planck-Institute Saarbrucken (Germany),
// and Tel-Aviv University (Israel).
//
// ----------------------------------------------------------------------
//
// release : $CGAL_Revision: CGAL-2.0-I-20 $
// release_date : $CGAL_Date: 1999/06/02 $
//
// file : demo/Alpha_shapes_2/demo_weight.C
// package : Alpha_shapes_2(1.0)
// source : $RCSfile$
@ -54,9 +76,8 @@
#include <CGAL/Delaunay_triangulation_2.h>
#include <CGAL/Regular_triangulation_2.h>
#include <CGAL/Weighted_alpha_shape_2.h>
#include "weights_heuristic_2.h"
#include "Parse_weight.C"
#include "Timing.C"

View File

@ -1,229 +0,0 @@
#include <CGAL/basic.h>
#include <stdio.h>
#include <string.h>
#include <iostream.h>
#include <fstream.h>
#include <strstream.h>
#include <assert.h>
// #include <CGAL/Cartesian.h>
// //#include <CGAL/Homogeneous.h>
// //#include <CGAL/Integer.h>
// //#include <CGAL/Rational.h>
// //#include <CGAL/Fixed.h>
// //#include <CGAL/Real.h>
// #include <CGAL/squared_distance_2.h> // to avoid a g++ problem
// #include <CGAL/Point_2.h>
// #include <CGAL/predicates_on_points_2.h>
// #include <CGAL/Triangle_2.h>
// #include <CGAL/Segment_2.h>
#include <CGAL/Alpha_shape_short_names_2.h>
//#include <CGAL/Triangulation_short_names_2.h>
#include <CGAL/Alpha_shape_euclidean_traits_2.h>
#include <CGAL/Alpha_shape_vertex_base_2.h>
#include <CGAL/Alpha_shape_face_base_2.h>
#define CGAL::ALPHA_WINDOW_STREAM
#include <CGAL/Alpha_shape_2.h>
#include "parse.h"
//typedef leda_integer coord_type;
typedef double coord_type;
//typedef leda_real coord_type;
//typedef CGAL::Fixed coord_type;
typedef CGAL::Cartesian<coord_type> Rep;
//typedef CGAL::Homogeneous<coord_type> Rep;
//typedef CGAL::Point_2<Rep> Point;
//typedef CGAL::Segment_2<Rep> Segment;
typedef CGAL::Ray_2<Rep> Ray;
typedef CGAL::Line_2<Rep> Line;
//typedef CGAL::Triangle_2<Rep> Triangle;
typedef CGAL::Alpha_shape_euclidean_traits_2<Rep> Gt;
typedef CGAL::Alpha_shape_euclidean_traits_2<Rep>::Point Point;
typedef CGAL::Alpha_shape_euclidean_traits_2<Rep>::Segment Segment;
typedef CGAL::Alpha_shape_euclidean_traits_2<Rep>::Triangle Triangle;
typedef CGAL::Alpha_shape_vertex_base_2<Gt> Vb;
typedef CGAL::Alpha_shape_face_base_2<Gt> Fb;
typedef CGAL::Triangulation_default_data_structure_2<Gt,Vb,Fb> Tds;
typedef CGAL::Alpha_shape_2<Gt,Tds> Alpha_shape_2;
typedef typename Alpha_shape_2::Face Face;
typedef typename Alpha_shape_2::Vertex Vertex;
typedef typename Alpha_shape_2::Edge Edge;
typedef typename Alpha_shape_2::Face_handle Face_handle;
typedef typename Alpha_shape_2::Vertex_handle Vertex_handle;
typedef typename Alpha_shape_2::Face_circulator Face_circulator;
typedef typename Alpha_shape_2::Vertex_circulator Vertex_circulator;
typedef typename Alpha_shape_2::Locate_type Locate_type;
typedef typename Alpha_shape_2::Face_iterator Face_iterator;
typedef typename Alpha_shape_2::Vertex_iterator Vertex_iterator;
typedef typename Alpha_shape_2::Edge_iterator Edge_iterator;
typedef typename Alpha_shape_2::Edge_circulator Edge_circulator;
typedef typename Alpha_shape_2::Coord_type Coord_type;
typedef typename Alpha_shape_2::Alpha_iterator Alpha_iterator;
#define CGAL::ALPHA_WINDOW_STREAM
typedef CGAL::Window_stream Window_stream;
void
random_input(Alpha_shape_2 &A,
CGAL::Window_stream &W)
// Generate random points inside the window
// insert them into the alpha shape
{
int n = 5;
vector<Point> V;
V.reserve(n);
double x0 = W.xmin();
double y0 = W.ymin();
double x1 = W.xmax();
double y1 = W.ymax();
double dx = x1 - x0;
double dy = y1 - y0;
int xmin = int(x0 + 0.1*dx);
int xmax = int(x1 - 0.1*dx);
int ymin = int(y0 + 0.1*dy);
int ymax = int(y1 - 0.1*dy);
for(int i = 0; i<n; i++)
{
int x = rand_int(xmin,xmax);
int y = rand_int(ymin,ymax);
cerr << "Point " << x << "," << y << endl;
Point p((double)x,(double)y);
V.push_back(p);
}
cerr << "Generating " << n << " random points" << endl;
// vector<Point> V;
// V.reserve(3);
// Point p((double) 2,(double) 1);
// V.push_back(p);
// Point p1((double) 1,(double) 1);
// V.push_back(p1);
// Point p2((double) 5,(double) 2);
// V.push_back(p2);
n = A.make_Alpha_shape(V.begin(),V.end());
cerr << "Inserted " << n << " points" << endl;
}
void
container_input(Alpha_shape_2 &T,
Window_stream &W)
{
vector<Point> V(3);
V[0] = Point(0, 0);
V[1] = Point(1, 4);
V[2] = Point(3, 4);
//list<Vertex*> Vertices;
int n = T.make_Alpha_shape(V.begin(), V.end());
cerr << n << " points inserted from a vector." << endl;
}
void
window_input(Alpha_shape_2 &T,
Window_stream &W)
{
cerr << "Enter points with the left button" << endl;
cerr << "Remove points with the middle button" << endl;
cerr << "Right button terminates input of points" << endl;
Point p;
Point q(coord_type(W.xmin()-1),
coord_type(W.ymin()-1));
Face_handle highlight;
Vertex_handle hv;
vector<Point> V;
double x, y;
int b,n;
while(1) {
b = W.get_mouse(x,y);
bool button_pressed = (b == MOUSE_BUTTON(1)) ||
(b == MOUSE_BUTTON(2)) ||
(b == MOUSE_BUTTON(3));
p = Point(coord_type(x),
coord_type(y));
bool mouse_moved = p != q;
bool face_change = true,
vertex_change = false;
if(b == MOUSE_BUTTON(1)) {
W.draw_node(x,y);
V.push_back(p);
} else if(b == MOUSE_BUTTON(3)){
n=T.make_Alpha_shape(V.begin(),V.end());
cerr << n << " points inserted from a vector." << endl;
W.clear();
cerr << "Alpha optimal pour 1 cc :" << *(T.find_optimal_alpha(1)) << endl;
T.set_alpha(*(T.find_optimal_alpha(1)));
W << T;
cerr << "Affiche Alpha shape" << endl;
V.erase(V.begin(),V.end());
return;
} else if(b == MOUSE_BUTTON(2))
{W.clear();}
q = p;
}
}
void main()
{
Alpha_shape_2 T;
Window_stream W(800, 800); // physical window size
// W_global = &W;
//W.init(opt.min, opt.max, opt.min); // logical window size
W.init(-7,7,-7);
W.set_show_coordinates(true);
W << CGAL::GREEN;
W.display();
// random_input(T, W);
// container_input(T,W);
while (1){
window_input(T,W);}
T.set_alpha(4);
W.clear();
W << T;
cerr << "Affiche Alpha shape" << endl;
while (1) {};
}

View File

@ -1,3 +1,4 @@
# This is a makefile exemple for compiling a CGAL application.
#---------------------------------------------------------------------#

View File

@ -0,0 +1,631 @@
// ======================================================================
//
// Copyright (c) 1999 The GALIA Consortium
//
// This software and related documentation is part of the
// Computational Geometry Algorithms Library (CGAL).
//
// Every use of CGAL requires a license. Licenses come in three kinds:
//
// - For academic research and teaching purposes, permission to use and
// copy the software and its documentation is hereby granted free of
// charge, provided that
// (1) it is not a component of a commercial product, and
// (2) this notice appears in all copies of the software and
// related documentation.
// - Development licenses grant access to the source code of the library
// to develop programs. These programs may be sold to other parties as
// executable code. To obtain a development license, please contact
// the GALIA Consortium (at cgal@cs.uu.nl).
// - Commercialization licenses grant access to the source code and the
// right to sell development licenses. To obtain a commercialization
// license, please contact the GALIA Consortium (at cgal@cs.uu.nl).
//
// This software and documentation is provided "as-is" and without
// warranty of any kind. In no event shall the CGAL Consortium be
// liable for any damage of any kind.
//
// The GALIA Consortium consists of Utrecht University (The Netherlands),
// ETH Zurich (Switzerland), Free University of Berlin (Germany),
// INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg
// (Germany), Max-Planck-Institute Saarbrucken (Germany),
// and Tel-Aviv University (Israel).
//
// ----------------------------------------------------------------------
//
// file : include/CGAL/Weighted_alpha_shape_2.h
// package : Alpha_shapes_2 (1.0)
// source : $RCSfile$
// revision : $Revision$
// revision_date : $Date$
// author(s) : Tran Kai Frank DA <Frank.Da@sophia.inria.fr>
//
// coordinator : INRIA Sophia-Antipolis (<Mariette.Yvinec@sophia.inria.fr>)
//
// ======================================================================
#ifndef CGAL_WEIGHTED_ALPHA_SHAPE_2_H
#define CGAL_WEIGHTED_ALPHA_SHAPE_2_H
#ifdef CGAL_STL_SGI_CC
#define STL_HASH_TABLES
#endif
#include <CGAL/basic.h>
// SGI MIPSpro C++ 7.x
#ifdef STL_HASH_TABLES
#include <hash_set>
#include <hash_map>
#include <map>
#else
#include <set>
#include <map>
#endif
#include <algorithm>
#include <utility>
#include <iostream>
#include <CGAL/Alpha_shape_2.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <CGAL/less_partial.h>
//-------------------------------------------------------------------
CGAL_BEGIN_NAMESPACE
//-------------------------------------------------------------------
template < class Rt >
class Weighted_alpha_shape_2 : public Alpha_shape_2<Rt>
{
//------------------------- TYPES ------------------------------------
public:
typedef typename Alpha_shape_2<Rt>::Gt Gt;
typedef typename Alpha_shape_2<Rt>::Triangulation_data_structure Tds;
typedef typename Gt::Coord_type Coord_type;
typedef typename Gt::Point Point;
typedef typename Gt::Distance Distance;
typedef typename Gt::Ray Ray;
typedef typename Gt::Line Line;
typedef typename Gt::Direction Direction;
typedef typename Alpha_shape_2<Rt>::Face_handle Face_handle;
typedef typename Alpha_shape_2<Rt>::Vertex_handle Vertex_handle;
typedef typename Alpha_shape_2<Rt>::Edge Edge;
typedef typename Alpha_shape_2<Rt>::Face_circulator Face_circulator;
typedef typename Alpha_shape_2<Rt>::Edge_circulator Edge_circulator;
typedef typename Alpha_shape_2<Rt>::Vertex_circulator Vertex_circulator;
typedef typename Alpha_shape_2<Rt>::Face_iterator Face_iterator;
typedef typename Alpha_shape_2<Rt>::Edge_iterator Edge_iterator;
typedef typename Alpha_shape_2<Rt>::Vertex_iterator Vertex_iterator;
typedef typename Alpha_shape_2<Rt>::Locate_type Locate_type;
typedef typename Alpha_shape_2<Rt>::Mode Mode;
public:
//------------------------- CONSTRUCTORS ------------------------------
// Introduces an empty alpha-shape `A' for a positive
// alpha-value `alpha'. Precondition: `alpha' >= 0.
Weighted_alpha_shape_2(Coord_type alpha = 0,
Mode m = GENERAL)
: Alpha_shape_2<Rt>(alpha, m)
{}
// Introduces an alpha-shape `A' for a positive alpha-value
// `alpha' that is initialized with the points in the range
// from first to last
#ifndef CGAL_CFG_NO_MEMBER_TEMPLATES
template <class InputIterator>
Weighted_alpha_shape_2( InputIterator first,
InputIterator last,
const Coord_type& alpha = 0,
Mode = GENERAL)
: Alpha_shape_2<Rt>(first, last, alpha, m)
{}
#else //CGAL_CFG_NO_MEMBER_TEMPLATES
#if defined(LIST) || defined(__SGI_STL_LIST)
Weighted_alpha_shape_2(typename std::list<Point>::const_iterator first,
typename std::list<Point>::const_iterator last,
const Coord_type& alpha = 0,
Mode m = GENERAL)
: Alpha_shape_2<Rt>(first, last, alpha, m)
{}
#endif //LIST
#if defined(VECTOR) || defined(__SGI_STL_VECTOR)
Weighted_alpha_shape_2(typename std::vector<Point>::const_iterator first,
typename std::vector<Point>::const_iterator last,
const Coord_type& alpha = 0,
Mode m = GENERAL)
: Alpha_shape_2<Rt>(first, last, alpha, m)
{}
#endif // VECTOR
#endif //CGAL_CFG_NO_MEMBER_TEMPLATES
//---------------heuristic initialization of weights----------------
#ifndef CGAL_CFG_NO_MEMBER_TEMPLATES
template <class Iterator>
void
initialize_weights_to_the_nearest_voronoi_vertex
(Iterator first, Iterator last, const Coord_type &k);
//---------------------------------------------------------------------
template <class Iterator>
void
initialize_weights_to_the_nearest_voronoi_edge
(Iterator first, Iterator last, const Coord_type &k);
//---------------------------------------------------------------------
template <class Iterator>
void
initialize_weights_to_the_nearest_vertex
(Iterator first, Iterator last, const Coord_type &k);
#else //CGAL_CFG_NO_MEMBER_TEMPLATES
#if defined(LIST) || defined(__SGI_STL_LIST)
void
initialize_weights_to_the_nearest_voronoi_vertex
(typename std::list<Point>::iterator first,
typename std::list<Point>::iterator last, const Coord_type &k);
//---------------------------------------------------------------------
void
initialize_weights_to_the_nearest_voronoi_edge
(typename std::list<Point>::iterator first,
typename std::list<Point>::iterator last, const Coord_type &k);
//---------------------------------------------------------------------
void
initialize_weights_to_the_nearest_vertex
(typename std::list<Point>::iterator first,
typename std::list<Point>::iterator last, const Coord_type &k);
#endif //LIST
#if defined(VECTOR) || defined(__SGI_STL_VECTOR)
void
initialize_weights_to_the_nearest_voronoi_vertex
(typename std::vector<Point>::iterator first,
typename std::vector<Point>::iterator last, const Coord_type &k);
//---------------------------------------------------------------------
void
initialize_weights_to_the_nearest_voronoi_edge
(typename std::vector<Point>::iterator first,
typename std::vector<Point>::iterator last, const Coord_type &k);
//---------------------------------------------------------------------
void
initialize_weights_to_the_nearest_vertex
(typename std::vector<Point>::iterator first,
typename std::vector<Point>::iterator last, const Coord_type &k);
//---------------------------------------------------------------------
#endif // VECTOR
#endif // CGAL_CFG_NO_MEMBER_TEMPLATES
};
//---------------------- MEMBER FUNCTIONS -----------------------------
#ifndef CGAL_CFG_NO_MEMBER_TEMPLATES
template <class Rt> template <class Iterator>
void
Weighted_alpha_shape_2<Rt>::initialize_weights_to_the_nearest_voronoi_vertex
(Iterator first, Iterator last, const Coord_type &k)
{
Delaunay_triangulation_2<Gt, Tds> D;
Iterator point_it;
D.insert(first, last);
for( point_it = first;
point_it != last;
++point_it)
{
Face_circulator face_circ=D.incident_faces(D.nearest_vertex(*point_it)),
done = face_circ;
double d=DBL_MAX;
if (!face_circ.is_empty())
{
do
{
Face_handle f = face_circ;
if (!D.is_infinite(f))
{
Point p = D.dual(f);
double dd = squared_distance(p, *point_it);
d = std::min(dd, d);
}
}
while(++face_circ != done);
}
(*point_it) = Point((*point_it).point(), k*k*d);
}
}
//---------------------------------------------------------------------
template <class Rt> template <class Iterator>
void
Weighted_alpha_shape_2<Rt>::initialize_weights_to_the_nearest_voronoi_edge
(Iterator first, Iterator last, const Coord_type &k)
{
typedef Delaunay_triangulation_2<Gt, Tds> Dt_int;
Dt_int D;
Iterator point_it;
D.insert(first, last);
for( point_it = first;
point_it != last;
++point_it)
{
typename Dt_int::Face_circulator face_circ=
D.incident_faces(D.nearest_vertex(*point_it)),
done = face_circ;
double d = DBL_MAX;
double dd = DBL_MAX;
if (!face_circ.is_empty())
{
do
{
typename Dt_int::Face_handle f = face_circ;
if (!D.is_infinite(f))
{
for ( int i=0; i!=3; ++i)
{
typename Dt_int::Edge e(f,i);
if ((!D.is_infinite(e.first))&&
(!D.is_infinite(e.first->neighbor(e.second))))
{
typename Gt::Segment seg(D.dual(e.first),
D.dual(e.first
->neighbor(e.second)));
dd = squared_distance(seg, *point_it);
}
d = std::min(dd, d);
}
}
}
while(++face_circ != done);
}
if (d != DBL_MAX)
(*point_it) = Point((*point_it).point(), k*k*d);
else
(*point_it) = Point((*point_it).point(), Coord_type(0));
}
}
//---------------------------------------------------------------------
template <class Rt> template <class Iterator>
void
Weighted_alpha_shape_2<Rt>::initialize_weights_to_the_nearest_vertex
(Iterator first, Iterator last, const Coord_type &k)
{
Delaunay_triangulation_2<Gt, Tds> D;
Iterator point_it;
D.insert(first, last);
for( point_it = first;
point_it != last;
++point_it)
{
D.remove(D.nearest_vertex(*point_it));
Point neighbor = D.nearest_vertex(*point_it)->point();
(*point_it) = Point((*point_it).point(),k*k*
squared_distance(neighbor, *point_it));
D.insert(*point_it);
}
}
#else // CGAL_CFG_NO_MEMBER_TEMPLATES
//-------------------------------------------------------------------
#if defined(VECTOR) || defined(__SGI_STL_VECTOR)
template<class Rt>
void
Weighted_alpha_shape_2<Rt>::initialize_weights_to_the_nearest_voronoi_vertex
(typename std::vector<Point>::iterator first,
typename std::vector<Point>::iterator last, const Coord_type &k)
{
Delaunay_triangulation_2<Gt, Tds> D;
typename std::vector<Point>::iterator point_it;
D.insert(first, last);
for( point_it = first;
point_it != last;
++point_it)
{
Face_circulator face_circ=D.incident_faces(D.nearest_vertex(*point_it)),
done = face_circ;
double d=DBL_MAX;
if (!face_circ.is_empty())
{
do
{
Face_handle f = face_circ;
if (!D.is_infinite(f))
{
Point p = D.dual(f);
double dd = squared_distance(p, *point_it);
d = std::min(dd, d);
}
}
while(++face_circ != done);
}
(*point_it) = Point((*point_it).point(), k*k*d);
}
}
//-----------------------------------------------------------------------
template<class Rt>
void
Weighted_alpha_shape_2<Rt>::initialize_weights_to_the_nearest_voronoi_edge
(typename std::vector<Point>::iterator first,
typename std::vector<Point>::iterator last, const Coord_type &k)
{
typedef Delaunay_triangulation_2<Gt, Tds> Dt_int;
Dt_int D;
typename std::vector<Point>::iterator point_it;
D.insert(first, last);
for( point_it = first;
point_it != last;
++point_it)
{
typename Dt_int::Face_circulator face_circ=
D.incident_faces(D.nearest_vertex(*point_it)),
done = face_circ;
double d = DBL_MAX;
double dd = DBL_MAX;
if (!face_circ.is_empty())
{
do
{
typename Dt_int::Face_handle f = face_circ;
if (!D.is_infinite(f))
{
for ( int i=0; i!=3; ++i)
{
typename Dt_int::Edge e(f,i);
if ((!D.is_infinite(e.first))&&
(!D.is_infinite(e.first->neighbor(e.second))))
{
typename Gt::Segment seg(D.dual(e.first),
D.dual(e.first
->neighbor(e.second)));
dd = squared_distance(seg, *point_it);
}
d = std::min(dd, d);
}
}
}
while(++face_circ != done);
}
if (d != DBL_MAX)
(*point_it) = Point((*point_it).point(), k*k*d);
else
(*point_it) = Point((*point_it).point(), Coord_type(0));
}
}
//-----------------------------------------------------------------------
template<class Rt>
void
Weighted_alpha_shape_2<Rt>::initialize_weights_to_the_nearest_vertex
(typename std::vector<Point>::iterator first,
typename std::vector<Point>::iterator last, const Coord_type &k)
{
Delaunay_triangulation_2<Gt, Tds> D;
typename std::vector<Point>::iterator point_it;
D.insert(first, last);
for( point_it = first;
point_it != last;
++point_it)
{
D.remove(D.nearest_vertex(*point_it));
Point neighbor = D.nearest_vertex(*point_it)->point();
(*point_it) = Point((*point_it).point(),k*k*
squared_distance(neighbor, *point_it));
D.insert(*point_it);
}
}
#endif //VECTOR
//-----------------------------------------------------------------------
#if defined(LIST) || defined(__SGI_STL_LIST)
template<class Rt>
void
Weighted_alpha_shape_2<Rt>::initialize_weights_to_the_nearest_voronoi_vertex
(typename std::list<Point>::iterator first,
typename std::list<Point>::iterator last, const Coord_type &k)
{
Delaunay_triangulation_2<Gt, Tds> D;
typename std::list<Point>::iterator point_it;
D.insert(first, last);
for( point_it = first;
point_it != last;
++point_it)
{
Face_circulator face_circ=D.incident_faces(D.nearest_vertex(*point_it)),
done = face_circ;
double d=DBL_MAX;
if (!face_circ.is_empty())
{
do
{
Face_handle f = face_circ;
if (!D.is_infinite(f))
{
Point p = D.dual(f);
double dd = squared_distance(p, *point_it);
d = std::min(dd, d);
}
}
while(++face_circ != done);
}
(*point_it) = Point((*point_it).point(), k*k*d);
}
}
//-----------------------------------------------------------------------
template<class Rt>
void
Weighted_alpha_shape_2<Rt>::initialize_weights_to_the_nearest_voronoi_edge
(typename std::list<Point>::iterator first,
typename std::list<Point>::iterator last, const Coord_type &k)
{
typedef Delaunay_triangulation_2<Gt, Tds> Dt_int;
Dt_int D;
typename std::list<Point>::iterator point_it;
D.insert(first, last);
for( point_it = first;
point_it != last;
++point_it)
{
typename Dt_int::Face_circulator face_circ=
D.incident_faces(D.nearest_vertex(*point_it)),
done = face_circ;
double d = DBL_MAX;
double dd = DBL_MAX;
if (!face_circ.is_empty())
{
do
{
typename Dt_int::Face_handle f = face_circ;
if (!D.is_infinite(f))
{
for ( int i=0; i!=3; ++i)
{
typename Dt_int::Edge e(f,i);
if ((!D.is_infinite(e.first))&&
(!D.is_infinite(e.first->neighbor(e.second))))
{
typename Gt::Segment seg(D.dual(e.first),
D.dual(e.first
->neighbor(e.second)));
dd = squared_distance(seg, *point_it);
}
d = std::min(dd, d);
}
}
}
while(++face_circ != done);
}
if (d != DBL_MAX)
(*point_it) = Point((*point_it).point(), k*k*d);
else
(*point_it) = Point((*point_it).point(), Coord_type(0));
}
}
//-----------------------------------------------------------------------
template<class Rt>
void
Weighted_alpha_shape_2<Rt>::initialize_weights_to_the_nearest_vertex
(typename std::list<Point>::iterator first,
typename std::list<Point>::iterator last, const Coord_type &k)
{
Delaunay_triangulation_2<Gt, Tds> D;
typename std::list<Point>::iterator point_it;
D.insert(first, last);
for( point_it = first;
point_it != last;
++point_it)
{
D.remove(D.nearest_vertex(*point_it));
Point neighbor = D.nearest_vertex(*point_it)->point();
(*point_it) = Point((*point_it).point(),k*k*
squared_distance(neighbor, *point_it));
D.insert(*point_it);
}
}
//-------------------------------------------------------------------
#endif // LIST
#endif // CGAL_CFG_NO_MEMBER_TEMPLATES
//-------------------------------------------------------------------
CGAL_END_NAMESPACE
//-------------------------------------------------------------------
#endif //CGAL_WEIGHTED_ALPHA_2_H

View File

@ -1,6 +1,50 @@
% ======================================================================
%
% Copyright (c) 1999 The GALIA Consortium
%
% This software and related documentation is part of the
% Computational Geometry Algorithms Library (CGAL).
%
% Every use of CGAL requires a license. Licenses come in three kinds:
%
% - For academic research and teaching purposes, permission to use and
% copy the software and its documentation is hereby granted free of
% charge, provided that
% (1) it is not a component of a commercial product, and
% (2) this notice appears in all copies of the software and
% related documentation.
% - Development licenses grant access to the source code of the library
% to develop programs. These programs may be sold to other parties as
% executable code. To obtain a development license, please contact
% the GALIA Consortium (at cgal@cs.uu.nl).
% - Commercialization licenses grant access to the source code and the
% right to sell development licenses. To obtain a commercialization
% license, please contact the GALIA Consortium (at cgal@cs.uu.nl).
%
% This software and documentation is provided "as-is" and without
% warranty of any kind. In no event shall the CGAL Consortium be
% liable for any damage of any kind.
%
% The GALIA Consortium consists of Utrecht University (The Netherlands),
% ETH Zurich (Switzerland), Free University of Berlin (Germany),
% INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg
% (Germany), Max-Planck-Institute Saarbrucken (Germany),
% and Tel-Aviv University (Israel).
%
% ----------------------------------------------------------------------
%
% package : Alpha_shapes_2
% author(s) : Tran Kai Frank DA <Frank.Da@sophia.inria.fr>
%
% coordinator : INRIA Sophia-Antipolis (<Mariette.Yvinec@sophia.inria.fr>)
%
% ======================================================================
\RCSdef{\alphashapeRevision}{$Revision$}
\RCSdefDate{\alphashapeDate}{$Date$}
%----------------------------------------------------------------------
\chapter{Alpha-Shapes} \label{I1_ChapterAlphashapes}
\ccChapterSubTitle{\alphashapeRevision, \alphashapeDate}
@ -8,8 +52,7 @@
\section{Introduction}
This chapter presents a framework for alpha shapes. The description is based on
the articles \cite{em-tdas-94,e-was-92}. Alpha shapes can be used for shape
reconstruction from a dense unorganized set of data points. Alpha shapes are
the articles \cite{em-tdas-94,e-was-92}. Alpha shapes are
the generalization of the convex hull of a point set. Let $S$ be a finite set of
points in $\R^d$, $d = 2,3$ and $\alpha$ a parameter with $0 \leq \alpha \leq
\infty$. For $\alpha = \infty$, the $\alpha$-shape is the convex hull of $S$. As
@ -17,14 +60,16 @@ $\alpha$ decreases, the $\alpha$-shape shrinks and develops cavities, as soon as
a sphere of radius $\sqrt{\alpha}$ can be put inside.
Finally, for $\alpha = 0$, the $\alpha$-shape is the set $S$ itself.
We can describe two versions of alpha shapes, one is based on the Delaunay
We distinguish two versions of alpha shapes, one is based on the Delaunay
triangulation and the other on its generalization, the regular triangulation,
replacing the natural distance by the power to weighted points. The metric used
determines an underlying triangulation of the alpha shape and thus, the version
computed.
In one hand, there is the classic alpha shapes associated with the Delaunay triangulations
(cf. \ref{I1_Sect_Delaunay}), in the other hand, the weighted alpha shapes
associated with the regular triangulations (cf. \ref{I1_Sect_Regular}).
In one hand, there is the {\em classic alpha shapes}
(cf. \ref{I1_SectClassicAS}) associated with the Delaunay triangulations
(cf. \ref{I1_Sect_Delaunay}), in the other hand, the {\em weighted alpha shapes}
(cf. \ref{I1_SectWeightedAS}) associated with the regular triangulations
(cf. \ref{I1_Sect_Regular}).
There is a close connection between alpha shapes and the underlying
triangulations. More precisely, the $\alpha$-complex of $S$ is a
@ -34,9 +79,7 @@ open disk (resp.\ ball) of radius $\sqrt{\alpha}$ through the vertices of the
simplex that does not contain any other point of $S$, for the metric used in
the computation of the underlying triangulation. The corresponding
$\alpha$-shape is defined as the underlying interior space of the
$\alpha$-complex. The $\alpha$-shape is demarcated by a frontier, which is,
under conditions described in \cite{bb-srmua-97t}, a linear approximation of the
original contour.
$\alpha$-complex.
In general, an $\alpha$-complex is a non-connected and non-pure polytope, it
means, that one $k$-simplice, $0 \leq k \leq d-1$ is not necessary adjacent to
@ -44,7 +87,7 @@ a $(k+1)$-simplice.
The $\alpha$-shapes of $S$ form a discrete family, even though they
are defined for all real numbers $\alpha$ with $0 \leq \alpha
\leq \infty$. Thus, we can represent the entire family of $\alpha$ shapes
\leq \infty$. Thus, we can represent the entire family of $\alpha$-shapes
of $S$ by the underlying triangulation of $S$. In this representation
each $k$-simplex of the underlying triangulation is associated with an
interval that specifies for which values of $\alpha$ the $k$-simplex
@ -54,6 +97,13 @@ easily. Furthermore, we can select an appropriate $\alpha$-shape from a
finite number of different $\alpha$-shapes and corresponding
$\alpha$-values.
\subsection*{Main Application}
Alpha shapes can be used for shape reconstruction from a dense unorganized set
of data points. The $\alpha$-shape is demarcated by a frontier, which is, under
conditions described for the classic version in \cite{bb-srmua-97t}, a linear
approximation of the original contour.
%----------------------------------------------------------------------
\section{Generic Alpha-Shapes of Points in a Plane \label{I1_SectAlpha_Shape_2}}
@ -61,25 +111,25 @@ $\alpha$-values.
\begin{ccClassTemplate} {Alpha_shape_2<Dt>}
\ccDefinition
The class \ccClassTemplateName\ represents the family of
$\alpha$-shapes of points in a plane for {\em all} positive
$\alpha$. It maintains the underlying triangulation \ccStyle{Dt} which
$\alpha$. It maintains the underlying triangulation \ccc{Dt} which
represents connectivity and order among its faces. Each
$k$-dimensional face of the \ccStyle{Dt} is associated with
$k$-dimensional face of the \ccc{Dt} is associated with
an interval that specifies for which values of $\alpha$ the face
belongs to the $\alpha$-shape. There are links between the intervals
and the $k$-dimensional faces of the triangulation.
\ccInclude{CGAL/Alpha_shape_2.h}
\ccInheritsFrom
\ccStyle{Dt}
\ccc{Dt}
This class is the underlying triangulation class.
The modifying functions \ccStyle{insert} and \ccStyle{remove} will overwrite
The modifying functions \ccc{insert} and \ccc{remove} will overwrite
the inherited functions. At the moment, only the static version is implemented.
\ccTypes
@ -87,24 +137,24 @@ the inherited functions. At the moment, only the static version is implemented.
\ccThreeToTwo
\ccNestedType{Gt}{the alpha shape traits type.}
it contains a Delaunay triangulation traits class. For example \ccStyle{Dt::Point} is a Point class.
it contains a Delaunay triangulation traits class. For example \ccc{Dt::Point} is a Point class.
\ccTypedef{typedef Gt::Coord_type Coord_type;}{the number type for computation.}
\ccNestedType{Alpha_iterator}{An iterator that allow to traverse
the increasing sequence of different $\alpha$-values. The iterator is
bidirectional and non-mutable. Its \ccStyle{value_type}
is \ccStyle{Coord_type}}
bidirectional and non-mutable. Its \ccc{value_type}
is \ccc{Coord_type}}
\ccEnum{enum Classification_type {EXTERIOR, SINGULAR, REGULAR, INTERIOR};}
{Distinguishes the different cases for classifying a $k$-dimensional face
of the underlying triangulation of the $\alpha$-shape. \\
\ccStyle{EXTERIOR} if the face does not belong to the $\alpha$-complex.\\
\ccStyle{SINGULAR} if the face belongs to the boundary of the $\alpha$-shape,
\ccc{EXTERIOR} if the face does not belong to the $\alpha$-complex.\\
\ccc{SINGULAR} if the face belongs to the boundary of the $\alpha$-shape,
but is not incident to any 2-dimensional face of the $\alpha$-complex\\
\ccStyle{REGULAR} if the face belongs to the boundary of the $\alpha$-shape
\ccc{REGULAR} if the face belongs to the boundary of the $\alpha$-shape
and is incident to a 2-dimensional face of the $\alpha$-complex\\
\ccStyle{INTERIOR} if the face belongs to the $\alpha$-complex, but does
\ccc{INTERIOR} if the face belongs to the $\alpha$-complex, but does
not belong to the boundary of the $\alpha$-shape\\}
\ccEnum{enum Mode {GENERAL, REGULARIZED};}
@ -118,8 +168,8 @@ and their vertices}
\ccConstructor{Alpha_shape_2(Coord_type alpha = 0,
Mode m = GENERAL);}
{Introduces an empty $\alpha$-shape \ccVar\ for a positive $\alpha$-value
\ccStyle{alpha}.
\ccPrecond \ccStyle{alpha}~$\geq~0$.}
\ccc{alpha}.
\ccPrecond \ccc{alpha}~$\geq~0$.}
\ccConstructor{template < class InputIterator >
@ -129,12 +179,12 @@ and their vertices}
const Coord_type& alpha = 0,
Mode m = GENERAL);}
{Initializes the family of alpha-shapes with the points in the range
$\left[\right.$\ccStyle{first}, \ccStyle{last}$\left.\right)$ and
$\left[\right.$\ccc{first}, \ccc{last}$\left.\right)$ and
introduces an $\alpha$-shape \ccVar\ for a positive $\alpha$-value
\ccStyle{alpha}.
\ccPrecond The \ccStyle{value_type} of \ccStyle{first} and
\ccStyle{last} is \ccStyle{Point}.\\
\ccStyle{alpha} $\geq 0$.}
\ccc{alpha}.
\ccPrecond The \ccc{value_type} of \ccc{first} and
\ccc{last} is \ccc{Point}.\\
\ccc{alpha} $\geq 0$.}
\ccOperations
@ -145,14 +195,14 @@ introduces an $\alpha$-shape \ccVar\ for a positive $\alpha$-value
const Coord_type& alpha = 0,
Mode m = GENERAL);}
{Initialize the family of alpha-shapes with the points in the range
$\left[\right.$\ccStyle{first}, \ccStyle{last}$\left.\right)$ and
$\left[\right.$\ccc{first}, \ccc{last}$\left.\right)$ and
introduces an $\alpha$-shape \ccVar\ for a positive $\alpha$-value
\ccStyle{alpha}. Returns the number of inserted points. \\
\ccc{alpha}. Returns the number of inserted points. \\
If the function is applied to an non-empty family of alpha-shape, it is cleared
before initialization.
\ccPrecond The \ccStyle{value_type} of \ccStyle{first} and
\ccStyle{last} is \ccStyle{Point}.\\
\ccStyle{alpha} $\geq 0$.}
\ccPrecond The \ccc{value_type} of \ccc{first} and
\ccc{last} is \ccc{Point}.\\
\ccc{alpha} $\geq 0$.}
\ccMethod{void
clear();}
@ -160,9 +210,9 @@ before initialization.
\ccMethod{Coord_type
set_alpha(const Coord_type& alpha);}
{Sets the $\alpha$-value to \ccStyle{alpha}.
{Sets the $\alpha$-value to \ccc{alpha}.
Returns the previous $\alpha$-value.
\ccPrecond \ccStyle{alpha} $\geq 0$.}
\ccPrecond \ccc{alpha} $\geq 0$.}
\ccMethod{const Coord_type&
get_alpha(void) const;}
@ -170,7 +220,7 @@ before initialization.
\ccMethod{const Coord_type& get_nth_alpha(int n) const;}
{Returns the $n$-th alpha-value, sorted in an increasing order.
\ccPrecond \ccStyle{n} < number of alphas.}
\ccPrecond \ccc{n} < number of alphas.}
\ccMethod{int number_of_alphas() const;}
{Returns the number of different alpha-values.}
@ -178,9 +228,9 @@ before initialization.
% dynamic version
%
% \ccMethod{Vertex_handle insert(const Point& p);}
% {Inserts point \ccStyle{p} in the alpha shape and returns the
% {Inserts point \ccc{p} in the alpha shape and returns the
% corresponding vertex of the underlying Delaunay triangulation.\\ If
% point \ccStyle{p} coincides with an already existing vertex, this
% point \ccc{p} coincides with an already existing vertex, this
% vertex is returned and the alpha shape remains unchanged.\\ Otherwise,
% the vertex is inserted in the underlying Delaunay triangulation and
% the associated intervals are updated. }
@ -204,8 +254,8 @@ Returns the previous mode.}
OutputIterator get_alpha_shape_vertices(
OutputIterator result);}
{Writes the vertices of the alpha shape \ccVar\ for the current $\alpha$-value
to the container where \ccStyle{result} refers to.
The \ccStyle{value_type} of \ccStyle{result} is \ccStyle{Vertex_handle}.
to the container where \ccc{result} refers to.
The \ccc{value_type} of \ccc{result} is \ccc{Vertex_handle}.
Returns an output iterator which is the end of the constructed range.}
\ccMethod{template < class OutputIterator >
@ -213,8 +263,8 @@ Returns an output iterator which is the end of the constructed range.}
OutputIterator result);}
{Writes the edges
of the alpha shape \ccVar\ for the current $\alpha$-value
to the container where \ccStyle{result} refers to.
The \ccStyle{value_type} of \ccStyle{result} is \ccStyle{pair<Face_handle, int>}.
to the container where \ccc{result} refers to.
The \ccc{value_type} of \ccc{result} is \ccc{pair<Face_handle, int>}.
Returns an output iterator which is the end of the constructed range.}
\ccHeading{Predicates}
@ -223,26 +273,26 @@ Returns an output iterator which is the end of the constructed range.}
\ccMethod{Classification_type
classify(const Point& p,
const Coord_type& alpha = get_alpha()) const;}
{Locates a point \ccStyle{p} in the underlying triangulation and Classifies the
{Locates a point \ccc{p} in the underlying triangulation and Classifies the
associated k-face with respect to \ccVar.}
\ccMethod{Classification_type
classify(Face_handle f, const Coord_type& alpha = get_alpha()) const;}
{Classifies the face \ccStyle{f} of the underlying triangulation with respect to \ccVar.}
{Classifies the face \ccc{f} of the underlying triangulation with respect to \ccVar.}
\ccMethod{Classification_type
classify(pair<Face_handle, int> e, const Coord_type& alpha = get_alpha()) const;}
{Classifies the edge \ccStyle{e} of the underlying triangulation with respect to \ccVar.}
{Classifies the edge \ccc{e} of the underlying triangulation with respect to \ccVar.}
\ccMethod{Classification_type
classify(Face_handle f, int i, const Coord_type& alpha = get_alpha()) const;}
{Classifies the edge of the face \ccStyle{f} opposite to the vertex with index
\ccStyle{i}
{Classifies the edge of the face \ccc{f} opposite to the vertex with index
\ccc{i}
of the underlying triangulation with respect to \ccVar.}
\ccMethod{Classification_type
classify(Vertex_handle v, const Coord_type& alpha = get_alpha()) const;}
{Classifies the vertex \ccStyle{v} of the underlying triangulation with respect to \ccVar.}
{Classifies the vertex \ccc{v} of the underlying triangulation with respect to \ccVar.}
\ccHeading{Traversal of the $\alpha$-Values}
@ -251,7 +301,7 @@ of the underlying triangulation with respect to \ccVar.}
The alpha shape class defines an iterator that allows to visit the
sorted sequence of $\alpha$-values. This iterator is
non-mutable and bidirectional. Its value type is
\ccStyle{Coord_type}.
\ccc{Coord_type}.
\ccMethod{Alpha_iterator alpha_begin() const;}
{Returns an iterator that allows to traverse the
@ -262,16 +312,16 @@ sorted sequence of $\alpha$-values of the family of alpha shapes.}
\ccMethod{Alpha_iterator alpha_find(const Coord_type& alpha) const;}
{Returns an iterator pointing to an element with $\alpha$-value
\ccStyle{alpha}, or the corresponding past-the-end iterator if such
\ccc{alpha}, or the corresponding past-the-end iterator if such
an element is not found.}
\ccMethod{Alpha_iterator alpha_lower_bound(const Coord_type& alpha) const;}
{Returns an iterator pointing to the first element with
$\alpha$-value not less than \ccStyle{alpha}.}
$\alpha$-value not less than \ccc{alpha}.}
\ccMethod{Alpha_iterator alpha_upper_bound(const Coord_type& alpha) const;}
{Returns an iterator pointing to the first element with $\alpha$-value
greater than \ccStyle{alpha}.}
greater than \ccc{alpha}.}
\ccHeading{Operations}
@ -283,14 +333,14 @@ regularized version.}
\ccMethod{Alpha_iterator find_optimal_alpha(int nb_components) const;}
{Returns an iterator pointing to the first element with $\alpha$-value
such that \ccVar\ satisfies the following two properties:\\
\ccStyle{nb_components} equals the number of solid components and \\
\ccc{nb_components} equals the number of solid components and \\
all data points are either on the boundary or in the interior of the regularized version of \ccVar.\\
If no such value is found, the iterator points to the first element with
$\alpha$-value such that \ccVar\ satisfies the second property.}
\ccHeading{I/O}
The I/O operators are defined for \ccStyle{iostream}, and for
The I/O operators are defined for \ccc{iostream}, and for
the window stream provided by \cgal. The format for the iostream
is an internal format.
@ -298,8 +348,8 @@ is an internal format.
\ccFunction{ostream& operator<<(ostream& os,
const Alpha_shape_2<Dt>& A);}
{Inserts the alpha shape \ccVar\ for the current $\alpha$-value into the stream \ccStyle{os}.
\ccPrecond The insert operator must be defined for \ccStyle{Point}.}
{Inserts the alpha shape \ccVar\ for the current $\alpha$-value into the stream \ccc{os}.
\ccPrecond The insert operator must be defined for \ccc{Point}.}
\ccInclude{CGAL/IO/Window_stream.h}
@ -307,16 +357,16 @@ is an internal format.
\ccFunction{Window_stream& operator<<(Window_stream& W,
const Alpha_shape_2<Dt>& A);}
{Inserts the alpha shape \ccVar\ for the current $\alpha$-value into the window stream \ccStyle{W}.
\ccPrecond The insert operator must be defined for \ccStyle{Point} and \ccStyle{Segment}.}
{Inserts the alpha shape \ccVar\ for the current $\alpha$-value into the window stream \ccc{W}.
\ccPrecond The insert operator must be defined for \ccc{Point} and \ccc{Segment}.}
\end{ccClassTemplate}
\ccImplementation
In the first static version, the set of intervals associated with the
$k$-dimensional faces of the underlying triangulation are
stored only as sorted \ccStyle{vectors}. By using an interval tree the
stored only as sorted \ccc{vectors}. By using an interval tree the
alpha-shape could be constructed more efficiently. For the dynamic
version, we need \ccStyle{multimaps} or dynamic interval trees.
version, we need \ccc{multimaps} or dynamic interval trees.
The cross links between the intervals and the $k$-dimensional faces of the
triangulation are actually realized using methods in the $k$-dimensional faces
@ -324,43 +374,46 @@ themselves. By this way, you can decide if you want to store or re-compute any
of these informations.
\ccStyle{A.alpha find} uses linear search, while
\ccStyle{A.alpha lower bound} and \ccStyle{A.alpha upper bound}
\ccc{A.alpha find} uses linear search, while
\ccc{A.alpha lower bound} and \ccc{A.alpha upper bound}
use binary search.
\ccStyle{A.number solid components} performs a graph traversal and takes time
\ccc{A.number solid components} performs a graph traversal and takes time
linear in the number of faces of the underlying triangulation.
\ccStyle{A.find optimal alpha} uses binary search and takes time
\ccc{A.find optimal alpha} uses binary search and takes time
$O(\mbox{ \em n } \log{\mbox{ \em n } })$, where $n$ is the number of points.
%----------------------------------------------------------------------
\section{The Underlying Triangulation\label{I1_SectDtClass}}
The class \ccStyle{Dt} must be parameterized with a special alpha shape
traits class and a triangulation data structure, with no more requirements as
For the \ccc{Dt} class, you have to choose between a Delaunay or a regular
triangulation, depending the version of alpha shapes, you want.
The class \ccc{Dt} must be parameterized with a special alpha shape
traits class and a simple triangulation data structure, with no more requirements as
for a simple triangulation class, but parameterized by a special vertex base
class and a special face base class.
\section*{The Alpha-Shape Traits Class\label{I1_ASTraits}}
\section*{The Alpha-Shape Traits Class (\mbox{\it Gt})\label{I1_ASTraits}}
\subsection{Requirements for the Alpha-Shape Traits Class}
First, this traits class has the same requirements as the
triangulation traits class, for the \ccStyle{Dt} triangulation, you choose.
triangulation traits class, for the \ccc{Dt} triangulation, you opted.
The following requirement catalog lists the primitives that must be defined
additionally.
\begin{ccClass} {Gt}
\subsection*{Alpha Shape Traits (\mbox{\it Gt})}
\subsection*{\protect \ccc{Alpha_shape_traits} (\mbox{\it Gt})}
\ccCreationVariable{t}
\ccDefinition
A class \ccClassName\ that satisfies the requirements of a alpha shape
traits class must provide the following predicate and operations in
addition to the requirements for the Delaunay triangulation traits
class.
A class \ccClassName\ that satisfies the requirements of a
\ccc{Alpha_shape_traits} class must provide the following predicate and
operations in addition to the requirements for the underlying triangulation
traits class.
\ccTypes
@ -368,15 +421,9 @@ class.
The type must provide a copy constructor, assignment, comparison
operators, negation, multiplication, division and allow the
declaration and initialization with a small integer constant
(cf. requirements for number types). An obvious choice would be
coordinate type of the point class.}
(cf. requirements for number types).
\ccPrecond An obvious choice would be coordinate type of the point class.}
\ccNestedType{Coord_type}{A type to hold a coordinate type class.
The type must provide a copy constructor, assignment, comparison
operators, negation, multiplication, division and allow the
declaration and initialization with a small integer constant
(cf. requirements for number types). An obvious choice would be
coordinate type of the point class.}
\ccCreation
Only a default constructor is required. Note that further constructors
@ -391,30 +438,30 @@ can be provided.
const Point& p1,
const Point& p2) const;}
{Returns the squared radius of the circle of the
points \ccStyle{p0, p1, p2}, associated with the metric
used by \ccStyle{Dt}.}
points \ccc{p0, p1, p2}, associated with the metric
used by \ccc{Dt}.}
\ccMethod{Coord_type squared_radius(const Point& p0,
const Point& p1) const;}
{Returns the squared radius of smallest circle of the
points \ccStyle{p0, p1}, associated with the metric
used by \ccStyle{Dt}.}
points \ccc{p0, p1}, associated with the metric
used by \ccc{Dt}.}
\ccHeading{Predicate}
\ccMethod{Bounded_side side_of_circle(const Point& p0,
const Point& p1,
const Point& test) const;}
{Returns the relative position of point \ccStyle{test} to the smallest circle of
the points \ccStyle{p0, p1}, using the same metric as \ccStyle{Dt}.}
{Returns the relative position of point \ccc{test} to the smallest circle of
the points \ccc{p0, p1}, using the same metric as \ccc{Dt}.}
\end{ccClass}
\section*{Triangulation Data Structure Class for an Alpha-Shape}
\section*{Triangulation Data Structure Class (\mbox{\it Tds}) for an Alpha-Shape}
The class \ccStyle{Alpha_shape_2<Dt>} parameterized with a
triangulation data structure class \ccStyle{Tds}, that has exactly the same
The class \ccc{Alpha_shape_2<Dt>} parameterized with a
triangulation data structure class \ccc{Tds}, that has exactly the same
requirements as the triangulation data structure class for a simple
triangulation.
@ -428,7 +475,7 @@ Alpha-Shape\label{I1_SectVertex}}
The information about the alpha values associated are accessible by the
vertices of the alpha shape. Thus the nested \ccc{Alpha_shape_vertex_base}
type of a alpha shape offers additional functionalities to deal with these
type of an alpha shape offers additional functionalities to deal with these
methods.
This additional functionalities related to the Alpha Shape
@ -439,7 +486,7 @@ They are listed below as such.
\ccInheritsFrom
\ccStyle{Triangulation_vertex_base}
\ccc{Triangulation_vertex_base}
\begin{ccClass}{Alpha_shape_vertex_base}
@ -453,8 +500,8 @@ operators, negation, multiplication, division and allow the
declaration and initialization with a small integer constant
(cf. requirements for number types). An obvious choice would be
coordinate type of the point class.
\ccPrecond Let's us precise that \ccStyle{Coord_type} has to be the same as the one used by
the \ccStyle{Gt}, already used by underlying triangulation \ccStyle{Dt}.}
\ccPrecond Let's us precise that \ccc{Coord_type} has to be the same as the one used by
the \ccc{Gt}, already used by underlying triangulation \ccc{Dt}.}
\ccCreation
@ -496,27 +543,27 @@ for $\alpha$ under $\alpha_1$, the vertex is regular.}
The information about the alpha values, associated to the face herself and the
incident edges, are accessible by the
faces of the alpha shape. Thus the nested \ccc{Alpha_shape_face_base<Df>}
type of a alpha shape offers additional functionalities to deal with these
type of an alpha shape offers additional functionalities to deal with these
methods.
\ccStyle{Df} has to be choosed as the face base for the underlying triangulation.
\ccc{Df} has to be choosed as the face base for the underlying triangulation.
This additional functionalities related to the alpha shape
are requirements which have to be fulfilled
by the base face for an alpha shape,
in addition to the functionalities required by an underlying triangulation face \ccStyle{Df}.
in addition to the functionalities required by an underlying triangulation face \ccc{Df}.
They are listed below as such.
\ccInheritsFrom
\ccStyle{Df}
\ccc{Df}
\begin{ccClass}{Alpha_shape_face_base<Df>}
\ccCreationVariable{f}
\ccTypes
\ccNestedType{Interval_3}{A container to get (and put) the three special values
\ccNestedType{Interval_3}{A container type to get (and put) the three special values
($\alpha_1, \alpha_2, \alpha_3$) associated with an alpha shape edge.}
\ccNestedType{Coord_type}{A type to hold a coordinate type class.
@ -525,9 +572,9 @@ operators, negation, multiplication, division and allow the
declaration and initialization with a small integer constant
(cf. requirements for number types). An obvious choice would be
coordinate type of the point class.
\ccPrecond Let's us precise that \ccStyle{Coord_type} has to be the same as the one used by
\ccStyle{Gt}, already used by the underlying triangulation \ccStyle{Dt}, and by
her face base \ccStyle{Df}.}
\ccPrecond Let's us precise that \ccc{Coord_type} has to be the same as the one used by
\ccc{Gt}, already used by the underlying triangulation \ccc{Dt}, and by
her face base \ccc{Df}.}
\ccCreation
@ -575,18 +622,18 @@ face.}
%----------------------------------------------------------------------
\section{Classic Version of Alpha-Shape}
\section{Classic Version of Alpha-Shape\label{I1_SectClassicAS}}
\subsection*{The Underlying Triangulation~: a Delaunay Triangulation}
For a simple alpha shape, you have to choose a Delaunay triangulation as
underlying triangulation \ccStyle{Dt} and follow the requirements listed above.
underlying triangulation \ccc{Dt} and follow the requirements listed above.
\ccInclude{CGAL/Delaunay_triangulation_2.h}
\subsection*{Predefined Geometric Traits Class}
\subsection*{Predefined Geometric Traits Class (\mbox{\it Gt})}
Of course, \cgal\ provides a default \ccc{Alpha_shape_traits} class in this
Of course, \cgal\ provides a default \ccc{Alpha_shape_traits} class in this
case, with an implementation of the appropriate predicate and constructions.
The class \ccc{Alpha_shape_euclidean_traits_2<Rp>} simply derived from
\ccc{Triangulation_euclidean_traits_2<Rp>}.
@ -632,18 +679,18 @@ typedef CGAL::Alpha_shape_2<Dt> Alpha_shape_2;
%----------------------------------------------------------------------
\section{Weighted Version of Alpha-Shape}
\section{Weighted Version of Alpha-Shape\label{I1_SectWeightedAS}}
\subsection*{The Underlying Triangulation~: a Regular Triangulation}
For a weighted alpha shape, you have to choose a regular triangulation as
underlying triangulation \ccStyle{Dt} and follow the requirements listed above.
underlying triangulation \ccc{Dt} and follow the requirements listed above.
\ccInclude{CGAL/Regular_triangulation_2.h}
\subsection*{Predefined Geometric Traits Class}
\subsection*{Predefined Geometric Traits Class (\mbox{\it Gt})}
Of course, \cgal\ provides a default \ccc{Alpha_shape_traits} class in this
Of course, \cgal\ provides a default \ccc{Alpha_shape_traits} class in this
case, with an implementation of the appropriate predicate and constructions.
The class \ccc{Weighted_alpha_shape_euclidean_traits_2<Rp>} simply derived from
\ccc{Regular_euclidean_traits_2<Rp>}.
@ -686,76 +733,3 @@ typedef CGAL::Triangulation_default_data_structure_2<Gt,Vb,Fb> Tds;
typedef CGAL::Regular_triangulation_2<Gt,Tds> Rt;
typedef CGAL::Alpha_shape_2<Rt> Alpha_shape_2;
\end{cprog}
%----------------------------------------------------------------------
\section{Additional Functionalities for Weighted Alpha-Shape\label{I2_SectWeighted_Alpha_Shape_2}}
\begin{ccClassTemplate} {Weighted_alpha_shape_2<Rt>}
\ccDefinition
Specially for the weighted version, the computation of alpha shape often
enforces an estimation of weights for the sample of points. This class
\ccClassTemplateName\ provides some heuristic methods to initialize these
weights in two dimensions. They can deal with samples of points extract from a
contour in a plane. The main idea is to control an union of sphere, dual of the
weighted alpha shape, which has to preserve the skeleton of the original
contour. The best results are in \ccc{GENERAL} mode, with $\alpha=0$.
\ccInclude{CGAL/Weighted_alpha_shape_2.h}
\ccInheritsFrom
\ccStyle{Alpha_shape_2<Rt>}
This\ccClassTemplateName\ has exactly the same requirements as the
\ccc{Alpha_shape_2} class, used for the weighted version of alpha shape.
\ccCreation
\ccCreationVariable{A}
\ccConstructor{Weighted_alpha_shape_2(Coord_type alpha = 0,
Mode m = GENERAL);}
{Introduces an empty $\alpha$-shape \ccVar\ for a positive $\alpha$-value
\ccStyle{alpha}.
\ccPrecond \ccStyle{alpha}~$\geq~0$.}
\ccConstructor{template < class InputIterator >
Weighted_alpha_shape_2(
InputIterator first,
InputIterator last,
const Coord_type& alpha = 0,
Mode m = GENERAL);}
{Initializes the family of alpha-shapes with the weighted points in the range
$\left[\right.$\ccStyle{first}, \ccStyle{last}$\left.\right)$ and
introduces an $\alpha$-shape \ccVar\ for a positive $\alpha$-value
\ccStyle{alpha}.
\ccPrecond The \ccStyle{value_type} of \ccStyle{first} and
\ccStyle{last} is \ccStyle{Weighted_point}.\\
\ccStyle{alpha} $\geq 0$.}
\ccOperations
\ccMethod{template < class Iterator >
void
initialize_weights_to_the_nearest_voronoi_vertex
(Iterator first, Iterator last, const Coord_type& k);}
{initialize the weight of each point, stored in a container of points, with a value
equal to the distance to his nearest Voronoi vertex multiply by $k \leq 1$.}
\ccMethod{template < class Iterator >
void
initialize_weights_to_the_nearest_voronoi_edge
(Iterator first, Iterator last, const Coord_type& k);}
{initialize the weight of each point, stored in a container of points, with a
value equal to the distance to his nearest Voronoi edge multiply by $k \geq 1$.}
\ccMethod{template < class Iterator >
void
initialize_weights_to_the_nearest_vertex
(Iterator first, Iterator last, const Coord_type& k);}
{initialize the weight of each point, stored in a container of points, with a
value equal to the distance to his nearest vertex multiply by $k$.}
\end{ccClassTemplate}

View File

@ -1,6 +1,50 @@
% ======================================================================
%
% Copyright (c) 1999 The GALIA Consortium
%
% This software and related documentation is part of the
% Computational Geometry Algorithms Library (CGAL).
%
% Every use of CGAL requires a license. Licenses come in three kinds:
%
% - For academic research and teaching purposes, permission to use and
% copy the software and its documentation is hereby granted free of
% charge, provided that
% (1) it is not a component of a commercial product, and
% (2) this notice appears in all copies of the software and
% related documentation.
% - Development licenses grant access to the source code of the library
% to develop programs. These programs may be sold to other parties as
% executable code. To obtain a development license, please contact
% the GALIA Consortium (at cgal@cs.uu.nl).
% - Commercialization licenses grant access to the source code and the
% right to sell development licenses. To obtain a commercialization
% license, please contact the GALIA Consortium (at cgal@cs.uu.nl).
%
% This software and documentation is provided "as-is" and without
% warranty of any kind. In no event shall the CGAL Consortium be
% liable for any damage of any kind.
%
% The GALIA Consortium consists of Utrecht University (The Netherlands),
% ETH Zurich (Switzerland), Free University of Berlin (Germany),
% INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg
% (Germany), Max-Planck-Institute Saarbrucken (Germany),
% and Tel-Aviv University (Israel).
%
% ----------------------------------------------------------------------
%
% package : Alpha_shapes_2
% author(s) : Tran Kai Frank DA <Frank.Da@sophia.inria.fr>
%
% coordinator : INRIA Sophia-Antipolis (<Mariette.Yvinec@sophia.inria.fr>)
%
% ======================================================================
\RCSdef{\alphashapeRevision}{$Revision$}
\RCSdefDate{\alphashapeDate}{$Date$}
%----------------------------------------------------------------------
\chapter{Alpha-Shapes} \label{I1_ChapterAlphashapes}
\ccChapterSubTitle{\alphashapeRevision, \alphashapeDate}
@ -8,8 +52,7 @@
\section{Introduction}
This chapter presents a framework for alpha shapes. The description is based on
the articles \cite{em-tdas-94,e-was-92}. Alpha shapes can be used for shape
reconstruction from a dense unorganized set of data points. Alpha shapes are
the articles \cite{em-tdas-94,e-was-92}. Alpha shapes are
the generalization of the convex hull of a point set. Let $S$ be a finite set of
points in $\R^d$, $d = 2,3$ and $\alpha$ a parameter with $0 \leq \alpha \leq
\infty$. For $\alpha = \infty$, the $\alpha$-shape is the convex hull of $S$. As
@ -17,14 +60,16 @@ $\alpha$ decreases, the $\alpha$-shape shrinks and develops cavities, as soon as
a sphere of radius $\sqrt{\alpha}$ can be put inside.
Finally, for $\alpha = 0$, the $\alpha$-shape is the set $S$ itself.
We can describe two versions of alpha shapes, one is based on the Delaunay
We distinguish two versions of alpha shapes, one is based on the Delaunay
triangulation and the other on its generalization, the regular triangulation,
replacing the natural distance by the power to weighted points. The metric used
determines an underlying triangulation of the alpha shape and thus, the version
computed.
In one hand, there is the classic alpha shapes associated with the Delaunay triangulations
(cf. \ref{I1_Sect_Delaunay}), in the other hand, the weighted alpha shapes
associated with the regular triangulations (cf. \ref{I1_Sect_Regular}).
In one hand, there is the {\em classic alpha shapes}
(cf. \ref{I1_SectClassicAS}) associated with the Delaunay triangulations
(cf. \ref{I1_Sect_Delaunay}), in the other hand, the {\em weighted alpha shapes}
(cf. \ref{I1_SectWeightedAS}) associated with the regular triangulations
(cf. \ref{I1_Sect_Regular}).
There is a close connection between alpha shapes and the underlying
triangulations. More precisely, the $\alpha$-complex of $S$ is a
@ -34,9 +79,7 @@ open disk (resp.\ ball) of radius $\sqrt{\alpha}$ through the vertices of the
simplex that does not contain any other point of $S$, for the metric used in
the computation of the underlying triangulation. The corresponding
$\alpha$-shape is defined as the underlying interior space of the
$\alpha$-complex. The $\alpha$-shape is demarcated by a frontier, which is,
under conditions described in \cite{bb-srmua-97t}, a linear approximation of the
original contour.
$\alpha$-complex.
In general, an $\alpha$-complex is a non-connected and non-pure polytope, it
means, that one $k$-simplice, $0 \leq k \leq d-1$ is not necessary adjacent to
@ -44,7 +87,7 @@ a $(k+1)$-simplice.
The $\alpha$-shapes of $S$ form a discrete family, even though they
are defined for all real numbers $\alpha$ with $0 \leq \alpha
\leq \infty$. Thus, we can represent the entire family of $\alpha$ shapes
\leq \infty$. Thus, we can represent the entire family of $\alpha$-shapes
of $S$ by the underlying triangulation of $S$. In this representation
each $k$-simplex of the underlying triangulation is associated with an
interval that specifies for which values of $\alpha$ the $k$-simplex
@ -54,6 +97,13 @@ easily. Furthermore, we can select an appropriate $\alpha$-shape from a
finite number of different $\alpha$-shapes and corresponding
$\alpha$-values.
\subsection*{Main Application}
Alpha shapes can be used for shape reconstruction from a dense unorganized set
of data points. The $\alpha$-shape is demarcated by a frontier, which is, under
conditions described for the classic version in \cite{bb-srmua-97t}, a linear
approximation of the original contour.
%----------------------------------------------------------------------
\section{Generic Alpha-Shapes of Points in a Plane \label{I1_SectAlpha_Shape_2}}
@ -61,25 +111,25 @@ $\alpha$-values.
\begin{ccClassTemplate} {Alpha_shape_2<Dt>}
\ccDefinition
The class \ccClassTemplateName\ represents the family of
$\alpha$-shapes of points in a plane for {\em all} positive
$\alpha$. It maintains the underlying triangulation \ccStyle{Dt} which
$\alpha$. It maintains the underlying triangulation \ccc{Dt} which
represents connectivity and order among its faces. Each
$k$-dimensional face of the \ccStyle{Dt} is associated with
$k$-dimensional face of the \ccc{Dt} is associated with
an interval that specifies for which values of $\alpha$ the face
belongs to the $\alpha$-shape. There are links between the intervals
and the $k$-dimensional faces of the triangulation.
\ccInclude{CGAL/Alpha_shape_2.h}
\ccInheritsFrom
\ccStyle{Dt}
\ccc{Dt}
This class is the underlying triangulation class.
The modifying functions \ccStyle{insert} and \ccStyle{remove} will overwrite
The modifying functions \ccc{insert} and \ccc{remove} will overwrite
the inherited functions. At the moment, only the static version is implemented.
\ccTypes
@ -87,24 +137,24 @@ the inherited functions. At the moment, only the static version is implemented.
\ccThreeToTwo
\ccNestedType{Gt}{the alpha shape traits type.}
it contains a Delaunay triangulation traits class. For example \ccStyle{Dt::Point} is a Point class.
it contains a Delaunay triangulation traits class. For example \ccc{Dt::Point} is a Point class.
\ccTypedef{typedef Gt::Coord_type Coord_type;}{the number type for computation.}
\ccNestedType{Alpha_iterator}{An iterator that allow to traverse
the increasing sequence of different $\alpha$-values. The iterator is
bidirectional and non-mutable. Its \ccStyle{value_type}
is \ccStyle{Coord_type}}
bidirectional and non-mutable. Its \ccc{value_type}
is \ccc{Coord_type}}
\ccEnum{enum Classification_type {EXTERIOR, SINGULAR, REGULAR, INTERIOR};}
{Distinguishes the different cases for classifying a $k$-dimensional face
of the underlying triangulation of the $\alpha$-shape. \\
\ccStyle{EXTERIOR} if the face does not belong to the $\alpha$-complex.\\
\ccStyle{SINGULAR} if the face belongs to the boundary of the $\alpha$-shape,
\ccc{EXTERIOR} if the face does not belong to the $\alpha$-complex.\\
\ccc{SINGULAR} if the face belongs to the boundary of the $\alpha$-shape,
but is not incident to any 2-dimensional face of the $\alpha$-complex\\
\ccStyle{REGULAR} if the face belongs to the boundary of the $\alpha$-shape
\ccc{REGULAR} if the face belongs to the boundary of the $\alpha$-shape
and is incident to a 2-dimensional face of the $\alpha$-complex\\
\ccStyle{INTERIOR} if the face belongs to the $\alpha$-complex, but does
\ccc{INTERIOR} if the face belongs to the $\alpha$-complex, but does
not belong to the boundary of the $\alpha$-shape\\}
\ccEnum{enum Mode {GENERAL, REGULARIZED};}
@ -118,8 +168,8 @@ and their vertices}
\ccConstructor{Alpha_shape_2(Coord_type alpha = 0,
Mode m = GENERAL);}
{Introduces an empty $\alpha$-shape \ccVar\ for a positive $\alpha$-value
\ccStyle{alpha}.
\ccPrecond \ccStyle{alpha}~$\geq~0$.}
\ccc{alpha}.
\ccPrecond \ccc{alpha}~$\geq~0$.}
\ccConstructor{template < class InputIterator >
@ -129,12 +179,12 @@ and their vertices}
const Coord_type& alpha = 0,
Mode m = GENERAL);}
{Initializes the family of alpha-shapes with the points in the range
$\left[\right.$\ccStyle{first}, \ccStyle{last}$\left.\right)$ and
$\left[\right.$\ccc{first}, \ccc{last}$\left.\right)$ and
introduces an $\alpha$-shape \ccVar\ for a positive $\alpha$-value
\ccStyle{alpha}.
\ccPrecond The \ccStyle{value_type} of \ccStyle{first} and
\ccStyle{last} is \ccStyle{Point}.\\
\ccStyle{alpha} $\geq 0$.}
\ccc{alpha}.
\ccPrecond The \ccc{value_type} of \ccc{first} and
\ccc{last} is \ccc{Point}.\\
\ccc{alpha} $\geq 0$.}
\ccOperations
@ -145,14 +195,14 @@ introduces an $\alpha$-shape \ccVar\ for a positive $\alpha$-value
const Coord_type& alpha = 0,
Mode m = GENERAL);}
{Initialize the family of alpha-shapes with the points in the range
$\left[\right.$\ccStyle{first}, \ccStyle{last}$\left.\right)$ and
$\left[\right.$\ccc{first}, \ccc{last}$\left.\right)$ and
introduces an $\alpha$-shape \ccVar\ for a positive $\alpha$-value
\ccStyle{alpha}. Returns the number of inserted points. \\
\ccc{alpha}. Returns the number of inserted points. \\
If the function is applied to an non-empty family of alpha-shape, it is cleared
before initialization.
\ccPrecond The \ccStyle{value_type} of \ccStyle{first} and
\ccStyle{last} is \ccStyle{Point}.\\
\ccStyle{alpha} $\geq 0$.}
\ccPrecond The \ccc{value_type} of \ccc{first} and
\ccc{last} is \ccc{Point}.\\
\ccc{alpha} $\geq 0$.}
\ccMethod{void
clear();}
@ -160,9 +210,9 @@ before initialization.
\ccMethod{Coord_type
set_alpha(const Coord_type& alpha);}
{Sets the $\alpha$-value to \ccStyle{alpha}.
{Sets the $\alpha$-value to \ccc{alpha}.
Returns the previous $\alpha$-value.
\ccPrecond \ccStyle{alpha} $\geq 0$.}
\ccPrecond \ccc{alpha} $\geq 0$.}
\ccMethod{const Coord_type&
get_alpha(void) const;}
@ -170,7 +220,7 @@ before initialization.
\ccMethod{const Coord_type& get_nth_alpha(int n) const;}
{Returns the $n$-th alpha-value, sorted in an increasing order.
\ccPrecond \ccStyle{n} < number of alphas.}
\ccPrecond \ccc{n} < number of alphas.}
\ccMethod{int number_of_alphas() const;}
{Returns the number of different alpha-values.}
@ -178,9 +228,9 @@ before initialization.
% dynamic version
%
% \ccMethod{Vertex_handle insert(const Point& p);}
% {Inserts point \ccStyle{p} in the alpha shape and returns the
% {Inserts point \ccc{p} in the alpha shape and returns the
% corresponding vertex of the underlying Delaunay triangulation.\\ If
% point \ccStyle{p} coincides with an already existing vertex, this
% point \ccc{p} coincides with an already existing vertex, this
% vertex is returned and the alpha shape remains unchanged.\\ Otherwise,
% the vertex is inserted in the underlying Delaunay triangulation and
% the associated intervals are updated. }
@ -204,8 +254,8 @@ Returns the previous mode.}
OutputIterator get_alpha_shape_vertices(
OutputIterator result);}
{Writes the vertices of the alpha shape \ccVar\ for the current $\alpha$-value
to the container where \ccStyle{result} refers to.
The \ccStyle{value_type} of \ccStyle{result} is \ccStyle{Vertex_handle}.
to the container where \ccc{result} refers to.
The \ccc{value_type} of \ccc{result} is \ccc{Vertex_handle}.
Returns an output iterator which is the end of the constructed range.}
\ccMethod{template < class OutputIterator >
@ -213,8 +263,8 @@ Returns an output iterator which is the end of the constructed range.}
OutputIterator result);}
{Writes the edges
of the alpha shape \ccVar\ for the current $\alpha$-value
to the container where \ccStyle{result} refers to.
The \ccStyle{value_type} of \ccStyle{result} is \ccStyle{pair<Face_handle, int>}.
to the container where \ccc{result} refers to.
The \ccc{value_type} of \ccc{result} is \ccc{pair<Face_handle, int>}.
Returns an output iterator which is the end of the constructed range.}
\ccHeading{Predicates}
@ -223,26 +273,26 @@ Returns an output iterator which is the end of the constructed range.}
\ccMethod{Classification_type
classify(const Point& p,
const Coord_type& alpha = get_alpha()) const;}
{Locates a point \ccStyle{p} in the underlying triangulation and Classifies the
{Locates a point \ccc{p} in the underlying triangulation and Classifies the
associated k-face with respect to \ccVar.}
\ccMethod{Classification_type
classify(Face_handle f, const Coord_type& alpha = get_alpha()) const;}
{Classifies the face \ccStyle{f} of the underlying triangulation with respect to \ccVar.}
{Classifies the face \ccc{f} of the underlying triangulation with respect to \ccVar.}
\ccMethod{Classification_type
classify(pair<Face_handle, int> e, const Coord_type& alpha = get_alpha()) const;}
{Classifies the edge \ccStyle{e} of the underlying triangulation with respect to \ccVar.}
{Classifies the edge \ccc{e} of the underlying triangulation with respect to \ccVar.}
\ccMethod{Classification_type
classify(Face_handle f, int i, const Coord_type& alpha = get_alpha()) const;}
{Classifies the edge of the face \ccStyle{f} opposite to the vertex with index
\ccStyle{i}
{Classifies the edge of the face \ccc{f} opposite to the vertex with index
\ccc{i}
of the underlying triangulation with respect to \ccVar.}
\ccMethod{Classification_type
classify(Vertex_handle v, const Coord_type& alpha = get_alpha()) const;}
{Classifies the vertex \ccStyle{v} of the underlying triangulation with respect to \ccVar.}
{Classifies the vertex \ccc{v} of the underlying triangulation with respect to \ccVar.}
\ccHeading{Traversal of the $\alpha$-Values}
@ -251,7 +301,7 @@ of the underlying triangulation with respect to \ccVar.}
The alpha shape class defines an iterator that allows to visit the
sorted sequence of $\alpha$-values. This iterator is
non-mutable and bidirectional. Its value type is
\ccStyle{Coord_type}.
\ccc{Coord_type}.
\ccMethod{Alpha_iterator alpha_begin() const;}
{Returns an iterator that allows to traverse the
@ -262,16 +312,16 @@ sorted sequence of $\alpha$-values of the family of alpha shapes.}
\ccMethod{Alpha_iterator alpha_find(const Coord_type& alpha) const;}
{Returns an iterator pointing to an element with $\alpha$-value
\ccStyle{alpha}, or the corresponding past-the-end iterator if such
\ccc{alpha}, or the corresponding past-the-end iterator if such
an element is not found.}
\ccMethod{Alpha_iterator alpha_lower_bound(const Coord_type& alpha) const;}
{Returns an iterator pointing to the first element with
$\alpha$-value not less than \ccStyle{alpha}.}
$\alpha$-value not less than \ccc{alpha}.}
\ccMethod{Alpha_iterator alpha_upper_bound(const Coord_type& alpha) const;}
{Returns an iterator pointing to the first element with $\alpha$-value
greater than \ccStyle{alpha}.}
greater than \ccc{alpha}.}
\ccHeading{Operations}
@ -283,14 +333,14 @@ regularized version.}
\ccMethod{Alpha_iterator find_optimal_alpha(int nb_components) const;}
{Returns an iterator pointing to the first element with $\alpha$-value
such that \ccVar\ satisfies the following two properties:\\
\ccStyle{nb_components} equals the number of solid components and \\
\ccc{nb_components} equals the number of solid components and \\
all data points are either on the boundary or in the interior of the regularized version of \ccVar.\\
If no such value is found, the iterator points to the first element with
$\alpha$-value such that \ccVar\ satisfies the second property.}
\ccHeading{I/O}
The I/O operators are defined for \ccStyle{iostream}, and for
The I/O operators are defined for \ccc{iostream}, and for
the window stream provided by \cgal. The format for the iostream
is an internal format.
@ -298,8 +348,8 @@ is an internal format.
\ccFunction{ostream& operator<<(ostream& os,
const Alpha_shape_2<Dt>& A);}
{Inserts the alpha shape \ccVar\ for the current $\alpha$-value into the stream \ccStyle{os}.
\ccPrecond The insert operator must be defined for \ccStyle{Point}.}
{Inserts the alpha shape \ccVar\ for the current $\alpha$-value into the stream \ccc{os}.
\ccPrecond The insert operator must be defined for \ccc{Point}.}
\ccInclude{CGAL/IO/Window_stream.h}
@ -307,16 +357,16 @@ is an internal format.
\ccFunction{Window_stream& operator<<(Window_stream& W,
const Alpha_shape_2<Dt>& A);}
{Inserts the alpha shape \ccVar\ for the current $\alpha$-value into the window stream \ccStyle{W}.
\ccPrecond The insert operator must be defined for \ccStyle{Point} and \ccStyle{Segment}.}
{Inserts the alpha shape \ccVar\ for the current $\alpha$-value into the window stream \ccc{W}.
\ccPrecond The insert operator must be defined for \ccc{Point} and \ccc{Segment}.}
\end{ccClassTemplate}
\ccImplementation
In the first static version, the set of intervals associated with the
$k$-dimensional faces of the underlying triangulation are
stored only as sorted \ccStyle{vectors}. By using an interval tree the
stored only as sorted \ccc{vectors}. By using an interval tree the
alpha-shape could be constructed more efficiently. For the dynamic
version, we need \ccStyle{multimaps} or dynamic interval trees.
version, we need \ccc{multimaps} or dynamic interval trees.
The cross links between the intervals and the $k$-dimensional faces of the
triangulation are actually realized using methods in the $k$-dimensional faces
@ -324,43 +374,46 @@ themselves. By this way, you can decide if you want to store or re-compute any
of these informations.
\ccStyle{A.alpha find} uses linear search, while
\ccStyle{A.alpha lower bound} and \ccStyle{A.alpha upper bound}
\ccc{A.alpha find} uses linear search, while
\ccc{A.alpha lower bound} and \ccc{A.alpha upper bound}
use binary search.
\ccStyle{A.number solid components} performs a graph traversal and takes time
\ccc{A.number solid components} performs a graph traversal and takes time
linear in the number of faces of the underlying triangulation.
\ccStyle{A.find optimal alpha} uses binary search and takes time
\ccc{A.find optimal alpha} uses binary search and takes time
$O(\mbox{ \em n } \log{\mbox{ \em n } })$, where $n$ is the number of points.
%----------------------------------------------------------------------
\section{The Underlying Triangulation\label{I1_SectDtClass}}
The class \ccStyle{Dt} must be parameterized with a special alpha shape
traits class and a triangulation data structure, with no more requirements as
For the \ccc{Dt} class, you have to choose between a Delaunay or a regular
triangulation, depending the version of alpha shapes, you want.
The class \ccc{Dt} must be parameterized with a special alpha shape
traits class and a simple triangulation data structure, with no more requirements as
for a simple triangulation class, but parameterized by a special vertex base
class and a special face base class.
\section*{The Alpha-Shape Traits Class\label{I1_ASTraits}}
\section*{The Alpha-Shape Traits Class (\mbox{\it Gt})\label{I1_ASTraits}}
\subsection{Requirements for the Alpha-Shape Traits Class}
First, this traits class has the same requirements as the
triangulation traits class, for the \ccStyle{Dt} triangulation, you choose.
triangulation traits class, for the \ccc{Dt} triangulation, you opted.
The following requirement catalog lists the primitives that must be defined
additionally.
\begin{ccClass} {Gt}
\subsection*{Alpha Shape Traits (\mbox{\it Gt})}
\subsection*{\protect \ccc{Alpha_shape_traits} (\mbox{\it Gt})}
\ccCreationVariable{t}
\ccDefinition
A class \ccClassName\ that satisfies the requirements of a alpha shape
traits class must provide the following predicate and operations in
addition to the requirements for the Delaunay triangulation traits
class.
A class \ccClassName\ that satisfies the requirements of a
\ccc{Alpha_shape_traits} class must provide the following predicate and
operations in addition to the requirements for the underlying triangulation
traits class.
\ccTypes
@ -368,15 +421,9 @@ class.
The type must provide a copy constructor, assignment, comparison
operators, negation, multiplication, division and allow the
declaration and initialization with a small integer constant
(cf. requirements for number types). An obvious choice would be
coordinate type of the point class.}
(cf. requirements for number types).
\ccPrecond An obvious choice would be coordinate type of the point class.}
\ccNestedType{Coord_type}{A type to hold a coordinate type class.
The type must provide a copy constructor, assignment, comparison
operators, negation, multiplication, division and allow the
declaration and initialization with a small integer constant
(cf. requirements for number types). An obvious choice would be
coordinate type of the point class.}
\ccCreation
Only a default constructor is required. Note that further constructors
@ -391,30 +438,30 @@ can be provided.
const Point& p1,
const Point& p2) const;}
{Returns the squared radius of the circle of the
points \ccStyle{p0, p1, p2}, associated with the metric
used by \ccStyle{Dt}.}
points \ccc{p0, p1, p2}, associated with the metric
used by \ccc{Dt}.}
\ccMethod{Coord_type squared_radius(const Point& p0,
const Point& p1) const;}
{Returns the squared radius of smallest circle of the
points \ccStyle{p0, p1}, associated with the metric
used by \ccStyle{Dt}.}
points \ccc{p0, p1}, associated with the metric
used by \ccc{Dt}.}
\ccHeading{Predicate}
\ccMethod{Bounded_side side_of_circle(const Point& p0,
const Point& p1,
const Point& test) const;}
{Returns the relative position of point \ccStyle{test} to the smallest circle of
the points \ccStyle{p0, p1}, using the same metric as \ccStyle{Dt}.}
{Returns the relative position of point \ccc{test} to the smallest circle of
the points \ccc{p0, p1}, using the same metric as \ccc{Dt}.}
\end{ccClass}
\section*{Triangulation Data Structure Class for an Alpha-Shape}
\section*{Triangulation Data Structure Class (\mbox{\it Tds}) for an Alpha-Shape}
The class \ccStyle{Alpha_shape_2<Dt>} parameterized with a
triangulation data structure class \ccStyle{Tds}, that has exactly the same
The class \ccc{Alpha_shape_2<Dt>} parameterized with a
triangulation data structure class \ccc{Tds}, that has exactly the same
requirements as the triangulation data structure class for a simple
triangulation.
@ -428,7 +475,7 @@ Alpha-Shape\label{I1_SectVertex}}
The information about the alpha values associated are accessible by the
vertices of the alpha shape. Thus the nested \ccc{Alpha_shape_vertex_base}
type of a alpha shape offers additional functionalities to deal with these
type of an alpha shape offers additional functionalities to deal with these
methods.
This additional functionalities related to the Alpha Shape
@ -439,7 +486,7 @@ They are listed below as such.
\ccInheritsFrom
\ccStyle{Triangulation_vertex_base}
\ccc{Triangulation_vertex_base}
\begin{ccClass}{Alpha_shape_vertex_base}
@ -453,8 +500,8 @@ operators, negation, multiplication, division and allow the
declaration and initialization with a small integer constant
(cf. requirements for number types). An obvious choice would be
coordinate type of the point class.
\ccPrecond Let's us precise that \ccStyle{Coord_type} has to be the same as the one used by
the \ccStyle{Gt}, already used by underlying triangulation \ccStyle{Dt}.}
\ccPrecond Let's us precise that \ccc{Coord_type} has to be the same as the one used by
the \ccc{Gt}, already used by underlying triangulation \ccc{Dt}.}
\ccCreation
@ -496,27 +543,27 @@ for $\alpha$ under $\alpha_1$, the vertex is regular.}
The information about the alpha values, associated to the face herself and the
incident edges, are accessible by the
faces of the alpha shape. Thus the nested \ccc{Alpha_shape_face_base<Df>}
type of a alpha shape offers additional functionalities to deal with these
type of an alpha shape offers additional functionalities to deal with these
methods.
\ccStyle{Df} has to be choosed as the face base for the underlying triangulation.
\ccc{Df} has to be choosed as the face base for the underlying triangulation.
This additional functionalities related to the alpha shape
are requirements which have to be fulfilled
by the base face for an alpha shape,
in addition to the functionalities required by an underlying triangulation face \ccStyle{Df}.
in addition to the functionalities required by an underlying triangulation face \ccc{Df}.
They are listed below as such.
\ccInheritsFrom
\ccStyle{Df}
\ccc{Df}
\begin{ccClass}{Alpha_shape_face_base<Df>}
\ccCreationVariable{f}
\ccTypes
\ccNestedType{Interval_3}{A container to get (and put) the three special values
\ccNestedType{Interval_3}{A container type to get (and put) the three special values
($\alpha_1, \alpha_2, \alpha_3$) associated with an alpha shape edge.}
\ccNestedType{Coord_type}{A type to hold a coordinate type class.
@ -525,9 +572,9 @@ operators, negation, multiplication, division and allow the
declaration and initialization with a small integer constant
(cf. requirements for number types). An obvious choice would be
coordinate type of the point class.
\ccPrecond Let's us precise that \ccStyle{Coord_type} has to be the same as the one used by
\ccStyle{Gt}, already used by the underlying triangulation \ccStyle{Dt}, and by
her face base \ccStyle{Df}.}
\ccPrecond Let's us precise that \ccc{Coord_type} has to be the same as the one used by
\ccc{Gt}, already used by the underlying triangulation \ccc{Dt}, and by
her face base \ccc{Df}.}
\ccCreation
@ -575,18 +622,18 @@ face.}
%----------------------------------------------------------------------
\section{Classic Version of Alpha-Shape}
\section{Classic Version of Alpha-Shape\label{I1_SectClassicAS}}
\subsection*{The Underlying Triangulation~: a Delaunay Triangulation}
For a simple alpha shape, you have to choose a Delaunay triangulation as
underlying triangulation \ccStyle{Dt} and follow the requirements listed above.
underlying triangulation \ccc{Dt} and follow the requirements listed above.
\ccInclude{CGAL/Delaunay_triangulation_2.h}
\subsection*{Predefined Geometric Traits Class}
\subsection*{Predefined Geometric Traits Class (\mbox{\it Gt})}
Of course, \cgal\ provides a default \ccc{Alpha_shape_traits} class in this
Of course, \cgal\ provides a default \ccc{Alpha_shape_traits} class in this
case, with an implementation of the appropriate predicate and constructions.
The class \ccc{Alpha_shape_euclidean_traits_2<Rp>} simply derived from
\ccc{Triangulation_euclidean_traits_2<Rp>}.
@ -632,18 +679,18 @@ typedef CGAL::Alpha_shape_2<Dt> Alpha_shape_2;
%----------------------------------------------------------------------
\section{Weighted Version of Alpha-Shape}
\section{Weighted Version of Alpha-Shape\label{I1_SectWeightedAS}}
\subsection*{The Underlying Triangulation~: a Regular Triangulation}
For a weighted alpha shape, you have to choose a regular triangulation as
underlying triangulation \ccStyle{Dt} and follow the requirements listed above.
underlying triangulation \ccc{Dt} and follow the requirements listed above.
\ccInclude{CGAL/Regular_triangulation_2.h}
\subsection*{Predefined Geometric Traits Class}
\subsection*{Predefined Geometric Traits Class (\mbox{\it Gt})}
Of course, \cgal\ provides a default \ccc{Alpha_shape_traits} class in this
Of course, \cgal\ provides a default \ccc{Alpha_shape_traits} class in this
case, with an implementation of the appropriate predicate and constructions.
The class \ccc{Weighted_alpha_shape_euclidean_traits_2<Rp>} simply derived from
\ccc{Regular_euclidean_traits_2<Rp>}.
@ -686,76 +733,3 @@ typedef CGAL::Triangulation_default_data_structure_2<Gt,Vb,Fb> Tds;
typedef CGAL::Regular_triangulation_2<Gt,Tds> Rt;
typedef CGAL::Alpha_shape_2<Rt> Alpha_shape_2;
\end{cprog}
%----------------------------------------------------------------------
\section{Additional Functionalities for Weighted Alpha-Shape\label{I2_SectWeighted_Alpha_Shape_2}}
\begin{ccClassTemplate} {Weighted_alpha_shape_2<Rt>}
\ccDefinition
Specially for the weighted version, the computation of alpha shape often
enforces an estimation of weights for the sample of points. This class
\ccClassTemplateName\ provides some heuristic methods to initialize these
weights in two dimensions. They can deal with samples of points extract from a
contour in a plane. The main idea is to control an union of sphere, dual of the
weighted alpha shape, which has to preserve the skeleton of the original
contour. The best results are in \ccc{GENERAL} mode, with $\alpha=0$.
\ccInclude{CGAL/Weighted_alpha_shape_2.h}
\ccInheritsFrom
\ccStyle{Alpha_shape_2<Rt>}
This\ccClassTemplateName\ has exactly the same requirements as the
\ccc{Alpha_shape_2} class, used for the weighted version of alpha shape.
\ccCreation
\ccCreationVariable{A}
\ccConstructor{Weighted_alpha_shape_2(Coord_type alpha = 0,
Mode m = GENERAL);}
{Introduces an empty $\alpha$-shape \ccVar\ for a positive $\alpha$-value
\ccStyle{alpha}.
\ccPrecond \ccStyle{alpha}~$\geq~0$.}
\ccConstructor{template < class InputIterator >
Weighted_alpha_shape_2(
InputIterator first,
InputIterator last,
const Coord_type& alpha = 0,
Mode m = GENERAL);}
{Initializes the family of alpha-shapes with the weighted points in the range
$\left[\right.$\ccStyle{first}, \ccStyle{last}$\left.\right)$ and
introduces an $\alpha$-shape \ccVar\ for a positive $\alpha$-value
\ccStyle{alpha}.
\ccPrecond The \ccStyle{value_type} of \ccStyle{first} and
\ccStyle{last} is \ccStyle{Weighted_point}.\\
\ccStyle{alpha} $\geq 0$.}
\ccOperations
\ccMethod{template < class Iterator >
void
initialize_weights_to_the_nearest_voronoi_vertex
(Iterator first, Iterator last, const Coord_type& k);}
{initialize the weight of each point, stored in a container of points, with a value
equal to the distance to his nearest Voronoi vertex multiply by $k \leq 1$.}
\ccMethod{template < class Iterator >
void
initialize_weights_to_the_nearest_voronoi_edge
(Iterator first, Iterator last, const Coord_type& k);}
{initialize the weight of each point, stored in a container of points, with a
value equal to the distance to his nearest Voronoi edge multiply by $k \geq 1$.}
\ccMethod{template < class Iterator >
void
initialize_weights_to_the_nearest_vertex
(Iterator first, Iterator last, const Coord_type& k);}
{initialize the weight of each point, stored in a container of points, with a
value equal to the distance to his nearest vertex multiply by $k$.}
\end{ccClassTemplate}

View File

@ -1 +1 @@
2.3 ( 9 Nov 1999)
2.4 (15 Nov 1999)