Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_GEOMETRY_GEOMETRY_LOCAL_TRIANGLE_FRAME_H
00002 #define OPENTISSUE_CORE_GEOMETRY_GEOMETRY_LOCAL_TRIANGLE_FRAME_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 namespace OpenTissue
00013 {
00014 namespace geometry
00015 {
00016
00017 template< typename vector3_type_ >
00018 class LocalTriangleFrame
00019 {
00020 public:
00021
00022 typedef vector3_type_ vector3_type;
00023 typedef typename vector3_type::value_type real_type;
00024
00025 protected:
00026
00027 vector3_type m_v0;
00028 vector3_type m_v1;
00029 vector3_type m_v2;
00030 vector3_type m_n;
00031
00032 protected:
00033
00034 vector3_type m_a_vec;
00035 vector3_type m_b_vec;
00036 vector3_type m_h_vec;
00037 real_type m_a_norm_inv;
00038 real_type m_b_norm;
00039 real_type m_h_norm_inv;
00040
00041 real_type m_a;
00042 real_type m_b;
00043 real_type m_h;
00044
00045
00046 unsigned int m_offset;
00047
00048 vector3_type m_nv0;
00049 vector3_type m_nv1;
00050 vector3_type m_nv2;
00051 vector3_type m_ne0;
00052 vector3_type m_ne1;
00053 vector3_type m_ne2;
00054
00055
00056 vector3_type m_a_unit;
00057 vector3_type m_h_unit;
00058
00059 public:
00060
00061 real_type const & a() const { return m_a; }
00062 real_type const & b() const { return m_b; }
00063 real_type const & h() const { return m_h; }
00064 vector3_type const & nv0() const { return m_nv0; }
00065 vector3_type const & nv1() const { return m_nv1; }
00066 vector3_type const & nv2() const { return m_nv2; }
00067 vector3_type const & ne0() const { return m_ne0; }
00068 vector3_type const & ne1() const { return m_ne1; }
00069 vector3_type const & ne2() const { return m_ne2; }
00070 vector3_type const & v0() const { return m_v0; }
00071 vector3_type const & v1() const { return m_v1; }
00072 vector3_type const & v2() const { return m_v2; }
00073 vector3_type const & n() const { return m_n; }
00074 vector3_type const & unit_a() const { return m_a_unit; }
00075 vector3_type const & unit_h( )const { return m_h_unit; }
00076
00077 private:
00078
00093 void find_permutation( vector3_type const & p0, vector3_type const & p1, vector3_type const & p2 )
00094 {
00095 real_type l0 = norm(p1-p0);
00096 real_type l1 = norm(p2-p1);
00097 real_type l2 = norm(p0-p2);
00098 if (l0>=l1 && l0>=l2)
00099 {
00100 m_offset = 0;
00101 m_v0 = p0;
00102 m_v1 = p1;
00103 m_v2 = p2;
00104 }
00105 else if (l1>=l0 && l1>=l2)
00106 {
00107 m_offset = 1;
00108 m_v0 = p1;
00109 m_v1 = p2;
00110 m_v2 = p0;
00111 }
00112 else if (l2>=l0 && l2>=l1)
00113 {
00114 m_offset = 2;
00115 m_v0 = p2;
00116 m_v1 = p0;
00117 m_v2 = p1;
00118 }
00119 else
00120 {
00121 assert(!"fuck nowhere to go!!!");
00122 }
00123 }
00124
00125 public:
00134 vector3_type xform_normal(vector3_type const & n)
00135 {
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 return vector3_type( m_a_unit*n, m_h_unit*n, m_n*n);
00148 }
00149
00150
00151 public:
00152
00160 void init( vector3_type const & p0, vector3_type const & p1, vector3_type const & p2)
00161 {
00162 find_permutation(p0,p1,p2);
00163
00164
00165 vector3_type e0 = m_v1 - m_v0;
00166 vector3_type e1 = m_v2 - m_v1;
00167 vector3_type e2 = m_v0 - m_v2;
00168 m_n = unit ( e0 % e1 );
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 m_b_vec = unit( e0 );
00188 m_b_norm = e2 * m_b_vec;
00189 m_b = std::fabs( m_b_norm );
00190
00191 assert( m_b_norm < 0 );
00192 m_b_vec *= m_b_norm ;
00193
00194 m_a_vec = e0 + m_b_vec ;
00195 m_a = std::sqrt(m_a_vec*m_a_vec);
00196 assert( m_a > 0 || !"LocalTriangleFrame::init(): a was non-positive");
00197 m_a_norm_inv = 1. / m_a;
00198
00199 m_h_vec = m_b_vec - e2;
00200 m_h = sqrt(m_h_vec*m_h_vec);
00201 assert( m_h > 0 || !"LocalTriangleFrame::init(): h was non-positive");
00202 m_h_norm_inv = 1. / m_h;
00203
00204 assert( !is_zero(m_a_vec) || !"LocalTriangleFrame::init(): a vector was zero");
00205 assert( !is_zero(m_h_vec) || !"LocalTriangleFrame::init(): h vector was zero");
00206
00207 m_a_unit = unit(m_a_vec);
00208 m_h_unit = unit(m_h_vec);
00209 }
00210
00211
00220 vector3_type get_local_coord( vector3_type const & p ) const
00221 {
00222
00223 vector3_type pp = p - m_v0 + m_b_vec;
00224 return vector3_type (
00225 (pp * m_a_vec) * m_a_norm_inv,
00226 (pp * m_h_vec) * m_h_norm_inv,
00227 m_n*(p -m_v0)
00228 );
00229 }
00230
00231
00247 void compute_local_normals(
00248 vector3_type const & nv0
00249 , vector3_type const & nv1
00250 , vector3_type const & nv2
00251 , vector3_type const & ne0
00252 , vector3_type const & ne1
00253 , vector3_type const & ne2
00254 )
00255 {
00256 switch(m_offset)
00257 {
00258 case 0:
00259 m_nv0 = xform_normal(nv0);
00260 m_nv1 = xform_normal(nv1);
00261 m_nv2 = xform_normal(nv2);
00262 m_ne0 = xform_normal(ne0);
00263 m_ne1 = xform_normal(ne1);
00264 m_ne2 = xform_normal(ne2);
00265 break;
00266 case 1:
00267 m_nv0 = xform_normal(nv1);
00268 m_nv1 = xform_normal(nv2);
00269 m_nv2 = xform_normal(nv0);
00270 m_ne0 = xform_normal(ne1);
00271 m_ne1 = xform_normal(ne2);
00272 m_ne2 = xform_normal(ne0);
00273 break;
00274 case 2:
00275 m_nv0 = xform_normal(nv2);
00276 m_nv1 = xform_normal(nv0);
00277 m_nv2 = xform_normal(nv1);
00278 m_ne0 = xform_normal(ne2);
00279 m_ne1 = xform_normal(ne0);
00280 m_ne2 = xform_normal(ne1);
00281 break;
00282 default:
00283 assert(!"LocalTriangleFrame::compute_local_normals(...): Unexpected offset value encountered!");
00284 break;
00285 };
00286 }
00287
00288 };
00289
00290 }
00291 }
00292
00293
00294 #endif