Go to the documentation of this file.00001 #ifndef OPENTISSUE_DYNAMICS_EDM_MODELS_EDM_QUADRATIC_BEZIER_PATCH_H
00002 #define OPENTISSUE_DYNAMICS_EDM_MODELS_EDM_QUADRATIC_BEZIER_PATCH_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/dynamics/edm/edm_surface.h>
00013
00014 #include <cmath>
00015 #include <cassert>
00016
00017
00018 namespace OpenTissue
00019 {
00020
00021 namespace edm
00022 {
00023
00024 template<typename edm_types>
00025 class QuadraticBezierPatch
00026 : public Surface<edm_types>
00027 {
00028 public:
00029
00030 typedef Surface<edm_types> base_type;
00031 typedef typename edm_types::value_traits value_traits;
00032 typedef typename edm_types::real_type real_type;
00033 typedef typename edm_types::vector3_type vector3_type;
00034
00035 public:
00036
00037 QuadraticBezierPatch()
00038 : base_type()
00039 {
00040 base_type::set(NUM_NODES);
00041 }
00042
00043 virtual ~QuadraticBezierPatch() {}
00044
00045 private:
00046
00047 vector3_type position(vector3_type const * a, real_type const & u, real_type const & v) const
00048 {
00049 real_type U[ORDER], V[ORDER];
00050 for (size_t i = 0; i < ORDER; ++i) {
00051 U[i] = B(i,u);
00052 V[i] = B(i,v);
00053 }
00054 vector3_type Q;
00055 for (size_t i = 0; i < ORDER; ++i)
00056 for (size_t j = 0; j < ORDER; ++j)
00057 Q += a[i*ORDER+j]*U[j]*V[i];
00058 return vector3_type(Q);
00059 }
00060
00061 vector3_type normal(size_t m, size_t n) const
00062 {
00063
00064
00065
00066
00067
00068 long lm = m;
00069 long ln = n;
00070
00071 vector3_type const v = this->r(lm+1,ln ) - this->r(lm-1,ln );
00072 vector3_type const w = this->r(lm, ln+1) - this->r(lm, ln-1);
00073 return vector3_type(unit( cross(v,w) ));
00074 }
00075
00076 size_t max_nodes() const
00077 {
00078 return NUM_NODES;
00079 }
00080
00081 private:
00082
00083 real_type B(size_t n, real_type const & t) const
00084 {
00085 assert(n<ORDER);
00086 real_type const tmp = value_traits::one()-t;
00087 switch (n) {
00088 case 0: return real_type(tmp*tmp);
00089 case 1: return real_type(value_traits::two()*t*tmp);
00090 case 2: return real_type(t*t);
00091 }
00092 return real_type(value_traits::zero());
00093 }
00094
00095 real_type dBdt(size_t n, real_type const & t) const
00096 {
00097 assert(n<ORDER);
00098 const real_type tmp = value_traits::two()*t;
00099 switch (n) {
00100 case 0: return real_type(tmp-value_traits::two());
00101 case 1: return real_type(-value_traits::two()*tmp+value_traits::two());
00102 case 2: return real_type(tmp);
00103 }
00104 return real_type(value_traits::zero());
00105 }
00106
00107 real_type ddtdBdt(size_t n, real_type const & t) const
00108 {
00109 assert(n<ORDER);
00110 switch (n) {
00111 case 0: return real_type(value_traits::two());
00112 case 1: return real_type(-value_traits::four());
00113 case 2: return real_type(value_traits::two());
00114 }
00115 return real_type(t);
00116 }
00117
00118 private:
00119
00120 enum {ORDER = 3, NUM_NODES = 9};
00121
00122 };
00123
00124 }
00125
00126 }
00127
00128
00129 #endif