00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef _BARYCOORDSYSTEM_H
00034 #define _BARYCOORDSYSTEM_H
00035
00036 #include "Array.h"
00037 #include "Volumes.h"
00038 #include <algorithm>
00039
00040 namespace Go {
00043
00044
00063 template <int Dim>
00064 class BaryCoordSystem {
00065 public:
00067 BaryCoordSystem()
00068 {}
00071 BaryCoordSystem(const Array<double, Dim>* corners)
00072 {
00073 std::copy(corners, corners+Dim+1, corners_);
00074 total_volume_ = simplex_volume(corners);
00075 }
00076
00078 void setCorners(const Array<double, Dim>* corners)
00079 {
00080 std::copy(corners, corners+Dim+1, corners_);
00081 total_volume_ = simplex_volume(corners);
00082 }
00083
00085 const Array<double,Dim>& corner(int i) const
00086 {
00087 return corners_[i];
00088 }
00089
00092 template<class T>
00093 Array<T, Dim> baryToCart(const Array<T, Dim+1>& bary_pt) const;
00094
00097 template<class T>
00098 Array<T, Dim+1> cartToBary(const Array<T, Dim>& cart_pt) const;
00099
00101 void read(std::istream& is)
00102 {
00103 bool is_good = is.good();
00104 if (!is_good) {
00105 THROW("Invalid input file!");
00106 }
00107 for (int i = 0; i <= Dim; ++i)
00108 is >> corners_[i];
00109 total_volume_ = simplex_volume(corners_);
00110
00111 }
00113 void write(std::ostream& os) const
00114 {
00115 for (int i = 0; i < Dim; ++i)
00116 os << corners_[i] << std::endl;
00117 os << corners_[Dim];
00118 }
00119
00120 private:
00121 Array<double, Dim> corners_[Dim+1];
00122 double total_volume_;
00123 };
00124
00125
00126
00127
00128 template <int Dim>
00129 template <class T>
00130 inline Array<T, Dim>
00131 BaryCoordSystem<Dim>::baryToCart(const Array<T, Dim+1>& bary_pt) const
00132 {
00133 Array<T, Dim> cart_pt = corners_[0] * bary_pt[0];
00134 for (int i = 1; i < Dim+1; ++i) {
00135 cart_pt += corners_[i] * bary_pt[i];
00136 }
00137 return cart_pt;
00138 }
00139
00140
00141 template <int Dim>
00142 template <class T>
00143 inline Array<T, Dim+1>
00144 BaryCoordSystem<Dim>::cartToBary(const Array<T, Dim>& cart_pt) const
00145 {
00146 static Array<T, Dim> subsimplex[Dim+1];
00147 for (int i = 1; i < Dim+1; ++i) {
00148 for (int d = 0; d < Dim; ++d) {
00149 subsimplex[i][d] = T(corners_[i][d]);
00150 }
00151 }
00152
00153 Array<T,Dim+1> bary_pt;
00154 for (int i = 0; i < Dim+1; ++i) {
00155 subsimplex[i] = cart_pt;
00156 bary_pt[i] = simplex_volume(subsimplex);
00157 for (int d = 0; d < Dim; ++d) {
00158 subsimplex[i][d] = T(corners_[i][d]);
00159 }
00160 }
00161 bary_pt /= total_volume_;
00162 return bary_pt;
00163 }
00164
00165
00166 template<class T, int Dim>
00167 inline Array<T, Dim> operator* (const Array<double, Dim>& a, const T b)
00168 {
00169 Array<T, Dim> result;
00170 for (int i = 0; i < Dim; ++i) {
00171 result[i] = a[i] * b;
00172 }
00173 return result;
00174 }
00175
00176
00177
00178
00179 typedef BaryCoordSystem<2> BaryCoordSystem2D;
00180 typedef BaryCoordSystem<3> BaryCoordSystem3D;
00181
00182
00184 };
00185
00186
00188 namespace std {
00191
00192
00193
00195 template<int Dim>
00196 inline std::istream& operator >> (std::istream& is,
00197 Go::BaryCoordSystem<Dim>& bc)
00198 {
00199 bc.read(is);
00200 return is;
00201 }
00202
00203
00205 template<int Dim>
00206 inline std::ostream& operator << (std::ostream& os,
00207 const Go::BaryCoordSystem<Dim>& bc)
00208 {
00209 bc.write(os);
00210 return os;
00211 }
00212
00213
00215 }
00216
00217
00218 #endif // _BARYCOORDSYSTEM_H
00219
00220