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 _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
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
00066
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
00099
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 }
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
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
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 }
00225
00226 #endif // _BEZIERTRIANGLE_H
00227
00228