BezierTriangle.h

00001 //===========================================================================
00002 // GoTools - SINTEF Geometry Tools
00003 //
00004 // GoTools module: Implicitization, version 1.0
00005 //
00006 // Copyright (C) 2000-2007 SINTEF ICT, Applied Mathematics, Norway.
00007 //
00008 // This program is free software; you can redistribute it and/or          
00009 // modify it under the terms of the GNU General Public License            
00010 // as published by the Free Software Foundation version 2 of the License. 
00011 //
00012 // This program is distributed in the hope that it will be useful,        
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of         
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          
00015 // GNU General Public License for more details.                           
00016 //
00017 // You should have received a copy of the GNU General Public License      
00018 // along with this program; if not, write to the Free Software            
00019 // Foundation, Inc.,                                                      
00020 // 59 Temple Place - Suite 330,                                           
00021 // Boston, MA  02111-1307, USA.                                           
00022 //
00023 // Contact information: E-mail: tor.dokken@sintef.no                      
00024 // SINTEF ICT, Department of Applied Mathematics,                         
00025 // P.O. Box 124 Blindern,                                                 
00026 // 0314 Oslo, Norway.                                                     
00027 //
00028 // Other licenses are also available for this software, notably licenses
00029 // for:
00030 // - Building commercial software.                                        
00031 // - Building software whose source code you wish to keep private.        
00032 //===========================================================================
00033 #ifndef _BEZIERTRIANGLE_H
00034 #define _BEZIERTRIANGLE_H
00035 
00036 
00037 #include "Array.h"
00038 #include "BernsteinTriangularPoly.h"
00039 #include "newmat.h"
00040 #include "Binomial.h"
00041 #include <vector>
00042 
00045 
00047 namespace std
00048 {
00051 
00052 
00053 
00054 // identity_element (not part of the C++ standard).
00055 
00056 template <class _Tp> inline _Tp identity_element(plus<_Tp>) {
00057   return _Tp(0);
00058 }
00059 template <class _Tp> inline _Tp identity_element(multiplies<_Tp>) {
00060   return _Tp(1);
00061 }
00062 
00063 
00064 
00065 // Returns __x ** __n, where __n >= 0.  _Note that "multiplication"
00066 // is required to be associative, but not necessarily commutative.
00067 
00068 template <class _Tp, class _Integer, class _MonoidOperation>
00069 _Tp __power(_Tp __x, _Integer __n, _MonoidOperation __oper)
00070 {
00071   if (__n == 0)
00072     return identity_element(__oper);
00073   else {
00074     while ((__n & 1) == 0) {
00075       __n >>= 1;
00076       __x = __oper(__x, __x);
00077     }
00078 
00079     _Tp __result = __x;
00080     __n >>= 1;
00081     while (__n != 0) {
00082       __x = __oper(__x, __x);
00083       if ((__n & 1) != 0)
00084         __result = __oper(__result, __x);
00085       __n >>= 1;
00086     }
00087     return __result;
00088   }
00089 }
00090 
00091 
00092 template <class _Tp, class _Integer>
00093 inline _Tp __power(_Tp __x, _Integer __n)
00094 {
00095   return __power(__x, __n, multiplies<_Tp>());
00096 }
00097 
00098 // Alias for the internal name __power.  Note that power is an extension,
00099 // not part of the C++ standard.
00100 
00101 template <class _Tp, class _Integer, class _MonoidOperation>
00102 inline _Tp power(_Tp __x, _Integer __n, _MonoidOperation __oper)
00103 {
00104   return __power(__x, __n, __oper);
00105 }
00106 
00107 template <class _Tp, class _Integer>
00108 inline _Tp power(_Tp __x, _Integer __n)
00109 {
00110   return __power(__x, __n);
00111 }
00112 
00114 } // namespace std
00115 
00117 namespace Go
00118 {
00121 
00122 
00123 
00125 template <int N>
00126 class BezierTriangle
00127 {
00128 public:
00130     BezierTriangle() : deg_(0), last_derivdir_(-1.0, -1.0, -1.0) { }
00131 
00133     BezierTriangle(int deg, const Array<double, N>* cp)
00134         : deg_(deg), last_derivdir_(-1.0, -1.0, -1.0)
00135     {
00136         int sz = (deg_+1)*(deg_+2)/2;
00137         std::vector<double> tmp(sz);
00138         for (int i = 0; i < N; ++i) {
00139             for (int j = 0; j < sz; ++j) {
00140                 tmp[j] = cp[j][i];
00141             }
00142             polys_[i] = BernsteinTriangularPoly(deg_, tmp);
00143         }
00144     }
00145 
00147     Array<double, N> eval(Vector3D beta)
00148     {
00149         Array<double, N> res;
00150         for (int i = 0; i < N; ++i) {
00151             res[i] = polys_[i](beta);
00152         }
00153         return res;
00154     }
00155 
00157     Array<double, N> evalderiv(Vector3D beta, Vector3D dir)
00158     {
00159         if (last_derivdir_.dist2(dir) > 0.0) {
00160             for (int i = 0; i < N; ++i) {
00161                 polys_[i].deriv(1, dir, derivpolys_[i]);
00162             }
00163         }
00164         last_derivdir_ = dir;
00165         Array<double, N> res;
00166         for (int i = 0; i < N; ++i) {
00167             res[i] = derivpolys_[i](beta);
00168         }
00169         return res;
00170     }
00171 
00173     void interpolate(int deg,
00174                      const Vector3D* nodes,
00175                      const Array<double, N>* values)
00176     {
00177         deg_ = deg;
00178         // Setting up interpolation matrix
00179         int sz = (deg+1)*(deg+2)/2;
00180         Matrix A(sz, sz);
00181         Binomial bin;
00182         for (int row = 0; row < sz; ++row) {
00183             Vector3D b = nodes[row];
00184             int col = 0;
00185             for (int i = deg; i >= 0; --i) {
00186                 for (int j = deg - i; j >= 0; --j) {
00187                     int k = deg - i - j;
00188                     double rr = std::power(b[0], i)
00189                         * std::power(b[1], j)
00190                         * std::power(b[2], k);
00191                     rr *= bin.trinomial(deg, i, j);
00192                     A.element(row, col) = rr;
00193                     ++col;
00194                 }
00195             }
00196         }
00197 
00198         // Solving the system for N right hand sides
00199         CroutMatrix ALUfact = A;
00200         DEBUG_ERROR_IF(ALUfact.IsSingular(),
00201                  "Matrix is singular! This should never happen!");
00202         ColumnVector coef(sz);
00203         ColumnVector rhs(sz);
00204         for (int i = 0; i < N; ++i) {
00205             for (int j = 0; j < sz; ++j) {
00206                 rhs.element(j) = values[j][i];
00207             }
00208             coef = ALUfact.i()*rhs;
00209             polys_[i] = BernsteinTriangularPoly(deg,
00210                                                 coef.Store(),
00211                                                 coef.Store() + sz);
00212         }
00213     }
00214    
00215 private:
00216     int deg_;
00217     Array<BernsteinTriangularPoly, N> polys_;
00218     mutable Array<BernsteinTriangularPoly, N> derivpolys_;
00219     mutable Vector3D last_derivdir_;
00220 };
00221 
00222 
00224 } // namespace Go
00225 
00226 #endif // _BEZIERTRIANGLE_H
00227 
00228 

Generated on Mon Jun 11 15:13:16 2007 for GoTools Implicitization Library by  doxygen 1.5.1