restore Apollonius_graph_2

This commit is contained in:
Maxime Gimeno 2021-05-12 16:34:08 +02:00
parent 516d921ea8
commit edfe67a7d3
132 changed files with 18449 additions and 1 deletions

2
Apollonius_graph_2/TODO Normal file
View File

@ -0,0 +1,2 @@
- rename file names if needed to match the names of the classes
they contain

View File

@ -0,0 +1,70 @@
Below you can find a description of the various generators in the
include/CGAL directory:
make_degenerate.h
=================
PROVIDES: make_degenerate (function)
INPUT: A input range of sites, an output iterator, and a traits class.
OUTPUT: Computes the Apollonius graph of the input range, then writes
the Voronoi circles of the Apollonius diagram of the input
sites to the output iterator. The output is a set of sites for
the Apollonius diagram.
EXAMPLE: mk_degen.cpp
USAGE: Can be used to generate a set of sites in almost degenerate or
degenerate configuration using the input set of sites.
random_sites_in_0x1_box.h
=========================
PROVIDES: Random_sites_in_0x1_box (functor)
INPUT: at construction time the max radius and a seed need to be passed.
OUTPUT: using operator*(), the user can get one random site with its
center in the box [0,1]x[0,1] and its radius between 0 and the
max radius passed at construction time; the random number
generator used is CGAL::Random.
EXAMPLE: gen_sites_in_0x1_box.cpp
USAGE: Can be used to generate random sites within the [0,1]x[0,1] box
with a prespecified max radius and seed for the random number
generator. There is no guarantee as to whether the site
returned is hidden or not by previously generated sites.
random_integral_sites_in_square_2.h
===================================
PROVIDES: Random_integral_sites_in_square_2 (functor)
INPUT: at construction two unsigned integers b and B and a seed need
to be passed.
OUTPUT: using operator*(), the user can get one random site with its
center in [-M,M]x[-M,M], where M = 2^b-1, and its weight in
[0,R], where R = 2^B-1; the random number generator used is
CGAL::Random. Zero bit size means that the corresponding
number is zero.
EXAMPLE: gen_integral_sites_in_square.cpp
USAGE: Can be used to generate sites with integer coordinates and
weight; the bit size of the coordinates and the weight can be
prescribed; allowed values of bit sizes are between 0 and 52,
inclusive. There is no guarantee as to whether the site
returned is hidden or not by previously generated sites.
random_integral_sites_on_parabola_2.h
=====================================
PROVIDES: Random_integral_sites_on_parabola_2 (functor)
INPUT: at construction an unsigned integer b, an unsigned integer p
and a seed need to be passed. By default p is set to 0.
OUTPUT: using operator*(), the user can get one random site of the
form {(t, t^2), w}, where t is in [-M, M], M = 2^b-1; the
weight w is equal to t^2 unless p is not equal to zero,
in which case w is equal t^2 + e, where e is an integer of bit
size at most p; the random number generator used is
CGAL::Random. Zero bit size means that the corresponding
number is zero.
EXAMPLE: gen_integral_sites_on_parabola.cpp
USAGE: Can be used to generate sites with integer coordinates and
weight with prescribed bit size; allowed values of bit sizes
are between 0 and 26, inclusive. There is no guarantee as to
whether the site returned is hidden or not by previously
generated sites. If p is equal to 0, the Apollonius diagram
created has a vertex of degree n-2, where n is the number of
sites created; all sites are tangent to the x-axis and all lie
above it. If p is non-zero, but small with respect to b, then
the centers of the sites still lie on the parabola y = x^2, but
the weights are perturbed by just a fe bits, thus providing a
set of input sites that are in almost degenerate configuration.

View File

@ -0,0 +1,62 @@
#include <CGAL/basic.h>
#include <CGAL/Apollonius_graph_2/random_integral_sites_in_square_2.h>
#include <CGAL/Random.h>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Apollonius_site_2.h>
typedef CGAL::Simple_cartesian<double> K;
typedef CGAL::Apollonius_site_2<K> Site_2;
typedef CGAL::Random Random;
int usage (int argc, char *argv[])
{
std::cerr << "usage: " << argv[0]
<< " <number of points> <bit size of coordinates> "
<< "[bit size of weights] [seed]" << std::endl;
return 2;
}
int main(int argc, char *argv[])
{
int num, seed = 17;
unsigned int b, B;
if ( argc < 3 ) {
return usage(argc, argv);
}
{
std::istringstream is(argv[1]);
if ( !(is >> num) ) { return usage(argc, argv); }
}
{
std::istringstream is(argv[2]);
if ( !(is >> b) ) { return usage(argc, argv); }
B = b;
}
if ( argc > 3 ) {
std::istringstream is(argv[3]);
if ( !(is >> B) ) { return usage(argc, argv); }
}
if ( argc > 4 ) {
std::istringstream is(argv[4]);
if ( !(is >> seed) ) { return usage(argc, argv); }
}
CGAL::Random_integral_sites_in_square_2<Site_2,Random> g(b, B, seed);
std::cout << std::setprecision(17);
for (int i = 0; i < num; ++i) {
std::cout << *g << std::endl;
}
return 0;
}

View File

@ -0,0 +1,61 @@
#include <CGAL/basic.h>
#include <CGAL/Apollonius_graph_2/random_integral_sites_on_parabola_2.h>
#include <CGAL/Random.h>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Apollonius_site_2.h>
typedef CGAL::Simple_cartesian<double> K;
typedef CGAL::Apollonius_site_2<K> Site_2;
typedef CGAL::Random Random;
int usage (int argc, char *argv[])
{
std::cerr << "usage: " << argv[0]
<< " <number of points> <bit size of coordinates> "
<< "[bit size of perturbation] [seed]" << std::endl;
return 2;
}
int main(int argc, char *argv[])
{
int num, seed = 17;
unsigned int b, p = 0;
if ( argc < 3 ) {
return usage(argc, argv);
}
{
std::istringstream is(argv[1]);
if ( !(is >> num) ) { return usage(argc, argv); }
}
{
std::istringstream is(argv[2]);
if ( !(is >> b) ) { return usage(argc, argv); }
}
if ( argc > 3 ) {
std::istringstream is(argv[3]);
if ( !(is >> p) ) { return usage(argc, argv); }
}
if ( argc > 4 ) {
std::istringstream is(argv[4]);
if ( !(is >> seed) ) { return usage(argc, argv); }
}
CGAL::Random_integral_sites_on_parabola_2<Site_2,Random> g(b, p, seed);
std::cout << std::setprecision(17);
for (int i = 0; i < num; ++i) {
std::cout << *g << std::endl;
}
return 0;
}

View File

@ -0,0 +1,52 @@
#include <CGAL/basic.h>
#include <CGAL/Apollonius_graph_2/random_sites_in_0x1_box.h>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Apollonius_site_2.h>
typedef CGAL::Simple_cartesian<double> K;
typedef CGAL::Apollonius_site_2<K> Site_2;
int usage (int argc, char **argv)
{
std::cerr << "usage: " << argv[0]
<< " <number of points> <max radius> [seed]" << std::endl;
return 2;
}
int main (int argc, char **argv)
{
int num, seed = 42;
double rmax;
if (argc < 3)
return usage (argc, argv);
{
std::istringstream is(argv[1]);
if ( !(is >> num) ) { return usage(argc, argv); }
}
{
std::istringstream is(argv[2]);
if ( !(is >> rmax) ) { return usage(argc, argv); }
}
if (argc > 3) {
std::istringstream is(argv[3]);
if ( !(is >> seed) ) { return usage(argc, argv); }
}
CGAL::Random_sites_in_0x1_box<Site_2> g(rmax, seed);
std::cout << std::setprecision(17);
for (int i = 0; i < num; ++i) {
std::cout << *g << std::endl;
}
return 0;
}

View File

@ -0,0 +1,39 @@
#ifndef CGAL_APOLLONIUS_GRAPH_2_MAKE_DEGENERATE_H
#define CGAL_APOLLONIUS_GRAPH_2_MAKE_DEGENERATE_H 1
#include <CGAL/basic.h>
#include <CGAL/Apollonius_graph_hierarchy_2.h>
namespace CGAL {
template<class InputIterator, class OutputIterator, class Traits>
OutputIterator
make_degenerate(InputIterator first,
InputIterator beyond,
OutputIterator oit,
const Traits& tr = Traits())
{
typedef CGAL::Apollonius_graph_hierarchy_2<Traits> Apollonius_graph;
typedef typename Apollonius_graph::Site_2 Site_2;
typedef typename Apollonius_graph::Finite_faces_iterator
Finite_faces_iterator;
Apollonius_graph ag;
Site_2 site;
for (InputIterator it = first; it != beyond; ++it) {
ag.insert(*it);
}
for (Finite_faces_iterator f = ag.finite_faces_begin();
f != ag.finite_faces_end(); ++f) {
*oit++ = ag.dual(f);
}
return oit;
}
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_MAKE_DEGENERATE_H

View File

@ -0,0 +1,54 @@
#ifndef CGAL_APOLLONIUS_GRAPH_2_RANDOM_INTEGRAL_SITES_IN_SQUARE_2_H
#define CGAL_APOLLONIUS_GRAPH_2_RANDOM_INTEGRAL_SITES_IN_SQUARE_2_H 1
#include <CGAL/basic.h>
#include <CGAL/random_integer.h>
namespace CGAL {
// creates a random site with x, y in [-M,M]x[-M,M]
// where M = 2^b - 1 and r in [0,R], R = 2^B - 1
template<class Site, class R>
class Random_integral_sites_in_square_2
{
public:
typedef Site Site_2;
typedef R Random;
public:
Random_integral_sites_in_square_2(unsigned int b)
: b_(b), B_(b), r_(0) {
CGAL_precondition( b >= 0 && b <= 52 );
}
Random_integral_sites_in_square_2(unsigned int b, int seed)
: b_(b), B_(b), r_(seed) {
CGAL_precondition( b >= 0 && b <= 52 );
}
Random_integral_sites_in_square_2(unsigned int b, unsigned int B, int seed)
: b_(b), B_(B), r_(seed) {
CGAL_precondition( b >= 0 && b <= 52 );
CGAL_precondition( B >= 0 && B <= 52 );
}
Site_2 operator*()
{
double x = random_integer(r_, b_, true);
double y = random_integer(r_, b_, true);
double w = random_integer(r_, B_, false);
CGAL_assertion( w >= 0 );
typename Site_2::Point_2 p(x, y);
return Site_2(p, w);
}
private:
unsigned int b_, B_;
Random r_;
};
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_RANDOM_INTEGRAL_SITES_IN_SQUARE_2_H

View File

@ -0,0 +1,54 @@
#ifndef CGAL_APOLLONIUS_GRAPH_2_RANDOM_INTEGRAL_SITES_ON_PARABOLA_2_H
#define CGAL_APOLLONIUS_GRAPH_2_RANDOM_INTEGRAL_SITES_ON_PARABOLA_2_H 1
#include <CGAL/basic.h>
#include <CGAL/random_integer.h>
namespace CGAL {
// creates a random site of the form {(t, t^2), t^2}, where t is in
// the range [-M, M], M = 2^b - 1
template<class Site, class R>
class Random_integral_sites_on_parabola_2
{
public:
typedef Site Site_2;
typedef R Random;
public:
Random_integral_sites_on_parabola_2(unsigned int b)
: b_(b), p_(0), r_(0) {
CGAL_precondition( b >= 0 && b <= 26 );
}
Random_integral_sites_on_parabola_2(unsigned int b, int seed)
: b_(b), p_(0), r_(seed) {
CGAL_precondition( b >= 0 && b <= 26 );
}
Random_integral_sites_on_parabola_2(unsigned int b, unsigned int p,
int seed)
: b_(b), p_(p), r_(seed) {
CGAL_precondition( b >= 0 && b <= 26 );
CGAL_precondition( p >= 0 && p <= 26 );
}
Site_2 operator*()
{
double t = random_integer(r_, b_, true);
double t2 = t * t;
double perb = random_integer(r_, p_, true);
typename Site_2::Point_2 p(t, t2);
return Site_2(p, t2 + perb);
}
private:
unsigned int b_, p_;
Random r_;
};
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_RANDOM_INTEGRAL_SITES_ON_PARABOLA_2_H

View File

@ -0,0 +1,37 @@
#ifndef CGAL_APOLLONIUS_GRAPH_2_RANDOM_SITES_IN_0X1_BOX_H
#define CGAL_APOLLONIUS_GRAPH_2_RANDOM_SITES_IN_0X1_BOX_H 1
#include <CGAL/basic.h>
#include <CGAL/Random.h>
namespace CGAL {
template<class Site>
class Random_sites_in_0x1_box
{
public:
typedef Site Site_2;
typedef Site_2 result_type;
private:
typedef typename Site_2::Point_2 Point_2;
public:
Random_sites_in_0x1_box(double rmax = 0.125, int seed = 0)
: rmax_(rmax), random_(seed) {}
Site_2 operator*() {
double x = random_.get_double(0, 1);
double y = random_.get_double(0, 1);
double w = random_.get_double(0, rmax_);
return Site_2(Point_2(x,y),w);
}
private:
double rmax_;
Random random_;
};
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_RANDOM_SITES_IN_0X1_BOX_H

View File

@ -0,0 +1,23 @@
#ifndef CGAL_BITS_H
#define CGAL_BITS_H
#include <CGAL/basic.h>
#include <cmath>
namespace CGAL {
double log2(double x)
{
return log10(x) / log10(2.0);
}
unsigned int bits(double x)
{
CGAL_precondition( static_cast<int>(x) == x );
if ( x == 0 ) { return 1; }
return static_cast<unsigned int>(log2( CGAL::abs(x) )) + 1;
}
} //namespace CGAL
#endif // CGAL_BITS_H

View File

@ -0,0 +1,110 @@
#ifndef CGAL_RANDOM_INTEGER_H
#define CGAL_RANDOM_INTEGER_H
#include <CGAL/basic.h>
#include <cstdlib>
#include <CGAL/Gmpz.h>
// type "man {rand, random, drand48}" for C functions that produce
// random numbers
//extern "C" int getpid();
//extern "C" int srandom(unsigned);
//extern "C" long random();
namespace CGAL {
// powers of 2 from 2^0 to 2^53
double
P2[54]={1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0,
512.0, 1024.0, 2048.0, 4096.0, 8192.0, 16384.0, 32768.0,
65536.0, 131072.0, 262144.0, 524288.0, 1048576.0,
2097152.0, 4194304.0, 8388608.0, 16777216.0, 33554432.0,
67108864.0, 134217728.0, 268435456.0, 536870912.0,
1073741824.0, 2147483648.0, 4294967296.0, 8589934592.0,
17179869184.0, 34359738368.0, 68719476736.0,
137438953472.0, 274877906944.0, 549755813888.0,
1099511627776.0, 2199023255552.0, 4398046511104.0,
8796093022208.0, 17592186044416.0, 35184372088832.0,
70368744177664.0, 140737488355328.0, 281474976710656.0,
562949953421312.0, 1125899906842624.0, 2251799813685248.0,
4503599627370496.0, 9007199254740992.0};
// set the random number generator seed
void set_seed(unsigned int seed)
{
srandom(seed);
}
// return random integer of b bits
double random_integer(int b, bool allow_negative = true)
{
double value;
if (b > 27) {
value = ((int)random()) % ((int)P2[27]);
value += ( ((int)random()) % ((int)P2[b - 27]) ) * P2[27];
} else {
value = ((int)random()) % (int)P2[b];
}
if ( allow_negative ) {
value *= ( ((int) random()) % 2 == 0 ) ? 1 : -1;
}
return value;
}
template<class Random>
double random_integer(Random& r, unsigned int b, bool allow_negative = true)
{
// returns random integers in the range [0, 2^b - 1).
// b is required to be at least 1 and at most 52
// and if allow_negative is true then the range includes negative
// numbers as well and becomes: [-2^b + 1, 2^b - 1).
CGAL_precondition( b >= 0 && b <= 52 );
if ( b == 0 ) { return 0; }
double M = pow(2.0,b);
CGAL::Gmpz z;
if ( allow_negative ) {
z = r.get_double(-M, M);
} else {
z = r.get_double(0, M);
}
return CGAL::to_double(z);
}
template<class Random>
double random_even_integer(Random& r, unsigned int b,
bool allow_negative = true)
{
// returns random even integers in the range [0, 2^b - 1).
// b is required to be at least 1 and at most 52
// and if allow_negative is true then the range includes negative
// numbers as well and becomes: [-2^b + 1, 2^b - 1).
CGAL_precondition( b >= 0 && b <= 52 );
if ( b == 0 ) { return 0; }
double M = pow(2.0,b);
CGAL::Gmpz z;
CGAL::Gmpz two(2);
do {
if ( allow_negative ) {
z = r.get_double(-M, M);
} else {
z = r.get_double(0, M);
}
} while ( z % two != 0 );
return CGAL::to_double(z);
}
} //namespace CGAL
#endif // CGAL_RANDOM_INTEGER_H

View File

@ -0,0 +1,44 @@
#include <CGAL/basic.h>
#include <CGAL/Apollonius_graph_2/make_degenerate.h>
#include <iostream>
#include <iomanip>
#include <vector>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/MP_Float.h>
#include <CGAL/Apollonius_graph_filtered_traits_2.h>
typedef CGAL::Simple_cartesian<double> CK;
typedef CGAL::Simple_cartesian<CGAL::MP_Float> EK;
typedef CGAL::Field_with_sqrt_tag CM;
typedef CGAL::Integral_domain_without_division_tag EM;
typedef CGAL::Apollonius_graph_filtered_traits_2<CK,CM,EK,EM> Traits;
typedef Traits::Site_2 Site;
typedef std::vector<Site> Site_vector;
int main()
{
Site_vector input, output;
Site site;
std::back_insert_iterator<Site_vector> oit(output);
while (std::cin >> site) { input.push_back(site); }
oit = CGAL::make_degenerate(input.begin(), input.end(), oit, Traits());
std::cout << std::setprecision(17);
for (std::vector<Site>::iterator it = output.begin();
it != output.end(); ++it)
{
std::cout << (*it) << std::endl;
}
return 0;
}

View File

@ -0,0 +1,407 @@
// Copyright (c) 2003,2004 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_MIXED_FILTERED_TRAITS_2_H
#define CGAL_APOLLONIUS_GRAPH_MIXED_FILTERED_TRAITS_2_H
#include <CGAL/Apollonius_graph_2/Delage_traits/Apollonius_graph_mixed_traits_2.h>
#include <CGAL/Filtered_predicate.h>
#include <CGAL/Filtered_construction.h>
// includes for the default parameters of the filtered traits
#include <CGAL/Simple_cartesian.h>
#include <CGAL/MP_Float.h>
#include <CGAL/Interval_arithmetic.h>
#include <CGAL/Cartesian_converter.h>
#include <CGAL/number_utils_classes.h>
namespace CGAL {
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// the filtered Traits class
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
template<class CK_t,
class CK_MTag = Integral_domain_without_division_tag,
class EK_t = Simple_cartesian< MP_Float >,
class EK_MTag = CK_MTag,
class FK_t = Simple_cartesian< Interval_nt<false> >,
class FK_MTag = CK_MTag,
class C2E_t = Cartesian_converter<CK_t, EK_t>,
class C2F_t =
Cartesian_converter<CK_t, FK_t, To_interval<typename CK_t::RT> > >
class Apollonius_graph_mixed_filtered_traits_2
{
private:
typedef Apollonius_graph_mixed_traits_2<CK_t, CK_MTag> CK_traits;
typedef Apollonius_graph_mixed_traits_2<FK_t, FK_MTag> FK_traits;
typedef Apollonius_graph_mixed_traits_2<EK_t, EK_MTag> EK_traits;
typedef
CGAL_APOLLONIUS_GRAPH_2_NS::Apollonius_graph_kernel_wrapper_2<CK_t> CK;
typedef
CGAL_APOLLONIUS_GRAPH_2_NS::Apollonius_graph_kernel_wrapper_2<FK_t> FK;
typedef
CGAL_APOLLONIUS_GRAPH_2_NS::Apollonius_graph_kernel_wrapper_2<EK_t> EK;
typedef
CGAL_APOLLONIUS_GRAPH_2_NS::
Apollonius_graph_cartesian_converter<CK, EK, C2E_t> C2E;
typedef
CGAL_APOLLONIUS_GRAPH_2_NS::
Apollonius_graph_cartesian_converter<CK, FK, C2F_t> C2F;
#if 0
// the following typedefs have been made in the direction of
// providing filtered constructions; however, there is a problem,
// namely, the Construct_Apollonius_site_2 functor has two
// different operator()'s with two different return types; this
// functor should be split in two (along with the appropriate
// changes in the spec/concept); see also changes needed for the
// filtered construction below.
typedef Cartesian_converter<FK, CK, To_double<typename FK::RT> > F2C_t;
typedef Cartesian_converter<EK, CK, To_double<typename EK::RT> > E2C_t;
typedef
Apollonius_graph_cartesian_converter<FK, CK, F2C_t> F2C;
typedef
Apollonius_graph_cartesian_converter<EK, CK, E2C_t> E2C;
#endif
// Types for the construction kernel
typedef typename CK::Point_2 CK_Point_2;
typedef typename CK::Site_2 CK_Site_2;
typedef typename CK::Line_2 CK_Line_2;
typedef typename CK::Ray_2 CK_Ray_2;
typedef typename CK::Segment_2 CK_Segment_2;
typedef typename CK::FT CK_FT;
typedef typename CK::RT CK_RT;
// Types for the exact kernel
typedef typename EK::Point_2 EK_Point_2;
typedef typename EK::Site_2 EK_Site_2;
typedef typename EK::Line_2 EK_Line_2;
typedef typename EK::Ray_2 EK_Ray_2;
typedef typename EK::Segment_2 EK_Segment_2;
typedef typename EK::FT EK_FT;
typedef typename EK::RT EK_RT;
// Types for the filtering kernel
typedef typename FK::Point_2 FK_Point_2;
typedef typename FK::Site_2 FK_Site_2;
typedef typename FK::Line_2 FK_Line_2;
typedef typename FK::Ray_2 FK_Ray_2;
typedef typename FK::Segment_2 FK_Segment_2;
typedef typename FK::FT FK_FT;
typedef typename FK::RT FK_RT;
public:
//-----------------------------------------------------------------------
// TYPE DEFINITIONS
//-----------------------------------------------------------------------
// BASIC TYPES
//------------
typedef CK_t R;
typedef CK_MTag Method_tag;
typedef CK_traits Construction_traits;
typedef FK_traits Filtering_traits;
typedef EK_traits Exact_traits;
typedef CK_MTag Construction_traits_method_tag;
typedef FK_MTag Filtering_traits_method_tag;
typedef EK_MTag Exact_traits_method_tag;
typedef typename CK::Point_2 Point_2;
typedef typename CK::Site_2 Site_2;
typedef typename CK::Line_2 Line_2;
typedef typename CK::Ray_2 Ray_2;
typedef typename CK::Segment_2 Segment_2;
typedef typename CK::Object_2 Object_2;
typedef typename CK::FT FT;
typedef typename CK::RT RT;
public:
// OBJECT CONSTRUCTION & ASSIGNMENT
//---------------------------------
typedef typename CK_traits::Construct_object_2 Construct_object_2;
typedef typename CK_traits::Assign_2 Assign_2;
// CONSTRUCTIONS
//--------------
// vertex and dual site
protected:
typedef typename CK_traits::Construct_Apollonius_vertex_2
CK_Construct_Apollonius_vertex_2;
typedef typename CK_traits::Construct_Apollonius_site_2
CK_Construct_Apollonius_site_2;
typedef typename FK_traits::Construct_Apollonius_vertex_2
FK_Construct_Apollonius_vertex_2;
typedef typename FK_traits::Construct_Apollonius_site_2
FK_Construct_Apollonius_site_2;
typedef typename EK_traits::Construct_Apollonius_vertex_2
EK_Construct_Apollonius_vertex_2;
typedef typename EK_traits::Construct_Apollonius_site_2
EK_Construct_Apollonius_site_2;
public:
#if 0
// the following typedefs have been made in the direction of
// providing filtered constructions; however, there is a problem,
// namely, the Construct_Apollonius_site_2 functor has two
// different operator()'s with two different return types; this
// functor should be split in two (along with the appropriate
// changes in the spec/concept); see also changes needed for the
// filtered construction above.
typedef Filtered_construction<CK_Construct_Apollonius_vertex_2,
EK_Construct_Apollonius_vertex_2,
FK_Construct_Apollonius_vertex_2,
C2E, C2F, E2C, F2C>
Construct_Apollonius_vertex_2;
typedef Filtered_construction<CK_Construct_Apollonius_site_2,
EK_Construct_Apollonius_site_2,
FK_Construct_Apollonius_site_2,
C2E, C2F, E2C, F2C>
Construct_Apollonius_site_2;
#else
typedef typename CK_traits::Construct_Apollonius_vertex_2
Construct_Apollonius_vertex_2;
typedef typename CK_traits::Construct_Apollonius_site_2
Construct_Apollonius_site_2;
#endif
private:
// PREDICATES FOR THE TWO KERNELS
//-------------------------------
// Predicates for the filtering kernel
typedef typename FK_traits::Compare_x_2 FK_Compare_x_2;
typedef typename FK_traits::Compare_y_2 FK_Compare_y_2;
typedef typename FK_traits::Compare_weight_2 FK_Compare_weight_2;
typedef typename FK_traits::Orientation_2 FK_Orientation_2;
typedef typename FK_traits::Orientation_new_2 FK_Orientation_new_2;
typedef typename FK_traits::Is_hidden_2 FK_Is_hidden_2;
typedef typename FK_traits::Vertex_conflict_2 FK_Vertex_conflict_2;
typedef typename FK_traits::Oriented_side_of_bisector_2
FK_Oriented_side_of_bisector_2;
typedef typename FK_traits::Finite_edge_interior_conflict_2
FK_Finite_edge_interior_conflict_2;
typedef typename FK_traits::Infinite_edge_interior_conflict_2
FK_Infinite_edge_interior_conflict_2;
typedef typename FK_traits::Is_degenerate_edge_2
FK_Is_degenerate_edge_2;
// Predicates for the exact kernel
typedef typename EK_traits::Compare_x_2 EK_Compare_x_2;
typedef typename EK_traits::Compare_y_2 EK_Compare_y_2;
typedef typename EK_traits::Compare_weight_2 EK_Compare_weight_2;
typedef typename EK_traits::Orientation_2 EK_Orientation_2;
typedef typename EK_traits::Orientation_new_2 EK_Orientation_new_2;
typedef typename EK_traits::Is_hidden_2 EK_Is_hidden_2;
typedef typename EK_traits::Vertex_conflict_2 EK_Vertex_conflict_2;
typedef typename EK_traits::Oriented_side_of_bisector_2
EK_Oriented_side_of_bisector_2;
typedef typename EK_traits::Finite_edge_interior_conflict_2
EK_Finite_edge_interior_conflict_2;
typedef typename EK_traits::Infinite_edge_interior_conflict_2
EK_Infinite_edge_interior_conflict_2;
typedef typename EK_traits::Is_degenerate_edge_2
EK_Is_degenerate_edge_2;
public:
// PREDICATES
//-----------
typedef
Filtered_predicate<EK_Compare_x_2, FK_Compare_x_2, C2E, C2F>
Compare_x_2;
typedef
Filtered_predicate<EK_Compare_y_2, FK_Compare_y_2, C2E, C2F>
Compare_y_2;
typedef
Filtered_predicate<EK_Compare_weight_2, FK_Compare_weight_2, C2E, C2F>
Compare_weight_2;
typedef
Filtered_predicate<EK_Orientation_2, FK_Orientation_2, C2E, C2F>
Orientation_2;
typedef
Filtered_predicate<EK_Orientation_new_2, FK_Orientation_new_2, C2E, C2F>
Orientation_new_2;
typedef
Filtered_predicate<EK_Is_hidden_2, FK_Is_hidden_2, C2E, C2F>
Is_hidden_2;
typedef
Filtered_predicate<EK_Oriented_side_of_bisector_2,
FK_Oriented_side_of_bisector_2, C2E, C2F>
Oriented_side_of_bisector_2;
typedef
Filtered_predicate<EK_Vertex_conflict_2,
FK_Vertex_conflict_2, C2E, C2F>
Vertex_conflict_2;
typedef
Filtered_predicate<EK_Finite_edge_interior_conflict_2,
FK_Finite_edge_interior_conflict_2, C2E, C2F>
Finite_edge_interior_conflict_2;
typedef
Filtered_predicate<EK_Infinite_edge_interior_conflict_2,
FK_Infinite_edge_interior_conflict_2, C2E, C2F>
Infinite_edge_interior_conflict_2;
typedef
Filtered_predicate<EK_Is_degenerate_edge_2,
FK_Is_degenerate_edge_2, C2E, C2F>
Is_degenerate_edge_2;
public:
//-----------------------------------------------------------------------
// ACCESS TO OBJECTS
//-----------------------------------------------------------------------
// OBJECT CONSTRUCTION & ASSIGNMENT
Assign_2
assign_2_object() const {
return Assign_2();
}
Construct_object_2
construct_object_2_object() const {
return Construct_object_2();
}
// CONSTRUCTIONS
//--------------
Construct_Apollonius_vertex_2
construct_Apollonius_vertex_2_object() const {
return Construct_Apollonius_vertex_2();
}
Construct_Apollonius_site_2
construct_Apollonius_site_2_object() const {
return Construct_Apollonius_site_2();
}
// PREDICATES
//-----------
Compare_x_2
compare_x_2_object() const {
return Compare_x_2();
}
Compare_y_2
compare_y_2_object() const {
return Compare_y_2();
}
Compare_weight_2
compare_weight_2_object() const {
return Compare_weight_2();
}
Orientation_2
orientation_2_object() const {
return Orientation_2();
}
Orientation_new_2
orientation_new_2_object() const {
return Orientation_new_2();
}
Is_hidden_2
is_hidden_2_object() const {
return Is_hidden_2();
}
Oriented_side_of_bisector_2
oriented_side_of_bisector_2_object() const {
return Oriented_side_of_bisector_2();
}
Vertex_conflict_2
vertex_conflict_2_object() const {
return Vertex_conflict_2();
}
Finite_edge_interior_conflict_2
finite_edge_interior_conflict_2_object() const {
return Finite_edge_interior_conflict_2();
}
Infinite_edge_interior_conflict_2
infinite_edge_interior_conflict_2_object() const {
return Infinite_edge_interior_conflict_2();
}
Is_degenerate_edge_2
is_degenerate_edge_2_object() const {
return Is_degenerate_edge_2();
}
};
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_UNCERTAIN_FILTERED_TRAITS_2_H

View File

@ -0,0 +1,206 @@
// Copyright (c) 2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
// Christophe Delage
// David Millman
#ifndef CGAL_APOLLONIUS_GRAPH_MIXED_TRAITS_2_H
#define CGAL_APOLLONIUS_GRAPH_MIXED_TRAITS_2_H
#include <CGAL/Apollonius_graph_2/Delage_traits/New_predicates_C2.h>
#include <CGAL/number_type_basic.h>
#include <CGAL/Apollonius_graph_2/Kernel_wrapper_2.h>
namespace CGAL {
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// the Traits class
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
template < class Rep, class MTag = Integral_domain_without_division_tag >
class Apollonius_graph_mixed_traits_2
{
public:
//-----------------------------------------------------------------------
// TYPE DEFINITIONS
//-----------------------------------------------------------------------
// BASIC TYPES
//------------
private:
typedef Apollonius_graph_new_traits_2<Rep,MTag> Self;
typedef
CGAL_APOLLONIUS_GRAPH_2_NS::Apollonius_graph_kernel_wrapper_2<Rep> Kernel;
public:
typedef Rep R;
typedef MTag Method_tag;
typedef typename Kernel::Point_2 Point_2;
typedef typename Kernel::Site_2 Site_2;
typedef typename Kernel::Line_2 Line_2;
typedef typename Kernel::Ray_2 Ray_2;
typedef typename Rep::Segment_2 Segment_2;
typedef typename Kernel::Object_2 Object_2;
typedef typename Kernel::FT FT;
typedef typename Kernel::RT RT;
public:
// OBJECT CONSTRUCTION & ASSIGNMENT
//---------------------------------
typedef typename Kernel::Construct_object_2 Construct_object_2;
typedef typename Kernel::Assign_2 Assign_2;
// CONSTRUCTIONS
//--------------
// vertex and dual site
typedef CGAL_APOLLONIUS_GRAPH_2_NS::Construct_Apollonius_vertex_2<Kernel>
/* */ Construct_Apollonius_vertex_2;
typedef CGAL_APOLLONIUS_GRAPH_2_NS::Construct_Apollonius_site_2<Kernel>
/* */ Construct_Apollonius_site_2;
// PREDICATES
//-----------
typedef CGAL_APOLLONIUS_GRAPH_2_NS::Compare_x_2<Kernel> Compare_x_2;
typedef CGAL_APOLLONIUS_GRAPH_2_NS::Compare_y_2<Kernel> Compare_y_2;
typedef CGAL_APOLLONIUS_GRAPH_2_NS::Compare_weight_2<Kernel>
Compare_weight_2;
typedef CGAL_APOLLONIUS_GRAPH_2_NS::Orientation_2<Kernel,MTag>
Orientation_2;
typedef CGAL_APOLLONIUS_GRAPH_2_NS::Orientation_new_2<Kernel,MTag>
Orientation_new_2;
typedef CGAL_APOLLONIUS_GRAPH_2_NS::Is_hidden_2<Kernel,MTag> Is_hidden_2;
typedef CGAL_APOLLONIUS_GRAPH_2_NS::Oriented_side_of_bisector_2<Kernel,MTag>
/* */ Oriented_side_of_bisector_2;
typedef CGAL_APOLLONIUS_GRAPH_2_NS::Vertex_conflict_new_2<Kernel,MTag>
Vertex_conflict_2;
typedef
CGAL_APOLLONIUS_GRAPH_2_NS::Finite_edge_interior_conflict_2<Kernel,MTag>
/* */ Finite_edge_interior_conflict_2;
typedef
CGAL_APOLLONIUS_GRAPH_2_NS::Infinite_edge_interior_conflict_2<Kernel,MTag>
/* */ Infinite_edge_interior_conflict_2;
typedef CGAL_APOLLONIUS_GRAPH_2_NS::Is_degenerate_edge_2<Kernel,MTag>
/* */ Is_degenerate_edge_2;
public:
//-----------------------------------------------------------------------
// ACCESS TO OBJECTS
//-----------------------------------------------------------------------
// OBJECT CONSTRUCTION & ASSIGNMENT
Assign_2
assign_2_object() const {
return Assign_2();
}
Construct_object_2
construct_object_2_object() const {
return Construct_object_2();
}
// CONSTRUCTIONS
//--------------
Construct_Apollonius_vertex_2
construct_Apollonius_vertex_2_object() const {
return Construct_Apollonius_vertex_2();
}
Construct_Apollonius_site_2
construct_Apollonius_site_2_object() const {
return Construct_Apollonius_site_2();
}
// PREDICATES
//-----------
Compare_x_2
compare_x_2_object() const {
return Compare_x_2();
}
Compare_y_2
compare_y_2_object() const {
return Compare_y_2();
}
Compare_weight_2
compare_weight_2_object() const {
return Compare_weight_2();
}
Orientation_2
orientation_2_object() const {
return Orientation_2();
}
Orientation_new_2
orientation_new_2_object() const {
return Orientation_new_2();
}
Is_hidden_2
is_hidden_2_object() const {
return Is_hidden_2();
}
Oriented_side_of_bisector_2
oriented_side_of_bisector_2_object() const {
return Oriented_side_of_bisector_2();
}
Vertex_conflict_2
vertex_conflict_2_object() const {
return Vertex_conflict_2();
}
Finite_edge_interior_conflict_2
finite_edge_interior_conflict_2_object() const {
return Finite_edge_interior_conflict_2();
}
Infinite_edge_interior_conflict_2
infinite_edge_interior_conflict_2_object() const {
return Infinite_edge_interior_conflict_2();
}
Is_degenerate_edge_2
is_degenerate_edge_2_object() const {
return Is_degenerate_edge_2();
}
};
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_NEW_TRAITS_2_H

View File

@ -0,0 +1,410 @@
// Copyright (c) 2003,2004,2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_NEW_FILTERED_TRAITS_2_H
#define CGAL_APOLLONIUS_GRAPH_NEW_FILTERED_TRAITS_2_H
#include <CGAL/Apollonius_graph_2/Delage_traits/Apollonius_graph_new_traits_2.h>
#include <CGAL/Filtered_predicate.h>
#include <CGAL/Filtered_construction.h>
// includes for the default parameters of the filtered traits
#include <CGAL/Simple_cartesian.h>
#include <CGAL/MP_Float.h>
#include <CGAL/Interval_arithmetic.h>
#include <CGAL/Cartesian_converter.h>
#include <CGAL/number_utils_classes.h>
namespace CGAL {
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// the filtered Traits class
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
template<class CK_t,
class CK_MTag = Integral_domain_without_division_tag,
class EK_t = Simple_cartesian< MP_Float >,
class EK_MTag = CK_MTag,
class FK_t = Simple_cartesian< Interval_nt<false> >,
class FK_MTag = CK_MTag,
class C2E_t = Cartesian_converter<CK_t, EK_t>,
class C2F_t =
Cartesian_converter<CK_t, FK_t, To_interval<typename CK_t::RT> > >
class Apollonius_graph_new_filtered_traits_2
{
private:
typedef Apollonius_graph_new_traits_2<CK_t, CK_MTag> CK_traits;
typedef Apollonius_graph_new_traits_2<FK_t, FK_MTag> FK_traits;
typedef Apollonius_graph_new_traits_2<EK_t, EK_MTag> EK_traits;
typedef
CGAL_APOLLONIUS_GRAPH_2_NS::Apollonius_graph_kernel_wrapper_2<CK_t> CK;
typedef
CGAL_APOLLONIUS_GRAPH_2_NS::Apollonius_graph_kernel_wrapper_2<FK_t> FK;
typedef
CGAL_APOLLONIUS_GRAPH_2_NS::Apollonius_graph_kernel_wrapper_2<EK_t> EK;
typedef
CGAL_APOLLONIUS_GRAPH_2_NS::
Apollonius_graph_cartesian_converter<CK, EK, C2E_t> C2E;
typedef
CGAL_APOLLONIUS_GRAPH_2_NS::
Apollonius_graph_cartesian_converter<CK, FK, C2F_t> C2F;
#if 0
// the following typedefs have been made in the direction of
// providing filtered constructions; however, there is a problem,
// namely, the Construct_Apollonius_site_2 functor has two
// different operator()'s with two different return types; this
// functor should be split in two (along with the appropriate
// changes in the spec/concept); see also changes needed for the
// filtered construction below.
typedef Cartesian_converter<FK, CK, To_double<typename FK::RT> > F2C_t;
typedef Cartesian_converter<EK, CK, To_double<typename EK::RT> > E2C_t;
typedef
Apollonius_graph_cartesian_converter<FK, CK, F2C_t> F2C;
typedef
Apollonius_graph_cartesian_converter<EK, CK, E2C_t> E2C;
#endif
// Types for the construction kernel
typedef typename CK::Point_2 CK_Point_2;
typedef typename CK::Site_2 CK_Site_2;
typedef typename CK::Line_2 CK_Line_2;
typedef typename CK::Ray_2 CK_Ray_2;
typedef typename CK::Segment_2 CK_Segment_2;
typedef typename CK::FT CK_FT;
typedef typename CK::RT CK_RT;
// Types for the exact kernel
typedef typename EK::Point_2 EK_Point_2;
typedef typename EK::Site_2 EK_Site_2;
typedef typename EK::Line_2 EK_Line_2;
typedef typename EK::Ray_2 EK_Ray_2;
typedef typename EK::Segment_2 EK_Segment_2;
typedef typename EK::FT EK_FT;
typedef typename EK::RT EK_RT;
// Types for the filtering kernel
typedef typename FK::Point_2 FK_Point_2;
typedef typename FK::Site_2 FK_Site_2;
typedef typename FK::Line_2 FK_Line_2;
typedef typename FK::Ray_2 FK_Ray_2;
typedef typename FK::Segment_2 FK_Segment_2;
typedef typename FK::FT FK_FT;
typedef typename FK::RT FK_RT;
public:
//-----------------------------------------------------------------------
// TYPE DEFINITIONS
//-----------------------------------------------------------------------
// BASIC TYPES
//------------
typedef CK_t R;
typedef CK_MTag Method_tag;
typedef CK_traits Construction_traits;
typedef FK_traits Filtering_traits;
typedef EK_traits Exact_traits;
typedef CK_MTag Construction_traits_method_tag;
typedef FK_MTag Filtering_traits_method_tag;
typedef EK_MTag Exact_traits_method_tag;
typedef typename CK::Point_2 Point_2;
typedef typename CK::Site_2 Site_2;
typedef typename CK::Line_2 Line_2;
typedef typename CK::Ray_2 Ray_2;
typedef typename CK::Segment_2 Segment_2;
typedef typename CK::Object_2 Object_2;
typedef typename CK::FT FT;
typedef typename CK::RT RT;
public:
// OBJECT CONSTRUCTION & ASSIGNMENT
//---------------------------------
typedef typename CK_traits::Construct_object_2 Construct_object_2;
typedef typename CK_traits::Assign_2 Assign_2;
// CONSTRUCTIONS
//--------------
// vertex and dual site
protected:
typedef typename CK_traits::Construct_Apollonius_vertex_2
CK_Construct_Apollonius_vertex_2;
typedef typename CK_traits::Construct_Apollonius_site_2
CK_Construct_Apollonius_site_2;
typedef typename FK_traits::Construct_Apollonius_vertex_2
FK_Construct_Apollonius_vertex_2;
typedef typename FK_traits::Construct_Apollonius_site_2
FK_Construct_Apollonius_site_2;
typedef typename EK_traits::Construct_Apollonius_vertex_2
EK_Construct_Apollonius_vertex_2;
typedef typename EK_traits::Construct_Apollonius_site_2
EK_Construct_Apollonius_site_2;
public:
#if 0
// the following typedefs have been made in the direction of
// providing filtered constructions; however, there is a problem,
// namely, the Construct_Apollonius_site_2 functor has two
// different operator()'s with two different return types; this
// functor should be split in two (along with the appropriate
// changes in the spec/concept); see also changes needed for the
// filtered construction above.
typedef Filtered_construction<CK_Construct_Apollonius_vertex_2,
EK_Construct_Apollonius_vertex_2,
FK_Construct_Apollonius_vertex_2,
C2E, C2F, E2C, F2C>
Construct_Apollonius_vertex_2;
typedef Filtered_construction<CK_Construct_Apollonius_site_2,
EK_Construct_Apollonius_site_2,
FK_Construct_Apollonius_site_2,
C2E, C2F, E2C, F2C>
Construct_Apollonius_site_2;
#else
typedef typename CK_traits::Construct_Apollonius_vertex_2
Construct_Apollonius_vertex_2;
typedef typename CK_traits::Construct_Apollonius_site_2
Construct_Apollonius_site_2;
#endif
private:
// PREDICATES FOR THE TWO KERNELS
//-------------------------------
// Predicates for the filtering kernel
typedef typename FK_traits::Compare_x_2 FK_Compare_x_2;
typedef typename FK_traits::Compare_y_2 FK_Compare_y_2;
typedef typename FK_traits::Compare_weight_2 FK_Compare_weight_2;
typedef typename FK_traits::Orientation_2 FK_Orientation_2;
typedef typename FK_traits::Orientation_new_2 FK_Orientation_new_2;
typedef typename FK_traits::Is_hidden_2 FK_Is_hidden_2;
typedef typename FK_traits::Oriented_side_of_bisector_2
FK_Oriented_side_of_bisector_2;
typedef typename FK_traits::Vertex_conflict_2 FK_Vertex_conflict_2;
typedef typename FK_traits::Finite_edge_interior_conflict_2
FK_Finite_edge_interior_conflict_2;
typedef typename FK_traits::Infinite_edge_interior_conflict_2
FK_Infinite_edge_interior_conflict_2;
typedef typename FK_traits::Is_degenerate_edge_2
FK_Is_degenerate_edge_2;
// Predicates for the exact kernel
typedef typename EK_traits::Compare_x_2 EK_Compare_x_2;
typedef typename EK_traits::Compare_y_2 EK_Compare_y_2;
typedef typename EK_traits::Compare_weight_2 EK_Compare_weight_2;
typedef typename EK_traits::Orientation_2 EK_Orientation_2;
typedef typename EK_traits::Orientation_new_2 EK_Orientation_new_2;
typedef typename EK_traits::Is_hidden_2 EK_Is_hidden_2;
typedef typename EK_traits::Oriented_side_of_bisector_2
EK_Oriented_side_of_bisector_2;
typedef typename EK_traits::Vertex_conflict_2 EK_Vertex_conflict_2;
typedef typename EK_traits::Finite_edge_interior_conflict_2
EK_Finite_edge_interior_conflict_2;
typedef typename EK_traits::Infinite_edge_interior_conflict_2
EK_Infinite_edge_interior_conflict_2;
typedef typename EK_traits::Is_degenerate_edge_2
EK_Is_degenerate_edge_2;
public:
// PREDICATES
//-----------
typedef
Filtered_predicate<EK_Compare_x_2, FK_Compare_x_2, C2E, C2F>
Compare_x_2;
typedef
Filtered_predicate<EK_Compare_y_2, FK_Compare_y_2, C2E, C2F>
Compare_y_2;
typedef
Filtered_predicate<EK_Compare_weight_2, FK_Compare_weight_2,
C2E, C2F>
Compare_weight_2;
typedef
Filtered_predicate<EK_Orientation_2, FK_Orientation_2, C2E, C2F>
Orientation_2;
typedef
Filtered_predicate<EK_Orientation_new_2, FK_Orientation_new_2, C2E, C2F>
Orientation_new_2;
typedef
Filtered_predicate<EK_Is_hidden_2, FK_Is_hidden_2, C2E, C2F>
Is_hidden_2;
typedef
Filtered_predicate<EK_Oriented_side_of_bisector_2,
FK_Oriented_side_of_bisector_2, C2E, C2F>
Oriented_side_of_bisector_2;
typedef
Filtered_predicate<EK_Vertex_conflict_2,
FK_Vertex_conflict_2, C2E, C2F>
Vertex_conflict_2;
typedef
Filtered_predicate<EK_Finite_edge_interior_conflict_2,
FK_Finite_edge_interior_conflict_2, C2E, C2F>
Finite_edge_interior_conflict_2;
typedef
Filtered_predicate<EK_Infinite_edge_interior_conflict_2,
FK_Infinite_edge_interior_conflict_2, C2E, C2F>
Infinite_edge_interior_conflict_2;
typedef
Filtered_predicate<EK_Is_degenerate_edge_2,
FK_Is_degenerate_edge_2, C2E, C2F>
Is_degenerate_edge_2;
public:
//-----------------------------------------------------------------------
// ACCESS TO OBJECTS
//-----------------------------------------------------------------------
// OBJECT CONSTRUCTION & ASSIGNMENT
Assign_2
assign_2_object() const {
return Assign_2();
}
Construct_object_2
construct_object_2_object() const {
return Construct_object_2();
}
// CONSTRUCTIONS
//--------------
Construct_Apollonius_vertex_2
construct_Apollonius_vertex_2_object() const {
return Construct_Apollonius_vertex_2();
}
Construct_Apollonius_site_2
construct_Apollonius_site_2_object() const {
return Construct_Apollonius_site_2();
}
// PREDICATES
//-----------
Compare_x_2
compare_x_2_object() const {
return Compare_x_2();
}
Compare_y_2
compare_y_2_object() const {
return Compare_y_2();
}
Compare_weight_2
compare_weight_2_object() const {
return Compare_weight_2();
}
Orientation_2
orientation_2_object() const {
return Orientation_2();
}
Orientation_new_2
orientation_new_2_object() const {
return Orientation_new_2();
}
Is_hidden_2
is_hidden_2_object() const {
return Is_hidden_2();
}
Oriented_side_of_bisector_2
oriented_side_of_bisector_2_object() const {
return Oriented_side_of_bisector_2();
}
Vertex_conflict_2
vertex_conflict_2_object() const {
return Vertex_conflict_2();
}
Finite_edge_interior_conflict_2
finite_edge_interior_conflict_2_object() const {
return Finite_edge_interior_conflict_2();
}
Infinite_edge_interior_conflict_2
infinite_edge_interior_conflict_2_object() const {
return Infinite_edge_interior_conflict_2();
}
Is_degenerate_edge_2
is_degenerate_edge_2_object() const {
return Is_degenerate_edge_2();
}
};
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_NEW_FILTERED_TRAITS_2_H

View File

@ -0,0 +1,209 @@
// Copyright (c) 2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
// Christophe Delage
// David Millman
#ifndef CGAL_APOLLONIUS_GRAPH_NEW_TRAITS_2_H
#define CGAL_APOLLONIUS_GRAPH_NEW_TRAITS_2_H
#include <CGAL/Apollonius_graph_2/Delage_traits/New_predicates_C2.h>
#include <CGAL/number_type_basic.h>
#include <CGAL/Apollonius_graph_2/Kernel_wrapper_2.h>
namespace CGAL {
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// the Traits class
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
template < class Rep, class MTag = Integral_domain_without_division_tag >
class Apollonius_graph_new_traits_2
{
public:
//-----------------------------------------------------------------------
// TYPE DEFINITIONS
//-----------------------------------------------------------------------
// BASIC TYPES
//------------
private:
typedef Apollonius_graph_new_traits_2<Rep,MTag> Self;
typedef
CGAL_APOLLONIUS_GRAPH_2_NS::Apollonius_graph_kernel_wrapper_2<Rep> Kernel;
public:
typedef Rep R;
typedef MTag Method_tag;
typedef typename Kernel::Point_2 Point_2;
typedef typename Kernel::Site_2 Site_2;
typedef typename Kernel::Line_2 Line_2;
typedef typename Kernel::Ray_2 Ray_2;
typedef typename Rep::Segment_2 Segment_2;
typedef typename Kernel::Object_2 Object_2;
typedef typename Kernel::FT FT;
typedef typename Kernel::RT RT;
public:
// OBJECT CONSTRUCTION & ASSIGNMENT
//---------------------------------
typedef typename Kernel::Construct_object_2 Construct_object_2;
typedef typename Kernel::Assign_2 Assign_2;
// CONSTRUCTIONS
//--------------
// vertex and dual site
typedef CGAL_APOLLONIUS_GRAPH_2_NS::Construct_Apollonius_vertex_2<Kernel>
/* */ Construct_Apollonius_vertex_2;
typedef CGAL_APOLLONIUS_GRAPH_2_NS::Construct_Apollonius_site_2<Kernel>
/* */ Construct_Apollonius_site_2;
// PREDICATES
//-----------
typedef CGAL_APOLLONIUS_GRAPH_2_NS::Compare_x_2<Kernel> Compare_x_2;
typedef CGAL_APOLLONIUS_GRAPH_2_NS::Compare_y_2<Kernel> Compare_y_2;
typedef CGAL_APOLLONIUS_GRAPH_2_NS::Compare_weight_2<Kernel>
Compare_weight_2;
// the following seems to be buggy
// typedef CGAL::AG2_Orientation_test_new_2<Kernel,MTag> Orientation_2;
// use the old one:
typedef CGAL_APOLLONIUS_GRAPH_2_NS::Orientation_new_2<Kernel,MTag>
Orientation_new_2;
typedef CGAL_APOLLONIUS_GRAPH_2_NS::Orientation_2<Kernel,MTag>
Orientation_2;
typedef CGAL_APOLLONIUS_GRAPH_2_NS::Is_hidden_2<Kernel,MTag> Is_hidden_2;
typedef CGAL_APOLLONIUS_GRAPH_2_NS::Oriented_side_of_bisector_2<Kernel,MTag>
/* */ Oriented_side_of_bisector_2;
typedef CGAL_APOLLONIUS_GRAPH_2_NS::Vertex_conflict_new_2<Kernel,MTag>
Vertex_conflict_2;
typedef
CGAL_APOLLONIUS_GRAPH_2_NS::Finite_edge_interior_conflict_new_2<Kernel,MTag>
/* */ Finite_edge_interior_conflict_2;
typedef
CGAL_APOLLONIUS_GRAPH_2_NS::Infinite_edge_interior_conflict_new_2<Kernel,MTag>
/* */ Infinite_edge_interior_conflict_2;
typedef CGAL_APOLLONIUS_GRAPH_2_NS::Is_degenerate_edge_2<Kernel,MTag>
/* */ Is_degenerate_edge_2;
public:
//-----------------------------------------------------------------------
// ACCESS TO OBJECTS
//-----------------------------------------------------------------------
// OBJECT CONSTRUCTION & ASSIGNMENT
Assign_2
assign_2_object() const {
return Assign_2();
}
Construct_object_2
construct_object_2_object() const {
return Construct_object_2();
}
// CONSTRUCTIONS
//--------------
Construct_Apollonius_vertex_2
construct_Apollonius_vertex_2_object() const {
return Construct_Apollonius_vertex_2();
}
Construct_Apollonius_site_2
construct_Apollonius_site_2_object() const {
return Construct_Apollonius_site_2();
}
// PREDICATES
//-----------
Compare_x_2
compare_x_2_object() const {
return Compare_x_2();
}
Compare_y_2
compare_y_2_object() const {
return Compare_y_2();
}
Compare_weight_2
compare_weight_2_object() const {
return Compare_weight_2();
}
Orientation_2
orientation_2_object() const {
return Orientation_2();
}
Orientation_new_2
orientation_new_2_object() const {
return Orientation_new_2();
}
Is_hidden_2
is_hidden_2_object() const {
return Is_hidden_2();
}
Oriented_side_of_bisector_2
oriented_side_of_bisector_2_object() const {
return Oriented_side_of_bisector_2();
}
Vertex_conflict_2
vertex_conflict_2_object() const {
return Vertex_conflict_2();
}
Finite_edge_interior_conflict_2
finite_edge_interior_conflict_2_object() const {
return Finite_edge_interior_conflict_2();
}
Infinite_edge_interior_conflict_2
infinite_edge_interior_conflict_2_object() const {
return Infinite_edge_interior_conflict_2();
}
Is_degenerate_edge_2
is_degenerate_edge_2_object() const {
return Is_degenerate_edge_2();
}
};
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_NEW_TRAITS_2_H

View File

@ -0,0 +1,181 @@
// Copyright (c) 2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
// Christophe Delage <Christophe.Delage@sophia.inria.fr>
// David Millman <dlm336@cs.nyu.edu>
#ifndef CGAL_APOLLONIUS_GRAPH_2_CONFLICT_2_H
#define CGAL_APOLLONIUS_GRAPH_2_CONFLICT_2_H 1
#include <CGAL/Apollonius_graph_2/basic.h>
#include <CGAL/Apollonius_graph_2/Predicate_constructions_C2.h>
namespace CGAL {
namespace ApolloniusGraph_2 {
//-----------------------------------------------------------------------
// Conflict Base
//-----------------------------------------------------------------------
template < class K, class Method_tag >
class Conflict_2
{
public:
typedef Inverted_weighted_point_2<K> Inverted_weighted_point;
typedef typename K::RT RT;
typedef typename K::Sign Sign;
typedef Sign result_type;
protected:
Sign orientation(const Inverted_weighted_point &p1,
const Inverted_weighted_point &p2,
const Inverted_weighted_point &p3) const
{
return sign_of_determinant( p1.p(), p2.p(), p3.p(),
p1.x(), p2.x(), p3.x(),
p1.y(), p2.y(), p3.y() );
}
Sign radical_intersection(const Inverted_weighted_point &p1,
const Inverted_weighted_point &p2,
const Inverted_weighted_point &p3, int i) const
{
Sign s = CGAL::sign(
CGAL::square(determinant<RT>(
p1.p(), p1.weight(), p1.y(),
p2.p(), p2.weight(), p2.y(),
p3.p(), p3.weight(), p3.y()))
+ CGAL::square(determinant<RT>(
p1.p(), p1.x(), p1.weight(),
p2.p(), p2.x(), p2.weight(),
p3.p(), p3.x(), p3.weight()))
- CGAL::square(determinant<RT>(
p1.p(), p1.x(), p1.y(),
p2.p(), p2.x(), p2.y(),
p3.p(), p3.x(), p3.y())));
if (s != ZERO || i < 0) { return s; }
// perturbation
switch (i) {
case (1) : return radical_side(p3, p2, p1, 3);
case (2) : return radical_side(p1, p3, p2, 3);
case (3) : return radical_side(p1, p2, p3, 3);
default :
CGAL_error_msg( "Case should not hapen");
return ZERO;
}
}
Sign radical_side(const Inverted_weighted_point &p1,
const Inverted_weighted_point &p2,
const Inverted_weighted_point &p3, int i) const
{
CGAL_assertion(i == -1 || i == 1 || i == 2 || i == 3);
Sign s = -CGAL::sign(
determinant<RT>(
p1.p(), p1.x(),
p2.p(), p2.x())
* determinant<RT>(
p1.p(), p1.weight(), p1.x(),
p2.p(), p2.weight(), p2.x(),
p3.p(), p3.weight(), p3.x())
+ determinant<RT>(
p1.p(), p1.y(),
p2.p(), p2.y())
* determinant<RT>(
p1.p(), p1.weight(), p1.y(),
p2.p(), p2.weight(), p2.y(),
p3.p(), p3.weight(), p3.y()));
if (s != ZERO || i < 1) { return s; }
// perturbation
return POSITIVE;
}
Sign power_test(const Inverted_weighted_point &p1,
const Inverted_weighted_point &p2,
const Inverted_weighted_point &p3, int i) const
{
CGAL_assertion(i == -1 || i == 1 || i == 2 || i == 3);
Sign s;
Sign s_xTest = sign_of_determinant(p2.p(), p2.x(), p1.p(), p1.x());
if ( s_xTest != ZERO ) {
s = s_xTest *
sign_of_determinant( p1.p(), p1.x(), p1.weight(),
p2.p(), p2.x(), p2.weight(),
p3.p(), p3.x(), p3.weight() );
} else {
s = sign_determinant2x2( p2.p(), p2.y(), p1.p(), p1.y() ) *
sign_of_determinant( p1.p(), p1.y(), p1.weight(),
p2.p(), p2.y(), p2.weight(),
p3.p(), p3.y(), p3.weight() );
}
if (s != ZERO || i < 1) { return s; }
switch (i) {
case 1:
return ordered_on_line (p1, p2, p3) ? NEGATIVE : POSITIVE;
case 2:
return ordered_on_line (p2, p1, p3) ? NEGATIVE : POSITIVE;
case 3:
return NEGATIVE;
default:
CGAL_error_msg( "this should not happen.");
}
// perturbation
bool ool;
if (i == 1) {
ool = ordered_on_line(p2, p1, p3);
} else if (i == 2) {
ool = ordered_on_line(p1, p2, p3);
} else if (i == 3) {
ool = ordered_on_line(p1, p3, p2);
} else {
CGAL_error_msg( "this does not happen.");
ool = false;
}
if (ool) { return NEGATIVE; }
return POSITIVE;
}
Sign ordered_on_line_test(const Inverted_weighted_point &p1,
const Inverted_weighted_point &p2) const
{
Sign s_det = sign_of_determinant( p1.p(), p1.x(), p2.p(), p2.x() );
if ( s_det != ZERO ) { return s_det; }
return sign_of_determinant( p1.p(), p1.y(), p2.p(), p2.y() );
}
bool ordered_on_line(const Inverted_weighted_point &p1,
const Inverted_weighted_point &p2,
const Inverted_weighted_point &p3) const
{
if (ordered_on_line_test(p1, p2) == POSITIVE) {
return ordered_on_line_test(p2, p3) == POSITIVE;
}
return ordered_on_line_test(p3, p2) == POSITIVE;
}
};
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_CONFLICT_2_H

View File

@ -0,0 +1,104 @@
// Copyright (c) 2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
// Christophe Delage <Christophe.Delage@sophia.inria.fr>
// David Millman <dlm336@cs.nyu.edu>
#ifndef CGAL_APOLLONIUS_GRAPH_2_EDGE_CONFLICT_2_H
#define CGAL_APOLLONIUS_GRAPH_2_EDGE_CONFLICT_2_H 1
#include <CGAL/Apollonius_graph_2/Delage_traits/Conflict_2.h>
namespace CGAL {
namespace ApolloniusGraph_2 {
//-----------------------------------------------------------------------
// Edge Conflict Base
//-----------------------------------------------------------------------
template < class K, class Method_tag >
class Edge_conflict_2 : public Conflict_2<K, Method_tag>
{
private:
typedef Conflict_2<K, Method_tag> Base;
public:
typedef typename Base::Inverted_weighted_point Inverted_weighted_point;
typedef bool result_type;
typedef typename Base::Sign Sign;
protected:
bool edge_conflict_test(const Inverted_weighted_point &p2,
const Inverted_weighted_point &p3,
const Inverted_weighted_point &p4,
const Inverted_weighted_point &q,
bool b, int /*i23Q*/, int /*i24Q*/) const
{
// orientations
Sign orient23Q = this->orientation(p2, p3, q);
Sign orient42Q = this->orientation(p4, p2, q);
Sign orient234 = this->orientation(p2, p3, p4);
// radical intersections
Sign radInt23Q = this->radical_intersection(p2, p3, q, -1);
Sign radInt24Q = this->radical_intersection(p2, p4, q, -1);
// radical side
Sign radSid2Q3 = this->radical_side(p2, q, p3, -1);
Sign radSid2Q4 = this->radical_side(p2, q, p4, -1);
// order of a line
bool oolQ24 = this->ordered_on_line(q, p2, p4);
bool oolQ23 = this->ordered_on_line(q, p2, p3);
if ( b )
{
if ( CGAL::sign(q.p()) != POSITIVE ) { return true; }
// degenerate case
if (orient234 == ZERO && orient23Q == ZERO && orient42Q == ZERO) {
return (oolQ23 || oolQ24);
} else if (! ((radInt23Q != NEGATIVE && radSid2Q3 == NEGATIVE) &&
(radInt24Q != NEGATIVE && radSid2Q4 == NEGATIVE))) {
// non degenerate case
return true;
} else if (orient234 != NEGATIVE) {
return orient23Q != POSITIVE && orient42Q != POSITIVE;
} else {
return orient23Q != POSITIVE || orient42Q != POSITIVE;
}
}
else
{
CGAL_assertion ( CGAL::sign(q.p()) == POSITIVE );
// degenerate case
if (orient234 == ZERO && orient23Q == ZERO && orient42Q == ZERO) {
return (oolQ23 && oolQ24);
} else if (! ((radInt23Q != NEGATIVE && radSid2Q3 == NEGATIVE) &&
(radInt24Q != NEGATIVE && radSid2Q4 == NEGATIVE))) {
// non degenerate case
return false;
} else if (orient234 != NEGATIVE) {
return orient23Q != POSITIVE || orient42Q != POSITIVE;
} else {
return orient23Q != POSITIVE && orient42Q != POSITIVE;
}
}
}
};
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_EDGE_CONFLICT_2_H

View File

@ -0,0 +1,83 @@
// Copyright (c) 2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
// Christophe Delage <Christophe.Delage@sophia.inria.fr>
// David Millman <dlm336@cs.nyu.edu>
#ifndef CGAL_APOLLONIUS_GRAPH_2_FINITE_EDGE_CONFLICT_2_H
#define CGAL_APOLLONIUS_GRAPH_2_FINITE_EDGE_CONFLICT_2_H
#include <CGAL/Apollonius_graph_2/Delage_traits/Edge_conflict_2.h>
namespace CGAL {
namespace ApolloniusGraph_2 {
//-----------------------------------------------------------------------
// Finite edge interior conflict
//-----------------------------------------------------------------------
template < class K, class Method_tag >
class Finite_edge_interior_conflict_new_2
: public Edge_conflict_2<K, Method_tag>
{
private:
typedef Edge_conflict_2<K,Method_tag> Base;
using Base::edge_conflict_test;
public:
typedef typename Base::Inverted_weighted_point Inverted_weighted_point;
typedef Weighted_point_inverter_2<K> Weighted_point_inverter;
typedef typename K::Site_2 Site_2;
typedef typename K::Point_2 Point_2;
typedef bool result_type;
inline
bool operator()(const Site_2& p1, const Site_2& p2,
const Site_2& q, bool b) const
{
Weighted_point_inverter inverter(p1);
Point_2 origin(0,0);
Site_2 origin_site(origin,0);
return edge_conflict_test(inverter(p2),
Inverted_weighted_point(origin_site,1),
Inverted_weighted_point(origin_site,1),
inverter(q), b, 2, 2);
}
inline
bool operator()(const Site_2& p1, const Site_2& p2,
const Site_2& p3, const Site_2& q, bool b) const
{
Weighted_point_inverter inverter(p2);
Point_2 origin(0,0);
Site_2 origin_site(origin,0);
return edge_conflict_test(inverter(p1),
Inverted_weighted_point(origin_site,1),
inverter(p3), inverter(q), b, 2, 1);
}
inline
bool operator()(const Site_2& p1, const Site_2& p2, const Site_2& p3,
const Site_2& p4, const Site_2& q, bool b) const
{
Weighted_point_inverter inverter(p2);
return edge_conflict_test(inverter(p1), inverter(p4), inverter(p3),
inverter(q), b, 1, 1);
}
};
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_FINITE_EDGE_CONFLICT_2_H

View File

@ -0,0 +1,62 @@
// Copyright (c) 2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
// Christophe Delage <Christophe.Delage@sophia.inria.fr>
// David Millman <dlm336@cs.nyu.edu>
#ifndef CGAL_APOLLONIUS_GRAPH_2_INFINITE_EDGE_CONFLICT_2_H
#define CGAL_APOLLONIUS_GRAPH_2_INFINITE_EDGE_CONFLICT_2_H
#include <CGAL/Apollonius_graph_2/Delage_traits/Edge_conflict_2.h>
namespace CGAL {
namespace ApolloniusGraph_2 {
//-----------------------------------------------------------------------
// Infinite edge interior conflict
//-----------------------------------------------------------------------
template < class K, class Method_tag >
class Infinite_edge_interior_conflict_new_2
: public Edge_conflict_2<K, Method_tag>
{
private:
typedef Edge_conflict_2<K,Method_tag> Base;
using Base::edge_conflict_test;
public:
typedef Weighted_point_inverter_2<K> Weighted_point_inverter;
typedef typename Base::Inverted_weighted_point Inverted_weighted_point;
typedef typename K::Site_2 Site_2;
typedef typename K::Point_2 Point_2;
typedef bool result_type;
inline
bool operator()(const Site_2& p2, const Site_2& p3,
const Site_2& p4, const Site_2& q, bool b) const
{
Weighted_point_inverter inverter(p2);
Point_2 origin(0,0);
Site_2 origin_site(origin,0);
return edge_conflict_test(Inverted_weighted_point(origin_site, 1),
inverter(p4), inverter(p3), inverter(q),
b, 1, 1);
}
};
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_INFINITE_EDGE_CONFLICT_2_H

View File

@ -0,0 +1,25 @@
// Copyright (c) 2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_NEW_PREDICATES_C2_H
#define CGAL_APOLLONIUS_GRAPH_2_NEW_PREDICATES_C2_H 1
#include <CGAL/Apollonius_graph_2/Predicates_C2.h>
#include <CGAL/Apollonius_graph_2/Delage_traits/Vertex_conflict_2.h>
#include <CGAL/Apollonius_graph_2/Delage_traits/Finite_edge_conflict_2.h>
#include <CGAL/Apollonius_graph_2/Delage_traits/Infinite_edge_conflict_2.h>
#include <CGAL/Apollonius_graph_2/Delage_traits/Orientation_2.h>
#endif // CGAL_APOLLONIUS_GRAPH_2_NEW_PREDICATES_C2_H

View File

@ -0,0 +1,92 @@
// Copyright (c) 2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
// Christophe Delage <Christophe.Delage@sophia.inria.fr>
// David Millman <dlm336@cs.nyu.edu>
#ifndef CGAL_APOLLONIUS_GRAPH_2_ORIENTATION_NEW_2_H
#define CGAL_APOLLONIUS_GRAPH_2_ORIENTATION_NEW_2_H
#include <CGAL/Apollonius_graph_2/Orientation_2.h>
namespace CGAL {
namespace ApolloniusGraph_2 {
template <class K, class MTag>
class Orientation_new_2 : public Orientation_2<K, MTag>
{
private:
typedef Orientation_2<K, MTag> Base;
public:
typedef K Kernel;
typedef typename K::RT RT;
typedef typename K::Site_2 Site_2;
typedef typename K::Point_2 Point_2;
typedef typename Base::Orientation Orientation;
typedef Orientation result_type;
typedef Site_2 argument_type;
Orientation operator() (const Site_2 &s0, const Site_2 &s1,
const Site_2 &s2, const Point_2 &q) const
{
RT x1 = s1.x() - s0.x();
RT y1 = s1.y() - s0.y();
RT w1 = s1.weight() - s0.weight();
RT x2 = s2.x() - s0.x();
RT y2 = s2.y() - s0.y();
RT w2 = s2.weight() - s0.weight();
RT xq = q.x() - s0.x();
RT yq = q.y() - s0.y();
RT a1 = CGAL::square(x1) + CGAL::square(y1) - CGAL::square(w1);
RT a2 = CGAL::square(x2) + CGAL::square(y2) - CGAL::square(w2);
CGAL_assertion (CGAL::sign(a1) == POSITIVE);
CGAL_assertion (CGAL::sign(a2) == POSITIVE);
RT x = a1 * x2 - a2 * x1;
RT y = a1 * y2 - a2 * y1;
RT w = a1 * w2 - a2 * w1;
RT s = x * xq + y * yq;
Sign W = CGAL::sign (w);
Sign S = CGAL::sign (s);
if (W == ZERO) { return -S; }
RT o = x * yq - y * xq;
Sign O = CGAL::sign(o);
if (S == 0) { return O * W; }
if (W * S * O != POSITIVE) { return -S; }
RT i = CGAL::square(w) * (CGAL::square(xq) + CGAL::square(yq))
- CGAL::square(s);
Sign I = CGAL::sign(i);
return S * I;
}
};
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_ORIENTATION_NEW_2_H

View File

@ -0,0 +1,320 @@
// Copyright (c) 2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
// Christophe Delage <Christophe.Delage@sophia.inria.fr>
// David Millman <dlm336@cs.nyu.edu>
#ifndef CGAL_APOLLONIUS_GRAPH_2_VERTEX_CONFLICT_2_H
#define CGAL_APOLLONIUS_GRAPH_2_VERTEX_CONFLICT_2_H
#include <CGAL/Apollonius_graph_2/basic.h>
namespace CGAL {
namespace ApolloniusGraph_2 {
//-----------------------------------------------------------------------
// Vertex conflict
//-----------------------------------------------------------------------
template < class K, class Method_tag >
class Vertex_conflict_new_2
{
public:
typedef typename K::Site_2 Site_2;
typedef typename K::RT RT;
typedef Sign result_type;
private:
inline
bool is_less (const Site_2 &p0, const Site_2 &p1) const
{
if (p0.weight() < p1.weight()) return true;
if (p0.weight() > p1.weight()) return false;
if (p0.x() < p1.x()) return true;
if (p0.x() > p1.x()) return false;
return p0.y() < p1.y();
}
inline
int max_radius(const Site_2 &p0, const Site_2 &p1,
const Site_2 &p2, const Site_2 &p3) const
{
int i = 0;
const Site_2 *p = &p0;
if (is_less (*p, p1)) { i = 1; p = &p1; }
if (is_less (*p, p2)) { i = 2; p = &p2; }
if (is_less (*p, p3)) { i = 3; }
return i;
}
inline
Sign predicate (const Site_2 &p1, const Site_2 &p2,
const Site_2 &p3, const Site_2 &q, bool perturb) const
{
RT xq = q.x() - p1.x();
RT yq = q.y() - p1.y();
RT wq = q.weight() - p1.weight();
RT aq = CGAL::square(xq) + CGAL::square(yq) - CGAL::square(wq);
// q is hiding p1
if (CGAL::sign(aq) != POSITIVE){
// I BELIEVE MENELAOS RETURNS -1 in this case even when degernate
//if (sign (aq) == ZERO && ! perturb) return ZERO;
//return NEGATIVE;
return POSITIVE;
}
RT x2 = p2.x() - p1.x();
RT y2 = p2.y() - p1.y();
RT w2 = p2.weight() - p1.weight();
RT a2 = CGAL::square(x2) + CGAL::square(y2) - CGAL::square(w2);
CGAL_assertion (a2 > 0);
RT x3 = p3.x() - p1.x();
RT y3 = p3.y() - p1.y();
RT w3 = p3.weight() - p1.weight();
RT a3 = CGAL::square(x3) + CGAL::square(y3) - CGAL::square(w3);
CGAL_assertion (a3 > 0);
RT ax3q = a3 * xq - x3 * aq;
RT ax2q = a2 * xq - x2 * aq;
RT ax23 = a2 * x3 - x2 * a3;
RT ay23 = a2 * y3 - y2 * a3;
RT ay2q = a2 * yq - y2 * aq;
RT ay3q = a3 * yq - y3 * aq;
RT axw23q = ax23 * wq - ax2q * w3 + ax3q * w2;
RT ayw23q = ay23 * wq - ay2q * w3 + ay3q * w2;
RT axy23q = y2 * ax3q - y3 * ax2q + yq * ax23;
// orientation
Sign orient = CGAL::sign(axy23q);
// orientation degenerate
if (orient == ZERO) {
Sign orient1 = CGAL::sign(ax23);
Sign power_test =
( orient1 == ZERO ?
(CGAL::sign(ay23) * CGAL::sign(ayw23q)) :
(orient1 * CGAL::sign(axw23q))
);
if (power_test != ZERO || !perturb) {
return -power_test;
}
int i = max_radius (p1, p2, p3, q);
if (i == 3) { return NEGATIVE; }
Sign o23, o2q, o3q;
if (orient1 == ZERO) {
o23 = CGAL::sign(ay23);
o2q = CGAL::sign(ay2q);
o3q = CGAL::sign(ay3q);
} else {
o23 = CGAL::sign(ax23);
o2q = CGAL::sign(ax2q);
o3q = CGAL::sign(ax3q);
}
if (o23 != o2q) { return i == 2 ? NEGATIVE : POSITIVE; }
if (o23 == o3q) { return i == 1 ? NEGATIVE : POSITIVE; }
return i == 0 ? NEGATIVE : POSITIVE;
}
// radical side
RT rs23q = ax23 * axw23q + ay23 * ayw23q;
Sign radSide = CGAL::sign(rs23q);
if (radSide == ZERO || radSide != orient) { return orient; }
// radical intersection
Sign radInt =
CGAL::sign(CGAL::square(axw23q) + CGAL::square(ayw23q)
- CGAL::square( axy23q));
// radical intersection degenerate
if (radInt == ZERO) {
Sign radSideQ = CGAL::sign(ax23 * axw23q + ay23 * ayw23q);
CGAL_assertion (radSideQ != ZERO);
if (!perturb) { return (radSideQ == orient) ? ZERO : orient; }
int i = max_radius (p1, p2, p3, q);
if (i == 3) {
radInt = radSideQ;
} else if (i == 2) {
radInt = -CGAL::sign(ax2q * axw23q + ay2q * ayw23q);
if (radInt == ZERO) { return NEGATIVE; }
} else if (i == 1) {
radInt = CGAL::sign(ax3q * axw23q + ay3q * ayw23q);
if (radInt == ZERO) { return NEGATIVE; }
} else {
CGAL_assertion (i == 0);
Sign radSide1 = -CGAL::sign(ax2q * axw23q + ay2q * ayw23q);
if (radSide1 == ZERO) { return NEGATIVE; }
Sign radSide2 = CGAL::sign(ax3q * axw23q + ay3q * ayw23q);
if (radSide2 == ZERO) { return NEGATIVE; }
radInt = Sign (-(radSideQ + radSide1 + radSide2));
}
}
CGAL_assertion (!perturb || radInt != ZERO);
if (radInt == NEGATIVE) { return orient; }
return -radSide;
}
inline
Sign predicate(const Site_2 &p1, const Site_2 &p2,
const Site_2 &q, bool perturb) const
{
// NOTE:***************************************
// * the perturb boolean variable is not used
// * for consistancy with Menelaos
// NOTE:***************************************
RT x2 = p2.x() - p1.x();
RT y2 = p2.y() - p1.y();
RT w2 = p2.weight() - p1.weight();
RT xq = q.x() - p1.x();
RT yq = q.y() - p1.y();
RT wq = q.weight() - p1.weight();
RT xw2q = x2 * wq - xq * w2;
RT yw2q = y2 * wq - yq * w2;
RT xy2q = x2 * yq - xq * y2;
// orientation
Sign orient = CGAL::sign(xy2q);
// orientation degenerate
if (orient == ZERO) {
Sign o12 = CGAL::sign(x2);
Sign o1q, o2q;
Sign power_test;
if (o12 != ZERO) {
power_test = o12 * CGAL::sign(xw2q);
// this results is consistant with Menelaos
if (power_test != ZERO) { return -power_test; }
// this result is consistant with the perturb on off idea
//if (power_test != ZERO || ! perturb) return -power_test;
o1q = CGAL::sign(xq);
o2q = CGAL::sign(q.x() - p2.x());
} else {
o12 = CGAL::sign(y2);
power_test = o12 * CGAL::sign(yw2q);
// this results is consistant with Menelaos
if (power_test != ZERO) { return -power_test; }
// this result is consistant with the perturb on off idea
//if (power_test != ZERO || ! perturb) return -power_test;
o1q = CGAL::sign(yq);
o2q = CGAL::sign(q.y() - p2.y());
}
if (o1q != o12) { return POSITIVE; }
if (o2q == o12) { return POSITIVE; }
return NEGATIVE;
}
// radical side
RT rs12q = x2 * xw2q + y2 * yw2q;
Sign radSide = CGAL::sign(rs12q);
if (radSide == ZERO || radSide == orient) {
return -orient;
}
// radical intersection
Sign radInt =
CGAL::sign(CGAL::square(xw2q) + CGAL::square(yw2q)
- CGAL::square(xy2q));
// radical intersection degerate
if (radInt == ZERO) {
CGAL_assertion (radSide != ZERO);
// this result is consistant with the perturb on off idea
//if (! perturb) return (radSide == orient) ? ZERO : orient;
RT rs2q1 = (p2.x() - q.x()) * xw2q + (p2.y() - q.y()) * yw2q;
Sign radSide1 = CGAL::sign(rs2q1);
if (radSide1 == ZERO) { return NEGATIVE; }
RT rsq12 = xq * xw2q + yq * yw2q;
Sign radSide2 = CGAL::sign(rsq12);
if (radSide2 == ZERO) { return NEGATIVE; }
return -(radSide1 * radSide2);
}
CGAL_assertion (!perturb || radInt != ZERO);
if (radInt == POSITIVE) { return orient; }
return radSide;
}
public:
inline
Sign operator()(const Site_2 &p1, const Site_2 &p2,
const Site_2 &p3, const Site_2 &q,
bool perturb = true) const
{
Sign newPred = predicate(p1, p2, p3, q, perturb);
CGAL_assertion (!perturb || newPred != ZERO);
return newPred;
}
inline
Sign operator()(const Site_2 &p1, const Site_2 &p2,
const Site_2 &q, bool perturb = true) const
{
Sign newPred = predicate(p1, p2, q, perturb);
CGAL_assertion (!perturb || newPred != ZERO);
return newPred;
}
};
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_VERTEX_CONFLICT_2_H

View File

@ -0,0 +1,194 @@
#include <CGAL/basic.h>
#include <cassert>
#include <fstream>
#include <CGAL/MP_Float.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Apollonius_graph_2.h>
#include <CGAL/Apollonius_graph_traits_2.h>
#include <CGAL/Apollonius_graph_2/Delage_traits/Apollonius_graph_new_traits_2.h>
typedef CGAL::Sign Sign;
template <class GT, class GT_test>
class Check_traits : public GT
{
GT_test test;
public:
typedef typename GT::Site_2 Site_2;
Check_traits (const GT &gt = GT(), const GT_test &gt_test = GT_test())
: GT(gt), test (gt_test)
{}
template <class Predicate, class New_predicate>
struct Checked_predicate : public Predicate
{
New_predicate newp;
typedef typename Predicate::result_type result_type;
Checked_predicate (const Predicate &p, const New_predicate &np)
: Predicate (p), newp (np)
{}
template <class T1>
result_type operator() (const T1 &t1) const
{
result_type r1 = Predicate::operator() (t1);
result_type r2 = newp (t1);
assert(r1 == r2);
return r1;
}
template <class T1, class T2>
result_type operator() (const T1 &t1, const T2 &t2) const
{
result_type r1 = Predicate::operator() (t1, t2);
result_type r2 = newp (t1, t2);
assert(r1 == r2);
return r1;
}
template <class T1, class T2, class T3>
result_type operator() (const T1 &t1, const T2 &t2, const T3 &t3) const
{
result_type r1 = Predicate::operator() (t1, t2, t3);
result_type r2 = newp (t1, t2, t3);
assert(r1 == r2);
return r1;
}
template <class T1, class T2, class T3, class T4>
result_type operator() (const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4) const
{
result_type r1 = Predicate::operator() (t1, t2, t3, t4);
result_type r2 = newp (t1, t2, t3, t4);
assert(r1 == r2);
return r1;
}
template <class T1, class T2, class T3, class T4, class T5>
result_type operator() (const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5) const
{
result_type r1 = Predicate::operator() (t1, t2, t3, t4, t5);
result_type r2 = newp (t1, t2, t3, t4, t5);
assert(r1 == r2);
return r1;
}
template <class T1, class T2, class T3, class T4, class T5, class T6>
result_type operator() (const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6) const
{
result_type r1 = Predicate::operator() (t1, t2, t3, t4, t5, t6);
result_type r2 = newp (t1, t2, t3, t4, t5, t6);
assert(r1 == r2);
return r1;
}
};
typedef Checked_predicate<typename GT::Vertex_conflict_2,
typename GT_test::Vertex_conflict_2>
Vertex_conflict_2;
typedef Checked_predicate<typename GT::Finite_edge_interior_conflict_2,
typename GT_test::Finite_edge_interior_conflict_2>
Finite_edge_interior_conflict_2;
typedef Checked_predicate<typename GT::Infinite_edge_interior_conflict_2,
typename GT_test::Infinite_edge_interior_conflict_2>
Infinite_edge_interior_conflict_2;
Vertex_conflict_2
vertex_conflict_2_object() const
{
return Vertex_conflict_2 (
GT::vertex_conflict_2_object(),
test.vertex_conflict_2_object());
}
Finite_edge_interior_conflict_2
finite_edge_interior_conflict_2_object() const
{
return Finite_edge_interior_conflict_2 (
GT::finite_edge_interior_conflict_2_object(),
test.finite_edge_interior_conflict_2_object());
}
Infinite_edge_interior_conflict_2
infinite_edge_interior_conflict_2_object() const
{
return Infinite_edge_interior_conflict_2 (
GT::infinite_edge_interior_conflict_2_object(),
test.infinite_edge_interior_conflict_2_object());
}
};
typedef CGAL::MP_Float NT;
typedef CGAL::Simple_cartesian<NT> K;
typedef CGAL::Apollonius_graph_traits_2<K> GT_old;
typedef CGAL::Apollonius_graph_new_traits_2<K> GT_new;
typedef Check_traits<GT_old,GT_new> GT;
typedef CGAL::Apollonius_graph_2<GT> AG;
typedef AG::Site_2 Site;
typedef AG::Finite_faces_iterator Finite_faces_iterator;
typedef AG::Finite_vertices_iterator Finite_vertices_iterator;
typedef AG::Vertex_handle Vertex_handle;
void test_orientation (const AG &ag,
Vertex_handle v0, Vertex_handle v1, Vertex_handle v2)
{
const Site &s0 = v0->site();
const Site &s1 = v1->site();
const Site &s2 = v2->site();
GT gt;
GT_new gt_new;
GT::Orientation_2 orientation1 = gt.orientation_2_object();
GT_new::Orientation_new_2 orientation2 = gt_new.orientation_new_2_object();
for (Finite_vertices_iterator _v = ag.finite_vertices_begin();
_v != ag.finite_vertices_end(); ++_v)
{
Vertex_handle v = _v;
if (v == v0) continue;
Sign o1 = orientation1 (s0, s1, s2, s0, v->site());
Sign o2 = orientation2 (s0, s1, s2, v->site().point());
assert(o1 == o2);
}
}
void test_file (const char *filename)
{
std::ifstream is (filename);
assert(is);
std::cout << "File " << filename << ": construction... " << std::flush;
AG ag;
Site s; while (is >> s) ag.insert (s);
std::cout << "validation... " << std::flush;
assert(ag.is_valid());
std::cout << "OK" << std::endl;
std::cout << "Test orientation... " << std::flush;
for (Finite_faces_iterator f = ag.finite_faces_begin();
f != ag.finite_faces_end(); ++f)
{
test_orientation (ag, f->vertex(0), f->vertex(1), f->vertex(2));
test_orientation (ag, f->vertex(1), f->vertex(2), f->vertex(0));
test_orientation (ag, f->vertex(2), f->vertex(0), f->vertex(1));
}
std::cout << "OK" << std::endl;
}
int main (void)
{
test_file ("data/traits.dat");
test_file ("data/algo.dat");
return 0;
}

View File

@ -0,0 +1,438 @@
namespace CGAL {
/*!
\mainpage User Manual
\anchor Chapter_2D_Apollonius_Graphs
\anchor chapterapollonius2
\cgalAutoToc
\authors Menelaos Karavelas and Mariette Yvinec
This chapter describes the two-dimensional Apollonius graph
of \cgal. We start with a few definitions in
Section \ref secapollonius2definitions.
The software design of the 2D Apollonius graph package is described
in Section \ref secapollonius2design.
In Section \ref secapollonius2traits we discuss the geometric
traits of the 2D Apollonius graph package and in Section
\ref secapollonius2hierarchy the Apollonius graph hierarchy, a data
structure suitable for fast nearest neighbor queries, is briefly
described.
\section secapollonius2definitions Definitions
\cgalFigureBegin{figapollonius,apollonius_diagram.png,apollonius_graph.png}
The Apollonius diagram (left) and its dual the Apollonius graph (right).
\cgalFigureEnd
The 2D Apollonius graph class of \cgal is designed to compute the
dual of the <I>Apollonius diagram</I> or, as it is also known, the
<I>Additively weighted Voronoi diagram</I>. The algorithm that has been
implemented is dynamic, which means that we can perform insertions and
deletions on line. The corresponding \cgal class is called
`Apollonius_graph_2<ApolloniusGraphTraits_2,ApolloniusGraphDataStructure_2>`
and will be discussed in more detail in the sequel. The interested
reader may want to refer to the paper by Karavelas and Yvinec
\cgalCite{cgal:ky-dawvd-02} for the general idea as well as the details of the
algorithm implemented.
Before describing the details of the implementation we make a brief
introduction to the theory of Apollonius diagrams.
The Apollonius diagram is defined over a set of sites
\f$ P_i=(c_i,w_i)\f$, \f$ i=1,\ldots,n\f$, where \f$ c_i\f$ is the point and \f$ w_i\f$
the weight of \f$ P_i\f$. It is a subdivision of the plane into connected
regions, called <I>cells</I>, associated with the sites (see
\cgalFigureRef{figapollonius} (left)). The cell of a
site \f$ P_i\f$ is the locus of points on the plane that are
closer to \f$ P_i\f$ than any other site \f$ P_j\f$, \f$ j\neq i\f$.
The distance \f$ \delta(x, P_i)\f$ of a point \f$ x\f$ in the plane to a
site \f$ P_i\f$ is defined as:
\f[ \delta(x,P_i)=\|x-c_i\|-w_i, \f]
where \f$ \|\cdot\|\f$ denotes the Euclidean norm.
It can easily be seen that it is a generalization of the Voronoi
diagram for points, which can actually be obtained if all the weights
\f$ w_i\f$ are equal. Unlike the case of points, however, it is
possible that a site \f$ P_i\f$ might have an empty cell. This
can also happen in the case of the power diagram, whose dual is the
regular triangulation (see Section
\ref Section_2D_Triangulations_Regular ). If this is
the case we call the site <I>hidden</I> (these are the black
circles in \cgalFigureRef{figapollonius} ). A site which is not
hidden will be referred to as <I>visible</I>.
If all weights \f$ w_i\f$ are non-negative, the Apollonius
diagram can be viewed as the Voronoi diagram of the set of circles
\f$ \{P_1,\ldots, P_n\}\f$, where \f$ c_i\f$ is the center of the circle \f$ P_i\f$
and \f$ w_i\f$ its radius. If the weights are allowed to be negative,
we need to go to 3D in order to explain what the Apollonius diagram
means geometrically. We identify the 2D Euclidean plane with the
\f$ xy\f$-plane in 3D. Then the Voronoi diagram of a set of points can be
seen as the vertical projection on the \f$ xy\f$-plane of the lower
envelope of a set of 3D cones defined as follows: for each point \f$ p\f$
in the set of 2D points we have a cone \f$ C_p\f$ whose apex is the point
\f$ p\f$. The axis of
\f$ C_p\f$ is a line parallel to the \f$ z\f$-axis passing through \f$ p\f$, the
angle of \f$ C_p\f$ is \f$ 45^\circ\f$ and, finally \f$ C_p\f$ is facing in the
positive \f$ z\f$-direction (that is, \f$ C_p\f$ is contained in the positive
\f$ z\f$-halfspace).
The Apollonius diagram corresponds to shifting the
apexes of these cones in the \f$ z\f$-direction by a quantity equal to the
weight. Sites with negative weight will give rise to
cones whose apex is in the negative \f$ z\f$-halfspace and sites
with positive weight will give rise to cones whose apex is in the
positive \f$ z\f$-halfspace. In a manner analogous to the case of points,
the Apollonius diagram can then be defined as the vertical projection
on the \f$ xy\f$-plane of the lower envelope of the set of shifted cones.
Notice that when all apexes are translated along the \f$ z\f$-direction by
the same amount, the projection of the lower envelope of the set of
cones does not change. In particular, we can translate all cones by a
large enough amount so that all apexes are in the positive
\f$ z\f$-halfspace. Algebraically, this means that the Apollonius diagram
does not change if we add to all weights the same quantity, which in
particular, implies that we can assume without loss of generality that
all weights are positive. Given the observations above and in order to
simplify our discussion of Apollonius diagrams, we will, from now on,
assume that all weights are positive, and we will refer to the
sites as circles.
The Apollonius diagram is a planar graph, and so is its dual, the
Apollonius graph. There are many ways to embed it on the plane and one
such way is shown in \cgalFigureRef{figapollonius} (right).
The Apollonius graph is uniquely defined once we have
the Apollonius diagram. If the circles are in <I>general position</I>
(see precise definition below), then the Apollonius graph is a graph
with triangular faces away from
the convex hull of the set of circles (by triangular we mean that
every face has exactly three edges). Near the convex hull we may
have some spikes (i.e., vertices of degree 1). To unify our approach
and handling of the Apollonius graph we add to the set of (finite)
circles a fictitious circle at infinity, which we call the
<I>site at infinity</I>. We can then connect all vertices of the outer
face of the Apollonius graph to the site at infinity which gives us
a graph with the property that all of its faces are now
triangular. However, the Apollonius graph is not a triangulation for
two main reasons: we cannot always embed it on the plane with straight
line segments that yield a triangulation and, moreover, we may have two
faces of the graph that have two edges in common, which is not allowed
in a triangulation. Both of these particularities appear when we
consider the Apollonius graph of the set of circles in
\cgalFigureRef{figapollonius}.
We would like to finish our brief introduction to the theory of
Apollonius graphs by discussing the concept of general position. We say
that a set of circles is in general position if no two triplets of
circles have the same tritangent circle. This statement is rather
technical and it is best understood in the context of points. The
equivalent statement for points is that we have no two triplets of
points that define the same circumcircle, or equivalently that no
four points are co-circular. The statement about general position made
above is a direct generalization of the (much simpler to understand)
statement about points. On the contrary, when we have circles in
degenerate position, the Apollonius graph has faces with more than
three edges on their boundary. We can get a triangulated version of
the graph by simply <I>triangulating</I> the corresponding faces in an
arbitrary way. In fact the algorithm that has been implemented in
\cgal has the property that it always returns a valid
<I>triangulated</I> version of the Apollonius graph. By valid we mean
that it contains the actual Apollonius graph (i.e., the actual dual of
the Apollonius diagram) and whenever there are faces with more than
three faces then they are triangulated. The way that they are
triangulated depends on the order of insertion and deletion of the
circles in the diagram.
One final point has to be made about hidden circles. First of all we
would like to be more precise about our definition of hidden circles:
we say that a circle is hidden if its cell has empty interior. This
definition allows us to guarantee that all visible circles have
cells that are two-dimensional regions.
Geometrically the fact that a circle is hidden means that it is
contained in the closure of the disk of another circle (see again
\cgalFigureRef{figapollonius} ). Note that a circle contained in the union
of several disks, but not in the closure of any one of them, is not
hidden.
Hidden circles pose an additional
difficulty to our algorithm and software design. Since we allow
circles to be inserted and deleted at wish, it is possible that a
circle that was hidden at some point in time, may become visible at
a later point in time; for example this can happen if we delete the
circle that hides it. For this purpose we store hidden circles and
have them reappear when they become visible. We will discuss this
issue in detail below. For the time being it suffices to say that the
user has the ability to control this behavior. More specifically it is
possible to discard the circles that become hidden. This choice is
totally natural when for example we expect to do only insertions,
since in this case a circle that becomes hidden will never
reappear. On the other hand if deletions are expected as well, then we
lose the ability to have the hidden circles reappear.
<b>Degenerate Dimensions.</b>
The dimension of the Apollonius graph is in general 2. The exceptions
to this rule are as follows:
<UL>
<LI>The dimension is \f$ -1\f$ if the Apollonius graph contains no circles.
<LI>The dimension is \f$ 0\f$ if the Apollonius graph contains exactly
one visible circle.
<LI>The dimension is \f$ 1\f$ is the Apollonius graph contains exactly
two visible circles.
</UL>
\section secapollonius2design Software Design
The 2D Apollonius graph class
`Apollonius_graph_2<ApolloniusGraphTraits_2,ApolloniusGraphDataStructure_2>`
follows the design of the triangulation packages of \cgal. It is
parametrized by two arguments:
<UL>
<LI>the <B>geometric traits</B> class. It provides the basic
geometric objects involved in the algorithm, such as sites, points
etc. It also provides the geometric predicates for the computation
of the Apollonius graph, as well as some basic constructions that
can be used, for example, to visualize the Apollonius graph or the
Apollonius diagram. The geometric traits for the Apollonius graph
will be discussed in more detail in the next section.
<LI>the <B>Apollonius graph data structure</B>. This is essentially
the same as the triangulation data structure (discussed in Chapter
\ref Chapter_2D_Triangulation_Data_Structure ), augmented with some
additional operations that are specific to Apollonius graphs. The
corresponding concept is that of
`ApolloniusGraphDataStructure_2`, which in fact is a refinement
of the `TriangulationDataStructure_2` concept. The class
`Triangulation_data_structure_2<Vb,Fb>` is a model of
the concept `ApolloniusGraphDataStructure_2`. A default value
for the corresponding template parameter is provided, so the user
does not need to specify it.
</UL>
<b>Storing Hidden Sites.</b>
As we have already mentioned a circle is hidden if it is contained
inside some visible circle. This creates a parent-child relationship
between visible and hidden circles: the parent of a hidden circle is the
visible circle that contains it. If more than one visible circles
contain a hidden circle then the hidden circle can be assigned to any of
the visible circles arbitrarily.
To store hidden circles we assign to every visible circle a list. This
list comprises the hidden circles that are contained in the
visible circle. The user can access the hidden circles associated with
a visible circle through an iterator called
`Hidden_sites_iterator`. This iterator is defined in the
`ApolloniusGraphVertexBase_2` concept and is implemented by its
model, the `Apollonius_graph_vertex_base_2<Gt,StoreHidden>`
class. It is also possible to iterate through the entire set of hidden
sites using an homonymous iterator defined by the
`Apollonius_graph_2<Gt,Agds>` class.
Since storing hidden sites may not be of interest in some cases (e.g.,
for example this is the case if we only perform insertions in the
Apollonius graph), the user has the possibility of controlling this
behavior. More precisely, the class
`Apollonius_graph_vertex_base_2<Gt,StoreHidden>` has two template
parameters, the second of which is a Boolean value. This value is by
default `true` and it indicates that hidden sites should be
stored. The user can indicate that hidden sites may be discarded
by setting this value to `false`.
\section secapollonius2traits The Geometric Traits
The predicates required for the computation of the Apollonius graph
are rather complicated. It is not the purpose of this document to
discuss them in detail. The interested reader may refer to the papers
by Karavelas and Emiris for the details
\cgalCite{cgal:ke-ppawv-02}, \cgalCite{cgal:ke-rctac-03}. However, we would like to give a brief
overview of what they
compute. There are several predicates needed by this algorithm. We
will discuss the most important/complicated ones. It turns out that
it is much easier to describe them in terms of the Apollonius diagram,
rather than the Apollonius graph. Whenever it is applicable we will also
describe their meaning in terms of the Apollonius graph.
The first two geometric predicates are called
`Is_hidden_2` and `Oriented_side_of_bisector_2`. The first one
involves two circles, say \f$ P_1\f$ and \f$ P_2\f$. It determines if \f$ P_1\f$ is
hidden with respect to \f$ P_2\f$; more precisely it checks whether the
circle \f$ P_1\f$ is contained in the closure of the disk defined by the
circle \f$ P_2\f$. As its name indicates, it determines if a circle is
hidden or not. The second predicate involves two circles \f$ P_1\f$ and
\f$ P_2\f$ and a point \f$ q\f$. It answers the question whether \f$ q\f$ is closer
to \f$ P_1\f$ or \f$ P_2\f$. Its name stems from the fact that answering the
aforementioned question is equivalent to determining the oriented
side of the bisector of \f$ P_1\f$ and \f$ P_2\f$ that contains the query point
\f$ q\f$. This predicate is used by the algorithm for closest neighbor
queries for points.
The next geometric predicate is called `Vertex_conflict_2` and it
involves four circles \f$ P_1\f$, \f$ P_2\f$, \f$ P_3\f$, and \f$ P_4\f$ (see
\cgalFigureRef{figag2vc} ). The first three (red circles in
\cgalFigureRef{figag2vc} ) define a tritangent circle (yellow
circle in \cgalFigureRef{figag2vc} ). What we want to determine is
the sign of the distance of the green circle from the yellow
circle. The distance between two circles \f$ K_1=(c_1,r_1)\f$ and
\f$ K_2=(c_2, r_2)\f$ is defined as the distance of their centers minus
their radii:
\f[ \delta(K_1, K_2) = \|c_1-c_2\|-r_1-r_2. \f]
This predicate determines if a vertex in the Apollonius diagram
(the center of the yellow circle) is destroyed when a new circle is
inserted in the diagram (the green circle). In the Apollonius graph
it tells us if a triangular face of the diagram is to be destroyed or
not.
\cgalFigureBegin{figag2vc,apollonius-vertex_conflict-false.png,apollonius-vertex_conflict-true.png}
The `Vertex_conflict_2` predicate. The left-most, bottom-most and top-most circles define the tritangent circle in the middle. We want to determine the sign of the distance of the left-most circle from the one in the middle. The almost horizontal curve is the bisector of the top-most and bottom-most circles. Left: the predicate returns `NEGATIVE`. Right: the predicate returns `POSITIVE`.
\cgalFigureEnd
What we essentially want to compute when we construct incrementally a
Voronoi diagram, is whether the object to be inserted destroys an edge
of the Voronoi diagram or not. In the case of points this is really
easy and it amounts to the well known <I>incircle</I> test.
In the case
of circles the situation is more complicated. We can have six possible
outcomes as to what portion of an edge of the Apollonius diagram the
new circle destroys (see \cgalFigureRef{figag2edgeconflict} ). The first
two can be answered directly by the `Vertex_conflict_2` predicate
evaluated for the two endpoints of the Apollonius diagram edge. This
is due to the fact that the value of the `Vertex_conflict_2`
predicate is different for the two endpoints. If the two values are
the same then we need an additional test which determines if the interior
of the Apollonius diagram edge is destroyed by the new circle. This is
what the `Finite_edge_interior_conflict_2` and
`Infinite_edge_interior_conflict_2` predicates do. In essence, it
is the same predicate (same idea) applied to two different types of
edges in the Apollonius diagram: a finite or an infinite edge. An edge
is infinite if its dual edge in the Apollonius graph connects the
site at infinity with the vertex corresponding to a (finite) circle;
otherwise it is a finite edge.
\cgalFigureAnchor{figag2edgeconflict}
<CENTER>
<TABLE BORDER>
<TR>
<TD>
\image html ./apollonius-left_vertex.png
\image latex ./apollonius-left_vertex.png
</TD>
<TD>
\image html ./apollonius-right_vertex.png
\image latex ./apollonius-right_vertex.png
</TD>
</TR>
<TR>
<TD>
\image html ./apollonius-no_conflict.png
\image latex ./apollonius-no_conflict.png
</TD>
<TD>
\image html ./apollonius-entire_edge.png
\image latex ./apollonius-entire_edge.png
</TD>
</TR>
<TR>
<TD>
\image html ./apollonius-interior.png
\image latex ./apollonius-interior.png
</TD>
<TD>
\image html ./apollonius-both_vertices.png
\image latex ./apollonius-both_vertices.png
</TD>
</TR>
</TABLE>
</CENTER>
\cgalFigureCaptionBegin{figag2edgeconflict}
The 6 possible outcomes of the
`Finite_edge_interior_conflict_2` predicate. Top left: only a
neighborhood around the left-most endpoint of the edge will be
destroyed. Top right: only a neighborhood around the right-most
endpoint of the edge will be destroyed. Middle left: no portion of the
edge is destroyed. Middle right: the entire edge will be
destroyed. Bottom left: a neighborhood in the interior of the edge
will be destroyed; the regions near the endpoints remain
unaffected. Bottom right: The neighborhood around the two endpoints
will be destroyed, but an interval in the interior of the edge will
remain in the new diagram.
\cgalFigureCaptionEnd
The last predicate that we want to discuss is called
`Is_degenerate_edge_2`. It tells us whether an edge in the
Apollonius diagram is degenerate, that is if its two endpoints
coincide. In the Apollonius graph such an edge corresponds to one of
the additional edges that we use to triangulate the non-triangular
faces.
The aforementioned predicates are part of the
`ApolloniusGraphTraits_2` concept of \cgal. \cgal also provides
a model for this concept, the
`Apollonius_graph_traits_2<K,Method_tag>` class. The first
template parameter of this class must be a model of the `Kernel`
concept. The second template parameter is a tag that indicates what
operations are allowed in the computations that take place within the
traits class.
The two possible values of the `Method_tag` parameter are
`Integral_domain_without_division_tag` and `Field_with_sqrt_tag`. When
`Integral_domain_without_division_tag` is used, only ring operations are used during the
evaluation of the predicates, whereas if `Field_with_sqrt_tag` is
chosen, all four field operations, as well as square roots, are used
during the predicate evaluation.
The `Apollonius_graph_traits_2<K,Method_tag>` class provides exact
predicates if the number type in the kernel `K` is an exact number
type. This is to be associated with the type of operations allowed for
the predicate evaluation. For example `MP_Float` as number
type, with `Integral_domain_without_division_tag` as tag will give exact predicates,
whereas `MP_Float` with `Field_with_sqrt_tag` will give
inexact predicates.
Although exact number types provide exact predicates and constructions,
their use often results in unacceptably large runtimes.
The class `Apollonius_graph_filtered_traits_2<CK,CM,EK,EM,FK,FM>`
aims to paliate this shortcoming. Similar to a filtered kernel, it takes a
constructions kernel `CK`, a filtering kernel `FK` and an
exact kernel `EK`, as well as the corresponding tags
(`CM`, `FM` and `EM`, respectively).
Predicates are evaluated by first using the filtering kernel, and
if this fails the evaluation is performed using the exact kernel,
thus yielding exact predicates at a generally much cheaper cost
than directly using an exact number type. The constructions
are done using the kernel `CK`, which means that
they are not necessarily exact. All template parameters except
`CK` have default values, which are explained in the reference
manual.
\section secapollonius2hierarchy The Apollonius Graph Hierarchy
The `Apollonius_graph_hierarchy_2<ApolloniusGraphTraits_2,ApolloniusGraphDataStructure_2>` class is nothing but the equivalent of the `Triangulation_hierarchy_2`
class, applied to the Apollonius graph. It consists of a series of
Apollonius graphs constructed in a manner analogous to the Delaunay
hierarchy by Devillers \cgalCite{d-iirdt-98}. The class
`Apollonius_graph_hierarchy_2<ApolloniusGraphTraits_2,ApolloniusGraphDataStructure_2>`
has exactly the same interface and functionality as the
`Apollonius_graph_2<ApolloniusGraphTraits_2,ApolloniusGraphDataStructure_2>`
class. Using the Apollonius graph hierarchy involves an additional
cost in space and time for maintaining the hierarchy. Our experiments
have shown that it usually pays off to use the hierarchy for inputs
consisting of more than 1,000 circles. This threshold holds for both
the construction of the Apollonius diagram itself, as well as for
nearest neighbor queries.
\section secapollonius2examples Examples
\subsection Apollonius_graph_2FirstExample First Example
\cgalExample{Apollonius_graph_2/ag2_exact_traits.cpp}
\subsection Apollonius_graph_2SecondExample Second Example
\cgalExample{Apollonius_graph_2/ag2_exact_traits_sqrt.cpp}
\subsection Apollonius_graph_2ThirdExample Third Example
\cgalExample{Apollonius_graph_2/ag2_filtered_traits_no_hidden.cpp}
\subsection Apollonius_graph_2FourthExample Fourth Example
\cgalExample{Apollonius_graph_2/ag2_hierarchy.cpp}
*/
} /* namespace CGAL */

View File

@ -0,0 +1,743 @@
namespace CGAL {
/*!
\ingroup PkgApolloniusGraph2Ref
The class `Apollonius_graph_2` represents the Apollonius graph.
It supports insertions and deletions of sites.
\tparam Gt is the geometric traits class and must be a model of `ApolloniusGraphTraits_2`.
\tparam Agds is the Apollonius graph data structure and must be a model of `ApolloniusGraphDataStructure_2`
whose vertex and face must be models of `ApolloniusGraphVertexBase_2` and `TriangulationFaceBase_2`,
respectively.
It defaults to:
\code
CGAL::Triangulation_data_structure_2<
CGAL::Apollonius_graph_vertex_base_2<Gt,true>,
CGAL::Triangulation_face_base_2<Gt> >`
\endcode
\cgalHeading{Traversal of the Apollonius Graph}
An Apollonius graph can be seen as a container of faces and vertices.
Therefore the Apollonius graph provides several iterators and
circulators that allow to traverse it (completely or partially).
\cgalHeading{Traversal of the Convex Hull}
Applied on the `infinite_vertex` the `incident_*` functions allow to
visit the vertices on the convex hull and the infinite edges and
faces. Note that a counterclockwise traversal of the vertices adjacent
to the `infinite_vertex` is a clockwise traversal of the convex hull.
\code{.cpp}
CGAL::Apollonius_graph_2<Gt, Agds> ag;
CGAL::Apollonius_graph_2<Gt, Agds>::Face f;
ag.incident_vertices(ag.infinite_vertex());
ag.incident_vertices(ag.infinite_vertex(), f);
ag.incident_faces(ag.infinite_vertex());
ag.incident_faces(ag.infinite_vertex(), f);
ag.incident_edges(ag.infinite_vertex());
ag.incident_edges(ag.infinite_vertex(), f);
\endcode
\cgalModels `DelaunayGraph_2`
\sa `CGAL::Apollonius_graph_traits_2<K,Method_tag>`
\sa `CGAL::Apollonius_graph_filtered_traits_2<CK,CM,EK,EM,FK,FM>`
\sa `CGAL::Apollonius_graph_hierarchy_2<Gt,Agds>`
*/
template< typename Gt, typename Agds >
class Apollonius_graph_2 {
public:
/// \name Types
/// @{
/*!
A type for the underlying
data structure.
*/
typedef Agds Data_structure;
/*!
Same as the `Data_structure` type. This type has been introduced
in order for the `Apollonius_graph_2` class to be a
model of the `DelaunayGraph_2` concept.
*/
typedef Data_structure Triangulation_data_structure;
/*!
A type for the geometric traits.
*/
typedef Gt Geom_traits;
/*!
A type for the
point defined in the geometric traits.
*/
typedef Gt::Point_2 Point_2;
/*!
A type for the Apollonius site, defined in the geometric traits.
*/
typedef Gt::Site_2 Site_2;
/// @}
/// \name Handles And Iterators
/// The vertices and faces of the Apollonius graph are accessed
/// through `handles`, `iterators`, and `circulators`. The iterators
/// and circulators are all bidirectional and non-mutable. The
/// circulators and iterators are assignable to the corresponding
/// handle types, and they are also convertible to the corresponding
/// handles. The edges of the Apollonius graph can also be visited
/// through iterators and circulators, the edge circulators and
/// iterators are also bidirectional and non-mutable. In the
/// following, we call <I>infinite</I> any face or edge incident to
/// the infinite vertex and the infinite vertex itself. Any other
/// feature (face, edge or vertex) of the Apollonius graph is said to
/// be <I>finite</I>. Some iterators (the `All` iterators ) allow to
/// visit finite or infinite features while the others (the `Finite`
/// iterators) visit only finite features. Circulators visit both
/// infinite and finite features.
/// @{
/*!
the edge type.
The `Edge(f,i)` is the edge common to faces `f` and
`f.neighbor(i)`. It is also the edge joining the vertices
`vertex(cw(i))` and `vertex(ccw(i))` of `f`.
\pre `i` must be `0`, `1` or `2`.
*/
typedef Data_structure::Edge Edge;
/*!
A type for a vertex.
*/
typedef Data_structure::Vertex Vertex;
/*!
A type for a face.
*/
typedef Data_structure::Face Face;
/*!
A type for a handle to a vertex.
*/
typedef Data_structure::Vertex_handle Vertex_handle;
/*!
A type for a handle to a face.
*/
typedef Data_structure::Face_handle Face_handle;
/*!
A type for a circulator over vertices incident to a given vertex.
*/
typedef Data_structure::Vertex_circulator Vertex_circulator;
/*!
A type for a circulator over faces incident to a given vertex.
*/
typedef Data_structure::Face_circulator Face_circulator;
/*!
A type for a circulator over edges incident to a given vertex.
*/
typedef Data_structure::Edge_circulator Edge_circulator;
/*!
A type for an iterator over all vertices.
*/
typedef Data_structure::Vertex_iterator
All_vertices_iterator;
/*!
A type for an iterator over all faces.
*/
typedef Data_structure::Face_iterator
All_faces_iterator;
/*!
A type for an iterator over all edges.
*/
typedef Data_structure::Edge_iterator
All_edges_iterator;
/*!
An unsigned integral type.
*/
typedef Data_structure::size_type size_type;
/*!
A type for an iterator over finite vertices.
*/
typedef unspecified_type Finite_vertices_iterator;
/*!
A type for an iterator over finite faces.
*/
typedef unspecified_type Finite_faces_iterator;
/*!
A type for an iterator over finite edges.
*/
typedef unspecified_type Finite_edges_iterator;
/// @}
/// \name Site Iterators
/// In addition to iterators and circulators for vertices and faces,
/// iterators for sites are provided. In particular there are
/// iterators for the entire set of sites, the hidden sites and the
/// visible sites of the Apollonius graph.
/// @{
/*!
A type for an iterator over all sites.
*/
typedef unspecified_type Sites_iterator;
/*!
A type for an iterator over all visible sites.
*/
typedef unspecified_type Visible_sites_iterator;
/*!
A type for an iterator over all hidden sites.
*/
typedef unspecified_type Hidden_sites_iterator;
/// @}
/// \name Creation
/// @{
/*!
Creates an
Apollonius graph `ag` using `gt` as geometric traits.
*/
Apollonius_graph_2(Gt gt=Gt());
/*!
Creates an Apollonius graph `ag` using `gt` as
geometric traits and inserts all sites in the range
[`first`, `beyond`).
\pre `Input_iterator` must be a model of `InputIterator`. The value type of `Input_iterator` must be `Site_2`.
*/
template< class Input_iterator >
Apollonius_graph_2(Input_iterator first, Input_iterator beyond,
Gt gt=Gt());
/*!
Copy constructor. All faces and vertices are duplicated. After the
construction,
`ag` and `other` refer to two different Apollonius graphs : if
`other` is modified, `ag` is not.
*/
Apollonius_graph_2(const Apollonius_graph_2<Gt,Agds>& other);
/*!
Assignment. If `ag` and `other` are the same object
nothing is done. Otherwise, all the vertices and faces are
duplicated. After the assignment, `ag` and `other` refer to
different Apollonius graphs : if `other` is modified, `ag` is
not.
*/
Apollonius_graph_2<Gt,Agds>
operator=(const Apollonius_graph_2<Gt,Agds>& other);
/// @}
/// \name Access Functions
/// @{
/*!
Returns a reference to the Apollonius graph traits object.
*/
const Geom_traits& geom_traits() const;
/*!
Returns a reference to the
underlying data structure.
*/
const Data_structure& data_structure() const;
/*!
Same as `data_structure()`. This
method has been added in compliance with the `DelaunayGraph_2`
concept.
*/
const Data_structure& tds() const;
/*!
Returns the dimension of the Apollonius graph.
*/
int dimension() const;
/*!
Returns the number of finite vertices.
*/
size_type number_of_vertices() const;
/*!
Returns the number of visible sites.
*/
size_type number_of_visible_sites() const;
/*!
Returns the number of hidden sites.
*/
size_type number_of_hidden_sites() const;
/*!
Returns the number of faces (both finite and infinite) of the
Apollonius graph.
*/
size_type number_of_faces() const;
/*!
Returns a face incident to the `infinite_vertex`.
*/
Face_handle infinite_face() const;
/*!
Returns the `infinite_vertex`.
*/
Vertex_handle infinite_vertex() const;
/*!
Returns a vertex distinct from the `infinite_vertex`.
\pre The number of (visible) vertices in the Apollonius graph must be at least one.
*/
Vertex_handle finite_vertex() const;
/// @}
/// \name Face, Edge and Vertex Iterators
/// The following iterators allow respectively to visit finite faces,
/// finite edges and finite vertices of the Apollonius graph. These
/// iterators are non-mutable, bidirectional and their value types are
/// respectively `Face`, `Edge` and `Vertex`. They are all invalidated
/// by any change in the Apollonius graph. The following iterators
/// allow respectively to visit all (both finite and infinite) faces,
/// edges and vertices of the Apollonius graph. These iterators are
/// non-mutable, bidirectional and their value types are respectively
/// `Face`, `Edge` and `Vertex`. They are all invalidated by any
/// change in the Apollonius graph.
/// @{
/*!
Starts at an arbitrary finite vertex.
*/
Finite_vertices_iterator finite_vertices_begin() const;
/*!
Past-the-end iterator.
*/
Finite_vertices_iterator finite_vertices_end() const;
/*!
Starts at an arbitrary finite edge.
*/
Finite_edges_iterator finite_edges_begin() const;
/*!
Past-the-end iterator.
*/
Finite_edges_iterator finite_edges_end() const;
/*!
Starts at an arbitrary finite face.
*/
Finite_faces_iterator finite_faces_begin() const;
/*!
Past-the-end iterator.
*/
Finite_faces_iterator finite_faces_end() const;
/*!
Starts at an arbitrary vertex.
*/
All_vertices_iterator all_vertices_begin() const;
/*!
Past-the-end iterator.
*/
All_vertices_iterator all_vertices_end() const;
/*!
Starts at an arbitrary edge.
*/
All_edges_iterator all_edges_begin() const;
/*!
Past-the-end iterator.
*/
All_edges_iterator all_edges_end() const;
/*!
Starts at an arbitrary face.
*/
All_faces_iterator all_faces_begin() const;
/*!
Past-the-end iterator.
*/
All_faces_iterator all_faces_end() const;
/// @}
/// \name Site Iterators
/// The following iterators allow respectively to visit all sites, the
/// visible sites and the hidden sites. These iterators are
/// non-mutable, bidirectional and their value type is `Site_2`. They
/// are all invalidated by any change in the Apollonius graph.
/// @{
/*!
Starts at an arbitrary site.
*/
Sites_iterator sites_begin() const;
/*!
Past-the-end iterator.
*/
Sites_iterator sites_end() const;
/*!
Starts at an arbitrary visible site.
*/
Visible_sites_iterator visible_sites_begin() const;
/*!
Past-the-end iterator.
*/
Visible_sites_iterator visible_sites_end() const;
/*!
Starts at an arbitrary hidden site.
*/
Hidden_sites_iterator hidden_sites_begin() const;
/*!
Past-the-end iterator.
*/
Hidden_sites_iterator hidden_sites_end() const;
/// @}
/// \name Face, Edge and Vertex Circulators
/// The Apollonius graph also provides circulators that allow to visit
/// respectively all faces or edges incident to a given vertex or all
/// vertices adjacent to a given vertex. These circulators are
/// non-mutable and bidirectional. The operator `operator++` moves the
/// circulator counterclockwise around the vertex while the
/// `operator--` moves clockwise. A face circulator is invalidated by
/// any modification of the face pointed to. An edge circulator is
/// invalidated by any modification in one of the two faces incident
/// to the edge pointed to. A vertex circulator is invalidated by any
/// modification in any of the faces adjacent to the vertex pointed
/// to.
/// @{
/*!
Starts at an arbitrary face incident
to `v`.
*/
Face_circulator incident_faces(Vertex_handle v) const;
/*!
Starts at face `f`.
\pre Face `f` is incident to vertex `v`.
*/
Face_circulator incident_faces(Vertex_handle v, Face_handle f) const;
/*!
Starts at an arbitrary edge incident
to `v`.
*/
Edge_circulator incident_edges(Vertex_handle v) const;
/*!
Starts at the first edge of `f` incident to
`v`, in counterclockwise order around `v`.
\pre Face `f` is incident to vertex `v`.
*/
Edge_circulator incident_edges(Vertex_handle v, Face_handle f) const;
/*!
Starts at an arbitrary vertex incident
to `v`.
*/
Vertex_circulator incident_vertices(Vertex_handle v) const;
/*!
Starts at the first vertex of `f` adjacent to `v`
in counterclockwise order around `v`.
\pre Face `f` is incident to vertex `v`.
*/
Vertex_circulator incident_vertices(Vertex_handle v, Face_handle f) const;
/// @}
/// \name Predicates
/// The class `Apollonius_graph_2` provides methods to test the finite
/// or infinite character of any feature.
/// @{
/*!
`true`, iff `v` is the `infinite_vertex`.
*/
bool
is_infinite(Vertex_handle v) const;
/*!
`true`, iff face `f` is infinite.
*/
bool
is_infinite(Face_handle f) const;
/*!
`true`, iff edge `(f,i)` is infinite.
*/
bool is_infinite(Face_handle f, int i) const;
/*!
`true`, iff edge `e` is infinite.
*/
bool
is_infinite(const Edge& e) const;
/*!
`true`, iff edge `*ec` is infinite.
*/
bool
is_infinite(Edge_circulator ec) const;
/// @}
/// \name Insertion
/// @{
/*!
Inserts the sites in the range
[`first`,`beyond`). The number of sites in the range
[`first`, `beyond`) is returned.
\pre `Input_iterator` must be a model of `InputIterator` and its value type must be `Site_2`.
*/
template< class Input_iterator >
unsigned int insert(Input_iterator first, Input_iterator beyond);
/*!
Inserts the
site `s` in the Apollonius graph. If `s` is visible then the
vertex handle of `s` is returned, otherwise
`Vertex_handle(nullptr)` is returned.
*/
Vertex_handle insert(const Site_2& s);
/*!
Inserts `s` in the Apollonius graph using the site
associated with `vnear` as an estimate for the nearest neighbor of
the center of `s`. If `s` is visible then the vertex handle of
`s` is returned, otherwise `Vertex_handle(nullptr)` is
returned.
*/
Vertex_handle insert(const Site_2& s, Vertex_handle vnear);
/// @}
/// \name Removal
/// @{
/*!
Removes the site
associated to the vertex handle `v` from the Apollonius
graph.
\pre `v` must correspond to a valid finite vertex of the Apollonius graph.
*/
void remove(Vertex_handle v);
/// @}
/// \name Nearest Neighbor Location
/// @{
/*!
Finds the nearest neighbor of the point `p`. In other words it
finds the site whose Apollonius cell contains `p`. Ties are broken
arbitrarily and one of the nearest neighbors of `p` is
returned. If there are no visible sites in the Apollonius diagram
`Vertex_handle(nullptr)` is returned.
*/
Vertex_handle nearest_neighbor(const Point_2& p) const;
/*!
Finds the nearest neighbor of the point
`p` using the site associated with `vnear` as an
estimate for the nearest neighbor of `p`. Ties are broken
arbitrarily and one of the nearest neighbors of `p` is
returned. If there are no visible sites in the Apollonius diagram
`Vertex_handle(nullptr)` is returned.
*/
Vertex_handle nearest_neighbor(const Point_2& p, Vertex_handle vnear) const;
/// @}
/// \name Access to the Dual
/// The `Apollonius_graph_2` class provides access to the duals of the
/// faces of the graph. The dual of a face of the Apollonius graph is
/// a site. If the originating face is infinite, its dual is a site
/// with center at infinity (or equivalently with infinite weight),
/// which means that it can be represented geometrically as a line. If
/// the originating face is finite, its dual is a site with finite
/// center and weight. In the following three methods the returned
/// object is assignable to either `Site_2` or `Gt::Line_2`, depending
/// on whether the corresponding face of the Apollonius graph is
/// finite or infinite, respectively.
/// @{
/*!
Returns the
dual corresponding to the face handle `f`. The returned object can
be assignable to one of the following: `Site_2`, `Gt::Line_2`.
*/
Gt::Object_2 dual(Face_handle f) const;
/*!
Returns the
dual of the face to which `it` points to. The returned object can
be assignable to one of the following: `Site_2`, `Gt::Line_2`.
*/
Gt::Object_2 dual(All_faces_iterator it) const;
/*!
Returns
the dual of the face to which `it` points to. The returned
object can be assignable to one of the following: `Site_2`,
`Gt::Line_2`.
*/
Gt::Object_2 dual(Finite_faces_iterator it) const;
/// @}
/// \name I/O
/// @{
/*!
Draws the Apollonius graph to
the stream `str`.
\pre The following operators must be defined:
`Stream& operator<<(Stream&, Gt::Segment_2)`,
`Stream& operator<<(Stream&, Gt::Ray_2)`.
*/
template< class Stream >
Stream& draw_primal(Stream& str) const;
/*!
Draws the dual of the
Apollonius graph, i.e., the Apollonius diagram, to the stream
`str`.
\pre The following operators must be defined:
`Stream& operator<<(Stream&, Gt::Segment_2)`,
`Stream& operator<<(Stream&, Gt::Ray_2)`,
`Stream& operator<<(Stream&, Gt::Line_2)`.
*/
template < class Stream >
Stream& draw_dual(Stream& str) const;
/*!
Draws the edge
`e` of the Apollonius graph to the stream `str`.
\pre The following operators must be defined:
`Stream& operator<<(Stream&, Gt::Segment_2)`,
`Stream& operator<<(Stream&, Gt::Ray_2)`.
*/
template< class Stream >
Stream& draw_primal_edge(const Edge& e, Stream& str) const;
/*!
Draws the dual of the
edge `e` to the stream `str`. The dual of `e` is an edge
of the Apollonius diagram.
\pre The following operators must be defined:
`Stream& operator<<(Stream&, Gt::Segment_2)`,
`Stream& operator<<(Stream&, Gt::Ray_2)`,
`Stream& operator<<(Stream&, Gt::Line_2)`.
*/
template< class Stream >
Stream& draw_dual_edge(const Edge& e, Stream& str) const;
/*!
Writes the current
state of the Apollonius graph to an output stream. In particular,
all visible and hidden sites are written as well as the
underlying combinatorial data structure.
*/
void file_output(std::ostream& os) const;
/*!
Reads the state of the
Apollonius graph from an input stream.
*/
void file_input(std::istream& is);
/*!
Writes the current state of the Apollonius graph to an output stream.
*/
std::ostream& operator<<(std::ostream& os, const Apollonius_graph_2<Gt,Agds>& ag) const;
/*!
Reads the state of the Apollonius graph from an input stream.
*/
std::istream& operator>>(std::istream& is, const Apollonius_graph_2<Gt,Agds>& ag);
/// @}
/// \name Validity Check
/// @{
/*!
Checks the validity of the Apollonius graph. If `verbose` is
`true` a short message is sent to `std::cerr`. If `level`
is 0, only the data structure is validated. If `level` is 1, then
both the data structure and the Apollonius graph are
validated. Negative values of `level` always return true, and
values greater than 1 are equivalent to `level` being 1.
*/
bool is_valid(bool verbose = false, int level = 1) const;
/// @}
/// \name Miscellaneous
/// @{
/*!
Clears all contents of the Apollonius graph.
*/
void clear();
/*!
The Apollonius graphs
`other` and `ag` are swapped. `ag.swap(other)` should
be preferred to `ag = other` or to `ag(other)` if
`other` is deleted afterwards.
*/
void swap(Apollonius_graph_2<Gt,Agds>& other);
/// @}
}; /* end Apollonius_graph_2 */
} /* end namespace CGAL */

View File

@ -0,0 +1,78 @@
namespace CGAL {
/*!
\ingroup PkgApolloniusGraph2Ref
The class `Apollonius_graph_filtered_traits_2` provides a model for the
`ApolloniusGraphTraits_2` concept.
The class `Apollonius_graph_filtered_traits_2` uses the filtering technique \cgalCite{cgal:bbp-iayed-01}
to achieve traits for the `Apollonius_graph_2<Gt,Agds>` class
with efficient and exact predicates given an exact
kernel `EK` and a filtering kernel `FK`. The geometric
constructions associated provided by this class are equivalent
to those provided by the traits class
`Apollonius_graph_traits_2<CK,CM>`, which means that they may
be inexact.
This class has six template parameters. The first, third and fifth
template parameters must be a models of the `Kernel` concept. The
second, fourth and sixth template parameters correspond to how
predicates are evaluated. There are two predefined possible values for
`Method_tag`, namely `CGAL::Field_with_sqrt_tag` and
`CGAL::Integral_domain_without_division_tag`. The first one must be used when the number type
used in the representation supports the exact evaluation of signs of
expressions involving all four basic operations and square roots,
whereas the second one requires the exact evaluation of signs of
ring-type expressions, i.e., expressions involving only additions,
subtractions and multiplications.
The way the predicates are evaluated is discussed in
\cgalCite{cgal:ke-ppawv-02}, \cgalCite{cgal:ke-rctac-03}.
The default values for the template parameters are as follows:
`CM = CGAL::Integral_domain_without_division_tag`,
`EK = CGAL::Simple_cartesian<CGAL::MP_Float>`,
`EM = CM`,
`FK = CGAL::Simple_cartesian<CGAL::Interval_nt<false> >`,
`FM = CM`.
\cgalModels `ApolloniusGraphTraits_2`
\sa `Kernel`
\sa `ApolloniusGraphTraits_2`
\sa `CGAL::Integral_domain_without_division_tag`
\sa `CGAL::Field_with_sqrt_tag`
\sa `CGAL::Apollonius_graph_2<Gt,Agds>`
\sa `CGAL::Apollonius_graph_traits_2<K,Method_tag>`
*/
template< typename CK, typename CM, typename EK, typename EM, typename FK, typename FM >
class Apollonius_graph_filtered_traits_2 {
public:
/// \name Creation
/// @{
/*!
%Default constructor.
*/
Apollonius_graph_filtered_traits_2<CK,CM,EK,EM,FK,FM>();
/*!
Copy
constructor.
*/
Apollonius_graph_filtered_traits_2
(Apollonius_graph_filtered_traits_2<CK,CM,EK,EM,FK,FM> other);
/*!
Assignment
operator.
*/
Apollonius_graph_filtered_traits_2<CK,CM,EK,EM,FK,FM> operator=(other);
/// @}
}; /* end Apollonius_graph_filtered_traits_2 */
} /* end namespace CGAL */

View File

@ -0,0 +1,231 @@
namespace CGAL {
/*!
\ingroup PkgApolloniusGraph2Ref
We provide an alternative to the class
`Apollonius_graph_2<Gt,Agds>` for the dynamic
construction of the Apollonius graph. The `Apollonius_graph_hierarchy_2` class maintains
a hierarchy of Apollonius graphs. The bottom-most level of the
hierarchy contains the full Apollonius diagram. A site that
is in level \f$ i\f$, is in level \f$ i+1\f$ with probability \f$ 1/\alpha\f$
where \f$ \alpha > 1\f$ is some constant. The difference between the
`Apollonius_graph_2<Gt,Agds>` class and the
`Apollonius_graph_hierarchy_2` is on how the nearest neighbor location is done. Given a
point \f$ p\f$ the location is done as follows: at the top most level we
find the nearest neighbor of \f$ p\f$ as in the
`Apollonius_graph_2<Gt,Agds>` class. At every subsequent level \f$ i\f$
we use the nearest neighbor found at level \f$ i+1\f$ to find the nearest
neighbor at level \f$ i\f$. This is a variant of the corresponding
hierarchy for points found in \cgalCite{d-iirdt-98}.
The class has two template parameters which have essentially the same
meaning as in the `Apollonius_graph_2<Gt,Agds>` class.
\tparam Gt is the geometric traits class and must be a model of `ApolloniusGraphTraits_2`.
\tparam Agds is the Apollonius graph data structure and must be a model of `ApolloniusGraphDataStructure_2`
whose vertex and face must be models of `ApolloniusGraphHierarchyVertexBase_2` and `TriangulationFaceBase_2`, respectively.
It defaults to:
\code
CGAL::Triangulation_data_structure_2<
CGAL::Apollonius_graph_hierarchy_vertex_base_2<CGAL::Apollonius_graph_vertex_base_2<Gt,true> >,
CGAL::Triangulation_face_base_2<Gt> >
\endcode
\cgalHeading{Heritage}
The `Apollonius_graph_hierarchy_2` class derives publicly from the
`Apollonius_graph_2<Gt,Agds>` class. The interface is
the same with its base class. In the sequel only the methods
overridden are documented.
`Apollonius_graph_hierarchy_2` does not introduce other types than those introduced by
its base class `Apollonius_graph_2<Gt,Agds>`.
\sa `CGAL::Apollonius_graph_2<Gt,Agds>`
\sa `CGAL::Apollonius_graph_traits_2<K,Method_tag>`
\sa `CGAL::Apollonius_graph_filtered_traits_2<CK,CM,EK,EM,FK,FM>`
*/
template< typename Gt, typename Agds >
class Apollonius_graph_hierarchy_2 : public CGAL::Apollonius_graph_2<Gt,Agds> {
public:
/// \name Creation
/// @{
/*!
Creates an hierarchy of Apollonius graphs using `gt` as
geometric traits.
*/
Apollonius_graph_hierarchy_2(Gt gt=Gt());
/*!
Creates an Apollonius graph hierarchy using
`gt` as geometric traits and inserts all sites in the
range [`first`, `beyond`).
*/
template< class Input_iterator >
Apollonius_graph_hierarchy_2(Input_iterator first, Input_iterator beyond, Gt gt=Gt());
/*!
Copy constructor. All faces, vertices, and inter-level pointers
are duplicated. After the construction, `agh` and `other` refer
to two different Apollonius graph hierarchies: if
`other` is modified, `agh` is not.
*/
Apollonius_graph_hierarchy_2(const Apollonius_graph_hierarchy_2<Gt,Agds>& other);
/*!
Assignment. All faces, vertices and inter-level pointers
are duplicated. After the construction, `agh` and `other` refer
to two different Apollonius graph hierarchies: if
`other` is modified, `agh` is not.
*/
Apollonius_graph_hierarchy_2<Gt,Agds>
operator=(Apollonius_graph_hierarchy_2<Gt,Agds>
other);
/// @}
/// \name Insertion
/// @{
/*!
Inserts the sites in the range
[`first`,`beyond`). The number of sites in the range
[`first`, `beyond`) is returned.
\pre `Input_iterator` must be a model of `InputIterator` and its value type must be `Site_2`.
*/
template< class Input_iterator >
unsigned int insert(Input_iterator first, Input_iterator beyond);
/*!
Inserts the
site `s` in the Apollonius graph hierarchy. If `s`
is visible then the vertex handle of `s` is returned, otherwise
`Vertex_handle(nullptr)` is returned.
*/
Vertex_handle insert(const Site_2& s);
/*!
Inserts `s` in the Apollonius graph hierarchy using the
site associated with `vnear` as
an estimate for the nearest neighbor of the center of `s`.
If `s` is visible then the vertex handle of `s` is
returned, otherwise `Vertex_handle(nullptr)` is returned.
A call to this method is equivalent to `agh.insert(s);` and it has
been added for the sake of conformity with the interface of the
`Apollonius_graph_2<Gt,Agds>` class.
*/
Vertex_handle insert(const Site_2& s, Vertex_handle vnear);
/// @}
/// \name Removal
/// @{
/*!
Removes the site
associated to the vertex handle `v` from the Apollonius
graph hierarchy.
\pre `v` must correspond to a valid finite vertex of the Apollonius graph hierarchy.
*/
void remove(Vertex_handle v);
/// @}
/// \name Nearest Neighbor Location
/// @{
/*!
Finds the nearest neighbor of the point `p`. In other words it
finds the site whose Apollonius cell contains `p`. Ties are broken
arbitrarily and one of the nearest neighbors of `p` is
returned. If there are no visible sites in the Apollonius diagram
`Vertex_handle(nullptr)` is returned.
*/
Vertex_handle nearest_neighbor(const Point_2& p) const;
/*!
Finds the nearest neighbor of the point
`p`. If there are no visible sites in the Apollonius diagram
`Vertex_handle(nullptr)` is returned.
A call to this method is equivalent to
`agh.nearest_neighbor(p);` and it has been added for the sake of
conformity with the interface of the
`Apollonius_graph_2<Gt,Agds>` class.
*/
Vertex_handle nearest_neighbor(const Point_2& p, Vertex_handle vnear) const;
/// @}
/// \name I/O
/// @{
/*!
Writes the current
state of the Apollonius graph hierarchy to an output stream. In particular,
all visible and hidden sites are written as well as the
underlying combinatorial hierarchical data structure.
*/
void file_output(std::ostream& os) const;
/*!
Reads the state of the
Apollonius graph hierarchy from an input stream.
*/
void file_input(std::istream& is);
/*!
Writes the current state of the Apollonius graph hierarchy to an
output stream.
*/
std::ostream& operator<<(std::ostream& os, Apollonius_graph_hierarchy_2<Gt,Agds> agh) const;
/*!
Reads the state of the Apollonius graph hierarchy from an input stream.
*/
std::istream& operator>>(std::istream& is, Apollonius_graph_hierarchy_2<Gt,Agds> agh);
/// @}
/// \name Validity Check
/// @{
/*!
Checks the validity of the Apollonius graph hierarchy. If
`verbose` is `true` a short message is sent to
`std::cerr`. If `level` is 0, the data structure at all levels
is validated, as well as the inter-level pointers. If `level` is
1, then the data structure at all levels is validated, the inter-level
pointers are validated and all levels of the Apollonius graph
hierarchy are also validated. Negative values of `level` always
return `true`, and values greater than 1 are equivalent to
`level` being 1.
*/
bool is_valid(bool verbose = false, int level = 1) const;
/// @}
/// \name Miscellaneous
/// @{
/*!
Clears all contents of the Apollonius graph
hierarchy.
*/
void clear();
/*!
The Apollonius graph hierarchies `other` and `agh` are
swapped. `agh.swap(other)` should be preferred to `agh = other`
or to `agh(other)` if `other` is deleted afterwards.
*/
void swap(Apollonius_graph_hierarchy_2<Gt,Agds>& other);
/// @}
}; /* end Apollonius_graph_hierarchy_2 */
} /* end namespace CGAL */

View File

@ -0,0 +1,49 @@
namespace CGAL {
/*!
\ingroup PkgApolloniusGraph2Ref
The class `Apollonius_graph_hierarchy_vertex_base_2` provides a model for the
`ApolloniusGraphHierarchyVertexBase_2` concept, which is the
vertex base required by the
`Apollonius_graph_hierarchy_2<Gt,Agds>` class. The class
`Apollonius_graph_hierarchy_vertex_base_2` is templated by a class `Agvb` which must be a model
of the `ApolloniusGraphVertexBase_2` concept.
\cgalModels `ApolloniusGraphHierarchyVertexBase_2`
\sa `CGAL::Apollonius_graph_vertex_base_2<Gt,StoreHidden>`
\sa `CGAL::Triangulation_data_structure_2<Vb,Fb>`
\sa `CGAL::Apollonius_graph_hierarchy_2<Gt,Agds>`
*/
template< typename Agvb >
class Apollonius_graph_hierarchy_vertex_base_2 : Agvb {
public:
/// \name Creation
/// @{
/*!
%Default constructor.
*/
Apollonius_graph_hierarchy_vertex_base_2();
/*!
Constructs a vertex associated with the site `s` and
embedded at the center of `s`.
*/
Apollonius_graph_hierarchy_vertex_base_2(const Site_2& s);
/*!
Constructs a vertex associated with
the site `s`, embedded at the center of `s`,
and pointing to the face associated with the face
handle `f`.
*/
Apollonius_graph_hierarchy_vertex_base_2(const Site_2& s, Face_handle f);
/// @}
}; /* end Apollonius_graph_hierarchy_vertex_base_2 */
} /* end namespace CGAL */

View File

@ -0,0 +1,54 @@
namespace CGAL {
/*!
\ingroup PkgApolloniusGraph2Ref
The class `Apollonius_graph_traits_2` provides a model for the
`ApolloniusGraphTraits_2` concept.
This class has two template parameters. The first template parameter
must be a model of the `Kernel` concept. The second template
parameter corresponds to how predicates are evaluated. There are two
predefined possible values for `Method_tag`, namely
`CGAL::Field_with_sqrt_tag` and `CGAL::Integral_domain_without_division_tag`. The first one
must be used when the number type used in the representation supports
the exact evaluation of signs of expressions involving all four basic
operations and square roots, whereas the second one requires the exact
evaluation of signs of ring-type expressions, i.e., expressions
involving only additions, subtractions and multiplications. The
default value for `Method_tag` is `CGAL::Integral_domain_without_division_tag`.
The way the predicates are evaluated is discussed in
\cgalCite{cgal:ke-ppawv-02}, \cgalCite{cgal:ke-rctac-03}.
\cgalModels `ApolloniusGraphTraits_2`
\sa `CGAL::Apollonius_graph_2<Gt,Agds>`
\sa `CGAL::Apollonius_graph_filtered_traits_2<CK,CM,EK,EM,FK,FM>`
*/
template< typename K, typename Method_tag >
class Apollonius_graph_traits_2 {
public:
/// \name Creation
/// @{
/*!
%Default constructor.
*/
Apollonius_graph_traits_2<K,Method_tag>();
/*!
Copy constructor.
*/
Apollonius_graph_traits_2<K,Method_tag>(const Apollonius_graph_traits_2<K,Method_tag>& other);
/*!
Assignment operator.
*/
Apollonius_graph_traits_2<K,Method_tag>
operator=(const Apollonius_graph_traits_2<K,Method_tag>& other);
/// @}
}; /* end Apollonius_graph_traits_2 */
} /* end namespace CGAL */

View File

@ -0,0 +1,54 @@
namespace CGAL {
/*!
\ingroup PkgApolloniusGraph2Ref
The class `Apollonius_graph_vertex_base_2` provides a model for the
`ApolloniusGraphVertexBase_2` concept which is the vertex base
required by the `ApolloniusGraphDataStructure_2` concept. The
class `Apollonius_graph_vertex_base_2` has two template arguments, the first being the
geometric traits of the Apollonius graph and should be a model of the
concept `ApolloniusGraphTraits_2`. The second is a Boolean which
controls whether hidden sites are actually stored. Such a
control is important if the user is not interested in hidden sites
and/or if only insertions are made, in which case no hidden
site can become visible. If `StoreHidden` is set to
`true`, hidden sites are stored, otherwise they are
discarded. By default `StoreHidden` is set to `true`.
\cgalModels `ApolloniusGraphVertexBase_2`
\sa `CGAL::Triangulation_data_structure_2<Vb,Fb>`
\sa `CGAL::Apollonius_graph_hierarchy_vertex_base_2<Gt>`
*/
template< typename Gt, typename StoreHidden >
class Apollonius_graph_vertex_base_2 {
public:
/// \name Creation
/// @{
/*!
%Default constructor.
*/
Apollonius_graph_vertex_base_2();
/*!
Constructs a vertex associated with the site `s` and
embedded at the center of `s`.
*/
Apollonius_graph_vertex_base_2(const Site_2& s);
/*!
Constructs a vertex associated with
the site `s`, embedded at the center of `s`,
and pointing to the face associated with the face
handle `f`.
*/
Apollonius_graph_vertex_base_2(const Site_2& s, Face_handle f);
/// @}
}; /* end Apollonius_graph_vertex_base_2 */
} /* end namespace CGAL */

View File

@ -0,0 +1,76 @@
namespace CGAL {
/*!
\ingroup PkgApolloniusGraph2Ref
The class `Apollonius_site_2` is a model for the concept
`ApolloniusSite_2`. It is parametrized by a template parameter
`K` which must be a model of the `Kernel` concept.
\cgalModels `ApolloniusSite_2`
\cgalHeading{Types}
The class `Apollonius_site_2` does not introduce any types in addition to the
concept `ApolloniusSite_2`.
\cgalHeading{I/O}
The I/O operators are defined for `iostream`.
The information output in the `iostream` is: the point of the
Apollonius site and its weight.
\sa `CGAL::Qt_widget`
\sa `CGAL::Apollonius_graph_traits_2<K,Method_tag>`
\sa `CGAL::Apollonius_graph_filtered_traits_2<CK,CM,EK,EM,FK,FM>`
*/
template< typename K >
class Apollonius_site_2 {
public:
/// \name Creation
/// @{
/*!
*/
Apollonius_site_2(Point_2 p=Point_2(), Weight w= Weight(0));
/*!
Copy constructor.
*/
Apollonius_site_2(const Apollonius_site_2<K>& other);
/// @}
}; /* end Apollonius_site_2 */
/*!
Inserts the
Apollonius site `s` into the stream `os`.
\note Included through `CGAL/IO/Qt_widget_Apollonius_site_2.h`.
\pre The insert operator must be defined for `Point_2` and `Weight`.
\relates Apollonius_site_2
*/
std::ostream& operator<<(std::ostream& os, const Apollonius_site_2<K>& s) const;
/*!
Reads an Apollonius site from the stream `is` and assigns it
to `s`.
\note Included through `CGAL/IO/Qt_widget_Apollonius_site_2.h`.
\pre The extract operator must be defined for `Point_2` and `Weight`.
\relates Apollonius_site_2
*/
std::istream& operator>>(std::istream& is, const Apollonius_site_2<K>& s);
/*!
Inserts the Apollonius site `s` into the `Qt_widget` stream `w`.
\note Included through `CGAL/IO/Qt_widget_Apollonius_site_2.h`.
\pre The insert operator must be defined for `K::Circle_2`.
\relates Apollonius_site_2
*/
Qt_widget& operator<<(Qt_widget& w, const Apollonius_site_2<K>& s) const;
} /* end namespace CGAL */

View File

@ -0,0 +1,68 @@
/*!
\ingroup PkgApolloniusGraph2Concepts
\cgalConcept
The concept `ApolloniusGraphDataStructure_2` refines the concept
`TriangulationDataStructure_2`. In addition
it provides two methods for the insertion and removal of a degree 2
vertex in the data structure. The insertion method adds a new vertex
to the specified edge, thus creating two new edges. Moreover, it
creates two new faces that have the two newly created edges in
common (see figure below). The removal method performs the reverse
operation.
\image html insert_degree_2.png
\image latex insert_degree_2.png
<center><b>Insertion and removal of degree 2 vertices. Left to right:
The edge `(f,i)` is replaced by two edges by means of inserting a
vertex `v` on the edge. The faces \f$ f_1\f$ and \f$ f_2\f$ are
created. Right to left: the faces \f$ f_1\f$ and \f$ f_2\f$ are
destroyed. The vertex `v` is deleted and its two adjacent edges are
merged. </b></center>
We only describe the additional requirements with respect to the
`TriangulationDataStructure_2` concept.
\cgalRefines `TriangulationDataStructure_2`
\cgalHasModel `CGAL::Triangulation_data_structure_2<Vb,Fb>`
\sa `TriangulationDataStructure_2`
\sa `ApolloniusGraphVertexBase_2`
\sa `TriangulationFaceBase_2`
*/
class ApolloniusGraphDataStructure_2 {
public:
/// \name Insertion
/// @{
/*!
inserts a degree two vertex and two faces adjacent to it that have two common edges.
The edge defined by the face handle `f` and the integer `i` is duplicated. It returns a handle
to the vertex created.
*/
Vertex_handle insert_degree_2(Face_handle f, int i);
/// @}
/// \name Removal
/// @{
/*!
Removes a degree 2
vertex and the two faces adjacent to it. The two edges of the star of
`v` that are not incident to it are collapsed.
\pre The degree of `v` must be equal to 2.
*/
void remove_degree_2(Vertex_handle v);
/// @}
}; /* end ApolloniusGraphDataStructure_2 */

View File

@ -0,0 +1,85 @@
/*!
\ingroup PkgApolloniusGraph2Concepts
\cgalConcept
The vertex of an Apollonius graph
included in an Apollonius graph hierarchy has to provide
some pointers to the corresponding vertices in the
graphs of the next and preceding levels.
Therefore, the concept `ApolloniusGraphHierarchyVertexBase_2`
refines the concept `ApolloniusGraphVertexBase_2`, by
adding two vertex handles to the corresponding vertices for the
next and previous level graphs.
\cgalRefines `ApolloniusGraphVertexBase_2`
\cgalHeading{Types}
`ApolloniusGraphHierarchyVertexBase_2` does not introduce any
types in addition to those of `ApolloniusGraphVertexBase_2`.
\cgalHasModel `CGAL::Apollonius_graph_hierarchy_vertex_base_2<CGAL::Apollonius_graph_vertex_base_2<Gt,StoreHidden> >`
\sa `ApolloniusGraphDataStructure_2`
\sa `CGAL::Apollonius_graph_hierarchy_2<Gt,Agds>`
\sa `CGAL::Triangulation_data_structure_2<Vb,Fb>`
*/
class ApolloniusGraphHierarchyVertexBase_2 {
public:
/// \name Creation
/// @{
/*!
%Default constructor.
*/
ApolloniusGraphHierarchyVertexBase_2();
/*!
Constructs a vertex associated with the site `s` and
embedded at the center of `s`.
*/
ApolloniusGraphHierarchyVertexBase_2(Site_2 s).;
/*!
Constructs a vertex associated with
the site `s`, embedded at the center of `s`,
and pointing to face `f`.
*/
ApolloniusGraphHierarchyVertexBase_2(Site_2 s, Face_handle f).;
/// @}
/// \name Operations
/// @{
/*!
Returns a handle to the corresponding
vertex of the next level Apollonius graph. If such a vertex does not
exist `Vertex_handle(nullptr)` is returned.
*/
Vertex_handle up();
/*!
Returns a handle to the corresponding
vertex of the previous level Apollonius graph.
*/
Vertex_handle down();
/*!
Sets the handle for the
vertex of the next level Apollonius graph.
*/
void set_up(Vertex_handle u);
/*!
Sets the handle for the
vertex of the previous level Apollonius graph;
*/
void set_down(Vertex_handle d);
/// @}
}; /* end ApolloniusGraphHierarchyVertexBase_2 */

View File

@ -0,0 +1,397 @@
/*!
\ingroup PkgApolloniusGraph2Concepts
\cgalConcept
\cgalRefines `TriangulationTraits_2`
The concept `ApolloniusGraphTraits_2` provides the traits
requirements for the `Apollonius_graph_2` class. In particular,
it provides a type `Site_2`, which must be a model of the concept
`ApolloniusSite_2`. It also provides
constructions for sites and several function object
types for the predicates.
\cgalHasModel `CGAL::Apollonius_graph_traits_2<K,Method_tag>`
\cgalHasModel `CGAL::Apollonius_graph_filtered_traits_2<CK,CM,EK,EM,FK,FM>`
\sa `CGAL::Apollonius_graph_2<Gt,Agds>`
\sa `CGAL::Apollonius_graph_traits_2<K,Method_tag>`
\sa `CGAL::Apollonius_graph_filtered_traits_2<CK,CM,EK,EM,FK,FM>`
*/
class ApolloniusGraphTraits_2 {
public:
/// \name Types
/// @{
/*!
A type for a point.
*/
typedef unspecified_type Point_2;
/*!
A type for an Apollonius site. Must be a model
of the concept `ApolloniusSite_2`.
*/
typedef unspecified_type Site_2;
/*!
A type for a line. Only required if access to
the dual of the Apollonius graph is required or if the primal
or dual diagram are inserted in a stream.
*/
typedef unspecified_type Line_2;
/*!
A type for a ray. Only required if access to
the dual of the Apollonius graph is required or if the primal
or dual diagram are inserted in a stream.
*/
typedef unspecified_type Ray_2;
/*!
A type for a segment. Only required if access to
the dual of the Apollonius graph is required or if the primal
or dual diagram are inserted in a stream.
*/
typedef unspecified_type Segment_2;
/*!
A type representing different types of objects
in two dimensions, namely: `Point_2`, `Site_2`,
`Line_2`, `Ray_2` and `Segment_2`.
*/
typedef unspecified_type Object_2;
/*!
A type for the field number type of sites.
*/
typedef unspecified_type FT;
/*!
A type for the ring number type of sites.
*/
typedef unspecified_type RT;
/*!
Must provide `template <class T> bool operator() ( T& t,
Object_2 o)` which assigns `o` to `t` if `o` was
constructed from an object of type `T`. Returns
`true`, if the assignment was possible.
*/
typedef unspecified_type Assign_2;
/*!
Must provide `template <class T>
Object_2 operator()( T t)` that constructs an object of type
`Object_2` that contains `t` and returns it.
*/
typedef unspecified_type Construct_object_2;
/*!
A constructor for a point of the Apollonius diagram equidistant
from three sites. Must provide
`Point_2 operator()(Site_2 s1, Site_2 s2, Site_2 s3)`, which
constructs a point equidistant from the sites `s1`, `s2` and
`s3`.
*/
typedef unspecified_type Construct_Apollonius_vertex_2;
/*!
A constructor for
a dual Apollonius site (a site whose center is a
vertex of the Apollonius diagram and its weight is the common
distance of its center from the three defining sites).
Must provide `Site_2 operator()(Site_2 s1,
Site_2 s2, Site_2 s3)`, which constructs a
dual site whose center \f$ c\f$ is equidistant from `s1`, `s2` and
`s3`, and its weight is equal to the (signed) distance of \f$ c\f$
from `s1` (or `s2` or `s3`).
Must also provide `Line_2 operator()(Site_2 s1, Site_2 s2)`, which
constructs a line bitangent to `s1` and `s2`. This line is the
dual site of `s1`, `s2` and the site at infinity; it can be
viewed as a dual Apollonius site whose center is at infinity
and its weight is infinite.
*/
typedef unspecified_type Construct_Apollonius_site_2;
/*!
A predicate object type. Must
provide `Comparison_result operator()(Site_2 s1,
Site_2 s2)`, which compares the \f$ x\f$-coordinates of the centers of
`s1` and `s2`.
*/
typedef unspecified_type Compare_x_2;
/*!
A predicate object type. Must
provide `Comparison_result operator()(Site_2 s1,
Site_2 s2)`, which compares the \f$ y\f$-coordinates of the centers of
`s1` and `s2`.
*/
typedef unspecified_type Compare_y_2;
/*!
A predicate object type. Must
provide `Comparison_result operator()(Site_2 s1,
Site_2 s2)`, which compares the weights of `s1`
and `s2`.
*/
typedef unspecified_type Compare_weight_2;
/*!
A predicate object type. Must
provide `Orientation operator()(Site_2 s1,
Site_2 s2, Site_2 s3)`, which performs the
usual orientation test for the centers of the three sites
`s1`, `s2` and `s3`.
Must also provide `Orientation operator()(Site_2 s1, Site_2 s2,
Site_2 s3, Site_2 p1, Site_2 p2)`,
which performs the usual orientation test for the Apollonius vertex of
`s1`, `s2`, `s3` and the centers of `p1` and
`p2`.
\pre the Apollonius vertex of `s1`, `s2` and `s3` must exist.
*/
typedef unspecified_type Orientation_2;
/*!
A predicate object type. Must
provide `bool operator()(Site_2 s1,
Site_2 s2)`, which returns `true` if the circle
corresponding to `s2` is contained in the closure of the disk
corresponding to `s1`, `false` otherwise.
*/
typedef unspecified_type Is_hidden_2;
/*!
A predicate object type.
Must provide `Oriented_side operator()(Site_2 s1,
Site_2 s2, Point_2 p)`, which returns
the oriented side of the bisector of `s1` and `s2` that
contains `p`. Returns `ON_POSITIVE_SIDE` if `p` lies in
the half-space of `s1` (i.e., `p` is closer to `s1` than
`s2`); returns `ON_NEGATIVE_SIDE` if `p` lies in the
half-space of `s2`; returns `ON_ORIENTED_BOUNDARY` if `p`
lies on the bisector of `s1` and `s2`.
*/
typedef unspecified_type Oriented_side_of_bisector_2;
/*!
A predicate object type.
Must provide `Sign operator()(Site_2 s1, Site_2
s2, Site_2 s3, Site_2 q)`, which
returns the sign of the distance of `q` from the dual Apollonius
site of `s1`, `s2`, `s3`.
\pre the dual Apollonius site of `s1`, `s2`, `s3` must exist.
Must also provide `Sign operator()(Site_2 s1,
Site_2 s2, Site_2 q)`, which returns the sign of the distance of
`q` from the bitangent line of `s1`, `s2` (a degenerate
dual Apollonius site, with its center at infinity).
*/
typedef unspecified_type Vertex_conflict_2;
/*!
A predicate object type.
Must provide `bool operator()(Site_2 s1, Site_2 s2, Site_2 s3, Site_2 s4, Site_2 q, bool b)`.
The sites `s1`, `s2`, `s3` and `s4` define an Apollonius edge that lies on the
bisector of `s1` and `s2` and has as endpoints the Apollonius
vertices defined by the triplets `s1`, `s2`, `s3` and
`s1`, `s4` and `s2`. The Boolean `b` denotes if the
two Apollonius vertices are in conflict with the site
`q` (in which case `b` should be `true`, otherwise
`false`). In case that `b` is `true`, the predicate
returns `true` if and only if the entire Apollonius edge is in
conflict with `q`. If `b` is `false`, the predicate returns
`false` if and only if `q` is not in conflict with the
Apollonius edge.
\pre the Apollonius vertices of `s1`, `s2`, `s3`, and `s1`, `s4`, `s2` must exist.
Must also provide `bool operator()(Site_2 s1,
Site_2 s2, Site_2 s3, Site_2 q, bool b)`. The
sites `s1`, `s2`, `s3` and the site at infinity
\f$ s_\infty\f$ define an Apollonius edge that lies on the bisector of
`s1` and `s2` and has as endpoints the Apollonius vertices
defined by the triplets `s1`, `s2`, `s3` and `s1`,
\f$ s_\infty\f$ and `s2` (the second Apollonius vertex is actually at
infinity). The Boolean `b` denotes if the two Apollonius vertices
are in conflict with the site `q` (in which case `b`
should be `true`, otherwise `false`).
In case that `b` is `true`, the predicate
returns `true` if and only if the entire Apollonius edge is in
conflict with `q`. If `b` is `false`, the predicate returns
`false` if and only if `q` is not in conflict with the
Apollonius edge.
\pre the Apollonius vertex of `s1`, `s2`, `s3` must exist.
Must finally provide `bool operator()(Site_2 s1,
Site_2 s2, Site_2 q, bool b)`. The
sites `s1`, `s2` and the site at infinity
\f$ s_\infty\f$ define an Apollonius edge that lies on the bisector of
`s1` and `s2` and has as endpoints the Apollonius vertices
defined by the triplets `s1`, `s2`, \f$ s_\infty\f$ and `s1`,
\f$ s_\infty\f$ and `s2` (both Apollonius vertices are actually at
infinity). The Boolean `b` denotes if the two Apollonius vertices
are in conflict with the site `q` (in which case `b`
should be `true`, otherwise `false`).
In case that `b` is `true`, the predicate
returns `true` if and only if the entire Apollonius edge is in
conflict with `q`. If `b` is `false`, the predicate returns
`false` if and only if `q` is not in conflict with the
Apollonius edge.
*/
typedef unspecified_type Finite_edge_interior_conflict_2;
/*!
A predicate
object type. Must provide `bool operator()(Site_2 s1,
Site_2 s2, Site_2 s3, Site_2 q, bool b)`. The
sites \f$ s_\infty\f$, `s1`, `s2` and `s3` define an
Apollonius edge that lies on the bisector of \f$ s_\infty\f$ and `s1`
and has as endpoints the Apollonius vertices defined by the triplets
\f$ s_\infty\f$, `s1`, `s2` and \f$ s_\infty\f$, `s3` and
`s1`. The Boolean `b` denotes if the two Apollonius vertices
are in conflict with the site `q` (in which case `b`
should be `true`, otherwise `false`.
In case that `b` is `true`, the predicate
returns `true` if and only if the entire Apollonius edge is in
conflict with `q`. If `b` is `false`, the predicate returns
`false` if and only if `q` is not in conflict with the
Apollonius edge.
*/
typedef unspecified_type Infinite_edge_interior_conflict_2;
/*!
A predicate object type.
Must provide `bool operator()(Site_2 s1, Site_2
s2, Site_2 s3, Site_2 s4)`. It returns `true` if
the Apollonius edge defined by `s1`, `s2`, `s3` and
`s4` is degenerate, `false` otherwise. An Apollonius edge is
called degenerate if its two endpoints coincide.
\pre the Apollonius vertices of `s1`, `s2`, `s3`, and `s1`, `s4`, `s2` must exist.
*/
typedef unspecified_type Is_degenerate_edge_2;
/// @}
/// \name Creation
/// @{
/*!
Default constructor.
*/
ApolloniusGraphTraits_2();
/*!
Copy constructor.
*/
ApolloniusGraphTraits_2(ApolloniusGraphTraits_2 other);
/*!
Assignment operator.
*/
ApolloniusGraphTraits_2 operator=(ApolloniusGraphTraits_2 other);
/// @}
/// \name Access to predicate objects
/// @{
/*!
*/
Compare_x_2 compare_x_2_object();
/*!
*/
Compare_y_2 compare_y_2_object();
/*!
*/
Compare_weight_2 compare_weight_2_object();
/*!
*/
Orientation_2 orientation_2_object();
/*!
*/
Is_hidden_2 is_hidden_2_object();
/*!
*/
Oriented_side_of_bisector_2
oriented_side_of_bisector_test_2_object();
/*!
*/
Vertex_conflict_2 vertex_conflict_2_object();
/*!
*/
Finite_edge_interior_conflict_2
finite_edge_interior_conflict_2_object();
/*!
*/
Infinite_edge_interior_conflict_2
infinite_edge_interior_conflict_2_object();
/*!
*/
Is_degenerate_edge_2 is_degenerate_edge_2_object();
/// @}
/// \name Access to constructor objects
/// @{
/*!
*/
Construct_object_2
construct_object_2_object();
/*!
*/
Construct_Apollonius_vertex_2
construct_Apollonius_vertex_2_object();
/*!
*/
Construct_Apollonius_site_2
construct_Apollonius_site_2_object();
/// @}
/// \name Access to other objects
/// @{
/*!
*/
Assign_2 assign_2_object();
/// @}
}; /* end ApolloniusGraphTraits_2 */

View File

@ -0,0 +1,166 @@
/*!
\ingroup PkgApolloniusGraph2Concepts
\cgalConcept
The concept `ApolloniusGraphVertexBase_2` describes the
requirements for the vertex base class of the
`ApolloniusGraphDataStructure_2` concept. A vertex stores an
Apollonius site and provides access to one of its incident faces
through a `Face_handle`. In addition, it maintains a container of
sites. The container stores the hidden sites related to the vertex.
\cgalRefines `TriangulationVertexBase_2`
\cgalHasModel `CGAL::Apollonius_graph_vertex_base_2<Gt,StoreHidden>`
\sa `ApolloniusGraphDataStructure_2`
\sa `CGAL::Apollonius_graph_2<Gt,Agds>`
\sa `CGAL::Triangulation_data_structure_2<Vb,Fb>`
*/
class ApolloniusGraphVertexBase_2 {
public:
/// \name Types
/// @{
/*!
A type for the geometric traits that defines
the site stored. \pre The type `Geom_traits` must define the type `Site_2`.
*/
typedef unspecified_type Geom_traits;
/*!
A Boolean that indicates if
hidden sites are actually stored or not. Its value is `true` if
hidden sites are stored, `false` otherwise.
*/
typedef unspecified_type Store_hidden;
/*!
A type for the site stored.
\pre This type must coincide with the type `Geom_traits::Site_2`.
*/
typedef unspecified_type Site_2;
/*!
A type for the
Apollonius graph data structure, to which the vertex belongs to.
*/
typedef unspecified_type Apollonius_graph_data_structure_2;
/*!
A type for the vertex handle of the
Apollonius graph data structure.
*/
typedef unspecified_type Vertex_handle;
/*!
A type for the face handle of the
Apollonius graph data structure.
*/
typedef unspecified_type Face_handle;
/*!
An iterator that
iterates over the hidden sites in the hidden sites
container of the vertex.
\pre Must be a model of `Iterator`.
*/
typedef unspecified_type Hidden_sites_iterator;
/// @}
/// \name Creation
/// @{
/*!
%Default constructor.
*/
ApolloniusGraphVertexBase_2();
/*!
Constructs a vertex associated with the Apollonius site `s` and
embedded at the center of `s`.
*/
ApolloniusGraphVertexBase_2(Site_2 s);
/*!
Constructs a vertex associated with
the site `s`, embedded at the center of `s`,
and pointing to the face associated with the face handle `f`.
*/
ApolloniusGraphVertexBase_2(Site_2 s,
Face_handle f);
/// @}
/// \name Access Functions
/// @{
/*!
Returns the Apollonius site.
*/
Site_2 site();
/*!
Returns a handle to an incident face.
*/
Face_handle face();
/*!
Returns the number of hidden sites in the hidden
sites container.
*/
unsigned int number_of_hidden_sites();
/*!
Starts at an arbitrary hidden site.
*/
Hidden_sites_iterator
hidden_sites_begin();
/*!
Past-the-end iterator.
*/
Hidden_sites_iterator hidden_sites_end();
/// @}
/// \name Setting and unsetting
/// @{
/*!
Sets the Apollonius site.
*/
void set_site(Site_2 s);
/*!
Sets the incident face.
*/
void set_face(Face_handle f);
/*!
Adds a hidden site to the container of hidden sites.
*/
void add_hidden_site(Site_2 s);
/*!
Clears the container of hidden sites.
*/
void clear_hidden_sites_container();
/// @}
/// \name Checking
/// @{
/*!
Performs any required tests on a vertex.
*/
bool is_valid(bool verbose, int level) const;
/// @}
}; /* end ApolloniusGraphVertexBase_2 */

View File

@ -0,0 +1,78 @@
/*!
\ingroup PkgApolloniusGraph2Concepts
\cgalConcept
The concept `ApolloniusSite_2` provides the requirements for an
Apollonius site class.
\sa `ApolloniusGraphTraits_2`
\sa `CGAL::Apollonius_site_2<K>`
\sa `CGAL::Apollonius_graph_traits_2<K,Method_tag>`
\sa `CGAL::Apollonius_graph_filtered_traits_2<CK,CM,EK,EM,FK,FM>`
*/
class ApolloniusSite_2 {
public:
/// \name Types
/// @{
/*!
The point type.
*/
typedef unspecified_type Point_2;
/*!
The field number type.
*/
typedef unspecified_type FT;
/*!
The ring number type.
*/
typedef unspecified_type RT;
/*!
The weight type.
\pre It must be the same as `FT`.
*/
typedef unspecified_type Weight;
/// @}
/// \name Creation
/// @{
/*!
*/
ApolloniusSite2(Point_2 p=Point_2(), Weight w= Weight(0));
/*!
Copy constructor.
*/
ApolloniusSite_2(ApolloniusSite_2 other);
/// @}
/// \name Access Functions
/// @{
/*!
Returns the center of the Apollonius
site.
*/
Point_2 point() const;
/*!
Returns the weight of the
Apollonius site.
*/
Weight weight() const;
/// @}
}; /* end ApolloniusSite_2 */

View File

@ -0,0 +1,9 @@
@INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS}
PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - 2D Apollonius Graphs (Delaunay Graphs of Disks)"
EXCLUDE_SYMBOLS += Agvb

View File

@ -0,0 +1,63 @@
/// \defgroup PkgApolloniusGraph2Ref 2D Apollonius Graphs (Delaunay Graphs of Disks) Reference
/// \defgroup PkgApolloniusGraph2Concepts Concepts
/// \ingroup PkgApolloniusGraph2Ref
/*!
\addtogroup PkgApolloniusGraph2Ref
\todo check generated documentation
\cgalPkgDescriptionBegin{2D Apollonius Graphs (Delaunay Graphs of Disks),PkgApolloniusGraph2}
\cgalPkgPicture{CircleVoronoi.png}
\cgalPkgSummaryBegin
\cgalPkgAuthors{Menelaos Karavelas and Mariette Yvinec}
\cgalPkgDesc{Algorithms for computing the Apollonius graph in two dimensions. The Apollonius graph is the dual of the Apollonius diagram, also known as the <I>additively weighted Voronoi diagram</I>. The latter can be thought of as the Voronoi diagram of a set of disks under the Euclidean metric, and it is a generalization of the standard Voronoi diagram for points. The algorithms provided are dynamic.}
\cgalPkgManuals{Chapter_2D_Apollonius_Graphs,PkgApolloniusGraph2Ref}
\cgalPkgSummaryEnd
\cgalPkgShortInfoBegin
\cgalPkgSince{3.0}
\cgalPkgDependsOn{\ref PkgTDS2}
\cgalPkgBib{cgal:ky-ag2}
\cgalPkgLicense{\ref licensesGPL "GPL"}
\cgalPkgDemo{2D Apollonius Graph,apollonius_graph_2.zip}
\cgalPkgShortInfoEnd
\cgalPkgDescriptionEnd
An Apollonius graph is the dual of the Apollonius diagram, also known
as the <I>additively weighted Voronoi diagram</I>. It is essentially the
Voronoi diagram of a set of disks, where the distance of a
point of the plane from a disk is defined as the Euclidean
distance of the point and the center of the circle, minus the radius
of the disk.
\cgal provides the class `CGAL::Apollonius_graph_2<Gt,Agds>` for
computing the 2D Apollonius graph. The two template parameters must be
models of the `ApolloniusGraphTraits_2` and
`ApolloniusGraphDataStructure_2` concepts. The first concept is
related to the geometric objects and predicates associated with
Apollonius graphs, whereas the second concept refers to the data
structure used to represent the Apollonius graph. The classes
`Apollonius_graph_traits_2<K,Method_tag>` and
`Triangulation_data_structure_2<Vb,Fb>` are models of the
aforementioned concepts.
\cgalClassifedRefPages
\cgalCRPSection{Concepts}
- `ApolloniusSite_2`
- `ApolloniusGraphTraits_2`
- `ApolloniusGraphDataStructure_2`
- `ApolloniusGraphVertexBase_2`
- `ApolloniusGraphHierarchyVertexBase_2`
\cgalCRPSection{Classes}
- `CGAL::Apollonius_graph_2<Gt,Agds>`
- `CGAL::Apollonius_site_2<K>`
- `CGAL::Apollonius_graph_traits_2<K,Method_tag>`
- `CGAL::Apollonius_graph_filtered_traits_2<CK,CM,EK,EM,FK,FM>`
- `CGAL::Apollonius_graph_vertex_base_2<Gt,StoreHidden>`
- `CGAL::Apollonius_graph_hierarchy_2<Gt,Agds>`
- `CGAL::Apollonius_graph_hierarchy_vertex_base_2<Agvb>`
*/

View File

@ -0,0 +1,10 @@
Manual
Kernel_23
STL_Extension
Algebraic_foundations
Circulator
Stream_support
Voronoi_diagram_2
Number_types
TDS_2
Triangulation_2

View File

@ -0,0 +1,6 @@
/*!
\example Apollonius_graph_2/ag2_exact_traits.cpp
\example Apollonius_graph_2/ag2_exact_traits_sqrt.cpp
\example Apollonius_graph_2/ag2_filtered_traits_no_hidden.cpp
\example Apollonius_graph_2/ag2_hierarchy.cpp
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -0,0 +1,75 @@
#FIG 3.2
Landscape
Center
Inches
Letter
100.00
Single
7
1200 2
6 1200 2100 4425 7050
6 1200 4200 1500 4425
4 1 0 50 0 1 18 0.0000 4 120 120 1275 4350 v\001
4 0 0 50 0 0 14 0.0000 4 150 105 1350 4425 0\001
-6
6 4125 4650 4425 4875
4 1 0 50 0 1 18 0.0000 4 120 120 4200 4800 v\001
4 0 0 50 0 0 14 0.0000 4 150 105 4275 4875 1\001
-6
1 3 0 1 0 0 50 0 20 0.000 1 0.0000 1500 4500 75 75 1500 4500 1575 4500
1 3 0 1 0 0 50 0 20 0.000 1 0.0000 2775 2400 75 75 2775 2400 2850 2400
1 3 0 1 0 0 50 0 20 0.000 1 0.0000 2775 6675 75 75 2775 6675 2850 6675
1 3 0 1 0 0 50 0 20 0.000 1 0.0000 4050 4500 75 75 4050 4500 4125 4500
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
1500 4500 4050 4500
2 3 0 2 0 7 52 0 -1 0.000 0 0 -1 0 0 5
2775 2400 1500 4500 2775 6675 4050 4500 2775 2400
4 1 0 50 0 1 18 0.0000 4 195 75 3000 2325 i\001
4 1 0 50 0 1 18 0.0000 4 255 75 2775 3825 f\001
4 1 0 50 0 1 18 0.0000 4 240 75 3000 6975 j\001
4 1 0 50 0 1 18 0.0000 4 180 120 2775 5325 g\001
-6
6 7650 2325 10875 6750
6 7650 4200 7950 4425
4 1 0 50 0 1 18 0.0000 4 120 120 7725 4350 v\001
4 0 0 50 0 0 14 0.0000 4 150 105 7800 4425 0\001
-6
6 10575 4650 10875 4875
4 1 0 50 0 1 18 0.0000 4 120 120 10650 4800 v\001
4 0 0 50 0 0 14 0.0000 4 150 105 10725 4875 1\001
-6
6 8850 4125 9150 4425
4 1 0 50 0 1 18 0.0000 4 255 75 8925 4350 f\001
4 0 0 50 0 0 14 0.0000 4 150 105 9000 4425 1\001
-6
6 8850 4650 9150 4950
4 1 0 50 0 1 18 0.0000 4 255 75 8925 4875 f\001
4 0 0 50 0 0 14 0.0000 4 150 105 9000 4950 2\001
-6
1 3 0 1 0 0 50 0 20 0.000 1 0.0000 9346 4494 75 75 9346 4494 9421 4494
1 3 0 1 0 0 50 0 20 0.000 1 0.0000 8025 4500 75 75 8025 4500 8100 4500
1 3 0 1 0 0 50 0 20 0.000 1 0.0000 9300 2400 75 75 9300 2400 9375 2400
1 3 0 1 0 0 50 0 20 0.000 1 0.0000 9300 6675 75 75 9300 6675 9375 6675
1 3 0 1 0 0 50 0 20 0.000 1 0.0000 10575 4500 75 75 10575 4500 10650 4500
2 1 0 2 0 7 51 0 -1 0.000 0 0 -1 0 0 2
8025 4500 10575 4500
2 3 0 2 0 7 52 0 -1 0.000 0 0 -1 0 0 5
9300 2400 8025 4500 9300 6675 10575 4500 9300 2400
3 0 0 2 0 7 50 0 -1 0.000 0 0 0 3
8025 4500 9300 5550 10575 4500
0.000 1.000 0.000
3 0 0 2 0 7 50 0 -1 0.000 0 0 0 3
8025 4500 9375 3450 10575 4500
0.000 1.000 0.000
4 1 0 50 0 1 18 0.0000 4 255 75 9300 3525 f\001
4 1 0 50 0 1 18 0.0000 4 180 120 9300 5625 g\001
4 1 0 50 0 1 18 0.0000 4 120 120 9525 4425 v\001
-6
2 1 0 4 0 7 50 0 -1 0.000 0 0 -1 1 0 2
2 1 4.00 240.00 480.00
4950 4275 7200 4275
2 1 0 4 0 7 50 0 -1 0.000 0 0 -1 1 0 2
2 1 4.00 240.00 480.00
7200 4725 4950 4725
4 1 0 50 0 1 14 0.0000 4 150 690 6450 5025 removal\001
4 1 0 50 0 1 14 0.0000 4 150 780 5625 4125 insertion\001

View File

@ -0,0 +1,18 @@
# Created by the script cgal_create_cmake_script
# This is the CMake script for compiling a CGAL application.
cmake_minimum_required(VERSION 3.1...3.20)
project(Apollonius_graph_2_Examples)
find_package(CGAL REQUIRED COMPONENTS Core)
include(${CGAL_USE_FILE})
# create a target per cppfile
file(
GLOB cppfiles
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
foreach(cppfile ${cppfiles})
create_single_source_cgal_program("${cppfile}")
endforeach()

View File

@ -0,0 +1,23 @@
This is the examples directory for the Apollonius_graph_2 package
There are 4 example programs in this directory. Each one of these is
aimed at describing a different usage for the Apollonius_graph_2
package. In particular:
* ag2_exact_traits.C: a very basic example. It uses an exact number
type that supports ring operations to achieve robustness.
* ag2_exact_traits_sqrt.C: it shows how to change the method the predicates
are evaluated. By default the predicates use only the operations +,-,*
and these are the only operations that is assumed they are exact. In
this example we show how to change that and how to define the traits
class so that the operations +,-,*,/,sqrt are used and are assumed
exact. Again an exact number type is used as the number type.
* ag2_filtered_traits_no_hidden.C: a variation of the first example. The
filtered traits are now used instead of and exact number type. We also
show how to use another parameter for the algorithm, namely the one
that indicates whether hidden weighted points are to be stored or not.
* ag2_hierarchy.C: same as the previous example except the fact that now
we store the hidden weighted points and on top of that we use a
hierarchy of Apollonius graphs.

View File

@ -0,0 +1,54 @@
// standard includes
#include <iostream>
#include <fstream>
#include <cassert>
// the number type
#include <CGAL/MP_Float.h>
// example that uses an exact number type
typedef CGAL::MP_Float NT;
// *** WARNING ***
// The use of a kernel based on an exact number type is highly inefficient.
// It is used in this example primarily for illustration purposes.
// In an efficiency critical context, and/or for the purposes of
// benchmarking the Apollonius_graph_filtered_traits_2<> class should
// be used.
// choose the kernel
#include <CGAL/Simple_cartesian.h>
typedef CGAL::Simple_cartesian<NT> Kernel;
// typedefs for the traits and the algorithm
#include <CGAL/Apollonius_graph_2.h>
#include <CGAL/Apollonius_graph_traits_2.h>
typedef CGAL::Apollonius_graph_traits_2<Kernel> Traits;
typedef CGAL::Apollonius_graph_2<Traits> Apollonius_graph;
int main()
{
std::ifstream ifs("data/sites.cin");
assert( ifs );
Apollonius_graph ag;
Apollonius_graph::Site_2 site;
// read the sites and insert them in the Apollonius graph
while ( ifs >> site ) {
ag.insert(site);
}
// validate the Apollonius graph
assert( ag.is_valid(true, 1) );
std::cout << std::endl;
return 0;
}

View File

@ -0,0 +1,71 @@
#include <CGAL/config.h>
// standard includes
#include <iostream>
#include <fstream>
#include <cassert>
#if defined(CGAL_USE_CORE) || defined(CGAL_USE_LEDA)
# include <CGAL/Exact_algebraic.h>
#endif
// *** WARNING ***
// The use of a kernel based on an exact number type is highly inefficient.
// It is used in this example primarily for illustration purposes.
// In an efficiency critical context, and/or for the purposes of
// benchmarking the Apollonius_graph_filtered_traits_2<> class should
// be used.
#if defined(CGAL_USE_CORE) || defined(CGAL_USE_LEDA)
// If LEDA is present use leda_real as the exact number type
// Otherwise if CORE is present use CORE's Expr as the exact number type
typedef CGAL::Exact_algebraic NT;
#else
// Otherwise just use double. This may cause numerical errors but it
// is still worth doing it to show how to define correctly the traits
// class
typedef double NT;
#endif
#include <CGAL/Simple_cartesian.h>
typedef CGAL::Simple_cartesian<NT> Kernel;
// typedefs for the traits and the algorithm
#include <CGAL/Apollonius_graph_2.h>
#include <CGAL/Apollonius_graph_traits_2.h>
// the traits class is now going to assume that the operations
// +,-,*,/ and sqrt are supported exactly
typedef
CGAL::Apollonius_graph_traits_2<Kernel,CGAL::Field_with_sqrt_tag> Traits;
typedef CGAL::Apollonius_graph_2<Traits> Apollonius_graph;
int main()
{
std::ifstream ifs("data/sites.cin");
assert( ifs );
Apollonius_graph ag;
Apollonius_graph::Site_2 site;
// read the sites and insert them in the Apollonius graph
while ( ifs >> site ) {
ag.insert(site);
}
// validate the Apollonius graph
assert( ag.is_valid(true, 1) );
std::cout << std::endl;
return 0;
}

View File

@ -0,0 +1,59 @@
// standard includes
#include <iostream>
#include <fstream>
#include <cassert>
// example that uses the filtered traits
// choose the representation
#include <CGAL/Simple_cartesian.h>
typedef CGAL::Simple_cartesian<double> Rep;
#include <CGAL/Apollonius_graph_2.h>
#include <CGAL/Triangulation_data_structure_2.h>
#include <CGAL/Apollonius_graph_vertex_base_2.h>
#include <CGAL/Triangulation_face_base_2.h>
#include <CGAL/Apollonius_graph_filtered_traits_2.h>
// typedef for the traits; the filtered traits class is used
typedef CGAL::Apollonius_graph_filtered_traits_2<Rep> Traits;
// typedefs for the algorithm
// With the second template argument in the vertex base class being
// false, we indicate that there is no need to store the hidden sites.
// One case where this is indeed not needed is when we only do
// insertions, like in the main program below.
typedef CGAL::Apollonius_graph_vertex_base_2<Traits,false> Vb;
typedef CGAL::Triangulation_face_base_2<Traits> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb,Fb> Agds;
typedef CGAL::Apollonius_graph_2<Traits,Agds> Apollonius_graph;
int main()
{
std::ifstream ifs("data/sites.cin");
assert( ifs );
Apollonius_graph ag;
Apollonius_graph::Site_2 site;
// read the sites and insert them in the Apollonius graph
while ( ifs >> site ) {
ag.insert(site);
}
// validate the Apollonius graph
assert( ag.is_valid(true, 1) );
std::cout << std::endl;
// now remove all sites
std::cout << "Removing all sites... " << std::flush;
while ( ag.number_of_vertices() > 0 ) {
ag.remove( ag.finite_vertex() );
}
std::cout << "done!" << std::endl << std::endl;
return 0;
}

View File

@ -0,0 +1,61 @@
// standard includes
#include <iostream>
#include <fstream>
#include <cassert>
// example that uses the filtered traits
#include <CGAL/MP_Float.h>
#include <CGAL/Simple_cartesian.h>
// constructions kernel (inexact)
typedef CGAL::Simple_cartesian<double> CK;
// exact kernel
typedef CGAL::Simple_cartesian<CGAL::MP_Float> EK;
// typedefs for the traits and the algorithm
#include <CGAL/Apollonius_graph_hierarchy_2.h>
#include <CGAL/Apollonius_graph_filtered_traits_2.h>
// Type definition for the traits class.
// In this example we explicitly define the exact kernel. We also
// explicitly define what operations to use for the evaluation of the
// predicates and constructions, when the filtering and the exact
// kernels are used respectively.
// Note that the operations allowed for the filtering and the
// constructions (field operations plus square roots) are different
// from the operations allowed when the exact kernel is used (ring
// operations).
typedef CGAL::Field_with_sqrt_tag CM;
typedef CGAL::Integral_domain_without_division_tag EM;
typedef CGAL::Apollonius_graph_filtered_traits_2<CK,CM,EK,EM> Traits;
// Now we use the Apollonius graph hierarchy.
// The hierarchy is faster for inputs consisting of about more than
// 1,000 sites
typedef CGAL::Apollonius_graph_hierarchy_2<Traits> Apollonius_graph;
int main()
{
std::ifstream ifs("data/hierarchy.cin");
assert( ifs );
Apollonius_graph ag;
Apollonius_graph::Site_2 site;
// read the sites and insert them in the Apollonius graph
while ( ifs >> site ) {
ag.insert(site);
}
// validate the Apollonius graph
assert( ag.is_valid(true, 1) );
return 0;
}

View File

@ -0,0 +1,500 @@
-199.259 28.7176 0.613542
141.606 166.862 1.13775
-5.56519 -156.845 3.31008
50.3311 161.726 1.07564
-64.7456 -87.8027 4.06628
14.8532 105.665 2.20139
76.5577 90.566 0.840065
-49.4694 41.2512 3.67553
-174.917 128.685 2.38958
188.251 -109.254 1.15084
16.9685 -57.0234 1.1601
-16.1697 -7.94008 0.430175
26.9857 83.0797 2.86061
-11.288 -52.1136 0.989749
100.909 33.9376 2.68043
6.5738 -40.7596 0.366094
-102.86 135.351 3.82307
138.391 -197.444 0.704697
67.0764 96.5988 1.01824
157.823 -112.234 0.871374
-99.2007 -20.1674 3.58348
92.8592 72.6406 0.881359
-24.0611 107.055 3.71868
123.825 -64.0966 1.07758
-42.2371 15.0832 4.83895
117.003 -170.482 2.42112
52.3544 -141.195 3.63537
54.9108 164.65 2.86525
-48.4905 -178.974 1.20371
39.2751 -97.515 0.676493
-180.892 -27.805 1.93648
91.7483 -141.127 0.597223
-1.19714 -70.6179 2.79646
134.706 -173.123 1.84428
-50.2105 -86.9171 3.81631
-20.693 -99.8014 2.77885
38.112 93.8881 0.933284
2.76229 -15.2827 4.11967
23.7883 -186.062 1.01354
126.273 -89.7657 4.00448
-101.532 -35.6463 4.24332
-42.6583 119.272 2.89018
86.7238 167.05 0.375211
113.6 -9.23294 4.55904
-173.317 138.309 1.43141
-73.1181 43.6142 3.67274
-179.23 -134.078 1.64915
5.48731 -59.4149 4.18367
19.4249 -129.841 1.98103
129.659 -48.7584 1.05945
-105.987 -128.4 2.2903
-186.715 -188.935 4.25707
180.336 42.2795 2.84112
-28.8974 72.2964 1.76112
-90.5882 37.0195 2.09466
153.026 151.532 3.68069
-181.052 45.3517 3.94031
-40.4665 177.283 1.5089
29.6921 111.977 4.25171
180.934 -129.54 3.37245
-147.467 -44.7849 4.54762
-136.401 138.439 4.71368
105.878 79.0047 4.46788
-21.8252 -93.7059 1.60666
-184.806 47.184 2.97431
166.727 -185.243 2.38713
12.0782 109.212 2.62399
-10.6384 24.4369 4.61816
-98.6612 145.149 2.48931
-28.2016 85.2863 2.25098
127.013 -44.9173 2.90765
65.4525 -81.108 3.70263
-55.5428 -104.013 2.52612
50.7513 -146.583 4.7533
-102.065 -18.0503 4.94323
-87.3077 -180.106 4.52731
-178.096 10.865 2.17829
46.3413 -179.216 4.54531
-8.50957 190.237 0.812045
-123.223 -10.6186 2.95952
31.8595 169.46 2.04719
150.751 2.0718 0.365349
-153.262 -101.717 2.17106
-99.845 100.372 0.305455
82.1047 80.6358 1.52965
101.999 76.0943 2.9383
-87.1359 38.2792 3.2121
-66.3517 -187.458 1.29137
-76.115 176.167 3.685
113.266 -158.869 4.64471
82.7263 77.8927 2.54295
-115.202 -158.332 1.92735
-16.9193 -129.104 2.51157
-116.548 44.5811 3.76351
164.088 69.0175 2.28982
40.1826 191.389 1.06481
-121.538 26.4532 2.47561
-108.996 -116.578 4.14621
-132.829 -13.2689 0.694777
-91.698 -118.469 4.61061
186.195 -146.892 3.14469
-172.137 56.5441 4.20466
-101.241 -189.268 1.49317
143.34 11.6578 2.53633
12.3573 -87.2613 2.08743
3.74654 95.9243 0.0897139
-169.8 181.109 1.07049
-86.3787 -20.842 2.20804
100.352 -89.1449 3.04768
181.883 -33.5627 4.40146
-165.009 -64.7142 4.22889
91.5355 186.861 4.57717
102.267 123.234 0.811658
-86.0748 -157.313 0.103406
26.6639 45.5936 2.75787
-77.4118 -187.412 0.304705
-96.3027 -180.235 0.682201
82.8553 -94.5959 2.10247
193.71 82.0472 0.856872
-39.8523 -74.1384 0.630415
95.4336 -122.022 1.06781
82.2942 -183.711 4.712
5.52791 182.463 3.49034
48.2153 -152.604 4.91441
-106.191 -144.332 2.74771
-93.6031 76.298 4.28006
-73.8378 100.674 0.576277
31.5663 155.25 4.11197
-86.3865 -76.5521 4.03335
39.4751 -8.0024 1.0352
117.453 42.4308 4.72811
133.742 127.855 3.25679
116.205 104.816 0.825892
163.601 -15.957 3.92858
-180.731 -22.8043 0.101193
95.5669 197.012 1.43116
-3.75869 139.417 3.00818
-48.5082 185.519 0.902761
74.9397 114.477 2.32293
-133.063 37.1446 0.316367
109.368 119.96 4.28453
37.2235 98.2094 3.45631
-57.961 -41.2472 2.40887
126.082 24.8242 1.95388
-96.7223 -60.8892 2.19474
-99.71 -52.7938 0.889331
-160.293 61.6986 3.34235
-174.774 -97.6468 0.235995
139.703 -25.4259 3.67274
-23.1525 160.408 4.50946
-103.192 185.718 3.37656
195.017 128.48 1.34185
-46.2301 4.9848 3.11734
178.594 197.695 2.19336
-82.2952 -45.9948 3.48434
64.9111 129.585 4.73796
-73.3903 -199.269 0.234298
28.9629 68.119 0.549627
-196.463 86.9986 4.79591
163.945 -19.1822 2.00651
149.663 -58.4257 3.2166
78.1433 -188.301 3.15432
-116.872 -80.9531 0.0764394
-119.177 168.434 4.80886
34.8278 -56.0969 1.28018
-35.5875 -177.35 4.59156
-34.8563 -198.313 1.17418
-166.737 -179.569 4.03622
120.261 -135.599 4.08043
-98.9209 -151.926 3.62975
42.6534 8.59436 3.00054
54.3523 -134.077 1.47733
173.399 118.268 2.51643
141.833 124.383 3.52671
-114.264 109.092 1.46206
-91.6138 -188.494 3.51722
-89.927 178.831 0.581516
-69.4964 -127.234 0.9973
-5.09564 195.664 0.000566293
42.9782 122.098 1.26406
-148.427 12.4784 4.29722
-82.5049 -147.478 2.47663
-164.237 -29.2921 2.14412
160.146 172.022 1.41703
69.238 54.1596 2.48874
80.7442 171.125 3.84356
59.5755 52.502 0.219476
132.342 99.0233 1.85077
128.005 178.807 4.28708
50.1037 178.853 2.3243
-137.418 -120.023 2.96896
-84.8963 -176.245 4.43765
85.8117 21.8849 4.88468
57.8341 193.414 4.38651
-88.0063 -93.2232 2.75198
-116.882 105.876 1.26129
135.62 13.3607 4.50598
34.6435 30.9187 3.66025
13.4508 178.98 2.76032
-7.69665 121.946 0.886613
72.2804 -92.1095 1.66889
96.0352 145.407 3.10769
-82.0799 100.419 1.68033
-88.6656 91.1938 4.90326
18.1112 42.1145 1.30318
-76.0132 -137.727 2.34216
137.347 -36.8239 1.53741
-31.7339 -76.3455 4.47045
-52.7535 -183.526 2.13859
-130.807 37.2997 4.54238
-22.9166 108.229 2.94588
-77.5094 -158.26 1.64632
-177.09 90.3548 3.12033
114.104 -175.219 4.51201
-43.7819 -182.958 2.23839
18.4912 -78.7035 3.78823
181.667 108.669 3.00507
-94.6783 -168.338 0.108398
-78.2039 189.298 1.94898
159.096 -39.6151 2.81389
67.3245 -76.2247 0.0274314
109.064 159.446 1.55856
-0.580817 -108.848 1.84494
24.2006 140.778 0.771231
41.2427 101.738 2.72396
162.539 -119.19 0.455097
71.2081 183.868 0.225937
102.87 24.2739 1.54246
92.1677 32.9458 3.06491
-147.447 188.864 2.55361
-23.6721 13.9753 0.895164
-64.2261 16.1698 4.75847
26.9257 140.855 2.25121
-32.2964 -111.55 0.0537161
-130.558 -49.8517 3.06925
-49.7482 168.065 2.60099
-65.88 -195.527 0.99109
158.394 -177.452 4.77696
-8.66023 -54.0558 3.42906
-19.7961 191.137 4.08597
194.179 -4.57438 1.29007
10.349 67.0388 2.98724
-48.7961 47.7163 0.823812
39.6537 -172.187 2.92011
189.802 -167.89 3.78813
157.867 77.6502 0.666279
162.339 -114.271 2.34278
184.887 -34.9835 1.8227
-69.1688 -52.8265 4.21445
-78.0318 -178.502 1.467
117.394 148.376 1.39424
-15.5675 -148.419 4.0236
-167.851 90.5603 0.913651
-140.038 156.465 3.90932
-107.928 -9.92617 3.78185
169.722 -106.876 3.25518
-144.548 -53.5733 2.78443
20.4682 133.849 2.59551
167.642 -120.335 4.2309
189.14 -183.179 0.755505
137.516 -65.8187 4.72293
189.097 45.7205 2.02833
79.657 -32.3914 2.43019
36.1223 40.7007 3.17972
-173.804 -46.5535 4.33062
-80.6796 -144.006 3.95215
65.7471 116.409 4.64529
-0.403869 -60.8368 2.40114
79.2614 146.804 1.99667
96.0828 85.2766 1.86092
-169.736 145.717 1.07986
75.9847 123.551 0.943572
-156.407 -114.182 4.43928
84.294 80.2336 2.39081
-162.26 -65.3891 2.71826
-106.265 -118.94 4.20977
-189.856 197.232 2.53161
-50.6931 168.856 0.0265606
-103.889 -39.0528 3.51733
181.388 120.68 2.21836
127.105 -130.446 2.59667
50.656 -44.0573 1.04647
136.474 31.4285 1.59139
16.7076 -13.4288 0.145065
151.319 177.836 0.616821
-167.621 -4.70256 1.78851
-170.389 -67.921 1.9153
198.467 134.608 3.78164
-40.5861 136.733 4.98303
-119.906 18.1189 4.75038
-50.3519 195.588 3.83919
105.591 3.32129 1.97239
-62.9807 87.0392 1.17831
123.591 -185.649 3.88716
101.427 -174.044 3.27864
-103.276 -124.699 3.68337
28.8033 18.3818 4.05351
-36.5889 171.606 4.03435
-99.8563 74.1371 1.02702
118.263 72.7794 2.0282
113.851 52.8096 3.8988
-82.8281 -40.0555 2.71869
-195.789 117.735 4.43143
-181.438 -188 3.47631
-155.483 122.973 2.24414
-80.1812 -14.736 3.4532
138.201 -120.066 1.31324
109.807 -195.785 3.35588
-16.0563 126.963 4.60767
-143.277 -190.876 3.58595
109.533 -28.6197 2.50909
-130.523 -116.716 3.97373
187.213 100.779 4.02637
199.213 55.2933 4.25839
122.186 -66.602 4.81486
-92.5501 112.929 1.31259
-12.6162 -10.8148 0.540102
-8.40121 94.2442 4.41268
-81.4385 -37.2857 1.71198
-72.3142 -68.6719 2.42102
99.0661 -181.796 1.29018
182.35 18.9313 2.15864
83.1297 -63.17 1.9988
-61.577 -141.06 1.98896
71.821 199.611 1.01629
-15.2495 184.8 2.35941
173.936 -110.192 4.70171
68.1799 -66.9843 2.09669
-169.106 -113.97 3.57871
-37.7777 22.9888 0.174783
-19.5733 -183.33 3.91311
199.358 -80.1157 3.69249
-63.8121 92.5755 2.23161
-4.87228 -147.521 3.9619
-5.26103 11.5961 2.35966
-20.461 92.899 4.66904
69.3466 -118.348 4.34324
-197.638 -142.212 2.69549
-111.607 25.5236 3.08166
111.382 -88.1795 0.109442
128.052 -74.1968 2.36478
-152.064 -161.148 2.35675
140.512 134.251 4.0591
192.991 -87.22 1.4982
4.58696 -170.268 3.93243
-102.514 18.5048 1.17667
-20.8624 -7.97184 4.5435
36.9259 -60.5128 4.57303
-137.55 155.126 0.677942
-25.73 1.65912 4.57021
100.073 10.4145 3.67086
138.925 199.597 4.27006
73.1762 -11.8635 3.52645
185.956 -87.1356 3.43884
-184.312 32.72 0.996175
34.193 -52.6854 2.21475
-173.779 41.4482 4.45397
-34.2916 4.92842 2.41554
-79.1656 -29.229 3.19616
122.494 25.0063 0.374536
-67.092 -9.37676 4.12545
-67.4954 -115.708 3.36201
120.641 -174.103 1.77672
-166.495 108.013 1.60117
66.2255 -16.8802 1.79727
-186.46 62.8138 4.72469
54.9883 -160.006 0.0524522
-140.083 196.311 2.12381
30.6877 -10.4454 3.63424
-144.306 -154.752 2.66541
46.3173 -124.79 4.32676
130.609 -194.754 0.983063
156.506 74.2077 4.99108
64.5186 -183.655 0.409895
-152.362 -55.5612 3.73771
110.452 88.2207 3.90696
150.446 66.1956 2.09432
146.757 70.3918 2.84328
-63.6882 -159.704 0.726874
-18.4407 131.035 1.42305
56.7697 -55.7323 4.50202
62.0162 -109.592 3.63463
-63.7761 -30.9468 3.09095
-47.4311 -31.6606 1.39743
97.0077 1.13095 1.99291
-14.7717 -99.8519 0.873568
-148.576 -187.295 0.254143
121.816 -19.7493 4.58861
162.112 -192.287 1.29251
93.1475 -134.137 3.562
-162.585 -20.2932 1.77162
-72.1766 -60.132 0.0468209
96.8767 -169.362 1.74962
-134.784 77.9146 3.65673
66.347 189.709 2.36933
166.495 -50.8575 4.68468
179.2 19.0279 0.327481
-40.549 39.3593 4.35018
-32.836 6.44796 3.87658
33.0268 109.848 2.54092
-187.266 -5.19188 3.00861
-47.3983 136.538 4.60641
-16.7599 140.283 3.31736
-138.845 -119.747 4.13256
-149.136 172.791 2.4619
0.00640806 -37.6626 2.04309
-180.966 -62.8882 1.78309
58.3937 -36.6897 3.77623
-135.158 -88.6754 0.865781
174.69 -178.549 3.77862
-30.5019 24.7249 3.93779
-93.9643 -134.586 0.845307
-153.681 -166.074 3.13581
-73.4283 99.3156 3.90024
-100.637 29.9208 4.53604
61.7003 -173.127 2.03612
198.812 -9.67982 2.27405
-37.8776 132.968 0.50397
73.447 35.0661 1.31449
94.898 104.329 0.998115
-80.3772 6.61785 3.11684
-14.9632 -78.3592 4.44229
18.9633 -10.7346 0.0212741
-81.7211 -159.87 1.60342
148.2 152.149 2.84546
175.073 115.032 1.11671
-34.6071 -122.078 1.10186
-101.639 59.8459 3.12839
133.427 100.164 1.54648
37.7553 -194.677 0.232704
-155.627 -114.828 1.72799
-33.9861 134.519 4.04095
155.279 89.9022 1.77799
195.409 91.6041 3.25648
147.559 -180.122 2.60897
62.591 47.5143 2.29738
140.513 136.851 4.36479
0.358935 -175 0.594302
-99.4775 75.2715 4.76214
-94.1548 198.99 2.73408
-8.98291 -182.394 3.28874
-74.4637 -44.1547 0.363914
-184.561 -120.879 4.8049
107.043 21.3604 4.74752
126.92 -118.121 4.092
-25.5652 90.5964 2.37439
-88.714 -125.613 1.6308
-63.7139 -176.429 4.13529
-188.442 -128.885 0.391819
-189.452 -147.914 1.71488
-171.846 70.8118 4.1026
-16.001 -66.089 0.671801
63.1202 -36.9759 0.864783
-115.519 -52.5835 4.70282
-33.6409 -72.7818 3.78932
-143.044 -145.422 0.969758
-68.6574 44.5294 2.36083
-45.0868 174.994 4.06441
26.028 105.817 4.20888
78.1137 137.162 4.34072
-51.0745 -125.647 4.69265
82.8366 -197.439 1.99263
-154.139 -143.695 0.281635
-6.72277 -74.5127 1.33764
120.495 -98.2873 3.41713
175.074 -195.142 4.12907
19.6032 -117.561 0.770857
-5.40327 71.3057 2.70727
-99.5867 -3.54152 0.532623
-162.425 -66.8311 4.00904
-88.0717 -119.573 0.870613
-85.5111 -144.161 4.40607
-29.2065 15.2491 4.97933
96.2809 37.7799 2.39529
197.994 144.791 1.40149
-197.148 18.1617 1.08991
-114.709 -51.5123 3.83495
156.597 10.1562 1.26741
-46.9446 -173.262 2.52257
86.2243 -130.652 2.99227
166.651 190.071 4.39137
-177.51 -140.28 0.822481
37.7388 -187.794 2.9574
-124.481 -189.448 1.66091
-179.69 2.17599 1.63583
38.4717 114.295 1.67148
186.959 -198.512 2.73762
-2.88438 108.283 2.19508
23.8536 -190.324 4.10827
93.2015 11.4819 2.68608
83.2728 -149.137 2.26922
142.993 -197.827 2.55034
155.199 -132.029 0.522073
165.752 104.563 1.46606
-32.0722 -162.564 1.71993
-117.777 -31.6971 4.70083
-116.29 102.021 4.53782
191.994 -78.9689 2.00176
-198.33 96.6377 4.79993
13.1517 25.2997 3.46495

View File

@ -0,0 +1,9 @@
20.0 -20 5
9 -9 15.
1000 -1000 20
10.0 5.0 5
1.0 1.0 10
-10 -10 11
95 67 33
-99 -100 -31

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,98 @@
// Copyright (c) 2003,2004,2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_BOUNDED_SIDE_OF_CCW_CIRCLE_C2_H
#define CGAL_APOLLONIUS_GRAPH_2_BOUNDED_SIDE_OF_CCW_CIRCLE_C2_H
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/Apollonius_graph_2/basic.h>
#include <CGAL/Apollonius_graph_2/Predicate_constructions_C2.h>
namespace CGAL {
namespace ApolloniusGraph_2 {
//--------------------------------------------------------------------
template< class K >
class Sign_of_Voronoi_radius
{
public:
typedef Voronoi_radius_2<K> Voronoi_radius;
typedef typename K::FT FT;
typedef typename K::Sign Sign;
public:
inline
Sign operator()(const Voronoi_radius& vr, const Field_with_sqrt_tag&) const
{
FT r = vr.c1() + vr.c2() * CGAL::sqrt(vr.delta());
return CGAL::sign(r);
}
inline
Sign operator()(const Voronoi_radius& vr, const Integral_domain_without_division_tag&) const
{
// this is another way of doing this; the degree becomes 10
// instead of 5 in this case.
// return sign_a_plus_b_x_sqrt_c(vr.c1(), vr.c2(), vr.delta());
bool is_first_root = CGAL::is_negative(vr.c2());
Sign s_beta = CGAL::sign(vr.b());
Sign s_gamma = CGAL::sign(vr.c());
// the existence test
Sign sign_of_root;
if ( is_first_root ) {
sign_of_root = sign_of_first_root(s_beta, s_gamma);
} else {
sign_of_root = sign_of_second_root(s_beta, s_gamma);
}
return sign_of_root;
}
};
template< class K >
class Bounded_side_of_CCW_circle_2
{
private:
Sign_of_Voronoi_radius<K> test;
public:
typedef Voronoi_radius_2<K> Voronoi_radius;
typedef typename K::Bounded_side Bounded_dide;
public:
template<class Tag>
inline Bounded_side
operator()(const Voronoi_radius& vr, const Tag& tag)
{
return enum_cast<Bounded_side>( -test(vr, tag ) );
}
};
//--------------------------------------------------------------------
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_BOUNDED_SIDE_OF_CCW_CIRCLE_C2_H

View File

@ -0,0 +1,52 @@
// Copyright (c) 2003,2004,2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_COMPARE_WEIGHT_2_H
#define CGAL_APOLLONIUS_GRAPH_2_COMPARE_WEIGHT_2_H
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/Apollonius_graph_2/basic.h>
//--------------------------------------------------------------------
namespace CGAL {
namespace ApolloniusGraph_2 {
template<class K>
class Compare_weight_2
{
public:
typedef K Kernel;
typedef typename K::Site_2 Site_2;
typedef typename K::Comparison_result result_type;
typedef Site_2 argument_type;
inline
result_type operator()(const Site_2& s1, const Site_2& s2) const
{
return CGAL::compare(s1.weight(), s2.weight());
}
};
//--------------------------------------------------------------------
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_COMPARE_WEIGHT_2_H

View File

@ -0,0 +1,52 @@
// Copyright (c) 2003,2004,2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_COMPARE_X_2_H
#define CGAL_APOLLONIUS_GRAPH_2_COMPARE_X_2_H
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/Apollonius_graph_2/basic.h>
//--------------------------------------------------------------------
namespace CGAL {
namespace ApolloniusGraph_2 {
template<class K>
class Compare_x_2
{
public:
typedef K Kernel;
typedef typename K::Site_2 Site_2;
typedef typename K::Comparison_result result_type;
typedef Site_2 argument_type;
inline
result_type operator()(const Site_2& s1, const Site_2& s2) const
{
return CGAL::compare(s1.x(), s2.x());
}
};
//--------------------------------------------------------------------
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_COMPARE_X_2_H

View File

@ -0,0 +1,52 @@
// Copyright (c) 2003,2004,2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_COMPARE_Y_2_H
#define CGAL_APOLLONIUS_GRAPH_2_COMPARE_Y_2_H
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/Apollonius_graph_2/basic.h>
//--------------------------------------------------------------------
namespace CGAL {
namespace ApolloniusGraph_2 {
template<class K>
class Compare_y_2
{
public:
typedef K Kernel;
typedef typename K::Site_2 Site_2;
typedef typename K::Comparison_result result_type;
typedef Site_2 argument_type;
inline
result_type operator()(const Site_2& s1, const Site_2& s2) const
{
return CGAL::compare(s1.y(), s2.y());
}
};
//--------------------------------------------------------------------
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_COMPARE_Y_2_H

View File

@ -0,0 +1,430 @@
// Copyright (c) 2003,2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_CONSTRUCTIONS_C2_H
#define CGAL_APOLLONIUS_GRAPH_2_CONSTRUCTIONS_C2_H 1
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/Apollonius_graph_2/basic.h>
#include <CGAL/Parabola_segment_2.h>
#include <CGAL/Hyperbola_2.h>
#include <CGAL/Hyperbola_segment_2.h>
#include <CGAL/Hyperbola_ray_2.h>
#include <CGAL/Apollonius_graph_2/Constructions_ftC2.h>
namespace CGAL {
namespace ApolloniusGraph_2 {
//***********************************************************************
//***********************************************************************
// CONSTRUCTIONS
//***********************************************************************
//***********************************************************************
//-----------------------------------------------------------------------
// Apollonius vertex
//-----------------------------------------------------------------------
template < class Gt >
inline
typename Gt::Point_2
ad_circumcenter_2(const typename Gt::Site_2& p,
const typename Gt::Site_2& q,
const typename Gt::Site_2& r)
{
typedef typename Gt::Point_2 Point_2;
typename Gt::FT x,y;
ad_circumcenterC2(p.x(),p.y(),p.weight(),
q.x(),q.y(),q.weight(),
r.x(),r.y(),r.weight(),x,y);
return Point_2(x,y);
}
template < class Gt >
class Construct_Apollonius_vertex_2
{
public:
typedef typename Gt::Point_2 Point_2;
typedef typename Gt::Site_2 Site_2;
typedef Point_2 result_type;
Point_2 operator() (const Site_2& p, const Site_2& q,
const Site_2& r) const
{
return ad_circumcenter_2< Gt >(p,q,r);
}
};
//-----------------------------------------------------------------------
// Apollonius site (dual site)
//-----------------------------------------------------------------------
template < class Gt >
inline
typename Gt::Site_2
ad_circumcircle_2(const typename Gt::Site_2& p,
const typename Gt::Site_2& q,
const typename Gt::Site_2& r)
{
typedef typename Gt::Site_2 Site_2;
typedef typename Gt::Point_2 Point_2;
typename Gt::FT x, y, wt;
ad_circumcircleC2(p.x(),p.y(),p.weight(),
q.x(),q.y(),q.weight(),
r.x(),r.y(),r.weight(),x,y,wt);
return Site_2(Point_2(x,y), wt);
}
template < class Gt >
inline
typename Gt::Line_2
ad_left_bitangent_line_2(const typename Gt::Site_2& p,
const typename Gt::Site_2& q)
{
typedef typename Gt::Line_2 Line_2;
typename Gt::FT a, b, c;
ad_left_bitangent_lineC2(p.x(),p.y(),p.weight(),
q.x(),q.y(),q.weight(),
a,b,c);
return Line_2(a, b, c);
}
template < class Gt >
class Construct_Apollonius_site_2
{
public:
typedef typename Gt::Line_2 Line_2;
typedef typename Gt::Point_2 Point_2;
typedef typename Gt::Site_2 Site_2;
#if 0
// WARNING: the following type is just a hack; it is not
// really valid
typedef Site_2 result_type;
#endif
inline Site_2 operator()(const Site_2& p,
const Site_2& q,
const Site_2& r) const
{
// CGAL_precondition( ! collinear(p, q, r) );
return ad_circumcircle_2< Gt >(p,q,r);
}
inline Line_2 operator()(const Site_2 &p,
const Site_2 &q) const
{
return ad_left_bitangent_line_2< Gt >(p, q);
}
};
//-----------------------------------------------------------------------
// Apollonius bisector
//-----------------------------------------------------------------------
template< class Gt >
class Construct_Apollonius_bisector_2
{
public:
typedef typename Gt::Point_2 Point_2;
typedef typename Gt::Line_2 Line_2;
typedef typename Gt::Site_2 Site_2;
typedef typename Gt::Object_2 Object_2;
typedef typename Gt::Construct_object_2 Construct_object_2;
typedef CGAL::Hyperbola_2<Gt> Hyperbola_2;
private:
template<class T>
Object_2 make_object(const T& t) const
{
return Construct_object_2()(t);
}
public:
Object_2 operator() (const Site_2& p, const Site_2& q) const
{
Comparison_result cr = CGAL::compare(p.weight(), q.weight());
if ( cr == EQUAL ) {
Line_2 l1(p.point(), q.point());
Line_2 l = l1.perpendicular(midpoint(p.point(), q.point()));
return make_object(l);
}
Hyperbola_2 h(p, q);
return make_object(h);
}
};
//-----------------------------------------------------------------------
// Apollonius bisector ray
//-----------------------------------------------------------------------
template< class Gt >
class Construct_Apollonius_bisector_ray_2
{
public:
typedef typename Gt::Point_2 Point_2;
typedef typename Gt::Line_2 Line_2;
typedef typename Gt::Ray_2 Ray_2;
typedef typename Gt::Site_2 Site_2;
typedef typename Gt::Object_2 Object_2;
typedef typename Gt::Construct_object_2 Construct_object_2;
typedef typename Gt::Construct_Apollonius_vertex_2 Apollonius_vertex_2;
typedef CGAL::Hyperbola_ray_2<Gt> Hyperbola_ray_2;
typedef CGAL::Sign Hyperbola_direction;
private:
template<class T>
Object_2 make_object(const T& t) const
{
return Construct_object_2()(t);
}
public:
Object_2
operator() (const Site_2& p,
const Site_2& q,
const Point_2& r,
const Hyperbola_direction& direction) const {
//
Comparison_result cr = CGAL::compare(p.weight(), q.weight());
if ( cr == EQUAL ) {
Line_2 l1(p.point(), q.point());
Line_2 l = l1.perpendicular(midpoint(p.point(), q.point()));
Ray_2 ray(r, l.direction());
return make_object(ray);
}
Hyperbola_ray_2 hr(p, q, r, direction);
return make_object(hr);
}
Object_2
operator() (const Site_2& p,
const Site_2& q,
const Site_2& r) const {
Point_2 c = Apollonius_vertex_2()(p, q, r);
Comparison_result cr = CGAL::compare(p.weight(), q.weight());
if ( cr == EQUAL ) {
Line_2 l1(q.point(), p.point());
Line_2 l = l1.perpendicular(midpoint(p.point(), q.point()));
Ray_2 ray(c, l.direction());
return make_object(ray);
}
Hyperbola_ray_2 hr(p, q, c, NEGATIVE);
return make_object(hr);
}
};
//-----------------------------------------------------------------------
// Apollonius bisector segment
//-----------------------------------------------------------------------
template< class Gt >
class Construct_Apollonius_bisector_segment_2
{
public:
typedef typename Gt::Point_2 Point_2;
typedef typename Gt::Segment_2 Segment_2;
typedef typename Gt::Site_2 Site_2;
typedef typename Gt::Object_2 Object_2;
typedef typename Gt::Construct_object_2 Construct_object_2;
typedef typename Gt::Construct_Apollonius_vertex_2 Apollonius_vertex_2;
typedef CGAL::Hyperbola_segment_2<Gt> Hyperbola_segment_2;
private:
template<class T>
Object_2 make_object(const T& t) const
{
return Construct_object_2()(t);
}
public:
inline Object_2 operator() (const Site_2& p,
const Site_2& q,
const Point_2& r, const Point_2& s) const {
//
Comparison_result cr = CGAL::compare(p.weight(), q.weight());
if ( cr == EQUAL ) {
Segment_2 seg(r, s);
return make_object(seg);
}
Hyperbola_segment_2 hs(p, q, r, s);
return make_object(hs);
}
inline Object_2 operator() (const Site_2& p,
const Site_2& q,
const Site_2& r,
const Site_2& s) const {
Apollonius_vertex_2 apollonius_vertex_2;
Point_2 c_pqr = apollonius_vertex_2(p,q,r);
Point_2 c_qps = apollonius_vertex_2(q,p,s);
//
Comparison_result cr = CGAL::compare(p.weight(), q.weight());
if ( cr == EQUAL ) {
Segment_2 seg(c_pqr, c_qps);
return make_object(seg);
}
Hyperbola_segment_2 hs(p, q, c_pqr, c_qps);
return make_object(hs);
}
};
//-----------------------------------------------------------------------
// Apollonius primal ray
//-----------------------------------------------------------------------
template< class Gt >
class Construct_Apollonius_primal_ray_2
{
private:
typedef typename Gt::RT RT;
public:
typedef typename Gt::Point_2 Point_2;
typedef typename Gt::Line_2 Line_2;
typedef typename Gt::Ray_2 Ray_2;
typedef typename Gt::Site_2 Site_2;
typedef typename Gt::Construct_Apollonius_site_2 Apollonius_circle_2;
inline Ray_2 operator() (const Site_2& p,
const Site_2& r,
const Site_2& s) const {
//
Apollonius_circle_2 apollonius_circle_2;
Line_2 l1 = apollonius_circle_2(r, p);
Line_2 l2 = apollonius_circle_2(p, s);
RT d1 = CGAL::sqrt( CGAL::square(l1.a()) + CGAL::square(l1.b()) );
RT d2 = CGAL::sqrt( CGAL::square(l2.a()) + CGAL::square(l2.b()) );
RT a = l1.a() / d1 - l2.a() / d2;
RT b = l1.b() / d1 - l2.b() / d2;
Point_2 c(p.x() + b, p.y() - a);
return Ray_2(p.point(), c);
}
};
//-----------------------------------------------------------------------
// Apollonius primal segment
//-----------------------------------------------------------------------
template< class Gt >
class Construct_Apollonius_primal_segment_2
{
public:
typedef typename Gt::Point_2 Point_2;
typedef typename Gt::Line_2 Line_2;
typedef typename Gt::Segment_2 Segment_2;
typedef typename Gt::Site_2 Site_2;
typedef typename Gt::Object_2 Object_2;
typedef typename Gt::Construct_object_2 Construct_object_2;
typedef typename Gt::RT Weight;
typedef CGAL::Hyperbola_segment_2<Gt> Hyperbola_segment_2;
typedef CGAL::Parabola_segment_2<Gt> Parabola_segment_2;
typedef typename Gt::Construct_Apollonius_site_2 Apollonius_circle_2;
typedef typename Gt::Construct_Apollonius_vertex_2 Apollonius_vertex_2;
typedef typename Gt::Is_degenerate_edge_2 Is_degenerate_edge_2;
private:
template<class T>
Object_2 make_object(const T& t) const
{
return Construct_object_2()(t);
}
public:
inline Segment_2
operator() (const Site_2& p,
const Site_2& q) const {
//
return Segment_2(p.point(), q.point());
}
inline Object_2
operator() (const Site_2& p,
const Site_2& q,
const Point_2& r, const Point_2& s) const {
//
Comparison_result cr = CGAL::compare(p.weight(), q.weight());
if ( cr == EQUAL ) {
Segment_2 seg(r, s);
return make_object(seg);
}
Hyperbola_segment_2 hs(p, q, r, s);
return make_object(hs);
}
inline Object_2
operator() (const Site_2& p,
const Site_2& q,
const Site_2& r,
const Site_2& s) const {
if ( Is_degenerate_edge_2()(p, q, r, s) ) {
Point_2 v = Apollonius_vertex_2()(p, q, r);
Segment_2 seg1(p.point(), v);
Segment_2 seg2(v, q.point());
return make_object(std::pair<Segment_2,Segment_2>(seg1, seg2));
}
Apollonius_circle_2 apollonius_circle_2;
Site_2 c_pqr = apollonius_circle_2(p, q, r);
Site_2 c_qps = apollonius_circle_2(q, p, s);
//
Comparison_result cr = CGAL::compare(c_pqr.weight(), c_qps.weight());
if ( cr == EQUAL ) {
Segment_2 seg(p.point(), q.point());
return make_object(seg);
}
Hyperbola_segment_2 hs(c_pqr, c_qps, p.point(), q.point());
return make_object(hs);
}
inline Parabola_segment_2
operator() (const Site_2& p,
const Site_2& q,
const Site_2& r) const {
//
Apollonius_circle_2 apollonius_circle_2;
Site_2 c = apollonius_circle_2(p, q, r);
Line_2 l = apollonius_circle_2(q, p);
return Parabola_segment_2(c, l, q.point(), p.point());
}
};
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_CONSTRUCTIONS_C2_H

View File

@ -0,0 +1,182 @@
// Copyright (c) 2003,2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_CONSTRUCTIONS_FTC2_H
#define CGAL_APOLLONIUS_GRAPH_2_CONSTRUCTIONS_FTC2_H 1
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/Apollonius_graph_2/basic.h>
#include <CGAL/determinant.h>
namespace CGAL {
namespace ApolloniusGraph_2 {
template < class FT >
inline
void
invert_C2(const FT &x, const FT &y, const FT &wt,
FT &new_x, FT &new_y, FT &new_wt)
{
FT p = CGAL::square(x) + CGAL::square(y) - CGAL::square(wt);
CGAL_assertion( CGAL::is_positive(p) );
new_x = x / p;
new_y = -y / p;
new_wt = wt / p;
}
template < class FT >
void
w_plane_tangent_line_2(const FT &x1, const FT &y1, const FT &w1,
const FT &x2, const FT &y2, const FT &w2,
const FT &x3, const FT &y3, const FT &w3,
FT & a, FT & b, FT & c)
{
// we assume that the weight w1 is the smallest among w1, w2, w3.
FT u2, v2;
FT u3, v3;
FT r2, r3;
invert_C2(x2-x1, y2-y1, w2-w1, u2, v2, r2);
invert_C2(x3-x1, y3-y1, w3-w1, u3, v3, r3);
FT Du = u2 - u3;
FT Dv = v2 - v3;
FT Dr = r2 - r3;
FT Duv = determinant(u2, v2, u3, v3);
FT Dur = determinant(u2, r2, u3, r3);
FT Dvr = determinant(v2, r2, v3, r3);
FT D1 = CGAL::square(Du) + CGAL::square(Dv);
FT D1inv = FT(1) / D1;
FT sqrtD = CGAL::sqrt(D1 - CGAL::square(Dr));
a = (Du * Dr - Dv * sqrtD) * D1inv;
b = (Dv * Dr + Du * sqrtD) * D1inv;
c = (Du * Dur + Dv * Dvr - Duv * sqrtD) * D1inv;
}
template < class FT >
inline
void
z_plane_circumcircle_2(const FT &x1, const FT &y1, const FT &w1,
const FT &x2, const FT &y2, const FT &w2,
const FT &x3, const FT &y3, const FT &w3,
FT &cx, FT &cy, FT &cwt)
{
// we assume that the weight w1 is the smallest among w1, w2, w3.
FT a, b, c;
w_plane_tangent_line_2(x1, y1, w1, x2, y2, w2,
x3, y3, w3, a, b, c);
cx = -a / (FT(2) * c) + x1;
cy = b / (FT(2) * c) + y1;
// this the only part that is computed at vain when only the center
// is needed.
#if 0
FT cwt2 = (CGAL::square(a) + CGAL::square(b)) /
(FT(4) * CGAL::square(c));
#endif
// cwt = CGAL::sqrt(cwt2) - FT(w1);
cwt = FT(1) / (FT(2) * c) - FT(w1);
}
template < class FT >
void
ad_circumcircleC2(const FT &x1, const FT &y1, const FT &w1,
const FT &x2, const FT &y2, const FT &w2,
const FT &x3, const FT &y3, const FT &w3,
FT &cx, FT &cy, FT &cwt)
{
if (CGAL::compare(w2, w1) != LARGER &&
CGAL::compare(w2, w3) != LARGER) {
z_plane_circumcircle_2(x2, y2, w2,
x3, y3, w3,
x1, y1, w1,
cx, cy, cwt);
return;
} else if (CGAL::compare(w3, w1) != LARGER &&
CGAL::compare(w3, w2) != LARGER) {
z_plane_circumcircle_2(x3, y3, w3,
x1, y1, w1,
x2, y2, w2,
cx, cy, cwt);
return;
}
z_plane_circumcircle_2(x1, y1, w1,
x2, y2, w2,
x3, y3, w3,
cx, cy, cwt);
}
template < class FT >
inline
void
ad_circumcenterC2(const FT &x1, const FT &y1, const FT &w1,
const FT &x2, const FT &y2, const FT &w2,
const FT &x3, const FT &y3, const FT &w3,
FT &cx, FT &cy)
{
FT cwt;
ad_circumcircleC2(x1, y1, w1,
x2, y2, w2,
x3, y3, w3,
cx, cy, cwt);
}
template < class FT >
void
ad_left_bitangent_lineC2(const FT &x1, const FT &y1, const FT &w1,
const FT &x2, const FT &y2, const FT &w2,
FT & a, FT & b, FT & c)
{
FT dx = x1 - x2;
FT dy = y1 - y2;
FT dw = w1 - w2;
FT dxw = determinant(x1, w1, x2, w2);
FT dyw = determinant(y1, w1, y2, w2);
FT dxy = determinant(x1, y1, x2, y2);
FT D1 = CGAL::square(dx) + CGAL::square(dy);
FT invD1 = FT(1) / D1;
FT D = D1 - CGAL::square(dw);
FT sqrtD = CGAL::sqrt(D);
a = -(dx * dw - dy * sqrtD) * invD1;
b = -(dy * dw + dx * sqrtD) * invD1;
c = -(dx * dxw + dy * dyw - dxy * sqrtD) * invD1;
}
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_CONSTRUCTIONS_FTC2_H

View File

@ -0,0 +1,79 @@
// Copyright (c) 2003 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_CONSTRUCTIONS_RTH2_H
#define CGAL_APOLLONIUS_GRAPH_2_CONSTRUCTIONS_RTH2_H
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/determinant.h>
#include <CGAL/Apollonius_graph_2/Constructions_ftC2.h>
namespace CGAL {
template < class RT, class We >
inline
void
ad_circumcenterH2(const RT &hx1, const RT &hy1, const RT &hw1,
const We &w1,
const RT &hx2, const RT &hy2, const RT &hw2,
const We &w2,
const RT &hx3, const RT &hy3, const RT &hw3,
const We &w3,
RT & cx, RT & cy, RT & cw)
{
We cwt;
ad_circumcircleH2(hx1, hy1, hw1, w1,
hx2, hy2, hw2, w2,
hx3, hy3, hw3, w3,
cx, cy, cw, cwt);
}
template < class RT, class We >
inline
void
ad_circumcircleH2(const RT &hx1, const RT &hy1, const RT &hw1,
const We &w1,
const RT &hx2, const RT &hy2, const RT &hw2,
const We &w2,
const RT &hx3, const RT &hy3, const RT &hw3,
const We &w3,
RT & cx, RT & cy, RT & cw,
We &cwt)
{
ad_circumcircleC2<RT, We>(RT(hx1/hw1), RT(hy1/hw1), w1,
RT(hx2/hw2), RT(hy2/hw2), w2,
RT(hx3/hw3), RT(hy3/hw3), w3,
cx, cy, cwt);
cw = RT(1);
}
template < class RT, class We >
void
ad_left_bitangent_lineH2(const FT &hx1, const FT &hy1, const We &w1,
const FT &hx2, const FT &hy2, const We &w2,
RT & a, RT & b, RT & c)
{
ad_left_bitangent_lineC2(RT(hx1/hw1), RT(hy1/hw1), w1,
RT(hx2/hw2), RT(hy2/hw2), w2,
a, b, c);
}
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_CONSTRUCTIONS_RTH2_H

View File

@ -0,0 +1,752 @@
// Copyright (c) 2007 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_FINITE_EDGE_TEST8_C2_H
#define CGAL_APOLLONIUS_GRAPH_2_FINITE_EDGE_TEST8_C2_H
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/Apollonius_graph_2/Finite_edge_test_C2.h>
#include <CGAL/Apollonius_graph_2/Orientation8_C2.h>
#include <CGAL/Apollonius_graph_2/Oriented_side_of_bisector_C2.h>
namespace CGAL {
namespace ApolloniusGraph_2 {
//--------------------------------------------------------------------
//--------------------------------------------------------------------
template < class K, class MTag >
class Inside_Voronoi_quadrilateral8
{
public:
typedef K Kernel;
typedef MTag Method_tag;
typedef typename K::Site_2 Site_2;
typedef typename K::Orientation Orientation;
typedef typename K::Oriented_side Oriented_side;
private:
typedef Orientation8_C2<K,MTag> Orientation_2;
typedef Constructive_orientation8_C2<K,MTag> Constructive_orientation_2;
typedef Oriented_side_of_bisector_2<K,MTag> Side_of_bisector_2;
public:
bool
operator()(const Site_2& p1,
const Site_2& p2,
const Site_2& p3,
const Site_2& p4,
const Site_2& q, bool b, const Method_tag& tag) const
{
#if 1
Constructive_orientation_2 orientation123(p1, p2, p3, true);
Constructive_orientation_2 orientation142(p1, p4, p2, false);
Orientation o123_s = orientation123();
Orientation o142_s = orientation142();
#if 0
#ifndef NDEBUG
Orientation o123_s1 = orientation123(p1, p2);
Orientation o142_s1 = orientation142(p1, p2);
CGAL_assertion( o123_s == o123_s1 );
CGAL_assertion( o142_s == o142_s1 );
#endif
#endif
// first we consider the case where both Voronoi circles are in
// conflict; we want to determine if the entire edge is in
// conflict
if ( b ) {
if ( o123_s != o142_s ) {
Orientation o123_1 = orientation123(p1, q);
Orientation o123_2 = orientation123(p2, q);
if ( o123_1 == POSITIVE && o123_2 == NEGATIVE ) { return true; }
Orientation o142_1 = orientation142(p1, q);
Orientation o142_2 = orientation142(p2, q);
return (o142_1 == NEGATIVE && o142_2 == POSITIVE);
}
Oriented_side os = Side_of_bisector_2()(p1, p2, q.point());
if ( o123_s == POSITIVE ) {
if ( os == ON_POSITIVE_SIDE ) {
Orientation o142_1 = orientation142(p1, q);
if ( o142_1 == NEGATIVE ) { return true; }
Orientation o123_1 = orientation123(p1, q);
return o123_1 == POSITIVE;
}
Orientation o142_2 = orientation142(p2, q);
if ( o142_2 == POSITIVE ) { return true; }
Orientation o123_2 = orientation123(p2, q);
return o123_2 == NEGATIVE;
}
if ( o123_s == NEGATIVE ) {
if ( os == ON_POSITIVE_SIDE ) {
Orientation o123_1 = orientation123(p1, q);
if ( o123_1 == POSITIVE ) { return true; }
Orientation o142_1 = orientation142(p1, q);
return o142_1 == NEGATIVE;
}
Orientation o123_2 = orientation123(p2, q);
if ( o123_2 == NEGATIVE ) { return true; }
Orientation o142_2 = orientation142(p2, q);
return o142_2 == POSITIVE;
}
CGAL_assertion( o123_s == ZERO );
return true;
}
// now consider the case where the two Voronoi circles are not in
// conflict; we want to determine if part of the interior is in
// conflict
if ( o123_s != o142_s ) {
Orientation o123_1 = orientation123(p1, q);
if ( o123_1 != POSITIVE ) { return false; }
Orientation o123_2 = orientation123(p2, q);
if ( o123_2 != NEGATIVE ) { return false; }
Orientation o142_1 = orientation142(p1, q);
if ( o142_1 != NEGATIVE ) { return false; }
Orientation o142_2 = orientation142(p2, q);
return o142_2 == POSITIVE;
}
Oriented_side os = Side_of_bisector_2()(p1, p2, q.point());
if ( o123_s == POSITIVE ) {
if ( os == ON_POSITIVE_SIDE ) {
Orientation o123_1 = orientation123(p1, q);
if ( o123_1 != POSITIVE ) { return false; }
Orientation o142_1 = orientation142(p1, q);
return o142_1 == NEGATIVE;
}
Orientation o123_2 = orientation123(p2, q);
if ( o123_2 != NEGATIVE ) { return false; }
Orientation o142_2 = orientation142(p2, q);
return o142_2 == POSITIVE;
}
if ( o123_s == NEGATIVE ) {
if ( os == ON_POSITIVE_SIDE ) {
Orientation o142_1 = orientation142(p1, q);
if ( o142_1 != NEGATIVE ) { return false; }
Orientation o123_1 = orientation123(p1, q);
return o123_1 == POSITIVE;
}
Orientation o142_2 = orientation142(p2, q);
if ( o142_2 != POSITIVE ) { return false; }
Orientation o123_2 = orientation123(p2, q);
return o123_2 == NEGATIVE;
}
CGAL_assertion( o123_s == ZERO );
return false;
#if 0
if ( os == ON_POSITIVE_SIDE ) {
Orientation o123_1 = orientation(p1, p2, p3, p1, q);
Orientation o142_1 = orientation(p1, p4, p2, p1, q);
// std::cerr << "o123_1: " << o123_1 << std::endl;
// std::cerr << "o142_1: " << o142_1 << std::endl;
if ( b ) {
return !(o123_1 == NEGATIVE && o142_1 == POSITIVE);
}
return o123_1 == POSITIVE && o142_1 == NEGATIVE;
}
Orientation o123_2 = orientation(p1, p2, p3, p2, q);
Orientation o142_2 = orientation(p1, p4, p2, p2, q);
// std::cerr << "o123_2: " << o123_2 << std::endl;
// std::cerr << "o142_2: " << o142_2 << std::endl;
if ( b ) {
return !(o123_2 == POSITIVE && o142_2 == NEGATIVE);
}
return o123_2 == NEGATIVE && o142_2 == POSITIVE;
#endif
#else
Constructive_orientation_2 orientation123(p1, p2, p3);
Constructive_orientation_2 orientation142(p1, p4, p2);
Orientation o123_s = orientation123(p1, p2);
Orientation o142_s = orientation142(p1, p2);
// first we consider the case where both Voronoi circles are in
// conflict; we want to determine if the entire edge is in
// conflict
if ( b ) {
if ( o123_s != o142_s ) {
Orientation o123_1 = orientation123(p1, q);
Orientation o123_2 = orientation123(p2, q);
if ( o123_1 == POSITIVE && o123_2 == NEGATIVE ) { return true; }
Orientation o142_1 = orientation142(p1, q);
Orientation o142_2 = orientation142(p2, q);
return (o142_1 == NEGATIVE && o142_2 == POSITIVE);
}
if ( o123_s == POSITIVE ) {
Orientation o142_1 = orientation142(p1, q);
if ( o142_1 == NEGATIVE ) { return true; }
Orientation o142_2 = orientation142(p2, q);
if ( o142_2 == POSITIVE ) { return true; }
Orientation o123_1 = orientation123(p1, q);
if ( o123_1 != POSITIVE ) { return false; }
Orientation o123_2 = orientation123(p2, q);
return o123_2 == NEGATIVE;
}
if ( o123_s == NEGATIVE ) {
Orientation o123_1 = orientation123(p1, q);
if ( o123_1 == POSITIVE ) { return true; }
Orientation o123_2 = orientation123(p2, q);
if ( o123_2 == NEGATIVE ) { return true; }
Orientation o142_1 = orientation142(p1, q);
if ( o142_1 != NEGATIVE ) { return false; }
Orientation o142_2 = orientation142(p2, q);
return o142_2 == POSITIVE;
}
CGAL_assertion( o123_s == ZERO );
return true;
}
// now consider the case where the two Voronoi circles are not in
// conflict; we want to determine if part of the interior is in
// conflict
if ( o123_s != o142_s ) {
Orientation o123_1 = orientation123(p1, q);
if ( o123_1 != POSITIVE ) { return false; }
Orientation o123_2 = orientation123(p2, q);
if ( o123_2 != NEGATIVE ) { return false; }
Orientation o142_1 = orientation142(p1, q);
if ( o142_1 != NEGATIVE ) { return false; }
Orientation o142_2 = orientation142(p2, q);
return o142_2 == POSITIVE;
}
if ( o123_s == POSITIVE ) {
Orientation o123_1 = orientation123(p1, q);
if ( o123_1 != POSITIVE ) { return false; }
Orientation o123_2 = orientation123(p2, q);
if ( o123_2 != NEGATIVE ) { return false; }
Orientation o142_1 = orientation142(p1, q);
if ( o142_1 == NEGATIVE ) { return true; }
Orientation o142_2 = orientation142(p2, q);
return o142_2 == POSITIVE;
}
if ( o123_s == NEGATIVE ) {
Orientation o142_1 = orientation142(p1, q);
if ( o142_1 != NEGATIVE ) { return false; }
Orientation o142_2 = orientation142(p2, q);
if ( o142_2 != POSITIVE ) { return false; }
Orientation o123_1 = orientation123(p1, q);
if ( o123_1 == POSITIVE ) { return true; }
Orientation o123_2 = orientation123(p2, q);
return o123_2 == NEGATIVE;
}
CGAL_assertion( o123_s == ZERO );
return false;
#endif
}
};
//--------------------------------------------------------------------
template < class K, class MTag >
class Finite_edge_interior_conflict8
{
public:
typedef MTag Method_tag;
typedef typename K::Site_2 Site_2;
typedef Weighted_point_inverter_2<K> Weighted_point_inverter;
typedef Inverted_weighted_point_2<K> Inverted_weighted_point;
typedef Voronoi_radius_2<K> Voronoi_radius;
typedef Voronoi_circle_2<K> Voronoi_circle;
typedef Bitangent_line_2<K> Bitangent_line;
typedef typename K::FT FT;
typedef typename K::Sign Sign;
typedef typename K::Bounded_side Bounded_side;
typedef typename K::Comparison_result Comparison_result;
typedef Bounded_side_of_CCW_circle_2<K> Bounded_side_of_CCW_circle;
typedef Sign_of_distance_from_bitangent_line_2<K>
Sign_of_distance_from_bitangent_line;
typedef Sign_of_distance_from_CCW_circle_2<K>
Sign_of_distance_from_CCW_circle;
public:
bool
operator()(const Site_2& p1,
const Site_2& p2,
const Site_2& p3,
const Site_2& p4,
const Site_2& q, bool b, const Method_tag& tag) const
{
typedef Inside_Voronoi_quadrilateral8<K,Method_tag> Inside_quadrilateral;
#ifdef AG2_PROFILE_PREDICATES
ag2_predicate_profiler::shadow_region_type_counter++;
#endif
//
Weighted_point_inverter inverter(p1);
Inverted_weighted_point u2 = inverter(p2);
Inverted_weighted_point v = inverter(q);
//
Voronoi_radius vr_12q(u2, v);
Voronoi_radius vr_1q2 = vr_12q.get_symmetric();
Bounded_side bs1 = Bounded_side_of_CCW_circle()(vr_12q, tag );
Bounded_side bs2 = Bounded_side_of_CCW_circle()(vr_1q2, tag );
bool is_bs1 = (bs1 == ON_UNBOUNDED_SIDE);
bool is_bs2 = (bs2 == ON_UNBOUNDED_SIDE);
// both the ccw and cw circles do not exist
if ( !is_bs1 && !is_bs2 ) {
return b;
}
// the ccw circle exists but not the cw
if ( is_bs1 && !is_bs2 ) {
return b;
}
// the cw circle exists but not the ccw
if ( !is_bs1 && is_bs2 ) {
return b;
}
// both circles exist
// check whether the shadow region is connected, i.e., whether it is
// of the form (a, b) or (-oo, a) U (b, +oo)
Bitangent_line bl_12(p1, p2);
Sign stc =
Sign_of_distance_from_bitangent_line()(bl_12, q, tag);
CGAL_assertion( stc != ZERO );
bool is_shadow_region_connected = (stc == POSITIVE);
if ( is_shadow_region_connected ) {
if ( b ) { return true; }
#if 0
Inverted_weighted_point u3 = inverter(p3);
Bitangent_line blinv_23(u2, u3);
Voronoi_circle vc_123(blinv_23);
Voronoi_circle vc_12q(vr_12q);
Comparison_result r =
Order_on_finite_bisector()(vc_123, vc_12q, p1, p2, tag);
if ( r != SMALLER ) { return false; }
Inverted_weighted_point u4 = inverter(p4);
Bitangent_line blinv_42(u4, u2);
Voronoi_circle vc_142(blinv_42);
Voronoi_circle vc_1q2(vr_1q2);
r = Order_on_finite_bisector()(vc_142, vc_1q2, p1, p2, tag);
return ( r == LARGER );
#else
return Inside_quadrilateral()(p1, p2, p3, p4, q, b, tag);
#endif
}
// the shadow region is of the form (-oo, a) U (b, +oo)
if ( !b ) { return false; }
#if 0
Inverted_weighted_point u3 = inverter(p3);
Bitangent_line blinv_23(u2, u3);
Voronoi_circle vc_123(blinv_23);
Voronoi_circle vc_1q2(vr_1q2);
Comparison_result r =
Order_on_finite_bisector()(vc_123, vc_1q2, p1, p2, tag);
if ( r != SMALLER ) { return true; }
Inverted_weighted_point u4 = inverter(p4);
Bitangent_line blinv_42(u4, u2);
Voronoi_circle vc_142(blinv_42);
Voronoi_circle vc_12q(vr_12q);
r = Order_on_finite_bisector()(vc_142, vc_12q, p1, p2, tag);
return ( r != LARGER );
#else
return Inside_quadrilateral()(p1, p2, p3, p4, q, b, tag);
#endif
}
};
//--------------------------------------------------------------------
template < class K, class MTag >
class Finite_edge_interior_conflict_degenerated8
{
public:
typedef typename K::Site_2 Site_2;
typedef Weighted_point_inverter_2<K> Weighted_point_inverter;
typedef Inverted_weighted_point_2<K> Inverted_weighted_point;
typedef Voronoi_radius_2<K> Voronoi_radius;
typedef Voronoi_circle_2<K> Voronoi_circle;
typedef Bitangent_line_2<K> Bitangent_line;
typedef typename K::FT FT;
typedef typename K::Sign Sign;
typedef typename K::Comparison_result Comparison_result;
typedef typename K::Orientation Orientation;
typedef typename K::Bounded_side Bounded_side;
typedef typename K::Oriented_side Oriented_side;
typedef Bounded_side_of_CCW_circle_2<K> Bounded_side_of_CCW_circle;
typedef Order_on_finite_bisector_2<K> Order_on_finite_bisector;
typedef Orientation8_C2<K,MTag> Orientation_2;
typedef Sign_of_distance_from_bitangent_line_2<K>
Sign_of_distance_from_bitangent_line;
typedef Sign_of_distance_from_CCW_circle_2<K>
Sign_of_distance_from_CCW_circle;
typedef Oriented_side_of_bisector_2<K,MTag> Side_of_bisector_2;
public:
template<class Method_tag>
bool
operator()(const Site_2& p1, const Site_2& p2, const Site_2& p3,
const Site_2& q, bool b, const Method_tag& tag) const
{
#ifdef AG2_PROFILE_PREDICATES
ag2_predicate_profiler::shadow_region_type_counter++;
#endif
//
Weighted_point_inverter inverter(p1);
Inverted_weighted_point u2 = inverter(p2);
Inverted_weighted_point v = inverter(q);
Voronoi_radius vr_12q(u2, v);
Voronoi_radius vr_1q2 = vr_12q.get_symmetric();
Bounded_side bs1 = Bounded_side_of_CCW_circle()(vr_12q, tag );
Bounded_side bs2 = Bounded_side_of_CCW_circle()(vr_1q2, tag );
bool is_bs1 = (bs1 == ON_UNBOUNDED_SIDE);
bool is_bs2 = (bs2 == ON_UNBOUNDED_SIDE);
// both the ccw and cw circles do not exist
if ( !is_bs1 && !is_bs2 ) {
return b;
}
// the ccw circle exists but not the cw
if ( is_bs1 && !is_bs2 ) {
return b;
}
// the cw circle exists but not the ccw
if ( !is_bs1 && is_bs2 ) {
return b;
}
// both circles exist
// check whether the shadow region is connected, i.e., whether it is
// of the form (a, b) or (-oo, a) U (b, +oo)
Bitangent_line bl_12(p1, p2);
Sign stc = Sign_of_distance_from_bitangent_line()(bl_12, q, tag);
Inverted_weighted_point u3 = inverter(p3);
Bitangent_line blinv_23(u2, u3);
CGAL_assertion( stc != ZERO );
bool is_shadow_region_connected = (stc == POSITIVE);
if ( is_shadow_region_connected ) {
// the shadow region is of the form (a, b)
if ( b ) { return false; }
Voronoi_circle vc_123(blinv_23);
Voronoi_circle vc_12q(vr_12q);
Comparison_result r =
Order_on_finite_bisector()(vc_123, vc_12q, p1, p2, tag);
return ( r == SMALLER );
}
// the shadow region is of the form (-oo, a) U (b, +oo)
if ( !b ) { return false; }
Voronoi_circle vc_123(blinv_23);
Voronoi_circle vc_1q2(vr_1q2);
Comparison_result r =
Order_on_finite_bisector()(vc_123, vc_1q2, p1, p2, tag);
return ( r != SMALLER );
}
inline
Sign sqrt_ext_sign(const FT& A1, const FT& Dr, const FT& B,
const FT& Dx1, const FT& Dy1,
const FT& Dx2, const FT& Dy2,
const Field_with_sqrt_tag&) const
{
FT D = CGAL::square(Dx1) + CGAL::square(Dy1) - CGAL::square(Dr);
return CGAL::sign(A1 * Dr + B * CGAL::sqrt(D));
}
inline
Sign sqrt_ext_sign(const FT& A1, const FT& Dr, const FT& B,
const FT& Dx1, const FT& Dy1,
const FT& Dx2, const FT& Dy2,
const Integral_domain_without_division_tag&) const
{
Sign sA = CGAL::sign(A1) * CGAL::sign(Dr);
Sign sB = CGAL::sign(B);
if ( sA == CGAL::ZERO ) { return sB; }
if ( sB == CGAL::ZERO ) { return sA; }
if ( sA == sB ) { return sA; }
FT C = (CGAL::square(Dx2) + CGAL::square(Dy2)) * CGAL::square(Dr);
return sA * CGAL::sign(C - CGAL::square(B));
}
template<class Method_tag>
Orientation
orientation_wrt_bitangent_perp(const Site_2& p1, const Site_2& p2,
const Site_2& q1, const Site_2& q2,
const Method_tag& tag) const
{
// computes the orientation predicate of the line perpendicular to
// the bitangent of p1 and p2, passing through the center of q1,
// and the center of q2
FT Dx1 = p1.x() - p2.x();
FT Dy1 = p1.y() - p2.y();
FT Dr = p1.weight() - p2.weight();
FT Dx2 = q1.x() - q2.x();
FT Dy2 = q1.y() - q2.y();
FT A1 = Dx1 * Dy2 - Dy1 * Dx2;
FT B = Dx1 * Dx2 + Dy1 * Dy2;
return sqrt_ext_sign(A1, Dr, B, Dx1, Dy1, Dx2, Dy2, tag);
}
template<class Method_tag>
bool
operator()(const Site_2& p1, const Site_2& p2,
const Site_2& q, bool b, const Method_tag& tag) const
{
#if 0
Side_of_bisector_2 side_of_bisector;
Orientation o12_sym = Orientation_2()(p1, p2, q);
Oriented_side os = side_of_bisector(p1, p2, q.point());
if ( o12_sym == CGAL::POSITIVE ) {
if ( os == ON_POSITIVE_SIDE ) {
Orientation o21_1 = orientation_wrt_bitangent_perp(p2, p1, p1, q, tag);
return o21_1 == NEGATIVE;
}
Orientation o21_2 = orientation_wrt_bitangent_perp(p2, p1, p2, q, tag);
return o21_2 == POSITIVE;
} else {
if ( os == ON_POSITIVE_SIDE ) {
Orientation o12_1 = orientation_wrt_bitangent_perp(p1, p2, p1, q, tag);
return o12_1 == POSITIVE;
}
Orientation o12_2 = orientation_wrt_bitangent_perp(p1, p2, p2, q, tag);
return o12_2 == NEGATIVE;
}
#else
Orientation o12_sym = Orientation_2()(p1, p2, q);
if ( o12_sym == CGAL::POSITIVE ) {
Orientation o21_1 = orientation_wrt_bitangent_perp(p2, p1, p1, q, tag);
if ( o21_1 != NEGATIVE ) { return false; }
Orientation o21_2 = orientation_wrt_bitangent_perp(p2, p1, p2, q, tag);
return o21_2 == POSITIVE;
} else {
Orientation o12_1 = orientation_wrt_bitangent_perp(p1, p2, p1, q, tag);
if ( o12_1 != POSITIVE ) { return false; }
Orientation o12_2 = orientation_wrt_bitangent_perp(p1, p2, p2, q, tag);
return o12_2 == NEGATIVE;
}
#endif
#ifdef AG2_PROFILE_PREDICATES
ag2_predicate_profiler::shadow_region_type_counter++;
#endif
}
};
//--------------------------------------------------------------------
template<class K, class MTag>
class Finite_edge_interior_conflict8_2
{
public:
typedef K Kernel;
typedef MTag Method_tag;
typedef typename K::Site_2 Site_2;
private:
typedef Finite_edge_interior_conflict_degenerated8<K,MTag> Test_degenerated;
typedef Finite_edge_interior_conflict8<K,MTag> Test;
public:
typedef bool result_type;
struct argument_type {};
inline
bool operator()(const Site_2& p1, const Site_2& p2,
const Site_2& q, bool b) const
{
typedef Finite_edge_interior_conflict_2<K,MTag> Old_Test;
bool t = Test_degenerated()(p1, p2, q, b, Method_tag());
// bool t = Old_Test()(p1, p2, q, b);
#ifndef NDEBUG
bool t_old = Old_Test()(p1, p2, q, b);
if ( t != t_old ) {
std::cerr << std::endl;
std::cerr << "b: " << b << "; t: " << t
<< "; t_old: " << t_old << std::endl;
std::cerr << "p1: " << p1 << std::endl;
std::cerr << "p2: " << p2 << std::endl;
std::cerr << "q: " << q << std::endl;
}
CGAL_assertion( t == t_old );
#endif
return t;
}
inline
bool operator()(const Site_2& p1, const Site_2& p2,
const Site_2& p3, const Site_2& q, bool b) const
{
return Test_degenerated()(p1, p2, p3, q, b, Method_tag());
}
inline
bool operator()(const Site_2& p1, const Site_2& p2,
const Site_2& p3, const Site_2& p4,
const Site_2& q, bool b) const
{
typedef Finite_edge_interior_conflict_2<K,MTag> Old_Test;
bool t = Test()(p1, p2, p3, p4, q, b, Method_tag());
// bool t = Old_Test()(p1, p2, p3, p4, q, b);
#ifndef NDEBUG
bool t_old = Old_Test()(p1, p2, p3, p4, q, b);
if ( t != t_old ) {
Oriented_side_of_bisector_2<K,MTag> side_of_bisector;
Oriented_side os = side_of_bisector(p1, p2, q.point());
std::cerr << "b: " << b << std::endl;
std::cerr << "t: " << t << "; t_old: " << t_old << std::endl;
std::cerr << "os: " << os << std::endl;
std::cerr << "p1: " << p1 << std::endl;
std::cerr << "p2: " << p2 << std::endl;
std::cerr << "p3: " << p3 << std::endl;
std::cerr << "p4: " << p4 << std::endl;
std::cerr << "q: " << q << std::endl;
}
CGAL_assertion( t == t_old );
#endif
return t; //Test()(p1, p2, p3, p4, q, b, Method_tag());
}
};
//--------------------------------------------------------------------
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_FINITE_EDGE_TEST8_C2_H

View File

@ -0,0 +1,632 @@
// Copyright (c) 2003,2004,2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_FINITE_EDGE_TEST_C2_H
#define CGAL_APOLLONIUS_GRAPH_2_FINITE_EDGE_TEST_C2_H
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/Apollonius_graph_2/basic.h>
#include <CGAL/Apollonius_graph_2/Predicate_constructions_C2.h>
#include <CGAL/functions_on_signs.h>
#include <CGAL/Apollonius_graph_2/compare_quadratic.h>
namespace CGAL {
namespace ApolloniusGraph_2 {
//--------------------------------------------------------------------
template< class K >
class Orientation_wrt_symmetry_axis_2
{
public:
typedef typename K::Point_2 Point_2;
typedef Voronoi_circle_2<K> Voronoi_circle;
typedef typename K::FT FT;
typedef typename K::Orientation Orientation;
public:
Orientation
operator()(const Voronoi_circle& vc, const Point_2& p1,
const Point_2& p2, const Field_with_sqrt_tag&) const
{
FT a = vc.a1() + vc.a2() * CGAL::sqrt(vc.delta());
FT b = vc.b1() + vc.b2() * CGAL::sqrt(vc.delta());
FT det = a * (p2.y() - p1.y()) - b * (p2.x() - p1.x());
return CGAL::sign(det);
}
Orientation
operator()(const Voronoi_circle& vc, const Point_2& p1,
const Point_2& p2, const Integral_domain_without_division_tag&) const
{
FT dx = p2.x() - p1.x();
FT dy = p2.y() - p1.y();
FT A = vc.a1() * dy - vc.b1() * dx;
FT B = vc.a2() * dy - vc.b2() * dx;
return sign_a_plus_b_x_sqrt_c(A, B, vc.delta());
}
};
//--------------------------------------------------------------------
template< class K >
class Compare_Voronoi_radii_2
{
public:
typedef Voronoi_circle_2<K> Voronoi_circle;
typedef typename K::FT FT;
typedef typename K::Sign Sign;
typedef typename K::Comparison_result Comparison_result;
private:
Sign sign_of_P4(const FT& u, const FT& v,
const FT& du, const FT& dv, const FT& dr,
const FT& Du, const FT& Dv, const FT& Dr) const
{
std::pair<FT,FT> factors = factors_of_P4(u, v, du, dv, dr,
Du, Dv, Dr);
Sign s1 = CGAL::sign(factors.first);
Sign s2 = CGAL::sign(factors.second);
return s1 * s2;
}
std::pair<FT,FT>
factors_of_P4(const FT& u, const FT& v,
const FT& du, const FT& dv, const FT& dr,
const FT& Du, const FT& Dv, const FT& Dr) const
{
FT u2 = CGAL::square(u);
FT v2 = CGAL::square(v);
FT du2 = CGAL::square(du);
FT Du2 = CGAL::square(Du);
FT dv2 = CGAL::square(dv);
FT Dv2 = CGAL::square(Dv);
FT dr2 = CGAL::square(dr);
FT Dr2 = CGAL::square(Dr);
FT u2_P_v2 = u2 + v2;
FT u2_M_v2 = u2 - v2;
FT uv = FT(2) * u * v;
FT drDr = FT(2) * dr * Dr;
FT du2_P_dv2 = du2 + dv2;
FT Du2_P_Dv2 = Du2 + Dv2;
FT uU_P_vV = du * Du + dv * Dv;
FT uU_M_vV = du * Du - dv * Dv;
FT uV_P_Uv = du * Dv + Du * dv;
FT uV_M_Uv = du * Dv - Du * dv;
FT F1 = du2_P_dv2 * Dr2 + Du2_P_Dv2 * dr2
- uU_P_vV * drDr - CGAL::square(uV_M_Uv);
FT F2 = CGAL::square(u2_P_v2) * (du2_P_dv2 * Dr2 + Du2_P_Dv2 * dr2);
F2 -= u2_P_v2 * (u2_M_v2 * uU_M_vV + uv * uV_P_Uv) * drDr;
F2 -= CGAL::square(u2_M_v2 * uV_P_Uv - uv * uU_M_vV);
std::pair<FT, FT> factors(F1,F2);
return factors;
}
public:
Comparison_result
operator()(const Voronoi_circle& vc1, const Voronoi_circle& vc2,
const Field_with_sqrt_tag&) const
{
FT c1 = (vc1.c1() + vc1.c2() * CGAL::sqrt(vc1.delta())) / vc1.d();
FT c2 = (vc2.c1() + vc2.c2() * CGAL::sqrt(vc2.delta())) / vc2.d();
Comparison_result r = CGAL::compare(c2, c1);
return r;
}
// this is the naive way but without divisions and square roots; the
// degree becomes 36 in this case.
/*
Comparison_result
operator()(const Voronoi_circle& vc1, const Voronoi_circle& vc2,
Integral_domain_without_division_tag)
{
FT A = vc1.c1() * vc2.d() - vc2.c1() * vc1.d();
FT B = vc1.c2() * vc2.d();
FT C = -vc2.c2() * vc1.d();
FT E = vc1.delta();
FT F = vc2.delta();
Sign s = sign_a_plus_b_x_sqrt_e_plus_c_x_sqrt_f(A,B,C,E,F);
if ( s == ZERO ) { return EQUAL; }
return ( s == POSITIVE ) ? SMALLER : LARGER;
}
*/
Comparison_result
operator()(const Voronoi_circle& vc1, const Voronoi_circle& vc2,
const Integral_domain_without_division_tag&) const
{
bool is_first_root1 = vc1.is_first_root();
bool is_first_root2 = vc2.is_first_root();
CGAL_precondition( CGAL::is_positive(vc1.alpha()) );
CGAL_precondition( CGAL::is_positive(vc2.alpha()) );
Comparison_result r;
if ( is_first_root1 && is_first_root2 ) {
r = ke_compare_l1_l2(vc1.alpha(), vc1.beta(), vc1.gamma(),
vc2.alpha(), vc2.beta(), vc2.gamma());
} else if ( is_first_root1 && !is_first_root2 ) {
r = ke_compare_l1_r2(vc1.alpha(), vc1.beta(), vc1.gamma(),
vc2.alpha(), vc2.beta(), vc2.gamma());
} else if ( !is_first_root1 && is_first_root2 ) {
r = ke_compare_r1_l2(vc1.alpha(), vc1.beta(), vc1.gamma(),
vc2.alpha(), vc2.beta(), vc2.gamma());
} else {
r = ke_compare_r1_r2(vc1.alpha(), vc1.beta(), vc1.gamma(),
vc2.alpha(), vc2.beta(), vc2.gamma());
}
#ifdef COMPARATOR_PROFILER
if ( comparator_profiler::count_cases ) {
// count cases only for the tree r1-r2
if ( !is_first_root1 && !is_first_root2 ) {
comparator_profiler::count_case(vc1.alpha(), vc1.beta(),
vc1.gamma(),
vc2.alpha(), vc2.beta(),
vc2.gamma());
}
}
#endif
if ( r == EQUAL ) { return EQUAL; }
return ( r == LARGER ) ? SMALLER : LARGER;
}
// this uses the DFMT trees; slightly slower but same degree (20).
/*
Comparison_result
operator()(const Voronoi_circle& vc1, const Voronoi_circle& vc2,
Integral_domain_without_division_tag)
{
bool is_first_root1 = vc1.is_first_root();
bool is_first_root2 = vc2.is_first_root();
CGAL_precondition( CGAL::is_positive(vc1.alpha()) );
CGAL_precondition( CGAL::is_positive(vc2.alpha()) );
Comparison_result r;
if ( is_first_root1 && is_first_root2 ) {
r = dfmt_compare_l1_l2(vc1.alpha(), vc1.beta(), vc1.gamma(),
vc2.alpha(), vc2.beta(), vc2.gamma());
} else if ( is_first_root1 && !is_first_root2 ) {
r = dfmt_compare_l1_r2(vc1.alpha(), vc1.beta(), vc1.gamma(),
vc2.alpha(), vc2.beta(), vc2.gamma());
} else if ( !is_first_root1 && is_first_root2 ) {
r = dfmt_compare_r1_l2(vc1.alpha(), vc1.beta(), vc1.gamma(),
vc2.alpha(), vc2.beta(), vc2.gamma());
} else {
r = dfmt_compare_r1_r2(vc1.alpha(), vc1.beta(), vc1.gamma(),
vc2.alpha(), vc2.beta(), vc2.gamma());
}
if ( r == EQUAL ) { return EQUAL; }
return ( r == LARGER ) ? SMALLER : LARGER;
}
*/
};
//--------------------------------------------------------------------
template< class K >
class Order_on_finite_bisector_2
{
public:
typedef Voronoi_circle_2<K> Voronoi_circle;
typedef typename K::Site_2 Site_2;
typedef typename K::FT FT;
typedef typename K::Comparison_result Comparison_result;
typedef typename K::Orientation Orientation;
typedef Compare_Voronoi_radii_2<K> Compare_Voronoi_radii;
typedef Orientation_wrt_symmetry_axis_2<K>
Orientation_wrt_symmetry_axis;
public:
template<class Method_tag>
Comparison_result
operator()(const Voronoi_circle& vc1, const Voronoi_circle& vc2,
const Site_2& p1, const Site_2& p2,
const Method_tag& tag) const
{
#ifdef AG2_PROFILE_PREDICATES
ag2_predicate_profiler::order_on_bisector_counter++;
#endif
Orientation o1 =
Orientation_wrt_symmetry_axis()(vc1, p1.point(), p2.point(), tag);
Orientation o2 =
Orientation_wrt_symmetry_axis()(vc2, p1.point(), p2.point(), tag);
Comparison_result cr;
if ( o1 == LEFT_TURN ) {
if ( o2 != LEFT_TURN ) { return SMALLER; }
Comparison_result r = Compare_Voronoi_radii()(vc1, vc2, tag);
if ( r == EQUAL ) {
cr = EQUAL;
} else {
cr = (r == LARGER ) ? SMALLER : LARGER;
}
} else if ( o1 == COLLINEAR ) {
if ( o2 == COLLINEAR ) {
cr = EQUAL;
} else {
cr = (o2 == LEFT_TURN) ? LARGER : SMALLER;
}
} else {
if ( o2 != RIGHT_TURN ) {
cr = LARGER;
} else {
Comparison_result r =
Compare_Voronoi_radii()(vc1, vc2, tag);
cr = r;
}
}
return cr;
}
};
//--------------------------------------------------------------------
template < class K >
class Finite_edge_interior_conflict
{
public:
typedef typename K::Site_2 Site_2;
typedef Weighted_point_inverter_2<K> Weighted_point_inverter;
typedef Inverted_weighted_point_2<K> Inverted_weighted_point;
typedef Voronoi_radius_2<K> Voronoi_radius;
typedef Voronoi_circle_2<K> Voronoi_circle;
typedef Bitangent_line_2<K> Bitangent_line;
typedef typename K::FT FT;
typedef typename K::Sign Sign;
typedef typename K::Bounded_side Bounded_side;
typedef typename K::Comparison_result Comparison_result;
typedef Bounded_side_of_CCW_circle_2<K> Bounded_side_of_CCW_circle;
typedef Order_on_finite_bisector_2<K> Order_on_finite_bisector;
typedef Sign_of_distance_from_bitangent_line_2<K>
Sign_of_distance_from_bitangent_line;
typedef Sign_of_distance_from_CCW_circle_2<K>
Sign_of_distance_from_CCW_circle;
public:
template<class Method_tag>
bool
operator()(const Site_2& p1,
const Site_2& p2,
const Site_2& p3,
const Site_2& p4,
const Site_2& q, bool b, const Method_tag& tag) const
{
#ifdef AG2_PROFILE_PREDICATES
ag2_predicate_profiler::shadow_region_type_counter++;
#endif
//
Weighted_point_inverter inverter(p1);
Inverted_weighted_point u2 = inverter(p2);
Inverted_weighted_point v = inverter(q);
//
Voronoi_radius vr_12q(u2, v);
Voronoi_radius vr_1q2 = vr_12q.get_symmetric();
Bounded_side bs1 = Bounded_side_of_CCW_circle()(vr_12q, tag );
Bounded_side bs2 = Bounded_side_of_CCW_circle()(vr_1q2, tag );
bool is_bs1 = (bs1 == ON_UNBOUNDED_SIDE);
bool is_bs2 = (bs2 == ON_UNBOUNDED_SIDE);
// both the ccw and cw circles do not exist
if ( !is_bs1 && !is_bs2 ) {
return b;
}
// the ccw circle exists but not the cw
if ( is_bs1 && !is_bs2 ) {
return b;
}
// the cw circle exists but not the ccw
if ( !is_bs1 && is_bs2 ) {
return b;
}
// both circles exist
// check whether the shadow region is connected, i.e., whether it is
// of the form (a, b) or (-oo, a) U (b, +oo)
Bitangent_line bl_12(p1, p2);
Sign stc =
Sign_of_distance_from_bitangent_line()(bl_12, q, tag);
CGAL_assertion( stc != ZERO );
bool is_shadow_region_connected = (stc == POSITIVE);
if ( is_shadow_region_connected ) {
if ( b ) { return true; }
Inverted_weighted_point u3 = inverter(p3);
Bitangent_line blinv_23(u2, u3);
Voronoi_circle vc_123(blinv_23);
Voronoi_circle vc_12q(vr_12q);
Comparison_result r =
Order_on_finite_bisector()(vc_123, vc_12q, p1, p2, tag);
if ( r != SMALLER ) { return false; }
Inverted_weighted_point u4 = inverter(p4);
Bitangent_line blinv_42(u4, u2);
Voronoi_circle vc_142(blinv_42);
Voronoi_circle vc_1q2(vr_1q2);
r = Order_on_finite_bisector()(vc_142, vc_1q2, p1, p2, tag);
return ( r == LARGER );
}
// the shadow region is of the form (-oo, a) U (b, +oo)
if ( !b ) { return false; }
Inverted_weighted_point u3 = inverter(p3);
Bitangent_line blinv_23(u2, u3);
Voronoi_circle vc_123(blinv_23);
Voronoi_circle vc_1q2(vr_1q2);
Comparison_result r =
Order_on_finite_bisector()(vc_123, vc_1q2, p1, p2, tag);
if ( r != SMALLER ) { return true; }
Inverted_weighted_point u4 = inverter(p4);
Bitangent_line blinv_42(u4, u2);
Voronoi_circle vc_142(blinv_42);
Voronoi_circle vc_12q(vr_12q);
r = Order_on_finite_bisector()(vc_142, vc_12q, p1, p2, tag);
return ( r != LARGER );
}
};
//--------------------------------------------------------------------
template < class K >
class Finite_edge_interior_conflict_degenerated
{
public:
typedef typename K::Site_2 Site_2;
typedef Weighted_point_inverter_2<K> Weighted_point_inverter;
typedef Inverted_weighted_point_2<K> Inverted_weighted_point;
typedef Voronoi_radius_2<K> Voronoi_radius;
typedef Voronoi_circle_2<K> Voronoi_circle;
typedef Bitangent_line_2<K> Bitangent_line;
typedef typename K::FT FT;
typedef typename K::Sign Sign;
typedef typename K::Comparison_result Comparison_result;
typedef typename K::Bounded_side Bounded_side;
typedef Bounded_side_of_CCW_circle_2<K> Bounded_side_of_CCW_circle;
typedef Order_on_finite_bisector_2<K> Order_on_finite_bisector;
typedef Sign_of_distance_from_bitangent_line_2<K>
Sign_of_distance_from_bitangent_line;
typedef Sign_of_distance_from_CCW_circle_2<K>
Sign_of_distance_from_CCW_circle;
public:
template<class Method_tag>
bool
operator()(const Site_2& p1, const Site_2& p2, const Site_2& p3,
const Site_2& q, bool b, const Method_tag& tag) const
{
#ifdef AG2_PROFILE_PREDICATES
ag2_predicate_profiler::shadow_region_type_counter++;
#endif
//
Weighted_point_inverter inverter(p1);
Inverted_weighted_point u2 = inverter(p2);
Inverted_weighted_point v = inverter(q);
Voronoi_radius vr_12q(u2, v);
Voronoi_radius vr_1q2 = vr_12q.get_symmetric();
Bounded_side bs1 = Bounded_side_of_CCW_circle()(vr_12q, tag );
Bounded_side bs2 = Bounded_side_of_CCW_circle()(vr_1q2, tag );
bool is_bs1 = (bs1 == ON_UNBOUNDED_SIDE);
bool is_bs2 = (bs2 == ON_UNBOUNDED_SIDE);
// both the ccw and cw circles do not exist
if ( !is_bs1 && !is_bs2 ) {
return b;
}
// the ccw circle exists but not the cw
if ( is_bs1 && !is_bs2 ) {
return b;
}
// the cw circle exists but not the ccw
if ( !is_bs1 && is_bs2 ) {
return b;
}
// both circles exist
// check whether the shadow region is connected, i.e., whether it is
// of the form (a, b) or (-oo, a) U (b, +oo)
Bitangent_line bl_12(p1, p2);
Sign stc = Sign_of_distance_from_bitangent_line()(bl_12, q, tag);
Inverted_weighted_point u3 = inverter(p3);
Bitangent_line blinv_23(u2, u3);
CGAL_assertion( stc != ZERO );
bool is_shadow_region_connected = (stc == POSITIVE);
if ( is_shadow_region_connected ) {
// the shadow region is of the form (a, b)
if ( b ) { return false; }
Voronoi_circle vc_123(blinv_23);
Voronoi_circle vc_12q(vr_12q);
Comparison_result r =
Order_on_finite_bisector()(vc_123, vc_12q, p1, p2, tag);
return ( r == SMALLER );
}
// the shadow region is of the form (-oo, a) U (b, +oo)
if ( !b ) { return false; }
Voronoi_circle vc_123(blinv_23);
Voronoi_circle vc_1q2(vr_1q2);
Comparison_result r =
Order_on_finite_bisector()(vc_123, vc_1q2, p1, p2, tag);
return ( r != SMALLER );
}
template<class Method_tag>
bool
operator()(const Site_2& p1, const Site_2& p2,
const Site_2& q, bool b, const Method_tag& tag) const
{
#ifdef AG2_PROFILE_PREDICATES
ag2_predicate_profiler::shadow_region_type_counter++;
#endif
//
Weighted_point_inverter inverter(p1);
Inverted_weighted_point u2 = inverter(p2);
Inverted_weighted_point v = inverter(q);
Voronoi_radius vr_12q(u2, v);
Voronoi_radius vr_1q2 = vr_12q.get_symmetric();
Bounded_side bs1 = Bounded_side_of_CCW_circle()(vr_12q, tag );
Bounded_side bs2 = Bounded_side_of_CCW_circle()(vr_1q2, tag );
bool is_bs1 = (bs1 == ON_UNBOUNDED_SIDE);
bool is_bs2 = (bs2 == ON_UNBOUNDED_SIDE);
// both the ccw and cw circles do not exist
if ( !is_bs1 && !is_bs2 ) {
return b;
}
// only the ccw circle exists
if ( is_bs1 && !is_bs2 ) { return false; }
// only the cw circle exists
if ( !is_bs1 && is_bs2 ) { return false; }
// both circles exist
// check whether the shadow region is connected, i.e., whether it is
// of the form (a, b) or (-oo, a) U (b, +oo)
return !b;
}
};
//--------------------------------------------------------------------
template<class K, class MTag>
class Finite_edge_interior_conflict_2
{
public:
typedef K Kernel;
typedef MTag Method_tag;
typedef typename K::Site_2 Site_2;
private:
typedef Finite_edge_interior_conflict_degenerated<K> Test_degenerated;
typedef Finite_edge_interior_conflict<K> Test;
public:
typedef bool result_type;
struct argument_type {};
inline
bool operator()(const Site_2& p1, const Site_2& p2,
const Site_2& q, bool b) const
{
return Test_degenerated()(p1, p2, q, b, Method_tag());
}
inline
bool operator()(const Site_2& p1, const Site_2& p2,
const Site_2& p3, const Site_2& q, bool b) const
{
return Test_degenerated()(p1, p2, p3, q, b, Method_tag());
}
inline
bool operator()(const Site_2& p1, const Site_2& p2,
const Site_2& p3, const Site_2& p4,
const Site_2& q, bool b) const
{
return Test()(p1, p2, p3, p4, q, b, Method_tag());
}
};
//--------------------------------------------------------------------
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_FINITE_EDGE_TEST_C2_H

View File

@ -0,0 +1,132 @@
// Copyright (c) 2007 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_INCIRCLE8_C2_H
#define CGAL_APOLLONIUS_GRAPH_2_INCIRCLE8_C2_H
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/determinant.h>
#include <CGAL/Apollonius_graph_2/Incircle_C2.h>
namespace CGAL {
namespace ApolloniusGraph_2 {
//--------------------------------------------------------------------
template < class K, class MTag >
class Vertex_conflict8_2
: public Vertex_conflict_2<K,MTag>
{
private:
typedef Vertex_conflict_2<K,MTag> Base;
public:
typedef typename Base::Kernel Kernel;
typedef typename Base::Method_tag Method_tag;
typedef typename Base::Site_2 Site_2;
typedef typename Base::FT FT;
typedef typename Base::Sign Sign;
public:
typedef Sign result_type;
typedef Site_2 argument_type;
private:
inline
Sign predicate(const FT& Exp, const FT& Eyp, const FT& Erp,
const FT& Exrp, const FT& Eyrp, const FT& Exyp,
const Field_with_sqrt_tag&) const
{
FT G = CGAL::square(Exp) + CGAL::square(Eyp) - CGAL::square(Erp);
return CGAL::sign(Exp * Exrp + Eyp * Eyrp + Exyp * CGAL::sqrt(G));
}
inline
Sign predicate(const FT& Exp, const FT& Eyp, const FT& /* Erp */,
const FT& Exrp, const FT& Eyrp, const FT& Exyp,
const Integral_domain_without_division_tag&) const
{
Sign sA = CGAL::sign(Exp * Exrp + Eyp * Eyrp);
Sign sB = CGAL::sign(Exyp);
if ( sA == CGAL::ZERO ) { return sB; }
if ( sB == CGAL::ZERO ) { return sA; }
if ( sA == sB ) { return sA; }
Sign s =
CGAL::sign(CGAL::square(Exrp) + CGAL::square(Eyrp) - CGAL::square(Exyp));
return sA * s;
}
public:
inline
Sign operator()(const Site_2& p1, const Site_2& p2,
const Site_2& p3, const Site_2& q) const
{
#ifdef AG2_PROFILE_PREDICATES
ag2_predicate_profiler::incircle_counter++;
#endif
FT xj = p2.x() - p1.x();
FT xk = p3.x() - p1.x();
FT xl = q.x() - p1.x();
FT yj = p2.y() - p1.y();
FT yk = p3.y() - p1.y();
FT yl = q.y() - p1.y();
FT rj = p2.weight() - p1.weight();
FT rk = p3.weight() - p1.weight();
FT rl = q.weight() - p1.weight();
FT pj = CGAL::square(xj) + CGAL::square(yj) - CGAL::square(rj);
FT pk = CGAL::square(xk) + CGAL::square(yk) - CGAL::square(rk);
FT pl = CGAL::square(xl) + CGAL::square(yl) - CGAL::square(rl);
FT Exp = determinant(xj, pj, xk, pk);
FT Eyp = determinant(yj, pj, yk, pk);
FT Erp = determinant(rj, pj, rk, pk);
FT Exy = determinant(xj, yj, xk, yk);
FT Exr = determinant(xj, rj, xk, rk);
FT Eyr = determinant(yj, rj, yk, rk);
FT Exyp = xl * Eyp - yl * Exp + pl * Exy;
FT Exrp = xl * Erp - rl * Exp + pl * Exr;
FT Eyrp = yl * Erp - rl * Eyp + pl * Eyr;
return predicate(Exp, Eyp, Erp, Exrp, Eyrp, Exyp, Method_tag());
}
inline
Sign operator()(const Site_2& p1, const Site_2& p2,
const Site_2& q) const
{
return Base::operator()(p1, p2, q);
}
};
//--------------------------------------------------------------------
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_INCIRCLE8_C2_H

View File

@ -0,0 +1,243 @@
// Copyright (c) 2003,2004,2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_INCIRCLE_C2_H
#define CGAL_APOLLONIUS_GRAPH_2_INCIRCLE_C2_H
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/Apollonius_graph_2/basic.h>
#include <CGAL/Apollonius_graph_2/Predicate_constructions_C2.h>
#include <CGAL/Apollonius_graph_2/Bounded_side_of_ccw_circle_C2.h>
#include <CGAL/functions_on_signs.h>
namespace CGAL {
namespace ApolloniusGraph_2 {
//--------------------------------------------------------------------
template< class K >
class Sign_of_distance_from_bitangent_line_2
{
public:
typedef Bitangent_line_2<K> Bitangent_line;
typedef typename K::Site_2 Site_2;
typedef Inverted_weighted_point_2<K> Inverted_weighted_point;
typedef typename K::FT FT;
typedef typename K::Sign Sign;
public:
inline Sign
operator()(const Bitangent_line& bl, const Site_2& q,
const Field_with_sqrt_tag&) const
{
#ifdef AG2_PROFILE_PREDICATES
ag2_predicate_profiler::distance_from_bitangent_counter++;
#endif
FT a = bl.a1() + bl.a2() * CGAL::sqrt(bl.delta());
FT b = bl.b1() + bl.b2() * CGAL::sqrt(bl.delta());
FT c = bl.c1() + bl.c2() * CGAL::sqrt(bl.delta());
FT r = a * q.x() + b * q.y() + c - q.weight() * bl.d();
return CGAL::sign(r);
}
inline Sign
operator()(const Bitangent_line& bl, const Site_2& q,
const Integral_domain_without_division_tag&) const
{
#ifdef AG2_PROFILE_PREDICATES
ag2_predicate_profiler::distance_from_bitangent_counter++;
#endif
FT A = bl.a1() * q.x() + bl.b1() * q.y() + bl.c1()
- q.weight() * bl.d();
FT B = bl.a2() * q.x() + bl.b2() * q.y() + bl.c2();
return sign_a_plus_b_x_sqrt_c(A, B, bl.delta());
}
};
//--------------------------------------------------------------------
template< class K >
class Sign_of_distance_from_CCW_circle_2
{
public:
typedef Bitangent_line_2<K> Bitangent_line;
typedef Inverted_weighted_point_2<K> Inverted_weighted_point;
typedef typename K::FT FT;
typedef typename K::Sign Sign;
public:
inline Sign
operator()(const Bitangent_line& bl,
const Inverted_weighted_point& v,
const Field_with_sqrt_tag&) const
{
FT a = bl.a1() + bl.a2() * CGAL::sqrt(bl.delta());
FT b = bl.b1() + bl.b2() * CGAL::sqrt(bl.delta());
FT c = bl.c1() + bl.c2() * CGAL::sqrt(bl.delta());
FT r = a * v.x() + b * v.y() + c * v.p() - v.weight() * bl.d();
return CGAL::sign(r);
}
inline Sign
operator()(const Bitangent_line& bl,
const Inverted_weighted_point& v,
const Integral_domain_without_division_tag&) const
{
FT A = bl.a1() * v.x() + bl.b1() * v.y() + bl.c1() * v.p()
- v.weight() * bl.d();
FT B = bl.a2() * v.x() + bl.b2() * v.y() + bl.c2() * v.p();
return sign_a_plus_b_x_sqrt_c(A, B, bl.delta());
}
};
template < class Weighted_point >
class Weighted_point_less_than
{
public:
inline
bool operator()(const Weighted_point& p1,
const Weighted_point& p2) const
{
if ( p1.x() == p2.x() ) {
return p1.y() < p2.y();
}
return p1.x() < p2.x();
}
};
template < class K, class MTag >
class Vertex_conflict_2
{
public:
typedef K Kernel;
typedef MTag Method_tag;
typedef typename K::Point_2 Point_2;
typedef typename K::Site_2 Site_2;
typedef Weighted_point_inverter_2<K> Weighted_point_inverter;
typedef Inverted_weighted_point_2<K> Inverted_weighted_point;
typedef Bitangent_line_2<K> Bitangent_line;
typedef Voronoi_radius_2<K> Voronoi_radius;
typedef typename K::FT FT;
typedef typename K::Orientation Orientation;
typedef typename K::Sign Sign;
typedef typename K::Bounded_side Bounded_side;
typedef Bounded_side_of_CCW_circle_2<K> Bounded_side_of_CCW_circle;
typedef Sign_of_distance_from_bitangent_line_2<K>
Sign_of_distance_from_bitangent_line;
typedef Sign_of_distance_from_CCW_circle_2<K>
Sign_of_distance_from_CCW_circle;
private:
inline Orientation
orientation(const Bitangent_line& l, const Point_2& p,
const Field_with_sqrt_tag&) const
{
FT A = l.a1() * p.x() + l.b1() * p.y() + l.c1();
FT B = l.a2() * p.x() + l.b2() * p.y() + l.c2();
FT P = A + B * CGAL::sqrt(l.delta());
return CGAL::sign(P);
}
inline Orientation
orientation(const Bitangent_line& l, const Point_2& p,
const Integral_domain_without_division_tag&) const
{
FT A = l.a1() * p.x() + l.b1() * p.y() + l.c1();
FT B = l.a2() * p.x() + l.b2() * p.y() + l.c2();
return sign_a_plus_b_x_sqrt_c(A, B, l.delta());
}
inline Orientation
orientation(const Bitangent_line& l,
const Inverted_weighted_point& u) const
{
FT A = l.a1() * u.x() / u.p() + l.b1() * u.y() / u.p() + l.c1();
FT B = l.a2() * u.x() / u.p() + l.b2() * u.y() / u.p() + l.c2();
FT P = A + B * CGAL::sqrt(l.delta());
return CGAL::sign(P);
}
public:
typedef Sign result_type;
typedef Site_2 argument_type;
inline
Sign operator()(const Site_2& p1, const Site_2& p2,
const Site_2& p3, const Site_2& q) const
{
#ifdef AG2_PROFILE_PREDICATES
ag2_predicate_profiler::incircle_counter++;
#endif
//
Method_tag tag;
Weighted_point_inverter inverter(p1);
Inverted_weighted_point u2 = inverter(p2);
Inverted_weighted_point u3 = inverter(p3);
Voronoi_radius vr_123(u2, u3);
Bounded_side bs = Bounded_side_of_CCW_circle()(vr_123, tag );
if ( bs != ON_UNBOUNDED_SIDE ) { return NEGATIVE; }
Inverted_weighted_point v = inverter(q);
Bitangent_line blinv_23(u2, u3);
Sign s = Sign_of_distance_from_CCW_circle()(blinv_23, v, tag);
return s;
}
inline
Sign operator()(const Site_2& p1, const Site_2& p2,
const Site_2& q) const
{
Method_tag tag;
//
Bitangent_line bl_21(p2, p1);
Sign s = Sign_of_distance_from_bitangent_line()(bl_21, q, tag);
if ( s != ZERO ) { return s; }
Bitangent_line bl1_perp = bl_21.perpendicular(p1.point());
Bitangent_line bl2_perp = bl_21.perpendicular(p2.point());
Orientation o1 = orientation(bl1_perp, q.point(), tag);
Orientation o2 = orientation(bl2_perp, q.point(), tag);
CGAL_assertion( o1 != COLLINEAR || o2 != COLLINEAR );
if ( o1 == o2 ) { return POSITIVE; }
return NEGATIVE;
}
};
//--------------------------------------------------------------------
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_INCIRCLE_C2_H

View File

@ -0,0 +1,316 @@
// Copyright (c) 2003,2004,2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_INFINITE_EDGE_TEST_C2_H
#define CGAL_APOLLONIUS_GRAPH_2_INFINITE_EDGE_TEST_C2_H
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/Apollonius_graph_2/basic.h>
#include <CGAL/Apollonius_graph_2/Predicate_constructions_C2.h>
namespace CGAL {
namespace ApolloniusGraph_2 {
//--------------------------------------------------------------------
template< class K >
class Bounded_side_of_CCW_circular_arc_2
{
public:
typedef Weighted_point_inverter_2<K> Weighted_point_inverter;
typedef Inverted_weighted_point_2<K> Inverted_weighted_point;
typedef Voronoi_radius_2<K> Voronoi_radius;
typedef Voronoi_circle_2<K> Voronoi_circle;
typedef Bitangent_line_2<K> Bitangent_line;
typedef typename K::FT FT;
typedef typename K::Bounded_side Bounded_side;
typedef typename K::Orientation Orientation;
typedef typename K::Sign Sign;
public:
template< class Method_tag >
Bounded_side operator()(const Bitangent_line& l1,
const Bitangent_line& l2,
const Bitangent_line& l3, Method_tag tag) const
{
#ifdef AG2_PROFILE_PREDICATES
ag2_predicate_profiler::inside_circular_arc_counter++;
#endif
// This function checks whether the direction (a3, b3) (defined in
// the unit circle) is inside the CCW circular arc defined on the
// unit circle by the directions (a1, b1) and (a2, b2). By CCW arc
// we mean that we walk on the unit circle in the CCW order from
// (a1,b1) to (a2, b2) to define the arc.
Orientation o = chi2(l1, l2, tag);
//sign_of_determinant(a1, b1, a2, b2);
if ( o == COLLINEAR ) {
Bitangent_line l2_rot = l2.get_rot90();
Sign dot = chi2(l1, l2_rot, tag);
//sign_of_determinant(a1, b1, -b2, a2);
CGAL_assertion( dot != ZERO );
Orientation o1 = chi2(l1, l3, tag);
//sign_of_determinant(a1, b1, a3, b3);
if ( dot == POSITIVE ) {
if ( o1 != COLLINEAR ) { return ON_UNBOUNDED_SIDE; }
Bitangent_line l3_rot = l3.get_rot90();
Sign dot1 = chi2(l1, l3_rot, tag);
//sign_of_determinant(a1, b1, -b3, a3);
CGAL_assertion( dot1 != ZERO );
return ( dot1 == POSITIVE ) ? ON_BOUNDARY : ON_UNBOUNDED_SIDE;
}
if ( o1 == LEFT_TURN ) { return ON_BOUNDED_SIDE; }
return ( o1 == COLLINEAR ) ? ON_BOUNDARY : ON_UNBOUNDED_SIDE;
} else if ( o == LEFT_TURN ) {
Orientation o1 = chi2(l1, l3, tag);
//sign_of_determinant(a1, b1, a3, b3);
Orientation o2 = chi2(l2, l3, tag);
//sign_of_determinant(a2, b2, a3, b3);
// std::cout << "orientation(l1, l3): " << int(o1) << std::endl;
// std::cout << "orientation(l2, l3): " << int(o2) << std::endl;
if ( o1 == LEFT_TURN ) {
if ( o2 == COLLINEAR ) { return ON_BOUNDARY; }
return ( o2 == RIGHT_TURN ) ? ON_BOUNDED_SIDE : ON_UNBOUNDED_SIDE;
} else if ( o1 == COLLINEAR ) {
CGAL_assertion( o2 != COLLINEAR );
return ( o2 == RIGHT_TURN ) ? ON_BOUNDARY : ON_UNBOUNDED_SIDE;
}
return ON_UNBOUNDED_SIDE;
}
Orientation o1 = chi2(l1, l3, tag);
//sign_of_determinant(a1, b1, a3, b3);
Orientation o2 = chi2(l2, l3, tag);
//sign_of_determinant(a2, b2, a3, b3);
// std::cout << "orientation(l1, l3): " << int(o1) << std::endl;
// std::cout << "orientation(l2, l3): " << int(o2) << std::endl;
if ( o1 == LEFT_TURN || o2 == RIGHT_TURN ) { return ON_BOUNDED_SIDE; }
if ( o1 == COLLINEAR || o2 == COLLINEAR ) { return ON_BOUNDARY; }
return ON_UNBOUNDED_SIDE;
}
Sign chi2(const Bitangent_line& bl1,
const Bitangent_line& bl2, Field_with_sqrt_tag) const
{
FT sigma = bl1.dx() * bl2.dx() + bl1.dy() * bl2.dy();
FT delta = bl1.dx() * bl2.dy() - bl1.dy() * bl2.dx();
// FT E1 = -bl2.dw() * sigma;
// FT E2 = bl1.dw() * sigma;
FT E1 = bl2.dw() * sigma;
FT E2 = -bl1.dw() * sigma;
FT E3 = delta;
FT E4 = bl1.dw() * bl2.dw() * delta;
FT p = bl1.delta();
FT P = bl2.delta();
FT E = E1 * CGAL::sqrt(p) + E2 * CGAL::sqrt(P)
+ E3 * CGAL::sqrt(p * P) + E4;
return CGAL::sign(E);
}
inline
Sign chi2(const Bitangent_line& bl1,
const Bitangent_line& bl2, Integral_domain_without_division_tag) const
{
return chi2(bl1.dx(), bl1.dy(), -bl1.dw(), bl1.d(), bl1.delta(),
bl2.dx(), bl2.dy(), -bl2.dw(), bl2.d(), bl2.delta());
}
Sign chi2(const FT& a, const FT& b, const FT& r,
const FT& d, const FT& p,
const FT& A, const FT& B, const FT& R,
const FT& D, const FT& P) const
{
FT sigma = a * A + b * B;
FT delta = determinant(a, b, A, B);
Sign sign_sigma = CGAL::sign(sigma);
Sign sign_delta = CGAL::sign(delta);
Sign sign_r = CGAL::sign(r);
Sign sign_R = CGAL::sign(R);
Sign sign_E1 = -sign_R * sign_sigma;
Sign sign_E2 = sign_r * sign_sigma;
Sign sign_E3 = sign_delta;
Sign sign_E4 = sign_r * sign_R * sign_delta;
Sign sign_E1_plus_E3_P, sign_E4_plus_E2_P;
// FT d = CGAL::square(a) + CGAL::square(b);
FT G = CGAL::square(R) * d;
FT delta2 = CGAL::square(delta);
if ( sign_E3 == ZERO ) {
sign_E1_plus_E3_P = sign_E1;
} else {
if ( sign_E3 == sign_E1 ) {
sign_E1_plus_E3_P = sign_E3;
} else {
FT F1 = delta2 - G;
sign_E1_plus_E3_P = sign_E3 * CGAL::sign(F1);
}
}
if ( sign_E2 == ZERO ) {
sign_E4_plus_E2_P = sign_E4;
} else {
if ( sign_E2 == sign_E4 ) {
sign_E4_plus_E2_P = sign_E2;
} else {
FT F2 = CGAL::square(sigma) - G;
if ( sign_r == ZERO ) {
sign_E4_plus_E2_P = ZERO;
} else {
sign_E4_plus_E2_P = sign_E2 * CGAL::sign(F2);
}
}
}
if ( sign_E1_plus_E3_P == ZERO ) { return sign_E4_plus_E2_P; }
if ( sign_E1_plus_E3_P == sign_E4_plus_E2_P ) {
return sign_E1_plus_E3_P;
}
Sign sign_E5 = -sign_R * sign_sigma * sign_delta;
// FT D = CGAL::square(A) + CGAL::square(B);
// FT P = D - CGAL::square(R);
FT F3 = P * delta2 + CGAL::square(R * sigma) - CGAL::square(r * D);
Sign sign_E6 = CGAL::sign(F3);
if ( sign_E5 == ZERO ) {
return sign_E1_plus_E3_P * sign_E6;
}
if ( sign_E5 == sign_E6 ) {
return sign_E1_plus_E3_P * sign_E5;
}
// FT p = d - CGAL::square(r);
FT rR = r * R;
FT pP = p * P;
//error();
FT F4 = CGAL::square(sigma - rR) - pP;
FT F5 = CGAL::square(sigma + rR) - pP;
Sign sign_E7 = -CGAL::sign(F4) * CGAL::sign(F5);
return sign_E1_plus_E3_P * sign_E5 * sign_E7;
}
};
//--------------------------------------------------------------------
template < class K, class MTag >
class Infinite_edge_interior_conflict_2
{
public:
typedef K Kernel;
typedef MTag Method_tag;
typedef typename K::Site_2 Site_2;
typedef Weighted_point_inverter_2<K> Weighted_point_inverter;
typedef Inverted_weighted_point_2<K> Inverted_weighted_point;
typedef Voronoi_radius_2<K> Voronoi_radius;
typedef Voronoi_circle_2<K> Voronoi_circle;
typedef Bitangent_line_2<K> Bitangent_line;
typedef typename K::FT FT;
typedef typename K::Bounded_side Bounded_side;
// typedef CGAL::Bounded_side_of_CCW_circle<K> Bounded_side_of_CCW_circle;
// typedef CGAL::Sign_of_distance_from_bitangent_line<K>
// Sign_of_distance_from_bitangent_line;
// typedef CGAL::Sign_of_distance_from_CCW_circle<K>
// Sign_of_distance_from_CCW_circle;
// typedef CGAL::Order_on_finite_bisector<K> Order_on_finite_bisector;
typedef Bounded_side_of_CCW_circular_arc_2<K>
Bounded_side_of_CCW_circular_arc;
public:
typedef bool result_type;
struct argument_type {};
bool operator()(const Site_2& p2, const Site_2& p3,
const Site_2& p4, const Site_2& q, bool b) const
{
Method_tag tag = Method_tag();
Bitangent_line bl_32(p3, p2);
Bitangent_line bl_24(p2, p4);
Bitangent_line bl_2q(p2, q);
Bounded_side bs1 =
Bounded_side_of_CCW_circular_arc()(bl_32, bl_24, bl_2q, tag);
if ( b ) {
if ( bs1 == ON_BOUNDARY ) {
Bitangent_line bl_q2(q, p2);
Bounded_side bs2 =
Bounded_side_of_CCW_circular_arc()(bl_32, bl_24, bl_q2, tag);
if ( bs2 != ON_BOUNDARY ) {
return ( bs2 != ON_BOUNDED_SIDE );
}
return !b;
}
return ( bs1 != ON_BOUNDED_SIDE );
}
if ( bs1 == ON_BOUNDARY ) {
Bitangent_line bl_q2(q, p2);
Bounded_side bs2 =
Bounded_side_of_CCW_circular_arc()(bl_32, bl_24, bl_q2, tag);
if ( bs2 != ON_BOUNDARY ) {
return ( bs2 == ON_BOUNDED_SIDE );
}
return !b;
}
return ( bs1 == ON_BOUNDED_SIDE );
}
};
//--------------------------------------------------------------------
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_INFINITE_EDGE_TEST_C2_H

View File

@ -0,0 +1,95 @@
// Copyright (c) 2003,2004 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_IS_DEGENERATE_EDGE_C2_H
#define CGAL_APOLLONIUS_GRAPH_2_IS_DEGENERATE_EDGE_C2_H
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/Apollonius_graph_2/basic.h>
#include <CGAL/Apollonius_graph_2/Predicate_constructions_C2.h>
#include <CGAL/Apollonius_graph_2/Incircle_C2.h>
#include <CGAL/Apollonius_graph_2/Finite_edge_test_C2.h>
namespace CGAL {
namespace ApolloniusGraph_2 {
//--------------------------------------------------------------------
template < class K, class MTag >
class Is_degenerate_edge_2
{
public:
typedef K Kernel;
typedef MTag Method_tag;
typedef typename K::Site_2 Site_2;
typedef Weighted_point_inverter_2<K> Weighted_point_inverter;
typedef Inverted_weighted_point_2<K> Inverted_weighted_point;
typedef Bitangent_line_2<K> Bitangent_line;
typedef Voronoi_circle_2<K> Voronoi_circle;
typedef typename K::FT FT;
typedef typename K::Sign Sign;
typedef typename K::Comparison_result Comparison_result;
typedef Order_on_finite_bisector_2<K> Order_on_finite_bisector;
typedef Sign_of_distance_from_CCW_circle_2<K>
Sign_of_distance_from_CCW_circle;
public:
typedef Site_2 argument_type;
typedef bool result_type;
bool operator()(const Site_2& p1, const Site_2& p2,
const Site_2& p3, const Site_2& p4) const
{
Method_tag tag;
Weighted_point_inverter inverter(p1);
Inverted_weighted_point u2 = inverter(p2);
Inverted_weighted_point u3 = inverter(p3);
Inverted_weighted_point u4 = inverter(p4);
Sign s;
Bitangent_line blinv_23(u2, u3);
s = Sign_of_distance_from_CCW_circle()(blinv_23, u4, tag);
if ( s != ZERO ) { return false; }
Bitangent_line blinv_42(u4, u2);
s = Sign_of_distance_from_CCW_circle()(blinv_42, u3, tag);
if ( s != ZERO ) { return false; }
Voronoi_circle vc_123(blinv_23);
Voronoi_circle vc_142(blinv_42);
Comparison_result r =
Order_on_finite_bisector()(vc_123, vc_142, p1, p2, tag);
return ( r == EQUAL );
}
};
//--------------------------------------------------------------------
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_IS_DEGENERATE_EDGE_C2_H

View File

@ -0,0 +1,85 @@
// Copyright (c) 2003,2004 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_IS_HIDDEN_C2_H
#define CGAL_APOLLONIUS_GRAPH_2_IS_HIDDEN_C2_H
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/Apollonius_graph_2/basic.h>
namespace CGAL {
namespace ApolloniusGraph_2 {
//--------------------------------------------------------------------
template<class K, class MTag>
class Is_hidden_2
{
public:
typedef K Kernel;
typedef MTag Method_tag;
typedef typename K::Site_2 Site_2;
typedef typename K::RT RT;
typedef typename K::Sign Sign;
private:
bool is_hidden(const Site_2& p, const Site_2& q,
const Integral_domain_without_division_tag&) const
{
RT w1 = p.weight();
RT w2 = q.weight();
Sign s = CGAL::sign( CGAL::square(p.x() - q.x())
+ CGAL::square(p.y() - q.y())
- CGAL::square(w1 - w2)
);
if ( s == POSITIVE ) { return false; }
return (CGAL::compare(w1, w2) != SMALLER);
}
bool is_hidden(const Site_2& p, const Site_2& q,
const Field_with_sqrt_tag&) const
{
RT d = CGAL::sqrt(CGAL::square(p.x() - q.x())
+ CGAL::square(p.y() - q.y()));
Sign s = CGAL::sign(d - p.weight() + q.weight());
return ( s != POSITIVE );
}
public:
typedef bool result_type;
typedef Site_2 argument_type;
inline bool operator()(const Site_2 &p, const Site_2 &q) const {
#ifdef AG2_PROFILE_PREDICATES
ag2_predicate_profiler::is_trivial_counter++;
#endif
return is_hidden(p, q, Method_tag());
}
};
//--------------------------------------------------------------------
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_IS_HIDDEN_C2_H

View File

@ -0,0 +1,82 @@
// Copyright (c) 2003,2004,2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_KERNEL_WRAPPER_2_H
#define CGAL_APOLLONIUS_GRAPH_2_KERNEL_WRAPPER_2_H
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/Apollonius_graph_2/basic.h>
#include <CGAL/Apollonius_site_2.h>
//#include <CGAL/Cartesian_converter.h>
namespace CGAL {
namespace ApolloniusGraph_2 {
template<class Kernel_base_2>
class Apollonius_graph_kernel_wrapper_2 : public Kernel_base_2
{
public:
typedef CGAL::Apollonius_site_2<Kernel_base_2> Site_2;
typedef Kernel_base_2 Base;
};
template<class K1, class K2, class Converter >
class Apollonius_graph_cartesian_converter
: public Converter
{
private:
typedef typename K2::Site_2 K2_Site_2;
typedef typename K2::Point_2 K2_Point_2;
typedef Converter Base;
typedef typename Converter::Number_type_converter NT_converter;
public:
#if defined(_MSC_VER)
bool operator()(bool b) const {
return Base::operator()(b);
}
K2_Point_2
operator()(const typename K1::Point_2& p) const
{
return Base::operator()(p);
}
#else
using Base::operator();
#endif
K2_Site_2
operator()(const typename K1::Site_2& t) const
{
NT_converter nt_cv;
return K2_Site_2( Base::operator()(t.point()),
nt_cv(t.weight())
);
}
};
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_KERNEL_WRAPPER_2_H

View File

@ -0,0 +1,318 @@
// Copyright (c) 2007 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_ORIENTATION8_C2_H
#define CGAL_APOLLONIUS_GRAPH_2_ORIENTATION8_C2_H
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/determinant.h>
#include <CGAL/Apollonius_graph_2/Orientation_2.h>
//--------------------------------------------------------------------
namespace CGAL {
namespace ApolloniusGraph_2 {
template<class K, class MTag>
class Orientation8_C2
: public Orientation_2<K,MTag>
{
private:
typedef Orientation_2<K,MTag> Base;
public:
typedef K Kernel;
typedef MTag Method_tag;
typedef typename K::Site_2 Site_2;
typedef typename K::Point_2 Point_2;
typedef typename K::Orientation Orientation;
typedef typename K::FT FT;
typedef Orientation result_type;
typedef Site_2 argument_type;
public:
inline
Orientation operator()(const Site_2& s1, const Site_2& s2,
const Site_2& s3) const
{
return Kernel().orientation_2_object()(s1.point(), s2.point(),
s3.point());
}
inline
Sign sqrt_ext_sign(const FT& A, const FT& B,
const FT& Exp, const FT& Eyp, const FT& Erp,
const FT& Exy2, const FT& Exr, const FT& Eyr,
const FT dx, const FT& dy,
const Field_with_sqrt_tag&) const
{
FT G = CGAL::square(Exp) + CGAL::square(Eyp) - CGAL::square(Erp);
return CGAL::sign(A + B * CGAL::sqrt(G));
}
inline
Sign sqrt_ext_sign(const FT& A, const FT& B,
const FT& Exp, const FT& Eyp, const FT& Erp,
const FT& Exy2, const FT& Exr, const FT& Eyr,
const FT dx, const FT& dy,
const Integral_domain_without_division_tag&) const
{
Sign sA = CGAL::sign(A);
Sign sB = CGAL::sign(B);
if ( sA == CGAL::ZERO ) { return sB; }
if ( sB == CGAL::ZERO ) { return sA; }
if ( sA == sB ) { return sA; }
Sign s = CGAL::sign(CGAL::square(Exy2 * Exr - Erp * dy)
+ CGAL::square(Exy2 * Eyr + Erp * dx)
- CGAL::square(B));
return sA * s;
}
Orientation predicate(const Site_2& s1, const Site_2& s2,
const Site_2& s3, const Site_2& p1,
const Site_2& p2) const
{
// computes the orientation of the Voronoi vertex of s1, s2, s3 and
// the points p1 and p2
FT xj = s2.x() - s1.x();
FT xk = s3.x() - s1.x();
FT xl = p1.x() - s1.x();
FT xm = p2.x() - s1.x();
FT yj = s2.y() - s1.y();
FT yk = s3.y() - s1.y();
FT yl = p1.y() - s1.y();
FT ym = p2.y() - s1.y();
FT dx = xl - xm;
FT dy = yl - ym;
FT rj = s2.weight() - s1.weight();
FT rk = s3.weight() - s1.weight();
FT pj = CGAL::square(xj) + CGAL::square(yj) - CGAL::square(rj);
FT pk = CGAL::square(xk) + CGAL::square(yk) - CGAL::square(rk);
FT Exp = determinant(xj, pj, xk, pk);
FT Eyp = determinant(yj, pj, yk, pk);
FT Erp = determinant(rj, pj, rk, pk);
FT Exy = determinant(xj, yj, xk, yk);
FT Exr = determinant(xj, rj, xk, rk);
FT Eyr = determinant(yj, rj, yk, rk);
FT Exy2 = 2 * determinant(xl, yl, xm, ym);
FT A = (Exp * Exr + Eyp * Eyr) * Exy2 + (Eyp * dx - Exp * dy) * Erp;
FT B = Exy * Exy2 - Exp * dx - Eyp * dy;
return sqrt_ext_sign(A, B, Exp, Eyp, Erp,
Exy2, Exr, Eyr, dx, dy, Method_tag());
}
Orientation operator()(const Site_2& s1, const Site_2& s2,
const Site_2& s3, const Site_2& p1,
const Site_2& p2) const
{
Orientation o = predicate(s1, s2, s3, p1, p2);
#ifndef NDEBUG
Orientation o_old = Base::operator()(s1, s2, s3, p1, p2);
CGAL_assertion( o == o_old );
#endif
return o;
}
};
//--------------------------------------------------------------------
template<class K, class MTag>
class Constructive_orientation8_C2
{
public:
typedef K Kernel;
typedef MTag Method_tag;
typedef typename K::Site_2 Site_2;
typedef typename K::Point_2 Point_2;
typedef typename K::Orientation Orientation;
typedef typename K::FT FT;
typedef Orientation result_type;
typedef Site_2 argument_type;
private:
FT s1x, s1y;
FT xj, xk, yj, yk, rj, rk, nj, nk, pj, pk, Exp, Eyp, Erp, Exy, Exr, Eyr, A1;
Orientation o_sym;
public:
Constructive_orientation8_C2(const Site_2& s1, const Site_2& s2,
const Site_2& s3, bool use_xj)
{
s1x = s1.x();
s1y = s1.y();
xj = s2.x() - s1.x();
xk = s3.x() - s1.x();
yj = s2.y() - s1.y();
yk = s3.y() - s1.y();
rj = s2.weight() - s1.weight();
rk = s3.weight() - s1.weight();
nj = CGAL::square(xj) + CGAL::square(yj);
nk = CGAL::square(xk) + CGAL::square(yk);
pj = nj - CGAL::square(rj);
pk = nk - CGAL::square(rk);
Exp = determinant(xj, pj, xk, pk);
Eyp = determinant(yj, pj, yk, pk);
Erp = determinant(rj, pj, rk, pk);
Exy = determinant(xj, yj, xk, yk);
Exr = determinant(xj, rj, xk, rk);
Eyr = determinant(yj, rj, yk, rk);
A1 = Exp * Exr + Eyp * Eyr;
FT A, B, norm;
if ( use_xj ) {
A = (-Eyp * xj + Exp * yj) * Erp;
B = Exp * xj + Eyp * yj;
norm = nj;
} else {
A = (-Eyp * xk + Exp * yk) * Erp;
B = Exp * xk + Eyp * yk;
norm = nk;
}
o_sym = sqrt_ext_sign(A, B, norm, Method_tag());
}
private:
inline
Sign sqrt_ext_sign(const FT& A, const FT& B, const FT& Exy2,
const FT& dx, const FT& dy,
const Field_with_sqrt_tag&) const
{
FT G = CGAL::square(Exp) + CGAL::square(Eyp) - CGAL::square(Erp);
return CGAL::sign(A + B * CGAL::sqrt(G));
}
inline
Sign sqrt_ext_sign(const FT& A, const FT& B, const FT&,
const Field_with_sqrt_tag&) const
{
FT G = CGAL::square(Exp) + CGAL::square(Eyp) - CGAL::square(Erp);
return CGAL::sign(A + B * CGAL::sqrt(G));
}
inline
Sign sqrt_ext_sign(const FT& A, const FT& B, const FT& norm,
const Integral_domain_without_division_tag&) const
{
Sign sA = CGAL::sign(A);
Sign sB = CGAL::sign(B);
if ( sA == CGAL::ZERO ) { return sB; }
if ( sB == CGAL::ZERO ) { return sA; }
if ( sA == sB ) { return sA; }
Sign s = CGAL::sign(CGAL::square(Erp) * norm - CGAL::square(B));
return sA * s;
}
inline
Sign sqrt_ext_sign(const FT& A, const FT& B, const FT& Exy2,
const FT dx, const FT& dy,
const Integral_domain_without_division_tag&) const
{
Sign sA = CGAL::sign(A);
Sign sB = CGAL::sign(B);
if ( sA == CGAL::ZERO ) { return sB; }
if ( sB == CGAL::ZERO ) { return sA; }
if ( sA == sB ) { return sA; }
Sign s = CGAL::sign(CGAL::square(Exy2 * Exr - Erp * dy)
+ CGAL::square(Exy2 * Eyr + Erp * dx)
- CGAL::square(B));
return sA * s;
}
Orientation predicate(const Site_2& p1, const Site_2& p2) const
{
// computes the orientation of the Voronoi vertex of s1, s2, s3 and
// the points p1 and p2
FT xl = p1.x() - s1x;
FT xm = p2.x() - s1x;
FT yl = p1.y() - s1y;
FT ym = p2.y() - s1y;
FT dx = xl - xm;
FT dy = yl - ym;
FT Exy2 = 2 * determinant(xl, yl, xm, ym);
FT A = A1 * Exy2 + (Eyp * dx - Exp * dy) * Erp;
FT B = Exy * Exy2 - Exp * dx - Eyp * dy;
return sqrt_ext_sign(A, B, Exy2, dx, dy, Method_tag());
}
public:
inline
Orientation operator()(const Site_2& s1, const Site_2& s2,
const Site_2& s3) const
{
return Kernel().orientation_2_object()(s1.point(), s2.point(),
s3.point());
}
inline
Orientation operator()(const Site_2& p1, const Site_2& p2) const
{
Orientation o = predicate(p1, p2);
return o;
}
inline
Orientation operator()() const {
return o_sym;
}
};
//--------------------------------------------------------------------
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_ORIENTATION8_C2_H

View File

@ -0,0 +1,109 @@
// Copyright (c) 2003,2004,2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_ORIENTATION_2_H
#define CGAL_APOLLONIUS_GRAPH_2_ORIENTATION_2_H
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/Apollonius_graph_2/basic.h>
#include <CGAL/Apollonius_graph_2/Predicate_constructions_C2.h>
//--------------------------------------------------------------------
namespace CGAL {
namespace ApolloniusGraph_2 {
template<class K, class MTag>
class Orientation_2
{
public:
typedef K Kernel;
typedef MTag Method_tag;
typedef typename K::Site_2 Site_2;
typedef typename K::Point_2 Point_2;
typedef typename K::Orientation Orientation;
typedef Orientation result_type;
typedef Site_2 argument_type;
private:
typedef Weighted_point_inverter_2<K> Weighted_point_inverter;
typedef Inverted_weighted_point_2<K> Inverted_weighted_point;
typedef Voronoi_circle_2<K> Voronoi_circle;
typedef Bitangent_line_2<K> Bitangent_line;
typedef typename Bitangent_line::FT FT;
private:
Orientation vv_orientation(const Voronoi_circle& vc, const Point_2& sp1,
const Point_2& p1, const Point_2& p2,
const Field_with_sqrt_tag&) const
{
FT a = vc.a1() + vc.a2() * CGAL::sqrt(vc.delta());
FT b = vc.b1() + vc.b2() * CGAL::sqrt(vc.delta());
FT det1 = a * (p2.y() - p1.y()) - b * (p2.x() - p1.x());
FT c = vc.c1() + vc.c2() * CGAL::sqrt(vc.delta());
FT det2 = determinant(p1.x() - sp1.x(), p1.y() - sp1.y(),
p2.x() - sp1.x(), p2.y() - sp1.y());
return CGAL::sign(det1 + FT(2) * c * det2);
}
Orientation vv_orientation(const Voronoi_circle vc, const Point_2& sp1,
const Point_2& p1, const Point_2& p2,
const Integral_domain_without_division_tag&) const
{
FT dx = p2.x() - p1.x();
FT dy = p2.y() - p1.y();
FT det1 = determinant(p1.x() - sp1.x(), p1.y() - sp1.y(),
p2.x() - sp1.x(), p2.y() - sp1.y());
FT A = vc.a1() * dy - vc.b1() * dx + FT(2) * vc.c1() * det1;
FT B = vc.a2() * dy - vc.b2() * dx + FT(2) * vc.c2() * det1;
return sign_a_plus_b_x_sqrt_c(A, B, vc.delta());
}
public:
inline
Orientation operator()(const Site_2& s1, const Site_2& s2,
const Site_2& s3) const
{
return Kernel().orientation_2_object()(s1.point(), s2.point(),
s3.point());
}
Orientation operator()(const Site_2& s1, const Site_2& s2,
const Site_2& s3, const Site_2& p1,
const Site_2& p2) const
{
// computes the operation of the Voronoi vertex of s1, s2, s3 and
// the points p1 and p2
Weighted_point_inverter inverter(s1);
Inverted_weighted_point u2 = inverter(s2);
Inverted_weighted_point u3 = inverter(s3);
Bitangent_line blinv_23(u2, u3);
Voronoi_circle vc(blinv_23);
return
vv_orientation(vc, s1.point(), p1.point(), p2.point(), Method_tag());
}
};
//--------------------------------------------------------------------
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_ORIENTATION_2_H

View File

@ -0,0 +1,125 @@
// Copyright (c) 2003,2004 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_ORIENTED_SIDE_OF_BISECTOR_C2_H
#define CGAL_APOLLONIUS_GRAPH_2_ORIENTED_SIDE_OF_BISECTOR_C2_H
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/Apollonius_graph_2/basic.h>
#include <CGAL/functions_on_signs.h>
namespace CGAL {
namespace ApolloniusGraph_2 {
//--------------------------------------------------------------------
template<class K, class MTag>
class Oriented_side_of_bisector_2
{
public:
typedef K Kernel;
typedef MTag Method_tag;
typedef typename K::Point_2 Point_2;
typedef typename K::Site_2 Site_2;
typedef typename K::Comparison_result Comparison_result;
typedef typename K::Sign Sign;
typedef typename K::Oriented_side Oriented_side;
private:
typedef typename Kernel::RT RT;
private:
Comparison_result
compare_distances(const Site_2& p1, const Site_2& p2,
const Point_2& p, const Integral_domain_without_division_tag&) const
{
#ifdef AG2_PROFILE_PREDICATES
ag2_predicate_profiler::side_of_bisector_counter++;
#endif
// this function compares the distances of the point(x, y) from the
// disks {(x1, y1), w1} and {(x2, y2), w2}
RT D1 = CGAL::square(p1.x() - p.x()) + CGAL::square(p1.y() - p.y());
RT D2 = CGAL::square(p2.x() - p.x()) + CGAL::square(p2.y() - p.y());
RT Dw = p2.weight() - p1.weight();
Sign sign_of_Dw = CGAL::sign(Dw);
Comparison_result R = CGAL::compare(D1, D2);
if ( sign_of_Dw == ZERO ) {
return R;
}
if ( sign_of_Dw == POSITIVE ) {
if ( R != SMALLER ) return LARGER;
Sign s = sign_a_plus_b_x_sqrt_c<RT>(D1 - D2 + CGAL::square(Dw),
RT(2) * Dw, D1);
return ((s == POSITIVE) ? LARGER : ((s == ZERO) ? EQUAL : SMALLER));
}
if ( R != LARGER ) return SMALLER;
Sign s = sign_a_plus_b_x_sqrt_c<RT>(D1 - D2 - CGAL::square(Dw),
RT(2) * Dw, D2);
return ((s == POSITIVE) ? LARGER : ((s == ZERO) ? EQUAL : SMALLER));
}
Comparison_result
compare_distances(const Site_2& p1, const Site_2& p2,
const Point_2 &p, const Field_with_sqrt_tag&) const
{
#ifdef AG2_PROFILE_PREDICATES
ag2_predicate_profiler::side_of_bisector_counter++;
#endif
// this function compares the distances of the point(x, y) from the
// disks {(x1, y1), w1} and {(x2, y2), w2}
RT D1 = CGAL::square(p1.x() - p.x()) + CGAL::square(p1.y() - p.y());
RT D2 = CGAL::square(p2.x() - p.x()) + CGAL::square(p2.y() - p.y());
RT d1 = CGAL::sqrt(D1) - p1.weight();
RT d2 = CGAL::sqrt(D2) - p2.weight();
return CGAL::compare(d1, d2);
}
public:
typedef Oriented_side result_type;
struct argument_type {};
inline
Oriented_side operator()(const Site_2& p1, const Site_2& p2,
const Point_2 &p) const
{
Comparison_result r = compare_distances(p1, p2, p, Method_tag());
if ( r == EQUAL ) { return ON_ORIENTED_BOUNDARY; }
return ( r == LARGER ) ? ON_NEGATIVE_SIDE : ON_POSITIVE_SIDE;
}
};
//--------------------------------------------------------------------
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_ORIENTED_SIDE_OF_BISECTOR_C2_H

View File

@ -0,0 +1,358 @@
// Copyright (c) 2003,2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_PREDICATE_CONSTRUCTIONS_2_H
#define CGAL_APOLLONIUS_GRAPH_2_PREDICATE_CONSTRUCTIONS_2_H 1
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/Apollonius_graph_2/basic.h>
namespace CGAL {
namespace ApolloniusGraph_2 {
template< class K >
class Inverted_weighted_point_2
: public K::Site_2
{
public:
typedef typename K::Site_2 K_Site_2;
typedef typename K::FT FT;
private:
FT _p;
public:
Inverted_weighted_point_2(const K_Site_2& wp, const FT& p)
: K_Site_2(wp), _p(p) {}
inline FT p() const { return _p; }
};
template< class K >
class Weighted_point_inverter_2
{
public:
typedef typename K::Point_2 Point_2;
typedef typename K::Site_2 Site_2;
typedef Inverted_weighted_point_2<K> Inverted_weighted_point;
typedef typename K::FT FT;
private:
Site_2 _pole;
public:
Weighted_point_inverter_2(const Site_2& pole)
: _pole(pole) {}
Inverted_weighted_point operator()(const Site_2& wp)
{
FT xs = wp.x() - _pole.x();
FT ys = wp.y() - _pole.y();
FT ws = wp.weight() - _pole.weight();
FT ps = CGAL::square(xs) + CGAL::square(ys)
- CGAL::square(ws);
return
Inverted_weighted_point(Site_2(Point_2(xs, ys), ws), ps);
}
Site_2 pole() const { return _pole; }
};
template< class K >
class Voronoi_radius_2
{
// this class stores the coefficients for the tritangent circle
// radius equation. In particular we have:
// a x^2 - 2 b x + c = 0;
// x here represents the inverse of the radius
public:
typedef typename K::FT FT;
typedef Inverted_weighted_point_2<K> Inverted_weighted_point;
private:
FT _a, _b, _c;
FT _c2, _delta;
FT _dxp, _dyp, _dwp;
Voronoi_radius_2(FT a, FT b, FT c, FT c2, FT delta,
FT dxp, FT dyp, FT dwp)
: _a(a), _b(b), _c(c), _c2(c2), _delta(delta), _dxp(dxp),
_dyp(dyp), _dwp(dwp) {}
public:
Voronoi_radius_2(const Inverted_weighted_point& u1,
const Inverted_weighted_point& u2)
{
FT dxp = determinant(u1.x(), u1.p(), u2.x(), u2.p());
FT dyp = determinant(u1.y(), u1.p(), u2.y(), u2.p());
FT dwp = determinant(u1.weight(), u1.p(), u2.weight(), u2.p());
FT dxy = determinant(u1.x(), u1.y(), u2.x(), u2.y());
FT dxw = determinant(u1.x(), u1.weight(), u2.x(), u2.weight());
FT dyw = determinant(u1.y(), u1.weight(), u2.y(), u2.weight());
_a = CGAL::square(dxp) + CGAL::square(dyp);
_b = dxp * dxw + dyp * dyw;
_c = CGAL::square(dxw) + CGAL::square(dyw) - CGAL::square(dxy);
_c2 = dxy;
_delta = _a - CGAL::square(dwp);
_dxp = dxp;
_dyp = dyp;
_dwp = dwp;
}
inline FT a() const { return _a; }
inline FT b() const { return _b; }
inline FT c() const { return _c; }
inline FT c1() const { return _b; }
inline FT c2() const { return _c2; }
inline FT delta() const { return _delta; }
inline FT d() const { return _a; }
inline FT dxp() const { return _dxp; }
inline FT dyp() const { return _dyp; }
inline FT dwp() const { return _dwp; }
inline bool is_first_root() const { return CGAL::is_negative(_c2); }
Voronoi_radius_2 get_symmetric()
{
return Voronoi_radius_2(_a, _b, _c, -_c2, _delta, -_dxp, -_dyp, -_dwp);
}
};
template< class K >
class Bitangent_line_2
{
// this class computes and stores the data for the left bitangent
// line of the weighted points p1, p2 oriented from p1 to p2
// or the left bitangent line of the inverted weighted point u1 and
// u2, oriented from u1 to u2
public:
typedef typename K::Point_2 Point_2;
typedef typename K::Site_2 Site_2;
typedef Inverted_weighted_point_2<K> Inverted_weighted_point;
typedef typename K::FT FT;
protected:
FT _a1, _a2;
FT _b1, _b2;
FT _c1, _c2;
FT _delta;
FT _d;
FT _dw;
FT _dxw, _dyw;
Bitangent_line_2(FT a1, FT a2, FT b1, FT b2, FT c1, FT c2,
FT delta, FT d, FT dw, FT dxw, FT dyw)
: _a1(a1), _a2(a2), _b1(b1), _b2(b2), _c1(c1), _c2(c2),
_delta(delta), _d(d), _dw(dw),_dxw(dxw), _dyw(dyw) {}
inline void
store(FT dx, FT dy, FT dw)
{
_dw = dw;
_a1 = dx * dw;
_a2 = dy;
_b1 = dy * dw;
_b2 = -dx;
}
inline void
store(FT dx, FT dy, FT dw, FT dxy, FT dxw, FT dyw)
{
store(dx, dy, dw);
_c1 = dx * dxw + dy * dyw;
_c2 = dxy;
_d = CGAL::square(dx) + CGAL::square(dy);
_delta = _d - CGAL::square(dw);
_dxw = dxw;
_dyw = dyw;
}
public:
Bitangent_line_2(const Site_2& p1, const Site_2& p2)
{
FT dx = p1.x() - p2.x();
FT dy = p1.y() - p2.y();
FT dw = p1.weight() - p2.weight();
FT dxy = determinant(p1.x(), p1.y(), p2.x(), p2.y());
FT dxw = determinant(p1.x(), p1.weight(), p2.x(), p2.weight());
FT dyw = determinant(p1.y(), p1.weight(), p2.y(), p2.weight());
store(dx, dy, dw, dxy, dxw, dyw);
}
Bitangent_line_2(const Inverted_weighted_point& u1,
const Inverted_weighted_point& u2)
{
FT dxp = determinant(u1.x(), u1.p(), u2.x(), u2.p());
FT dyp = determinant(u1.y(), u1.p(), u2.y(), u2.p());
FT dwp = determinant(u1.weight(), u1.p(), u2.weight(), u2.p());
FT dxy = determinant(u1.x(), u1.y(), u2.x(), u2.y());
FT dxw = determinant(u1.x(), u1.weight(), u2.x(), u2.weight());
FT dyw = determinant(u1.y(), u1.weight(), u2.y(), u2.weight());
store(dxp, dyp, dwp, dxy, dxw, dyw);
}
Bitangent_line_2 get_symmetric() const
{
return
Bitangent_line_2(_a1, -_a2, _b1, -_b2, _c1, -_c2, _delta, _d,
-_dw, -_dxw, -_dyw);
}
Bitangent_line_2 get_rot90() const
{
return
Bitangent_line_2(-_b1, -_b2, _a1, _a2, _c1, _c2, _delta, _d,
_dw, -_dyw, _dxw);
}
Bitangent_line_2 perpendicular(const Point_2& p) const
{
// THIS DOES NOT KEEP TRACK OF THE ADDITIONALLY STORED
// QUANTITIES; THIS IS INEVITABLE IN ANY CASE SINCE GIVEN p WE
// CANNOT ANY LONGER HOPE TO KEEP TRACK OF THOSE
Bitangent_line_2 rotated = get_rot90();
rotated._c1 = _b1 * p.x() - _a1 * p.y();
rotated._c2 = _b2 * p.x() - _a2 * p.y();
return rotated;
}
Bitangent_line_2 perpendicular(const Inverted_weighted_point& u) const
{
// THIS DOES NOT KEEP TRACK OF THE ADDITIONALLY STORED
// QUANTITIES; THIS IS INEVITABLE IN ANY CASE SINCE GIVEN p WE
// CANNOT ANY LONGER HOPE TO KEEP TRACK OF THOSE
Bitangent_line_2 rotated = get_rot90();
rotated._c1 = (_b1 * u.x() - _a1 * u.y()) * u.p();
rotated._c2 = (_b2 * u.x() - _a2 * u.y()) * u.p();
return rotated;
}
inline FT a1() const { return _a1; }
inline FT a2() const { return _a2; }
inline FT b1() const { return _b1; }
inline FT b2() const { return _b2; }
inline FT c1() const { return _c1; }
inline FT c2() const { return _c2; }
inline FT delta() const { return _delta; }
inline FT d() const { return _d; }
inline FT dx() const { return -_b2; }
inline FT dy() const { return _a2; }
inline FT dw() const { return _dw; }
inline FT dxw() const { return _dxw; }
inline FT dyw() const { return _dyw; }
};
template< class K >
class Voronoi_circle_2 : public Bitangent_line_2<K>
{
public:
typedef Inverted_weighted_point_2<K> Inverted_weighted_point;
typedef Bitangent_line_2<K> Bitangent_line;
typedef Voronoi_radius_2<K> Voronoi_radius;
typedef typename Bitangent_line::FT FT;
protected:
FT _gamma;
inline
void compute_gamma()
{
_gamma = CGAL::square(this->_dxw) + CGAL::square(this->_dyw)
- CGAL::square(this->_c2);
}
public:
Voronoi_circle_2(const Voronoi_radius& vr)
: Bitangent_line(FT(0), FT(0), FT(0), FT(0), vr.b(), vr.c2(),
vr.delta(), vr.d(), FT(0), FT(0), FT(0)), _gamma(vr.c())
{
this->store(vr.dxp(), vr.dyp(), vr.dwp());
}
Voronoi_circle_2(const Bitangent_line& bl)
: Bitangent_line(bl.a1(), bl.a2(), bl.b1(), bl.b2(), bl.c1(), bl.c2(),
bl.delta(), bl.d(), bl.dw(), bl.dxw(), bl.dyw())
{
compute_gamma();
}
inline FT alpha() const { return this->_d; }
inline FT beta() const { return this->_c1; }
inline FT gamma() const { return _gamma; }
inline bool is_first_root() const {
return CGAL::is_negative(this->_c2);
}
FT compute_P4(const Inverted_weighted_point& u1,
const Inverted_weighted_point& u2,
const Inverted_weighted_point& u3) const
{
FT dx1 = determinant(u2.x(), u2.p(), u1.x(), u1.p());
FT dy1 = determinant(u2.y(), u2.p(), u1.y(), u1.p());
FT dw1 = determinant(u2.weight(), u2.p(), u1.weight(), u1.p());
FT dx3 = determinant(u3.x(), u3.p(), u2.x(), u2.p());
FT dy3 = determinant(u3.y(), u3.p(), u2.y(), u2.p());
FT dw3 = determinant(u3.weight(), u3.p(), u2.weight(), u2.p());
FT u2Pv2 = CGAL::square(u2.x()) + CGAL::square(u2.y());
FT u2Mv2 = CGAL::square(u2.x()) - CGAL::square(u2.y());
FT u2v2 = FT(2) * u2.x() * u2.y();
FT vvMuu = dy1 * dy3 - dx1 * dx3;
FT vuPuv = dy1 * dx3 + dx1 * dy3;
FT dx2Pdy2_1 = CGAL::square(dx1) + CGAL::square(dy1);
FT dx2Pdy2_3 = CGAL::square(dx3) + CGAL::square(dy3);
FT fr1_sq = CGAL::square(dw1) * dx2Pdy2_3;
FT fr3_sq = CGAL::square(dw3) * dx2Pdy2_1;
FT f1 = (fr1_sq + fr3_sq) * CGAL::square(u2Pv2);
FT f2 = FT(2) * dw1 * dw3 * u2Pv2 * (u2Mv2 * vvMuu - u2v2 * vuPuv );
FT f3 = CGAL::square(u2Mv2 * vuPuv + u2v2 * vvMuu);
FT F = f1 + f2 - f3;
FT uuPvv = dy1 * dy3 + dx1 * dx3;
FT vuMuv = dy1 * dx3 - dx1 * dy3;
FT G = fr1_sq + fr3_sq - FT(2) * dw1 * dw3 * uuPvv
- CGAL::square(vuMuv);
return (F * G);
}
};
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_PREDICATE_CONSTRUCTIONS_2_H

View File

@ -0,0 +1,33 @@
// Copyright (c) 2003,2004 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_PREDICATES_C2_H
#define CGAL_APOLLONIUS_GRAPH_2_PREDICATES_C2_H
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/Apollonius_graph_2/Compare_x_2.h>
#include <CGAL/Apollonius_graph_2/Compare_y_2.h>
#include <CGAL/Apollonius_graph_2/Compare_weight_2.h>
#include <CGAL/Apollonius_graph_2/Orientation_2.h>
#include <CGAL/Apollonius_graph_2/Is_hidden_C2.h>
#include <CGAL/Apollonius_graph_2/Oriented_side_of_bisector_C2.h>
#include <CGAL/Apollonius_graph_2/Incircle_C2.h>
#include <CGAL/Apollonius_graph_2/Finite_edge_test_C2.h>
#include <CGAL/Apollonius_graph_2/Infinite_edge_test_C2.h>
#include <CGAL/Apollonius_graph_2/Is_degenerate_edge_C2.h>
#endif // CGAL_APOLLONIUS_GRAPH_2_PREDICATES_C2_H

View File

@ -0,0 +1,50 @@
// Copyright (c) 2003,2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_TRAITS_WRAPPER_2_H
#define CGAL_APOLLONIUS_GRAPH_2_TRAITS_WRAPPER_2_H
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/Apollonius_graph_2/basic.h>
namespace CGAL {
namespace ApolloniusGraph_2 {
template<class Gt_base>
class Apollonius_graph_traits_wrapper_2 : public Gt_base
{
public:
// struct Segment_2 {};
struct Triangle_2 {};
Apollonius_graph_traits_wrapper_2() {}
Apollonius_graph_traits_wrapper_2(const Gt_base& gtb)
: Gt_base(gtb) {}
};
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_TRAITS_WRAPPER_2_H

View File

@ -0,0 +1,25 @@
// Copyright (c) 2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_BASIC_H
#define CGAL_APOLLONIUS_GRAPH_2_BASIC_H 1
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/basic.h>
#include <CGAL/number_type_basic.h>
#define CGAL_APOLLONIUS_GRAPH_2_NS CGAL::ApolloniusGraph_2
#endif // CGAL_APOLLONIUS_GRAPH_2_BASIC_H

View File

@ -0,0 +1,986 @@
// Copyright (c) 2003,2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_COMPARE_QUADRATIC_H
#define CGAL_APOLLONIUS_GRAPH_2_COMPARE_QUADRATIC_H
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/Apollonius_graph_2/basic.h>
#include <CGAL/functions_on_signs.h>
namespace CGAL {
namespace ApolloniusGraph_2 {
#ifdef COMPARATOR_PROFILER
#include <CGAL/Apollonius_graph_2/comparator_profiler.h>
#endif
//--------------------------------------------------------------------
// help functions for the compulation of various quantites
template < class FT >
inline FT
value_of_D(const FT& a, const FT& b, const FT& c)
{
return CGAL::square(b) - a * c;
}
template < class FT >
inline FT
value_of_J(const FT& a1, const FT& b1, const FT& a2, const FT& b2)
{
return (a1 * b2 - a2 * b1);
}
template < class FT >
inline FT
value_of_Jp(const FT& b1, const FT& c1, const FT& b2, const FT& c2)
{
return (b1 * c2 - b2 * c1);
}
template < class FT >
inline FT
value_of_G(const FT& a1, const FT& c1, const FT& a2, const FT& c2)
{
return (a1 * c2 - a2 * c1);
}
template < class FT >
inline FT
value_of_K(const FT& a1c2, const FT& a2c1, const FT& b1b2)
{
return a1c2 + a2c1 - FT(2) * b1b2;
}
template < class FT >
inline FT
value_of_K(const FT& a1, const FT& b1, const FT& c1,
const FT& a2, const FT& b2, const FT& c2)
{
return c1 * a2 + a1 * c2 - FT(2) * b1 * b2;
}
template < class FT >
inline FT
value_of_R0(const FT& J, const FT& Jp,
const FT& a1, const FT& c1,
const FT& a2, const FT& c2)
{
return CGAL::square(a1 * c2 - c1 * a2) - FT(4) * J * Jp;
}
template < class FT >
inline FT
value_of_R0(const FT& D1, const FT& D2, const FT& K)
{
return CGAL::square(K) - FT(4) * D1 * D2;
}
template < class FT >
inline FT
value_of_P4(const FT& D1, const FT& D2, const FT& K)
{
return FT(4) * D1 * D2 - CGAL::square(K);
}
template < class FT >
inline FT
value_of_D(const FT& a1, const FT& D1, const FT& a2, const FT& D2)
{
return D1 * CGAL::square(a2) - D2 * CGAL::square(a1);
}
template < class FT >
inline FT
value_of_P3inf(const FT& a1, const FT& b1, const FT& J, const FT& G)
{
return FT(2) * b1 * J - a1 * G;
}
template < class FT >
inline FT
value_of_P3inf_bis(const FT& a1, const FT& K, const FT& a2, const FT& D1)
{
return -(a1 * K + FT(2) * a2 * D1);
}
template < class FT >
inline FT
value_of_P3pinf(const FT& c1, const FT& J, const FT& a1, const FT& Jp)
{
return c1 * J - a1 * Jp;
}
template < class FT >
inline FT
value_of_L(const FT& a1, const FT& c2, const FT& b1, const FT& b2)
{
return (a1 * c2 - b1 * b2);
}
template < class FT >
inline FT
value_of_Lp(const FT& a2, const FT& c1, const FT& b1, const FT& b2)
{
return (a2 * c1 - b1 * b2);
}
template < class FT >
inline FT
value_of_A(const FT& b1, const FT& J, const FT& a1, const FT& L)
{
return b1 * J + a1 * L;
}
template < class FT >
inline FT
value_of_Q3(const FT& b2, const FT& a2, const FT& J, const FT& L)
{
return (b2 * J + a2 * L);
}
template < class FT >
inline FT
value_of_Q3(const FT& a2, const FT& b2, const FT& J, const FT& G,
const FT& K)
{
return FT(2) * b2 * J - a2 * (G - K);
}
template < class FT >
inline FT
value_of_Q3p(const FT& a1, const FT& b1, const FT& J, const FT& G,
const FT& K)
{
return a1 * (G + K) - FT(2) * b1 * J;
}
//--------------------------------------------------------------------
// the trivial method that uses square roots
template < class FT >
inline
Comparison_result
sqrt_compare_l1_l2(const FT& a1, const FT& b1, const FT& c1,
const FT& a2, const FT& b2, const FT& c2)
{
FT D1 = value_of_D(a1, b1, c1);
FT D2 = value_of_D(a2, b2, c2);
FT l1 = ( b1 - CGAL::sqrt(D1) ) / a1;
FT l2 = ( b2 - CGAL::sqrt(D2) ) / a2;
return CGAL::compare(l1, l2);
}
template < class FT >
inline
Comparison_result
sqrt_compare_l1_r2(const FT& a1, const FT& b1, const FT& c1,
const FT& a2, const FT& b2, const FT& c2)
{
FT D1 = value_of_D(a1, b1, c1);
FT D2 = value_of_D(a2, b2, c2);
FT l1 = ( b1 - CGAL::sqrt(D1) ) / a1;
FT r2 = ( b2 + CGAL::sqrt(D2) ) / a2;
return CGAL::compare(l1, r2);
}
template < class FT >
inline
Comparison_result
sqrt_compare_r1_l2(const FT& a1, const FT& b1, const FT& c1,
const FT& a2, const FT& b2, const FT& c2)
{
FT D1 = value_of_D(a1, b1, c1);
FT D2 = value_of_D(a2, b2, c2);
FT r1 = ( b1 + CGAL::sqrt(D1) ) / a1;
FT l2 = ( b2 - CGAL::sqrt(D2) ) / a2;
return CGAL::compare(r1, l2);
}
template < class FT >
inline
Comparison_result
sqrt_compare_r1_r2(const FT& a1, const FT& b1, const FT& c1,
const FT& a2, const FT& b2, const FT& c2)
{
FT D1 = value_of_D(a1, b1, c1);
FT D2 = value_of_D(a2, b2, c2);
FT r1 = ( b1 + CGAL::sqrt(D1) ) / a1;
FT r2 = ( b2 + CGAL::sqrt(D2) ) / a2;
return CGAL::compare(r1, r2);
}
//--------------------------------------------------------------------
// the DFMT evaluation trees
template < class FT >
inline
Comparison_result
dfmt_compare_l1_l2(const FT& a1, const FT& b1, const FT& c1,
const FT& a2, const FT& b2, const FT& c2)
{
FT J = value_of_J(a1, b1, a2, b2);
FT K = value_of_K(a1, b1, c1, a2, b2, c2);
if ( CGAL::is_positive(J) ) {
if ( CGAL::is_positive(K) ) return SMALLER; // l1 < l2
FT D1 = value_of_D(a1, b1, c1);
FT D2 = value_of_D(a2, b2, c2);
FT D = value_of_D(a1, D1, a2, D2);
if ( CGAL::is_positive(D) ) return SMALLER; // l1 < l2
FT Jp = value_of_Jp(b1, c1, b2, c2);
if ( CGAL::is_negative(Jp) ) return LARGER; // l1 > l2
FT R0 = value_of_R0(D1, D2, K);
Sign s_R0 = CGAL::sign(R0);
if ( s_R0 == NEGATIVE ) return SMALLER; // l1 < l2
if ( s_R0 == POSITIVE ) return LARGER; // l1 > l2
return EQUAL;
} else { // J<0
if ( CGAL::is_positive(K) ) return LARGER; // l1 > l2
FT D1 = value_of_D(a1, b1, c1);
FT D2 = value_of_D(a2, b2, c2);
FT D = value_of_D(a1, D1, a2, D2);
if ( CGAL::is_negative(D) ) return LARGER; // l1 > l2
FT Jp = value_of_Jp(b1, c1, b2, c2);
if ( CGAL::is_positive(Jp) ) return SMALLER; // l1 < l2
FT R0 = value_of_R0(D1, D2, K);
Sign s_R0 = CGAL::sign(R0);
if ( s_R0 == NEGATIVE ) return LARGER; // l1 > l2
if ( s_R0 == POSITIVE ) return SMALLER; // l1 < l2
return EQUAL;
}
}
template < class FT >
inline
Comparison_result
dfmt_compare_l1_r2(const FT& a1, const FT& b1, const FT& c1,
const FT& a2, const FT& b2, const FT& c2)
{
FT J = value_of_J(a1, b1, a2, b2);
if ( CGAL::is_positive(J) ) return SMALLER; // l1 < r2
FT K = value_of_K(a1, b1, c1, a2, b2, c2);
if ( CGAL::is_negative(K) ) return SMALLER; // l1 < r2
FT Jp = value_of_Jp(b1, c1, b2, c2);
if ( CGAL::is_positive(Jp) ) return LARGER; // l1 > r2
FT R0 = value_of_R0(J, Jp, a1, c1, a2, c2);
Sign s_R0 = CGAL::sign(R0);
if ( s_R0 == NEGATIVE ) return SMALLER; // l1 < r2
if ( s_R0 == POSITIVE ) return LARGER; // l1 > r2
return EQUAL;
}
template < class FT >
inline
Comparison_result
dfmt_compare_r1_l2(const FT& a1, const FT& b1, const FT& c1,
const FT& a2, const FT& b2, const FT& c2)
{
FT J = value_of_J(a1, b1, a2, b2);
if ( CGAL::is_negative(J) ) return LARGER; // r1 > l2
FT K = value_of_K(a1, b1, c1, a2, b2, c2);
if ( CGAL::is_negative(K) ) return LARGER; // r1 > l2
FT Jp = value_of_Jp(b1, c1, b2, c2);
if ( CGAL::is_negative(Jp) ) return SMALLER; // r1 < l2
FT R0 = value_of_R0(J, Jp, a1, c1, a2, c2);
Sign s_R0 = CGAL::sign(R0);
if ( s_R0 == NEGATIVE ) return LARGER; // r1 > l2
if ( s_R0 == POSITIVE ) return SMALLER; // r1 < l2
return EQUAL;
}
template < class FT >
inline
Comparison_result
dfmt_compare_r1_r2(const FT& a1, const FT& b1, const FT& c1,
const FT& a2, const FT& b2, const FT& c2)
{
#ifdef COMPARATOR_PROFILER
comparator_profiler::counter_rr++;
#endif
FT J = value_of_J(a1, b1, a2, b2);
FT K = value_of_K(a1, b1, c1, a2, b2, c2);
if ( CGAL::is_positive(J) ){
if ( CGAL::is_positive(K) ) return SMALLER; // r1 < r2 1,2
#ifdef COMPARATOR_PROFILER
comparator_profiler::counter_rr_e++;
#endif
FT D1 = value_of_D(a1, b1, c1);
FT D2 = value_of_D(a2, b2, c2);
FT D = value_of_D(a1, D1, a2, D2);
if ( CGAL::is_negative(D) ) return SMALLER; // r1 < r2 2,3b
#ifdef COMPARATOR_PROFILER
comparator_profiler::counter_rr_r0++;
#endif
FT Jp = value_of_Jp(b1, c1, b2, c2);
if ( CGAL::is_negative(Jp) ) return LARGER; // r1 > r2 3a
FT R0 = value_of_R0(D1, D2, K);
Sign s_R0 = CGAL::sign(R0);
if ( s_R0 == NEGATIVE ) return SMALLER; // r1 < r2 2
if ( s_R0 == POSITIVE ) return LARGER; // r1 > r2 3a
return EQUAL;
} else { // J<0
if ( CGAL::is_positive(K) ) return LARGER; // r1 > r2 4,5
#ifdef COMPARATOR_PROFILER
comparator_profiler::counter_rr_e++;
#endif
FT D1 = value_of_D(a1, b1, c1);
FT D2 = value_of_D(a2, b2, c2);
FT D = value_of_D(a1, D1, a2, D2);
if ( CGAL::is_positive(D) ) return LARGER; // r1 > r2 3a,4
#ifdef COMPARATOR_PROFILER
comparator_profiler::counter_rr_r0++;
#endif
FT Jp = value_of_Jp(b1, c1, b2, c2);
if ( CGAL::is_positive(Jp) ) return SMALLER; // r1 < r2 3b
FT R0 = value_of_P4(D1, D2, K);
Sign s_R0 = CGAL::sign(R0);
if ( s_R0 == NEGATIVE ) return LARGER; // r1 > r2 4
if ( s_R0 == POSITIVE ) return SMALLER; // r1 < r2 3b
return EQUAL;
}
}
//--------------------------------------------------------------------
// the KE evaluation trees
template < class FT >
inline
Comparison_result
ke_compare_l1_l2(const FT& a1, const FT& b1, const FT& c1,
const FT& a2, const FT& b2, const FT& c2)
{
FT J = value_of_J(a1, b1, a2, b2);
Sign s_J = CGAL::sign(J);
if ( s_J == ZERO ) {
Sign s_G = CGAL::sign( value_of_G(a1, c1, a2, c2) );
if ( s_G == POSITIVE ) { return SMALLER; }
if ( s_G == NEGATIVE ) { return LARGER; }
return EQUAL;
}
FT a1c2 = a1 * c2;
FT a2c1 = a2 * c1;
FT K = value_of_K<FT>(a1c2, a2c1, b1 * b2);
Sign s_K = CGAL::sign(K);
if ( s_J == POSITIVE ) {
if ( s_K == POSITIVE ) { return SMALLER; }
if ( s_K == ZERO ) {
FT D1 = value_of_D(a1, b1, c1);
if ( CGAL::is_zero(D1) ) { return EQUAL; }
return SMALLER;
}
FT G = a1c2 - a2c1;
FT P3inf = value_of_P3inf(a1, b1, J, G);
if ( !(CGAL::is_positive(P3inf)) ) { return SMALLER; }
FT Jp = value_of_Jp(b1, c1, b2, c2);
if ( CGAL::is_negative(Jp) ) { return LARGER; }
FT P4 = value_of_P4(J, Jp, G);
Sign s_P4 = CGAL::sign(P4);
if ( s_P4 == POSITIVE ) { return SMALLER; }
if ( s_P4 == NEGATIVE ) { return LARGER; }
return EQUAL;
}
// J < 0
if ( s_K == POSITIVE ) { return LARGER; }
if ( s_K == ZERO ) {
FT D2 = value_of_D(a2, b2, c2);
if ( CGAL::is_zero(D2) ) { return EQUAL; }
return LARGER;
}
FT G = a1c2 - a2c1;
FT P3inf = value_of_P3inf(a1, b1, J, G);
if ( !(CGAL::is_negative(P3inf)) ) { return LARGER; }
FT Jp = value_of_Jp(b1, c1, b2, c2);
if ( CGAL::is_positive(Jp) ) { return SMALLER; }
FT P4 = value_of_P4(J, Jp, G);
Sign s_P4 = CGAL::sign(P4);
if ( s_P4 == POSITIVE ) { return LARGER; }
if ( s_P4 == NEGATIVE ) { return SMALLER; }
return EQUAL;
}
template < class FT >
inline
Comparison_result
ke_compare_l1_r2(const FT& a1, const FT& b1, const FT& c1,
const FT& a2, const FT& b2, const FT& c2)
{
FT J = value_of_J(a1, b1, a2, b2);
Sign s_J = CGAL::sign(J);
#if 0
if ( s_J == ZERO ) {
FT D1 = value_of_D(a1, b1, c1);
if ( CGAL::is_positive(D1) ) { return SMALLER; }
FT D2 = value_of_D(a2, b2, c2);
if ( CGAL::is_positive(D2) ) { return SMALLER; }
return EQUAL;
}
#endif
if ( s_J == POSITIVE ) { return SMALLER; }
FT a1c2 = a1 * c2;
FT a2c1 = a2 * c1;
FT K = value_of_K<FT>(a1c2, a2c1, b1 * b2);
Sign s_K = CGAL::sign(K);
if ( s_K == NEGATIVE ) { return SMALLER; }
#if 0
if ( s_K == ZERO ) {
FT D1 = value_of_D(a1, b1, c1);
if ( CGAL::is_zero(D1) ) { return EQUAL; }
FT D2 = value_of_D(a2, b2, c2);
if ( CGAL::is_zero(D2) ) { return EQUAL; }
return SMALLER;
}
#endif
FT Jp = value_of_Jp(b1, c1, b2, c2);
if ( CGAL::is_positive(Jp) ) { return LARGER; }
FT P4 = value_of_P4<FT>(J, Jp, a1c2 - a2c1);
Sign s_P4 = CGAL::sign(P4);
if ( s_P4 == POSITIVE ) { return SMALLER; }
if ( s_P4 == NEGATIVE ) { return LARGER; }
return EQUAL;
}
template < class FT >
inline
Comparison_result
ke_compare_r1_l2(const FT& a1, const FT& b1, const FT& c1,
const FT& a2, const FT& b2, const FT& c2)
{
FT J = value_of_J(a1, b1, a2, b2);
Sign s_J = CGAL::sign(J);
#if 0
if ( s_J == ZERO ) {
FT D1 = value_of_D(a1, b1, c1);
if ( CGAL::is_positive(D1) ) { return LARGER; }
FT D2 = value_of_D(a2, b2, c2);
if ( CGAL::is_positive(D2) ) { return LARGER; }
return EQUAL;
}
#endif
if ( s_J == NEGATIVE ) { return LARGER; }
FT a1c2 = a1 * c2;
FT a2c1 = a2 * c1;
FT K = value_of_K<FT>(a1c2, a2c1, b1 * b2);
Sign s_K = CGAL::sign(K);
if ( s_K == NEGATIVE ) { return LARGER; }
#if 0
if ( s_K == ZERO ) {
FT D1 = value_of_D(a1, b1, c1);
if ( CGAL::is_zero(D1) ) { return EQUAL; }
FT D2 = value_of_D(a2, b2, c2);
if ( CGAL::is_zero(D2) ) { return EQUAL; }
return LARGER;
}
#endif
FT Jp = value_of_Jp(b1, c1, b2, c2);
if ( CGAL::is_negative(Jp) ) { return SMALLER; }
FT P4 = value_of_P4<FT>(J, Jp, a1c2 - a2c1);
Sign s_P4 = CGAL::sign(P4);
if ( s_P4 == POSITIVE ) { return LARGER; }
if ( s_P4 == NEGATIVE ) { return SMALLER; }
return EQUAL;
}
template < class FT >
inline
Comparison_result
ke_compare_r1_r2(const FT& a1, const FT& b1, const FT& c1,
const FT& a2, const FT& b2, const FT& c2)
{
#ifdef COMPARATOR_PROFILER
comparator_profiler::counter_rr++;
#endif
FT J = value_of_J(a1, b1, a2, b2);
Sign s_J = CGAL::sign(J);
FT a1c2 = a1 * c2;
FT a2c1 = a2 * c1;
FT K = value_of_K<FT>(a1c2, a2c1, b1 * b2);
Sign s_K = CGAL::sign(K);
if ( s_J == POSITIVE ) {
if ( s_K == POSITIVE ) { return SMALLER; }
else if ( s_K == NEGATIVE ) {
#ifdef COMPARATOR_PROFILER
comparator_profiler::counter_rr_p3inf++;
#endif
FT G = a1c2 - a2c1;
FT P3inf = value_of_P3inf(a1, b1, J, G);
if ( !(CGAL::is_negative(P3inf)) ) { return SMALLER; }
#ifdef COMPARATOR_PROFILER
comparator_profiler::counter_rr_p4++;
#endif
FT Jp = value_of_Jp(b1, c1, b2, c2);
if ( CGAL::is_negative(Jp) ) { return LARGER; }
FT P4 = value_of_P4(J, Jp, G);
Sign s_P4 = CGAL::sign(P4);
if ( s_P4 == POSITIVE ) { return SMALLER; }
if ( s_P4 == NEGATIVE ) { return LARGER; }
return EQUAL;
} else { // K = 0
FT D2 = value_of_D(a2, b2, c2);
if ( CGAL::is_zero(D2) ) { return EQUAL; }
return SMALLER;
}
} else if ( s_J == NEGATIVE ) { // J < 0
if ( s_K == POSITIVE ) { return LARGER; }
else if ( s_K == NEGATIVE ) {
#ifdef COMPARATOR_PROFILER
comparator_profiler::counter_rr_p3inf++;
#endif
FT G = a1c2 - a2c1;
FT P3inf = value_of_P3inf(a1, b1, J, G);
if ( !(CGAL::is_positive(P3inf)) ) { return LARGER; }
#ifdef COMPARATOR_PROFILER
comparator_profiler::counter_rr_p4++;
#endif
FT Jp = value_of_Jp(b1, c1, b2, c2);
if ( CGAL::is_positive(Jp) ) { return SMALLER; }
FT P4 = value_of_P4(J, Jp, G);
Sign s_P4 = CGAL::sign(P4);
if ( s_P4 == POSITIVE ) { return LARGER; }
if ( s_P4 == NEGATIVE ) { return SMALLER; }
return EQUAL;
} else { // K = 0
FT D1 = value_of_D(a1, b1, c1);
if ( CGAL::is_zero(D1) ) { return EQUAL; }
return LARGER;
}
}
// J = 0
Sign s_G = CGAL::sign( value_of_G(a1, c1, a2, c2) );
if ( s_G == NEGATIVE ) { return SMALLER; }
if ( s_G == POSITIVE ) { return LARGER; }
return EQUAL;
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// the following functions do the filtering for the r1-r2 tree without
// using C++ exceptions
template < class CT, class ET >
inline
Comparison_result
sqrt_compare_r1_r2_filtered(const CT& a1, const CT& b1, const CT& c1,
const CT& a2, const CT& b2, const CT& c2)
{
typedef Interval_nt<false> IT;
FPU_CW_t backup = FPU_get_cw();
FPU_set_cw(CGAL_FE_UPWARD);
IT a1i(a1), b1i(b1), c1i(c1);
IT a2i(a2), b2i(b2), c2i(c2);
IT D1 = value_of_D(a1i, b1i, c1i);
IT D2 = value_of_D(a2i, b2i, c2i);
IT r1 = ( b1i + CGAL::sqrt(D1) ) / a1i;
IT r2 = ( b2i + CGAL::sqrt(D2) ) / a2i;
FPU_set_cw(backup);
if ( r1.sup() < r2.inf() ) { return SMALLER; }
if ( r1.inf() > r2.sup() ) { return LARGER; }
return sqrt_compare_r1_r2(ET(a1), ET(b1), ET(c1),
ET(a2), ET(b2), ET(c2));
}
//--------------------------------------------------------------------
template < class CT, class ET >
inline
Comparison_result
dfmt_compare_r1_r2_filtered(const CT& a1, const CT& b1, const CT& c1,
const CT& a2, const CT& b2, const CT& c2)
{
typedef Interval_nt<false> IT;
FPU_CW_t backup = FPU_get_cw();
FPU_set_cw(CGAL_FE_UPWARD);
IT a1i(a1), b1i(b1), c1i(c1);
IT a2i(a2), b2i(b2), c2i(c2);
IT J = value_of_J(a1i, b1i, a2i, b2i);
IT K = value_of_K(a1i, b1i, c1i, a2i, b2i, c2i);
if ( J.inf() > 0 ){
if ( K.inf() > 0 ) {
FPU_set_cw(backup);
return SMALLER;
}
if ( K.sup() > 0 ) {
FPU_set_cw(backup);
return dfmt_compare_r1_r2(ET(a1), ET(b1), ET(c1),
ET(a2), ET(b2), ET(c2));
}
IT D1 = value_of_D(a1i, b1i, c1i);
IT D2 = value_of_D(a2i, b2i, c2i);
IT D = value_of_D(a1i, D1, a2i, D2);
if ( D.sup() < 0 ) {
FPU_set_cw(backup);
return SMALLER;
}
if ( D.inf() < 0 ) {
FPU_set_cw(backup);
return dfmt_compare_r1_r2(ET(a1), ET(b1), ET(c1),
ET(a2), ET(b2), ET(c2));
}
IT Jp = value_of_Jp(b1i, c1i, b2i, c2i);
if ( Jp.sup() < 0 ) {
FPU_set_cw(backup);
return LARGER;
}
if ( Jp.inf() < 0 ) {
FPU_set_cw(backup);
return dfmt_compare_r1_r2(ET(a1), ET(b1), ET(c1),
ET(a2), ET(b2), ET(c2));
}
IT R0 = value_of_R0(D1, D2, K);
FPU_set_cw(backup);
if ( R0.sup() < 0 ) { return SMALLER; }
if ( R0.inf() > 0 ) { return LARGER; }
return dfmt_compare_r1_r2(ET(a1), ET(b1), ET(c1),
ET(a2), ET(b2), ET(c2));
} else if ( J.sup() > 0 ) {
FPU_set_cw(backup);
return dfmt_compare_r1_r2(ET(a1), ET(b1), ET(c1),
ET(a2), ET(b2), ET(c2));
} else { // J < 0
if ( K.inf() > 0 ) {
FPU_set_cw(backup);
return LARGER;
}
if ( K.sup() > 0 ) {
FPU_set_cw(backup);
return dfmt_compare_r1_r2(ET(a1), ET(b1), ET(c1),
ET(a2), ET(b2), ET(c2));
}
IT D1 = value_of_D(a1i, b1i, c1i);
IT D2 = value_of_D(a2i, b2i, c2i);
IT D = value_of_D(a1i, D1, a2i, D2);
if ( D.inf() > 0 ) {
FPU_set_cw(backup);
return LARGER;
}
if ( D.sup() > 0 ) {
FPU_set_cw(backup);
return dfmt_compare_r1_r2(ET(a1), ET(b1), ET(c1),
ET(a2), ET(b2), ET(c2));
}
IT Jp = value_of_Jp(b1i, c1i, b2i, c2i);
if ( Jp.inf() > 0 ) {
FPU_set_cw(backup);
return SMALLER;
}
if ( Jp.sup() > 0 ) {
FPU_set_cw(backup);
return dfmt_compare_r1_r2(ET(a1), ET(b1), ET(c1),
ET(a2), ET(b2), ET(c2));
}
IT R0 = value_of_P4(D1, D2, K);
FPU_set_cw(backup);
if ( R0.sup() < 0 ) { return LARGER; }
if ( R0.inf() > 0 ) { return SMALLER; }
return dfmt_compare_r1_r2(ET(a1), ET(b1), ET(c1),
ET(a2), ET(b2), ET(c2));
}
}
//--------------------------------------------------------------------
template < class CT, class ET >
inline
Comparison_result
ke_compare_r1_r2_filtered(const CT& a1, const CT& b1, const CT& c1,
const CT& a2, const CT& b2, const CT& c2)
{
typedef Interval_nt<false> IT;
FPU_CW_t backup = FPU_get_cw();
FPU_set_cw(CGAL_FE_UPWARD);
IT a1i(a1), b1i(b1), c1i(c1);
IT a2i(a2), b2i(b2), c2i(c2);
IT J = value_of_J(a1i, b1i, a2i, b2i);
IT a1c2 = a1i * c2i;
IT a2c1 = a2i * c1i;
IT K = value_of_K(a1c2, a2c1, b1i * b2i);
if ( J.inf() > 0 ) {
if ( K.inf() > 0 ) {
FPU_set_cw(backup);
return SMALLER;
} else if ( K.sup() < 0 ) {
IT G = a1c2 - a2c1;
IT P3inf = value_of_P3inf(a1i, b1i, J, G);
if ( P3inf.inf() >= 0 ) {
FPU_set_cw(backup);
return SMALLER;
}
if ( P3inf.sup() > 0 ) {
FPU_set_cw(backup);
return ke_compare_r1_r2(ET(a1), ET(b1), ET(c1),
ET(a2), ET(b2), ET(c2));
}
IT Jp = value_of_Jp(b1i, c1i, b2i, c2i);
if ( Jp.sup() < 0 ) {
FPU_set_cw(backup);
return LARGER;
}
if ( Jp.inf() < 0 ) {
FPU_set_cw(backup);
return ke_compare_r1_r2(ET(a1), ET(b1), ET(c1),
ET(a2), ET(b2), ET(c2));
}
IT P4 = value_of_P4(J, Jp, G);
FPU_set_cw(backup);
if ( P4.inf() > 0 ) { return SMALLER; }
if ( P4.sup() < 0 ) { return LARGER; }
return ke_compare_r1_r2(ET(a1), ET(b1), ET(c1),
ET(a2), ET(b2), ET(c2));
} else {
FPU_set_cw(backup);
return ke_compare_r1_r2(ET(a1), ET(b1), ET(c1),
ET(a2), ET(b2), ET(c2));
}
} else if ( J.sup() < 0 ) { // J < 0
if ( K.inf() > 0 ) {
FPU_set_cw(backup);
return LARGER;
} else if ( K.sup() < 0 ) {
IT G = a1c2 - a2c1;
IT P3inf = value_of_P3inf(a1i, b1i, J, G);
if ( P3inf.sup() <= 0 ) {
FPU_set_cw(backup);
return LARGER;
}
if ( P3inf.inf() < 0 ) {
FPU_set_cw(backup);
return ke_compare_r1_r2(ET(a1), ET(b1), ET(c1),
ET(a2), ET(b2), ET(c2));
}
IT Jp = value_of_Jp(b1i, c1i, b2i, c2i);
if ( Jp.inf() > 0 ) {
FPU_set_cw(backup);
return SMALLER;
}
if ( Jp.sup() > 0 ) {
FPU_set_cw(backup);
return ke_compare_r1_r2(ET(a1), ET(b1), ET(c1),
ET(a2), ET(b2), ET(c2));
}
IT P4 = value_of_P4(J, Jp, G);
FPU_set_cw(backup);
if ( P4.inf() > 0 ) { return LARGER; }
if ( P4.sup() < 0 ) { return SMALLER; }
return ke_compare_r1_r2(ET(a1), ET(b1), ET(c1),
ET(a2), ET(b2), ET(c2));
} else {
FPU_set_cw(backup);
return ke_compare_r1_r2(ET(a1), ET(b1), ET(c1),
ET(a2), ET(b2), ET(c2));
}
} else { // J = ?
FPU_set_cw(backup);
return ke_compare_r1_r2(ET(a1), ET(b1), ET(c1),
ET(a2), ET(b2), ET(c2));
}
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------
} //namespace ApolloniusGraph_2
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_COMPARE_QUADRATIC_H

View File

@ -0,0 +1,93 @@
// Copyright (c) 2003,2004 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_UNCERTAIN_IS_HIDDEN_C2_H
#define CGAL_APOLLONIUS_GRAPH_2_UNCERTAIN_IS_HIDDEN_C2_H
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/enum.h>
#include <CGAL/Uncertain.h>
#include <CGAL/number_type_basic.h>
namespace CGAL {
//--------------------------------------------------------------------
template<class K, class MTag>
class Ag2_uncertain_is_hidden_C2
{
public:
typedef K Kernel;
typedef MTag Method_tag;
typedef typename K::Site_2 Site_2;
typedef typename K::RT RT;
private:
Uncertain<bool> is_hidden(const Site_2& p, const Site_2& q,
const Integral_domain_without_division_tag&) const
{
RT w1 = p.weight();
RT w2 = q.weight();
Uncertain<Sign> s = CGAL::sign( CGAL::square(p.x() - q.x())
+ CGAL::square(p.y() - q.y())
- CGAL::square(w1 - w2)
);
if ( is_indeterminate(s) ) {
return Uncertain<bool>::indeterminate();
}
if ( s == POSITIVE ) { return false; }
Uncertain<Comparison_result> cr = CGAL::compare(w1, w2);
if ( is_indeterminate(cr) ) {
return Uncertain<bool>::indeterminate();
}
return (cr != SMALLER);
}
Uncertain<bool> is_hidden(const Site_2& p, const Site_2& q,
const Field_with_sqrt_tag&) const
{
RT d = CGAL::sqrt(CGAL::square(p.x() - q.x())
+ CGAL::square(p.y() - q.y()));
Uncertain<Sign> s = CGAL::sign(d - p.weight() + q.weight());
if ( is_indeterminate(s) ) {
return Uncertain<bool>::indeterminate();
}
return ( s != POSITIVE );
}
public:
typedef Uncertain<bool> result_type;
typedef Site_2 argument_type;
inline bool operator()(const Site_2 &p, const Site_2 &q) const {
#ifdef AG2_PROFILE_PREDICATES
ag2_predicate_profiler::is_trivial_counter++;
#endif
return is_hidden(p, q, Method_tag());
}
};
//--------------------------------------------------------------------
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_UNCERTAIN_IS_HIDDEN_C2_H

View File

@ -0,0 +1,121 @@
// Copyright (c) 2003,2004 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
#ifndef CGAL_APOLLONIUS_GRAPH_2_UNCERTAIN_ORIENTED_SIDE_OF_BISECTOR_C2_H
#define CGAL_APOLLONIUS_GRAPH_2_UNCERTAIN_ORIENTED_SIDE_OF_BISECTOR_C2_H
#include <CGAL/license/Apollonius_graph_2.h>
#include <CGAL/enum.h>
#include <CGAL/Uncertain.h>
#include <CGAL/number_type_basic.h>
#include <CGAL/Apollonius_graph_2/uncertain/uncertain_functions_on_signs.h>
namespace CGAL {
//--------------------------------------------------------------------
template<class K, class MTag>
class Ag2_uncertain_oriented_side_of_bisector_C2
{
public:
typedef K Kernel;
typedef MTag Method_tag;
typedef typename K::Point_2 Point_2;
typedef typename K::Site_2 Site_2;
private:
typedef typename Kernel::RT RT;
private:
Uncertain<Comparison_result>
compare_distances(const Site_2& p1, const Site_2& p2,
const Point_2& p, const Integral_domain_without_division_tag&) const
{
#ifdef AG2_PROFILE_PREDICATES
ag2_predicate_profiler::side_of_bisector_counter++;
#endif
// this function compares the distances of the point(x, y) from the
// disks {(x1, y1), w1} and {(x2, y2), w2}
RT D1 = CGAL::square(p1.x() - p.x()) + CGAL::square(p1.y() - p.y());
RT D2 = CGAL::square(p2.x() - p.x()) + CGAL::square(p2.y() - p.y());
RT Dw = p2.weight() - p1.weight();
Uncertain<Sign> sign_of_Dw = CGAL::sign(Dw);
if ( is_indeterminate(sign_of_Dw) ) {
return Uncertain<Comparison_result>::indeterminate();
}
Uncertain<Comparison_result> R = CGAL::compare(D1, D2);
if ( is_indeterminate(R) ) {
return Uncertain<Comparison_result>::indeterminate();
}
if ( sign_of_Dw == ZERO ) {
return R;
}
if ( sign_of_Dw == POSITIVE ) {
if ( R != SMALLER ) return LARGER;
return uncertain_sign_a_plus_b_x_sqrt_c(D1 - D2 + CGAL::square(Dw),
RT(2) * Dw, D1);
}
if ( R != LARGER ) return SMALLER;
return uncertain_sign_a_plus_b_x_sqrt_c(D1 - D2 - CGAL::square(Dw),
RT(2) * Dw, D2);
}
Comparison_result
compare_distances(const Site_2& p1, const Site_2& p2,
const Point_2 &p, const Field_with_sqrt_tag&) const
{
#ifdef AG2_PROFILE_PREDICATES
ag2_predicate_profiler::side_of_bisector_counter++;
#endif
// this function compares the distances of the point(x, y) from the
// disks {(x1, y1), w1} and {(x2, y2), w2}
RT D1 = CGAL::square(p1.x() - p.x()) + CGAL::square(p1.y() - p.y());
RT D2 = CGAL::square(p2.x() - p.x()) + CGAL::square(p2.y() - p.y());
RT d1 = CGAL::sqrt(D1) - p1.weight();
RT d2 = CGAL::sqrt(D2) - p2.weight();
return CGAL::compare(d1, d2);
}
public:
typedef Uncertain<Oriented_side> result_type;
struct argument_type {};
inline
Uncertain<Oriented_side>
operator()(const Site_2& p1, const Site_2& p2,
const Point_2 &p) const
{
return - compare_distances(p1, p2, p, Method_tag());
}
};
//--------------------------------------------------------------------
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_UNCERTAIN_ORIENTED_SIDE_OF_BISECTOR_C2_H

View File

@ -0,0 +1,403 @@
// Copyright (c) 2006 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
// Christophe Delage <Christophe.Delage@sophia.inria.fr>
// David Millman <dlm336@cs.nyu.edu>
#ifndef CGAL_APOLLONIUS_GRAPH_2_UNCERTAIN_VERTEX_CONFLICT_2_H
#define CGAL_APOLLONIUS_GRAPH_2_UNCERTAIN_VERTEX_CONFLICT_2_H
#include <CGAL/license/Apollonius_graph_2.h>
// FIXME: We include the old traits class file for now to get the functors.
#include <CGAL/Uncertain.h>
#include <CGAL/Apollonius_graph_traits_2.h>
namespace CGAL {
//-----------------------------------------------------------------------
// Vertex conflict
//-----------------------------------------------------------------------
template < class K, class Method_tag >
class Uncertain_vertex_conflict_new_2
{
public:
typedef typename K::Site_2 Site_2;
typedef typename K::RT RT;
typedef Uncertain<Sign> result_type;
private:
inline
Uncertain<bool> is_less (const Site_2 &p0, const Site_2 &p1) const
{
static const Uncertain<bool> uncertain_bool =
Uncertain<bool>::indeterminate();
Uncertain<Comparison_result> cr;
cr = CGAL::compare( p0.weight(), p1.weight() );
if ( is_indeterminate(cr) ) { return uncertain_bool; }
if ( cr == SMALLER ) { return true; }
if ( cr == LARGER ) { return false; }
cr = CGAL::compare(p0.x(), p1.x());
if ( is_indeterminate(cr) ) { return uncertain_bool; }
if ( cr == SMALLER ) { return true; }
if ( cr == LARGER ) { return false; }
cr = CGAL::compare(p0.y(), p1.y());
if ( is_indeterminate(cr) ) { return uncertain_bool; }
return cr == SMALLER;
}
inline
int max_radius(const Site_2 &p0, const Site_2 &p1,
const Site_2 &p2, const Site_2 &p3) const
{
int i = 0;
const Site_2 *p = &p0;
Uncertain<bool> b;
b = is_less (*p, p1);
if ( is_indeterminate(b) ) {
return -1;
} else if (b) {
i = 1; p = &p1;
}
b = is_less(*p, p2);
if ( is_indeterminate(b) ) {
return -1;
} else if (b) {
i = 2; p = &p2;
}
b = is_less(*p, p3);
if ( is_indeterminate(b) ) {
return -1;
} else if (b) {
i = 3;
}
return i;
}
inline
Uncertain<Sign>
predicate(const Site_2 &p1, const Site_2 &p2,
const Site_2 &p3, const Site_2 &q, bool perturb) const
{
RT xq = q.x() - p1.x();
RT yq = q.y() - p1.y();
RT wq = q.weight() - p1.weight();
RT aq = CGAL::square(xq) + CGAL::square(yq) - CGAL::square(wq);
// q is hiding p1
Uncertain<Sign> s = CGAL::sign(aq);
if ( is_indeterminate(s) ) { return s; }
if (s != POSITIVE){
// I BELIEVE MENELAOS RETURNS -1 in this case even when degernate
//if (sign (aq) == ZERO && ! perturb) return ZERO;
// return NEGATIVE;
return POSITIVE;
}
RT x2 = p2.x() - p1.x();
RT y2 = p2.y() - p1.y();
RT w2 = p2.weight() - p1.weight();
RT a2 = x2 * x2 + y2 * y2 - w2 * w2;
CGAL_assertion (a2 > 0);
RT x3 = p3.x() - p1.x();
RT y3 = p3.y() - p1.y();
RT w3 = p3.weight() - p1.weight();
RT a3 = x3 * x3 + y3 * y3 - w3 * w3;
CGAL_assertion (a3 > 0);
RT ax3q = a3 * xq - x3 * aq;
RT ax2q = a2 * xq - x2 * aq;
RT ax23 = a2 * x3 - x2 * a3;
RT ay23 = a2 * y3 - y2 * a3;
RT ay2q = a2 * yq - y2 * aq;
RT ay3q = a3 * yq - y3 * aq;
RT axw23q = ax23 * wq - ax2q * w3 + ax3q * w2;
RT ayw23q = ay23 * wq - ay2q * w3 + ay3q * w2;
RT axy23q = y2 * ax3q - y3 * ax2q + yq * ax23;
// orientation
Uncertain<Sign> orient = CGAL::sign(axy23q);
if ( is_indeterminate(orient) ) { return orient; }
// orientation degenerate
if (orient == ZERO) {
Uncertain<Sign> orient1 = CGAL::sign (ax23);
if ( is_indeterminate(orient1) ) { return orient1; }
Sign power_test;
if ( orient1 == ZERO ) {
Uncertain<Sign> s_ay23 = CGAL::sign(ay23);
if ( is_indeterminate(s_ay23) ) { return s_ay23; }
Uncertain<Sign> s_ayw23q = CGAL::sign(ayw23q);
if ( is_indeterminate(s_ayw23q) ) { return s_ayw23q; }
power_test = s_ay23 * s_ayw23q;
} else {
Uncertain<Sign> s_axw23q = CGAL::sign(axw23q);
if ( is_indeterminate(s_axw23q) ) { return s_axw23q; }
power_test = orient1 * s_axw23q;
}
if (power_test != ZERO || ! perturb) {
return -power_test;
}
int i = max_radius (p1, p2, p3, q);
if ( i == -1 ) {
return Uncertain<Sign>::indeterminate();
}
if (i == 3) { return NEGATIVE; }
Uncertain<Sign> o23, o2q, o3q;
if (orient1 == ZERO) {
o23 = CGAL::sign (ay23);
o2q = CGAL::sign (ay2q);
o3q = CGAL::sign (ay3q);
} else {
o23 = CGAL::sign (ax23);
o2q = CGAL::sign (ax2q);
o3q = CGAL::sign (ax3q);
}
if ( is_indeterminate(o23) ||
is_indeterminate(o2q) ||
is_indeterminate(o3q) ) {
return Uncertain<Sign>::indeterminate();
}
if (o23 != o2q) { return i == 2 ? NEGATIVE : POSITIVE; }
if (o23 == o3q) { return i == 1 ? NEGATIVE : POSITIVE; }
return i == 0 ? NEGATIVE : POSITIVE;
} // if (orient == ZERO )
// radical side
RT rs23q = ax23 * axw23q + ay23 * ayw23q;
Uncertain<Sign> radSide = CGAL::sign (rs23q);
if ( is_indeterminate(radSide) ) { return radSide; }
if (radSide == ZERO || radSide != orient) { return orient; }
// radical intersection
Uncertain<Sign> radInt =
CGAL::sign(axw23q * axw23q + ayw23q * ayw23q - axy23q * axy23q);
if ( is_indeterminate(radInt) ) { return radInt; }
// radical intersection degenerate
if (radInt == ZERO) {
Uncertain<Sign> radSideQ = CGAL::sign(ax23 * axw23q + ay23 * ayw23q);
if ( is_indeterminate(radSideQ) ) { return radSideQ; }
CGAL_assertion (radSideQ != ZERO);
if (! perturb) { return (radSideQ == orient) ? Uncertain<Sign>(ZERO) : orient; }
int i = max_radius (p1, p2, p3, q);
if ( i == -1 ) { return Uncertain<Sign>::indeterminate(); }
if (i == 3) {
radInt = radSideQ;
} else if (i == 2) {
radInt = -CGAL::sign(ax2q * axw23q + ay2q * ayw23q);
if ( is_indeterminate(radInt) ) { return radInt; }
if (radInt == ZERO) { return NEGATIVE; }
} else if (i == 1) {
radInt = CGAL::sign(ax3q * axw23q + ay3q * ayw23q);
if ( is_indeterminate(radInt) ) { return radInt; }
if (radInt == ZERO) { return NEGATIVE; }
} else {
CGAL_assertion (i == 0);
Uncertain<Sign> radSide1 =
-CGAL::sign(ax2q * axw23q + ay2q * ayw23q);
if ( is_indeterminate(radSide1) ) { return radSide1; }
if (radSide1 == ZERO) { return NEGATIVE; }
Uncertain<Sign> radSide2 = CGAL::sign(ax3q * axw23q + ay3q * ayw23q);
if ( is_indeterminate(radSide2) ) { return radSide2; }
if (radSide2 == ZERO) { return NEGATIVE; }
radInt = -Sign( Sign(radSideQ) + Sign(radSide1) + Sign(radSide2) );
}
}
CGAL_assertion (!perturb || radInt != ZERO);
if (radInt == NEGATIVE) { return orient; }
return -radSide;
}
inline
Uncertain<Sign>
predicate(const Site_2 &p1, const Site_2 &p2,
const Site_2 &q, bool perturb) const
{
// NOTE:***************************************
// * the perturb boolean variable is not used
// * for consistancy with Menelaos
// NOTE:***************************************
RT x2 = p2.x() - p1.x();
RT y2 = p2.y() - p1.y();
RT w2 = p2.weight() - p1.weight();
RT xq = q.x() - p1.x();
RT yq = q.y() - p1.y();
RT wq = q.weight() - p1.weight();
RT xw2q = x2 * wq - xq * w2;
RT yw2q = y2 * wq - yq * w2;
RT xy2q = x2 * yq - xq * y2;
// orientation
Uncertain<Sign> orient = CGAL::sign(xy2q);
if ( is_indeterminate(orient) ) { return orient; }
// orientation degenerate
if (orient == ZERO) {
Uncertain<Sign> o12 = CGAL::sign(x2);
if ( is_indeterminate(o12) ) { return o12; }
Uncertain<Sign> o1q, o2q;
Uncertain<Sign> power_test;
if (o12 != ZERO) {
Uncertain<Sign> s_xw2q = CGAL::sign(xw2q);
if ( is_indeterminate(s_xw2q) ) { return s_xw2q; }
power_test = o12 * s_xw2q;
// this results is consistant with Menelaos
if (power_test != ZERO) { return -power_test; }
// this result is consistant with the perturb on off idea
//if (power_test != ZERO || ! perturb) return -power_test;
o1q = CGAL::sign(xq);
o2q = CGAL::sign(q.x() - p2.x());
} else {
o12 = CGAL::sign(y2);
if ( is_indeterminate(o12) ) { return o12; }
Uncertain<Sign> s_yw2q = CGAL::sign(yw2q);
if ( is_indeterminate(s_yw2q) ) { return s_yw2q; }
power_test = o12 * s_yw2q;
// this results is consistant with Menelaos
if (power_test != ZERO) { return -power_test; }
// this result is consistant with the perturb on off idea
//if (power_test != ZERO || ! perturb) return -power_test;
o1q = CGAL::sign(yq);
o2q = CGAL::sign(q.y() - p2.y());
}
if ( is_indeterminate(o1q) || is_indeterminate(o2q) ) {
return Uncertain<Sign>::indeterminate();
}
if (o1q != o12) { return POSITIVE; }
if (o2q == o12) { return POSITIVE; }
return NEGATIVE;
}
// radical side
RT rs12q = x2 * xw2q + y2 * yw2q;
Uncertain<Sign> radSide = CGAL::sign(rs12q);
if ( is_indeterminate(radSide) ) { return radSide; }
if (radSide == ZERO || radSide == orient) {
return -orient;
}
// radical intersection
Uncertain<Sign> radInt =
CGAL::sign(CGAL::square(xw2q) + CGAL::square(yw2q)
- CGAL::square(xy2q));
if ( is_indeterminate(radInt) ) { return radInt; }
// radical intersection degerate
if (radInt == ZERO) {
CGAL_assertion (radSide != ZERO);
// this result is consistant with the perturb on off idea
//if (! perturb) return (radSide == orient) ? ZERO : orient;
RT rs2q1 = (p2.x() - q.x()) * xw2q + (p2.y() - q.y()) * yw2q;
Uncertain<Sign> radSide1 = CGAL::sign(rs2q1);
if ( is_indeterminate(radSide1) ) { return radSide1; }
if (radSide1 == ZERO) { return NEGATIVE; }
RT rsq12 = xq * xw2q + yq * yw2q;
Uncertain<Sign> radSide2 = CGAL::sign(rsq12);
if ( is_indeterminate(radSide2) ) { return radSide2; }
if (radSide2 == ZERO) { return NEGATIVE; }
return -(radSide1 * radSide2);
}
CGAL_assertion (!perturb || radInt != ZERO);
if (radInt == POSITIVE) { return orient; }
return radSide;
}
public:
inline
Uncertain<Sign> operator()(const Site_2 &p1, const Site_2 &p2,
const Site_2 &p3, const Site_2 &q,
bool perturb = true) const
{
Uncertain<Sign> newPred = predicate (p1, p2, p3, q, perturb);
if ( is_indeterminate(newPred) ) { return newPred; }
CGAL_assertion (! perturb || newPred != ZERO);
return newPred;
}
inline
Uncertain<Sign> operator()(const Site_2 &p1, const Site_2 &p2,
const Site_2 &q, bool perturb = true) const
{
Uncertain<Sign> newPred = predicate (p1, p2, q, perturb);
if ( is_indeterminate(newPred) ) { return newPred; }
CGAL_assertion (! perturb || newPred != ZERO);
return newPred;
}
};
} //namespace CGAL
#endif // CGAL_APOLLONIUS_GRAPH_2_UNCERTAIN_VERTEX_CONFLICT_2_H

Some files were not shown because too many files have changed in this diff Show More