//=========================================================================== // GoTools Core - SINTEF Geometry Tools Core library, version 2.0.1 // // Copyright (C) 2000-2007, 2010 SINTEF ICT, Applied Mathematics, Norway. // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., // 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. // // Contact information: E-mail: tor.dokken@sintef.no // SINTEF ICT, Department of Applied Mathematics, // P.O. Box 124 Blindern, // 0314 Oslo, Norway. // // Other licenses are also available for this software, notably licenses // for: // - Building commercial software. // - Building software whose source code you wish to keep private. //=========================================================================== 00014 #ifndef _BARYCOORDSYSTEM_H 00015 #define _BARYCOORDSYSTEM_H 00016 00017 #include "GoTools/utils/Array.h" 00018 #include "GoTools/utils/Volumes.h" 00019 #include <algorithm> 00020 00021 namespace Go { 00022 00041 template <int Dim> 00042 class BaryCoordSystem { 00043 public: 00045 BaryCoordSystem() 00046 {} 00049 BaryCoordSystem(const Array<double, Dim>* corners) 00050 { 00051 std::copy(corners, corners+Dim+1, corners_); 00052 total_volume_ = simplex_volume(corners); 00053 } 00054 00056 void setCorners(const Array<double, Dim>* corners) 00057 { 00058 std::copy(corners, corners+Dim+1, corners_); 00059 total_volume_ = simplex_volume(corners); 00060 } 00061 00063 const Array<double,Dim>& corner(int i) const 00064 { 00065 return corners_[i]; 00066 } 00067 00070 template<class T> 00071 Array<T, Dim> baryToCart(const Array<T, Dim+1>& bary_pt) const; 00072 00075 template<class T> 00076 Array<T, Dim+1> cartToBary(const Array<T, Dim>& cart_pt) const; 00077 00079 void read(std::istream& is) 00080 { 00081 bool is_good = is.good(); 00082 if (!is_good) { 00083 THROW("Invalid input file!"); 00084 } 00085 for (int i = 0; i <= Dim; ++i) 00086 is >> corners_[i]; 00087 total_volume_ = simplex_volume(corners_); 00088 00089 } 00091 void write(std::ostream& os) const 00092 { 00093 for (int i = 0; i < Dim; ++i) 00094 os << corners_[i] << std::endl; 00095 os << corners_[Dim]; 00096 } 00097 00098 private: 00099 Array<double, Dim> corners_[Dim+1]; 00100 double total_volume_; 00101 }; 00102 00103 00104 // Implementation of inline functions 00105 00106 template <int Dim> 00107 template <class T> 00108 inline Array<T, Dim> 00109 BaryCoordSystem<Dim>::baryToCart(const Array<T, Dim+1>& bary_pt) const 00110 { 00111 Array<T, Dim> cart_pt = corners_[0] * bary_pt[0]; 00112 for (int i = 1; i < Dim+1; ++i) { 00113 cart_pt += corners_[i] * bary_pt[i]; 00114 } 00115 return cart_pt; 00116 } 00117 00118 00119 template <int Dim> 00120 template <class T> 00121 inline Array<T, Dim+1> 00122 BaryCoordSystem<Dim>::cartToBary(const Array<T, Dim>& cart_pt) const 00123 { 00124 static Array<T, Dim> subsimplex[Dim+1]; 00125 for (int i = 1; i < Dim+1; ++i) { 00126 for (int d = 0; d < Dim; ++d) { 00127 subsimplex[i][d] = T(corners_[i][d]); 00128 } 00129 } 00130 00131 Array<T,Dim+1> bary_pt; 00132 for (int i = 0; i < Dim+1; ++i) { 00133 subsimplex[i] = cart_pt; 00134 bary_pt[i] = simplex_volume(subsimplex); 00135 for (int d = 0; d < Dim; ++d) { 00136 subsimplex[i][d] = T(corners_[i][d]); 00137 } 00138 } 00139 bary_pt /= total_volume_; 00140 return bary_pt; 00141 } 00142 00143 00144 template<class T, int Dim> 00145 inline Array<T, Dim> operator* (const Array<double, Dim>& a, const T b) 00146 { 00147 Array<T, Dim> result; 00148 for (int i = 0; i < Dim; ++i) { 00149 result[i] = a[i] * b; 00150 } 00151 return result; 00152 } 00153 00154 00155 // Typedefs 00156 00157 typedef BaryCoordSystem<2> BaryCoordSystem2D; 00158 typedef BaryCoordSystem<3> BaryCoordSystem3D; 00159 00160 00161 }; // namespace Go 00162 00163 00164 namespace std { 00165 00166 00168 template<int Dim> 00169 inline std::istream& operator >> (std::istream& is, 00170 Go::BaryCoordSystem<Dim>& bc) 00171 { 00172 bc.read(is); 00173 return is; 00174 } 00175 00176 00178 template<int Dim> 00179 inline std::ostream& operator << (std::ostream& os, 00180 const Go::BaryCoordSystem<Dim>& bc) 00181 { 00182 bc.write(os); 00183 return os; 00184 } 00185 00186 00187 } // namespace std 00188 00189 00190 #endif // _BARYCOORDSYSTEM_H 00191