mirror of https://github.com/CGAL/cgal
corrections for public release...
This commit is contained in:
parent
f6987ab722
commit
8a8e00aaa2
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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$
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {};
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
# This is a makefile exemple for compiling a CGAL application.
|
||||
|
||||
#---------------------------------------------------------------------#
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
2.3 ( 9 Nov 1999)
|
||||
2.4 (15 Nov 1999)
|
||||
|
|
|
|||
Loading…
Reference in New Issue