Go to the documentation of this file.00001 #ifndef OPENTISSUE_DYNAMICS_EDM_MODELS_EDM_GENERIC_BEZIER_SOLID_H
00002 #define OPENTISSUE_DYNAMICS_EDM_MODELS_EDM_GENERIC_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 #include <OpenTissue/core/math/math_functions.h>
00014 #include <vector>
00015 #include <cmath>
00016
00017
00018 namespace OpenTissue
00019 {
00020
00021 namespace edm
00022 {
00023
00024 template<typename edm_types>
00025 class GenericBezierSolid
00026 : public Solid<edm_types>
00027 {
00028 public:
00029
00030 typedef Solid<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 GenericBezierSolid()
00038 : base_type()
00039 , m_n(0)
00040 {}
00041
00042 virtual ~GenericBezierSolid() {}
00043
00044 void set(size_t order)
00045 {
00046 using std::pow;
00047 base_type::set(static_cast<size_t>(pow(static_cast<real_type>(order)+value_traits::one(),3)));
00048 m_n = order;
00049 }
00050
00051 private:
00052
00053 vector3_type position(vector3_type const * a, real_type const & u, real_type const & v, real_type const & w) const
00054 {
00055 std::vector<real_type> U(m_n+1), V(m_n+1), W(m_n+1);
00056 for (size_t i = 0; i <= m_n; ++i)
00057 {
00058 U[i] = B(i,u);
00059 V[i] = B(i,v);
00060 W[i] = B(i,w);
00061 }
00062 vector3_type Q;
00063 for (size_t i = 0; i <= m_n; ++i)
00064 for (size_t j = 0; j <= m_n; ++j)
00065 for (size_t k = 0; k <= m_n; ++k)
00066 Q += a[i*(m_n+1)*(m_n+1)+j*(m_n+1)+k]*W[i]*V[j]*U[k];
00067 return vector3_type(Q);
00068 }
00069
00070 vector3_type normal(size_t l, size_t m, size_t n) const
00071 {
00072
00073 if (!(n==0||m==0||l==0||n==this->m_N-1||m==this->m_M-1||l==this->m_L-1))
00074 return vector3_type(value_traits::zero());
00075
00076
00077 long lm = m;
00078 long ln = n;
00079 long ll = l;
00080
00081 vector3_type const u = this->r(ll+1,lm,ln) - this->r(ll-1,lm,ln);
00082 vector3_type const v = this->r(ll,lm+1,ln) - this->r(ll,lm-1,ln);
00083 vector3_type const w = this->r(ll,lm,ln+1) - this->r(ll,lm,ln-1);
00084
00085 vector3_type normal_;
00086 if (n==0)
00087 normal_ += cross( u, v);
00088 else if (n==this->m_N-1)
00089 normal_ += cross( v, u);
00090 if (m==0)
00091 normal_ += cross( w, u);
00092 else if (m==this->m_M-1)
00093 normal_ += cross( u, w);
00094 if (l==0)
00095 normal_ += cross( v, w);
00096 else if (l==this->m_L-1)
00097 normal_ += cross( w, v);
00098 return vector3_type(unit(normal_));
00099 }
00100
00101 private:
00102
00103 real_type B(size_t i, const real_type& t) const
00104 {
00105 using std::pow;
00106 return real_type(pow(t,static_cast<int>(i))*pow(value_traits::one()-t,static_cast<int>(m_n-i))*math::fac<real_type>(m_n)/math::fac<real_type>(i)/math::fac<real_type>(m_n-i));
00107 }
00108
00109 private:
00110
00111 size_t m_n;
00112
00113 };
00114
00115 }
00116
00117 }
00118
00119
00120 #endif