Power_center.

This commit is contained in:
Marc Glisse 2014-10-21 17:20:20 +02:00
parent b1f795a6da
commit 8c5e28cd3d
4 changed files with 105 additions and 1 deletions

View File

@ -57,7 +57,6 @@ template <class R_> struct Construct_sphere : Store_kernel<R_> {
typedef typename LA::Square_matrix Matrix;
typedef typename LA::Vector Vec;
typedef typename LA::Construct_vector CVec;
typedef typename Get_type<R_, Point_tag>::type Point;
typename Get_functor<R_, Compute_point_cartesian_coordinate_tag>::type c(this->kernel());
typename Get_functor<R_, Construct_ttag<Point_tag> >::type cp(this->kernel());
typename Get_functor<R_, Point_dimension_tag>::type pd(this->kernel());

View File

@ -75,6 +75,33 @@ template <class R_> struct Point_weight {
}
};
template <class R_> struct Power_distance : private Store_kernel<R_> {
CGAL_FUNCTOR_INIT_STORE(Power_distance)
typedef typename Get_type<R_, Weighted_point_tag>::type first_argument_type;
typedef first_argument_type second_argument_type;
typedef typename Get_type<R_, FT_tag>::type result_type;
result_type operator()(first_argument_type const&a, second_argument_type const&b)const{
typename Get_functor<R_, Point_drop_weight_tag>::type pdw(this->kernel());
typename Get_functor<R_, Point_weight_tag>::type pw(this->kernel());
typename Get_functor<R_, Squared_distance_tag>::type sd(this->kernel());
return sd(pdw(a),pdw(b))-pw(a)-pw(b);
}
};
template <class R_> struct Power_distance_to_point : private Store_kernel<R_> {
CGAL_FUNCTOR_INIT_STORE(Power_distance_to_point)
typedef typename Get_type<R_, Weighted_point_tag>::type first_argument_type;
typedef typename Get_type<R_, Point_tag>::type second_argument_type;
typedef typename Get_type<R_, FT_tag>::type result_type;
result_type operator()(first_argument_type const&a, second_argument_type const&b)const{
typename Get_functor<R_, Point_drop_weight_tag>::type pdw(this->kernel());
typename Get_functor<R_, Point_weight_tag>::type pw(this->kernel());
typename Get_functor<R_, Squared_distance_tag>::type sd(this->kernel());
return sd(pdw(a),b)-pw(a);
}
};
template<class R_> struct Power_test : private Store_kernel<R_> {
CGAL_FUNCTOR_INIT_STORE(Power_test)
typedef R_ R;
@ -114,6 +141,56 @@ template<class R_> struct In_flat_power_test : private Store_kernel<R_> {
}
};
// Construct a point at (weighted) distance 0 from all the input
template <class R_> struct Power_center : Store_kernel<R_> {
CGAL_FUNCTOR_INIT_STORE(Power_center)
typedef typename Get_type<R_, Weighted_point_tag>::type WPoint;
typedef WPoint result_type;
typedef typename Get_type<R_, Point_tag>::type Point;
typedef typename Get_type<R_, FT_tag>::type FT;
template <class Iter>
result_type operator()(Iter f, Iter e)const{
// 2*(x-y).c == (x^2-wx^2)-(y^2-wy^2)
typedef typename R_::LA LA;
typedef typename LA::Square_matrix Matrix;
typedef typename LA::Vector Vec;
typedef typename LA::Construct_vector CVec;
typename Get_functor<R_, Compute_point_cartesian_coordinate_tag>::type c(this->kernel());
typename Get_functor<R_, Construct_ttag<Point_tag> >::type cp(this->kernel());
typename Get_functor<R_, Point_dimension_tag>::type pd(this->kernel());
typename Get_functor<R_, Squared_distance_to_origin_tag>::type sdo(this->kernel());
typename Get_functor<R_, Power_distance_to_point_tag>::type pdp(this->kernel());
typename Get_functor<R_, Point_drop_weight_tag>::type pdw(this->kernel());
typename Get_functor<R_, Point_weight_tag>::type pw(this->kernel());
typename Get_functor<R_, Construct_ttag<Weighted_point_tag> >::type cwp(this->kernel());
WPoint const& wp0 = *f;
Point const& p0 = pdw(wp0);
int d = pd(p0);
FT const& n0 = sdo(p0) - pw(wp0);
Matrix m(d,d);
Vec b = typename CVec::Dimension()(d);
// Write the point coordinates in lines.
int i;
for(i=0; ++f!=e; ++i) {
WPoint const& wp=*f;
Point const& p=pdw(wp);
FT const& np = sdo(p) - pw(wp);
for(int j=0;j<d;++j) {
m(i,j)=2*(c(p,j)-c(p0,j));
b[i] = np - n0;
}
}
CGAL_assertion (i == d);
Vec res = typename CVec::Dimension()(d);;
//std::cout << "Mat: " << m << "\n Vec: " << one << std::endl;
LA::solve(res, CGAL_MOVE(m), CGAL_MOVE(b));
//std::cout << "Sol: " << res << std::endl;
Point center = cp(d,LA::vector_begin(res),LA::vector_end(res));
FT const& r2 = pdp (wp0, center);
return cwp(CGAL_MOVE(center), r2);
}
};
}
CGAL_KD_DEFAULT_TYPE(Weighted_point_tag,(CGAL::KerD::Weighted_point<K>),(Point_tag),());
CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag<Weighted_point_tag>,(CartesianDKernelFunctors::Construct_weighted_point<K>),(Weighted_point_tag,Point_tag),());
@ -121,5 +198,8 @@ CGAL_KD_DEFAULT_FUNCTOR(Point_drop_weight_tag,(CartesianDKernelFunctors::Point_d
CGAL_KD_DEFAULT_FUNCTOR(Point_weight_tag,(CartesianDKernelFunctors::Point_weight<K>),(Weighted_point_tag,Point_tag),());
CGAL_KD_DEFAULT_FUNCTOR(Power_test_tag,(CartesianDKernelFunctors::Power_test<K>),(Weighted_point_tag),(Power_test_raw_tag,Point_drop_weight_tag,Point_weight_tag));
CGAL_KD_DEFAULT_FUNCTOR(In_flat_power_test_tag,(CartesianDKernelFunctors::In_flat_power_test<K>),(Weighted_point_tag),(In_flat_power_test_raw_tag,Point_drop_weight_tag,Point_weight_tag));
CGAL_KD_DEFAULT_FUNCTOR(Power_distance_tag,(CartesianDKernelFunctors::Power_distance<K>),(Weighted_point_tag,Point_tag),(Squared_distance_tag,Point_drop_weight_tag,Point_weight_tag));
CGAL_KD_DEFAULT_FUNCTOR(Power_distance_to_point_tag,(CartesianDKernelFunctors::Power_distance_to_point<K>),(Weighted_point_tag,Point_tag),(Squared_distance_tag,Point_drop_weight_tag,Point_weight_tag));
CGAL_KD_DEFAULT_FUNCTOR(Power_center_tag,(CartesianDKernelFunctors::Power_center<K>),(Weighted_point_tag,Point_tag),(Compute_point_cartesian_coordinate_tag,Construct_ttag<Point_tag>,Construct_ttag<Weighted_point_tag>,Point_dimension_tag,Squared_distance_to_origin_tag,Point_drop_weight_tag,Point_weight_tag,Power_distance_to_point_tag));
} // namespace CGAL
#endif

View File

@ -218,6 +218,8 @@ namespace CGAL {
CGAL_DECL_COMPUTE(Hyperplane_translation);
CGAL_DECL_COMPUTE(Value_at);
CGAL_DECL_COMPUTE(Point_weight);
CGAL_DECL_COMPUTE(Power_distance);
CGAL_DECL_COMPUTE(Power_distance_to_point);
#undef CGAL_DECL_COMPUTE
#define CGAL_DECL_ITER_OBJ(X,Y,Z,C) struct X##_tag {}; \
@ -268,6 +270,7 @@ namespace CGAL {
CGAL_DECL_CONSTRUCT(Point_to_vector,Vector);
CGAL_DECL_CONSTRUCT(Vector_to_point,Point);
CGAL_DECL_CONSTRUCT(Point_drop_weight,Point);
CGAL_DECL_CONSTRUCT(Power_center,Weighted_point);
#undef CGAL_DECL_CONSTRUCT
#if 0
#define CGAL_DECL_ITER_CONSTRUCT(X,Y) struct X##_tag {}; \

View File

@ -74,6 +74,7 @@ void test2(){
typedef typename K1::Ray_d R;
typedef typename K1::Iso_box_d IB;
typedef typename K1::Flat_orientation_d FO;
typedef typename K1::Weighted_point_d WP;
//typedef K1::Construct_point CP;
typedef typename K1::Construct_point_d CP;
@ -122,6 +123,12 @@ void test2(){
typedef typename K1::Difference_of_vectors_d DV;
typedef typename K1::Difference_of_points_d DP;
typedef typename K1::Translated_point_d TP;
typedef typename CGAL::Get_functor<K1, CGAL::Power_center_tag>::type PC;
typedef typename CGAL::Get_functor<K1, CGAL::Power_distance_tag>::type PoD;
typedef typename K1::Weighted_point_d WP;
typedef typename K1::Construct_weighted_point_d CWP;
typedef typename K1::Point_drop_weight_d PDW;
typedef typename K1::Point_weight_d PW;
CGAL_USE_TYPE(AT);
CGAL_USE_TYPE(D);
@ -180,6 +187,11 @@ void test2(){
DV dv Kinit(difference_of_vectors_d_object);
DP dp Kinit(difference_of_points_d_object);
TP tp Kinit(translated_point_d_object);
PC pc (k);
CWP cwp Kinit(construct_weighted_point_d_object);
PDW pdw Kinit(point_drop_weight_d_object);
PW pw Kinit(point_weight_d_object);
PoD pod (k);
CGAL_USE(bc);
CGAL_USE(pol);
@ -335,6 +347,16 @@ void test2(){
#endif
P x2py1 = tp(x2,y1);
assert(x2py1[1]==-2);
WP tw[]={cwp(cp(5,0),1.5),cwp(cp(2,std::sqrt(3)),1),cwp(cp(2,-std::sqrt(3)),1)};
WP xw=pc(tw+0,tw+3);
assert(abs(pod(xw,tw[0]))<.0001);
assert(abs(pod(xw,tw[1]))<.0001);
assert(abs(pod(xw,tw[2]))<.0001);
assert(pdw(xw)[0]<2.95);
assert(pdw(xw)[0]>2.5);
assert(pw(xw)<2.95);
assert(pw(xw)>2.5);
Sp un1; CGAL_USE(un1);
H un2; CGAL_USE(un2);
S un3; CGAL_USE(un3);