BWAPI
|
00001 // Copyright (c) 2005 INRIA Sophia-Antipolis (France). 00002 // All rights reserved. 00003 // 00004 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public License as 00006 // published by the Free Software Foundation; version 2.1 of the License. 00007 // See the file LICENSE.LGPL distributed with CGAL. 00008 // 00009 // Licensees holding a valid commercial license may use this file in 00010 // accordance with the commercial license agreement provided with the software. 00011 // 00012 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00013 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00014 // 00015 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Principal_component_analysis/include/CGAL/barycenter.h $ 00016 // $Id: barycenter.h 42947 2008-04-17 21:04:05Z spion $ 00017 // 00018 // 00019 // Author(s) : Sylvain Pion 00020 00021 #ifndef CGAL_BARYCENTER_H 00022 #define CGAL_BARYCENTER_H 00023 00024 #include <CGAL/basic.h> 00025 #include <iterator> 00026 #include <CGAL/Kernel_traits.h> 00027 #include <CGAL/Kernel/Dimension_utils.h> 00028 #include <CGAL/Dimension.h> 00029 00030 // Functions to compute the point given its barycentric coordinates. 00031 // Works in 2D and 3D (and dD ?). 00032 // Special case for the centroid. 00033 00034 // TODO : Note : more numerically stable variants could be implemented as well. 00035 // TODO : Specify a traits class concept ? Maybe not for these computations. 00036 // TODO : Grep for "barycenter" and "centroid" in CGAL to check existing usages. 00037 // TODO : Add barycentric_coordinates() (to the kernel, this time). 00038 00039 CGAL_BEGIN_NAMESPACE 00040 00041 // This one takes an iterator range over std::pair<K::Point_[23], K::FT> 00042 template < typename InputIterator, typename K > 00043 typename std::iterator_traits<InputIterator>::value_type::first_type 00044 barycenter(InputIterator begin, InputIterator end, const K & ) 00045 { 00046 typedef typename std::iterator_traits<InputIterator>::value_type pair; 00047 typedef typename pair::second_type FT; 00048 typedef typename pair::first_type Point; 00049 typedef typename Access::Vector<K, typename Ambient_dimension<Point, K>::type>::type Vector; 00050 00051 CGAL_precondition(begin != end); 00052 00053 Vector v = NULL_VECTOR; 00054 FT norm = 0; 00055 00056 while (begin != end) { 00057 pair p = *begin++; 00058 v = v + p.second * (p.first - ORIGIN); 00059 norm += p.second; 00060 } 00061 00062 CGAL_assertion( norm != 0 ); 00063 00064 return ORIGIN + v / norm; 00065 } 00066 00067 // This one takes an iterator range over K::Point_[23], 00068 // and an iterator over K::FT. 00069 template < typename PointInputIterator, typename WeightInputIterator, 00070 typename K > 00071 typename std::iterator_traits<PointInputIterator>::value_type 00072 barycenter(PointInputIterator begin, PointInputIterator end, 00073 WeightInputIterator wbegin, const K & ) 00074 { 00075 typedef typename std::iterator_traits<PointInputIterator>::value_type Point; 00076 typedef typename std::iterator_traits<WeightInputIterator>::value_type FT; 00077 typedef typename Access::Vector<K, typename Ambient_dimension<Point, K>::type>::type Vector; 00078 00079 CGAL_precondition(begin != end); 00080 00081 Vector v = NULL_VECTOR; 00082 FT norm = 0; 00083 00084 while (begin != end) { 00085 FT weight = *wbegin++; 00086 v = v + weight * (*begin++ - ORIGIN); 00087 norm += weight; 00088 } 00089 00090 CGAL_assertion( norm != 0 ); 00091 00092 return ORIGIN + v / norm; 00093 } 00094 00095 // This one takes an iterator range over std::pair<K::Point_[23], K::FT> 00096 // And it uses Kernel_traits<> to find out its kernel. 00097 template < typename InputIterator > 00098 inline 00099 typename std::iterator_traits<InputIterator>::value_type::first_type 00100 barycenter(InputIterator begin, InputIterator end) 00101 { 00102 typedef typename std::iterator_traits<InputIterator>::value_type pair; 00103 typedef typename pair::first_type Point; 00104 typedef typename Kernel_traits<Point>::Kernel K; 00105 00106 return CGAL::barycenter(begin, end, K()); 00107 } 00108 00109 // This one takes an iterator range over K::Point_[23], 00110 // and an iterator over K::FT. 00111 // And it uses Kernel_traits<> to find out its kernel. 00112 // To differentiate it from the others, it takes an "int" as K parameter 00113 template < typename PointInputIterator, typename WeightInputIterator > 00114 inline 00115 typename std::iterator_traits<PointInputIterator>::value_type 00116 barycenter(PointInputIterator begin, PointInputIterator end, 00117 WeightInputIterator wbegin, int) 00118 { 00119 typedef typename std::iterator_traits<PointInputIterator>::value_type Point; 00120 typedef typename Kernel_traits<Point>::Kernel K; 00121 00122 return CGAL::barycenter(begin, end, wbegin, K()); 00123 } 00124 00125 CGAL_END_NAMESPACE 00126 00127 #endif