00001
00002
00020 #ifndef REVIVER_POINT_HPP
00021 #define REVIVER_POINT_HPP
00022
00023
00024 #include "assert.hpp"
00025 #include <iostream>
00026 #include <valarray>
00027 #include <stdio.h>
00028 #include <limits>
00029
00030
00031
00033 namespace reviver {
00034
00035
00036
00037
00038
00039
00040 template<typename NumType, unsigned D>
00041 class dpoint;
00042
00043
00045
00047
00048 template<typename T>
00049 class InternalNumberType;
00050
00051 template<>
00052 class InternalNumberType<float>{
00053 public:
00054 typedef double __INT;
00055 };
00056
00057
00058 template<>
00059 class InternalNumberType<int>{
00060 public:
00061 typedef long long __INT;
00062 };
00063
00064
00065 template<>
00066 class InternalNumberType<double>{
00067 public:
00068 typedef double __INT;
00069 };
00070
00071 template<>
00072 class InternalNumberType<long>{
00073 public:
00074 typedef long long __INT;
00075 };
00076
00077
00078
00079
00081
00083 template< typename NumType, unsigned D, unsigned I > struct origin
00084 {
00085 static inline void eval( dpoint<NumType,D>& p )
00086 {
00087 p[I] = 0.0;
00088 origin< NumType, D, I-1 >::eval( p );
00089 }
00090 };
00091
00092
00093
00094 template <typename NumType, unsigned D> struct origin<NumType, D, 0>
00095 {
00096 static inline void eval( dpoint<NumType,D>& p )
00097 {
00098 p[0] = 0.0;
00099 }
00100 };
00101
00102
00104
00107
00108
00110 template< typename NumType, unsigned D, unsigned I > struct Distance
00111 {
00112 static inline double eval( const dpoint<NumType,D>& p, const dpoint<NumType,D>& q )
00113 {
00114 double sum = ((double)p[I] - (double)q[I] ) *( (double)p[I] - (double)q[I] );
00115 return sum + Distance< NumType, D, I-1 >::eval( p,q );
00116 }
00117 };
00118
00119
00121 template <typename NumType, unsigned D> struct Distance<NumType, D, 0>
00122 {
00123 static inline double eval( const dpoint<NumType,D>& p, const dpoint<NumType,D>& q )
00124 {
00125 return ((double) p[0] - (double)q[0] )*( (double)p[0] - (double)q[0] );
00126 }
00127 };
00128
00129
00131
00134
00135
00137 template< typename __INT, typename NumType, unsigned D, unsigned I > struct DotProd
00138 {
00139 static inline __INT eval( const dpoint<NumType,D>& p, const dpoint<NumType,D>& q )
00140 {
00141 __INT sum = ( ((__INT)p[I]) * ((__INT)q[I]) );
00142 return sum + DotProd< __INT, NumType, D, I-1 >::eval( p,q );
00143 }
00144 };
00145
00146
00148 template < typename __INT, typename NumType, unsigned D> struct DotProd<__INT,NumType, D, 0>
00149 {
00150 static inline __INT eval( const dpoint<NumType,D>& p, const dpoint<NumType,D>& q )
00151 {
00152 return ( ((__INT)p[0]) * ((__INT)q[0]) );
00153 }
00154 };
00155
00156
00158
00160 template< typename NumType, unsigned D, unsigned I > struct IsEqual
00161 {
00162 static inline bool eval( const dpoint<NumType,D>& p, const dpoint<NumType,D>& q )
00163 {
00164 if( p[I] != q[I] ) return false;
00165 else return IsEqual< NumType, D, I-1 >::eval( p,q );
00166 }
00167 };
00168
00169
00170
00171 template <typename NumType, unsigned D> struct IsEqual<NumType, D, 0>
00172 {
00173 static inline NumType eval( const dpoint<NumType,D>& p, const dpoint<NumType,D>& q )
00174 {
00175 return (p[0] == q[0])?1:0;
00176 }
00177 };
00178
00179
00180
00182
00188 template<
00189 typename NumType1,
00190 typename NumType2,
00191 unsigned D,
00192 unsigned I
00193 > struct Equate
00194 {
00195 static inline void eval( dpoint<NumType1,D>& p,const dpoint<NumType2,D>& q )
00196 {
00197 p[I] = q[I];
00198 Equate< NumType1, NumType2, D, I-1 >::eval( p,q );
00199 }
00200 };
00201
00202
00204 template <
00205 typename NumType1,
00206 typename NumType2,
00207 unsigned D
00208 > struct Equate<NumType1,NumType2, D, 0>
00209 {
00210 static inline void eval( dpoint<NumType1,D>& p,const dpoint<NumType2,D>& q )
00211 {
00212 p[0] = q[0];
00213 }
00214 };
00215
00216
00218
00221
00222
00224 template< typename NumType, unsigned D, unsigned I > struct Add
00225 {
00226 static inline void eval( dpoint<NumType,D>& result, const dpoint<NumType,D>& p, const dpoint<NumType,D>& q )
00227 {
00228 result[I] = p[I] + q[I];
00229 Add< NumType, D, I-1 >::eval( result,p,q );
00230 }
00231 };
00232
00233
00235 template <typename NumType, unsigned D> struct Add<NumType, D, 0>
00236 {
00237 static inline void eval( dpoint<NumType,D>& result, const dpoint<NumType,D>& p, const dpoint<NumType,D>& q )
00238 {
00239 result[0] = p[0] + q[0];
00240 }
00241 };
00242
00243
00245
00247
00248
00249
00250
00251
00252 template< typename NumType >
00253 inline NumType Subtract_nums(const NumType& x, const NumType& y) {
00254 if(!std::numeric_limits<NumType>::is_signed) {std::cerr << "Exception: Can't subtract unsigned types."; exit(1);}
00255 return x - y;
00256 }
00257
00258
00260
00263 template< typename NumType, unsigned D, unsigned I > struct Subtract
00264 {
00265 static inline void eval( dpoint<NumType,D>& result, const dpoint<NumType,D>& p, const dpoint<NumType,D>& q )
00266 {
00267
00268 result[I] = Subtract_nums(p[I] , q[I]);
00269 Subtract< NumType, D, I-1 >::eval( result,p,q );
00270 }
00271 };
00272
00273
00275 template <typename NumType, unsigned D> struct Subtract<NumType, D, 0>
00276 {
00277 static inline void eval( dpoint<NumType,D>& result, const dpoint<NumType,D>& p, const dpoint<NumType,D>& q )
00278 {
00279 result[0] = Subtract_nums(p[0] , q[0]);
00280 }
00281 };
00282
00283
00284
00285
00286
00288
00292 template< typename NumType, unsigned D, unsigned I > struct Multiply
00293 {
00294 static inline void eval( dpoint<NumType,D>& result, const dpoint<NumType,D>& p, NumType k)
00295 {
00296 result[I] = p[I] * k;
00297 Multiply< NumType, D, I-1 >::eval( result,p,k );
00298 }
00299 };
00300
00301
00303 template <typename NumType, unsigned D> struct Multiply<NumType, D, 0>
00304 {
00305 static inline void eval( dpoint<NumType,D>& result, const dpoint<NumType,D>& p, NumType k )
00306 {
00307 result[0] = p[0] * k;
00308 }
00309 };
00310
00311
00312
00314
00318 template<typename NumType = double, unsigned D = 3>
00319 class dpoint {
00320
00321
00322 NumType x[D];
00323
00324 public:
00325
00326
00327 typedef NumType NT;
00328 typedef typename InternalNumberType<NumType>::__INT __INT;
00329
00330
00331
00332
00333
00334 inline void move2origin(){ origin<NumType, D, D-1>::eval(*this); };
00335
00336 dpoint(){
00337 Assert( (D >= 1), "Dimension < 1 not allowed" );
00338
00339 };
00340
00342 dpoint(NumType x0){ x[0] = x0; };
00344 dpoint(NumType x0,NumType x1){ x[0] = x0; x[1] = x1; };
00346 dpoint(NumType x0,NumType x1,NumType x2){ x[0] = x0; x[1] = x1; x[2] = x2; };
00348 dpoint(NumType ax[]){ for(int i =0; i < D; ++i) x[i] = ax[i]; };
00350 dpoint(const dpoint<NumType,D>& p){ Equate<NumType,NumType,D,D-1>::eval((*this),p); };
00351
00352
00355 template<class OtherNumType>
00356 explicit dpoint(const dpoint<OtherNumType,D>& p){ Equate<NumType,OtherNumType,D,D-1>::eval((*this),p); };
00357
00358
00359 ~dpoint(){};
00360
00361 inline int dim() const { return D; };
00362 inline double sqr_dist(const dpoint<NumType,D> q) const ;
00363 inline double distance(const dpoint<NumType,D> q) const ;
00364 inline __INT dotprod (const dpoint<NumType,D> q) const ;
00365 inline __INT sqr_length(void) const;
00366 inline void normalize (void);
00367 inline NumType& operator[](int i);
00368 inline NumType operator[](int i) const;
00369
00370 inline dpoint& operator= (const dpoint<NumType,D>& q);
00371
00372 template<typename NT, unsigned __DIM>
00373 friend dpoint<NT,__DIM> operator- (const dpoint<NT,__DIM>& p, const dpoint<NT,__DIM>& q);
00374
00375 template<typename NT, unsigned __DIM>
00376 friend dpoint<NT,__DIM> operator+ (const dpoint<NT,__DIM>& p, const dpoint<NT,__DIM>& q);
00377
00378 template<typename NT, unsigned __DIM>
00379 friend bool operator== (const dpoint<NT,__DIM>& p, const dpoint<NT,__DIM>& q);
00380
00381 template<typename NT, unsigned __DIM>
00382 friend bool operator!= (const dpoint<NT,__DIM>& p, const dpoint<NT,__DIM>& q);
00383
00384
00385
00386
00387
00388 template<typename __NT,unsigned __DIM>
00389 friend void iswap(dpoint<__NT,__DIM>& p,dpoint<__NT,__DIM>& q);
00390 };
00391
00392 template<typename NumType, unsigned D>
00393 void dpoint<NumType,D>::normalize (void){
00394 double len = sqrt(sqr_length());
00395 if (len > 0.00001)
00396 for(int i = 0; i < D; ++i){
00397 x[i] /= len;
00398 }
00399 }
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419 template<typename NT, unsigned __DIM>
00420 dpoint<NT,__DIM>
00421 operator+ (const dpoint<NT,__DIM>& p, const dpoint<NT,__DIM>& q){
00422 dpoint<NT,__DIM> result;
00423 Add<NT,__DIM,__DIM-1>::eval(result,p,q);
00424 return result;
00425 }
00426
00427 template<typename NT, unsigned __DIM>
00428 dpoint<NT,__DIM>
00429 operator- (const dpoint<NT,__DIM>& p, const dpoint<NT,__DIM>& q){
00430 dpoint<NT,__DIM> result;
00431
00432 Subtract<NT,__DIM,__DIM-1>::eval(result,p,q);
00433
00434 return result;
00435 }
00436
00437 template<typename NT, unsigned __DIM>
00438 bool
00439 operator== (const dpoint<NT,__DIM>& p, const dpoint<NT,__DIM>& q){
00440 return IsEqual<NT,__DIM,__DIM-1>::eval(p,q);
00441 }
00442
00443 template<typename NT, unsigned __DIM>
00444 bool
00445 operator!= (const dpoint<NT,__DIM>& p, const dpoint<NT,__DIM>& q){
00446 return !(IsEqual<NT,__DIM,__DIM-1>::eval(p,q));
00447 }
00448
00449 template<typename NT, unsigned __DIM>
00450 dpoint<NT,__DIM>
00451 operator* (const dpoint<NT,__DIM>& p, const NT k){
00452 dpoint<NT,__DIM> result;
00453 Multiply<NT,__DIM,__DIM-1>::eval(result,p,k);
00454 return result;
00455 }
00456
00457 template<typename NT, unsigned __DIM>
00458 dpoint<NT,__DIM>
00459 operator/ (const dpoint<NT,__DIM>& p, const NT k){
00460 Assert( (k != 0), "Hell division by zero man...\n");
00461 dpoint<NT,__DIM> result;
00462 Multiply<NT,__DIM,__DIM-1>::eval(result,p,((double)1.0)/k);
00463 return result;
00464 }
00465
00466 template < typename NumType, unsigned D >
00467 dpoint<NumType,D>&
00468 dpoint<NumType,D>::operator=(const dpoint<NumType,D> &q)
00469 {
00470 Assert((this != &q), "Error p = p");
00471 Equate<NumType,NumType,D,D-1>::eval(*this,q);
00472 return *this;
00473 }
00474
00475 template < typename NumType, unsigned D >
00476 NumType
00477 dpoint<NumType,D>::operator[](int i) const
00478 { return x[i]; }
00479
00480 template < typename NumType, unsigned D >
00481 NumType&
00482 dpoint<NumType,D>::operator[](int i)
00483 {
00484 return x[i]; }
00485
00486
00487 template<typename NumType, unsigned D>
00488 double
00489 dpoint<NumType,D>::sqr_dist (const dpoint<NumType,D> q) const {
00490 return Distance<NumType,D,D-1>::eval(*this,q);
00491 }
00492
00493 template<typename NumType, unsigned D>
00494 double
00495 dpoint<NumType,D>::distance (const dpoint<NumType,D> q) const {
00496 return sqrt(static_cast<double>(Distance<NumType,D,D-1>::eval(*this,q)));
00497 }
00498
00499
00500 template<typename NumType, unsigned D>
00501 typename dpoint<NumType,D>::__INT
00502 dpoint<NumType,D>::dotprod (const dpoint<NumType,D> q) const {
00503 return DotProd<__INT,NumType,D,D-1>::eval(*this,q);
00504 }
00505
00506 template<typename NumType, unsigned D>
00507 typename dpoint<NumType,D>::__INT
00508 dpoint<NumType,D>::sqr_length (void) const {
00509 #ifdef _DEBUG
00510 if( DotProd<__INT,NumType,D,D-1>::eval(*this,*this) < 0) {
00511 std::cerr << "Point that caused error: ";
00512 std::cerr << *this << std::endl;
00513 std::cerr << DotProd<__INT,NumType,D,D-1>::eval(*this,*this) << std::endl;
00514 std::cerr << "Fatal: Hell!\n"; exit(1);
00515 }
00516 #endif
00517 return DotProd<__INT,NumType,D,D-1>::eval(*this,*this);
00518
00519 }
00520
00521 template < class NumType, unsigned D >
00522 std::ostream&
00523 operator<<(std::ostream& os,const dpoint<NumType,D> &p)
00524 {
00525 os << "Point (d=";
00526 os << D << ", (";
00527 for (unsigned int i=0; i<D-1; ++i)
00528 os << p[i] << ", ";
00529 return os << p[D-1] << "))";
00530
00531 };
00532
00533 template < class NumType, unsigned D >
00534 std::istream&
00535 operator>>(std::istream& is,dpoint<NumType,D> &p)
00536 {
00537 for (int i=0; i<D; ++i)
00538 if(!(is >> p[i])){
00539 if(!is.eof()){
00540 std::cerr << "Error Reading Point:"
00541 << is << std::endl;
00542 exit(1);
00543 }
00544 }
00545
00546 return is;
00547
00548 };
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562 template < typename NumType, unsigned D >
00563 dpoint<NumType, D> CrossProd(const dpoint<NumType, D>& vector1,
00564 const dpoint<NumType, D>& vector2) {
00565 Assert(D == 3, "Cross product only defined for 3d vectors");
00566 dpoint<NumType, D> vector;
00567 vector[0] = (vector1[1] * vector2[2]) - (vector2[1] * vector1[2]);
00568 vector[1] = (vector2[0] * vector1[2]) - (vector1[0] * vector2[2]);
00569 vector[2] = (vector1[0] * vector2[1]) - (vector2[0] * vector1[1]);
00570 return vector;
00571 }
00572
00573
00574
00575
00576 template < typename __NT, unsigned __DIM >
00577 int
00578 orientation(const dpoint<__NT,__DIM> p[__DIM+1])
00579 {
00580 int _sign = + 1;
00581
00582 std::cerr << "Not yet implemented\n";
00583 exit(1);
00584 return _sign;
00585
00586 }
00587
00588
00589 template < typename __NT >
00590 inline __NT
00591 orientation(
00592 const dpoint<__NT,2>& p,
00593 const dpoint<__NT,2>& q,
00594 const dpoint<__NT,2>& r
00595 )
00596 {
00597
00598 std::cout << "FATAL";
00599 exit(1);
00600 return ((p[0]-r[0])*(q[1]-r[1]))-((q[0]-r[0])*(p[1]-r[1]));
00601 }
00602
00603
00604 extern "C" double orient2d(double *p, double *q, double *r);
00605
00606 template < >
00607 inline double
00608 orientation<double>(
00609 const dpoint<double,2>& p,
00610 const dpoint<double,2>& q,
00611 const dpoint<double,2>& r
00612 )
00613 {
00614
00615 double pp[2] = { p[0], p[1] };
00616 double qq[2] = { q[0], q[1] };
00617 double rr[2] = { r[0], r[1] };
00618 return orient2d(pp,qq,rr);
00619 }
00620
00621
00622 template < >
00623 inline float
00624 orientation<float>(
00625 const dpoint<float,2>& p,
00626 const dpoint<float,2>& q,
00627 const dpoint<float,2>& r
00628 )
00629 {
00630
00631 double pp[2] = { p[0], p[1] };
00632 double qq[2] = { q[0], q[1] };
00633 double rr[2] = { r[0], r[1] };
00634 return orient2d(pp,qq,rr);
00635 }
00636
00637
00638
00639 };
00640
00641
00642
00643
00644 #endif
00645
00646