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