00001
00015 #ifndef TET_H
00016 #define TET_H
00017
00018 #include "matrix.h"
00019 #include "linalg.h"
00020 #include "vector3.h"
00021 #include "vector4.h"
00022 #include "entity.h"
00023 #include "tetmesh.h"
00024
00025 namespace mesh {
00026
00027 class Point;
00028 class Edge;
00029 class Face;
00030 class TetMesh;
00031
00035 class Tet : public Entity {
00036 public:
00044 Tet(const TetMesh& mesh, id_t id, id_t corners[4], id_t material);
00048 ~Tet()
00049 {}
00053 id_t get_material_ID() const;
00057 double get_volume() const;
00058
00060 Vector3 get_center_of_gravity() const;
00061
00065 id_t get_face_id(int i) const
00066 { return _faces[i]; }
00070 void set_face_id(int i, id_t id);
00074 id_t get_edge_id(int i) const
00075 { return _edges[i]; }
00079 void set_edge_id(int i, id_t id);
00083 id_t get_corner_id(int i) const
00084 { return _corners[i]; }
00088 Face* get_face(int i) const;
00092 Edge* get_edge(int i) const;
00096 Point* get_corner(int i) const;
00098 bool get_edge_orientation(int edge_lid) const
00099 { return (_edge_orientation & (1 << edge_lid)) != 0; }
00104 void set_edge_orientation(int edge_lid, bool orientation);
00107 void cartesian_to_simplex(const Vector3& cartesian, Vector4& simplex) const;
00110 bool is_inside(const Vector3& point) const;
00114 bool is_inside_gracious(const Vector3& point) const;
00115
00116
00117
00118
00126 static void get_face_point_lids(int face_lid, int& node1_lid, int& node2_lid, int& node3_lid) {
00127 node1_lid = face_lid % 4;
00128 node2_lid = (1+face_lid) % 4;
00129 node3_lid = (2+face_lid) % 4;
00130 }
00131
00141 static void get_face_edge_lids(int face_lid, int& edge1_lid, int& edge2_lid, int& edge3_lid) {
00142 switch (face_lid) {
00143 case 0:
00144 edge1_lid = 0;
00145 edge2_lid = 1;
00146 edge3_lid = 3;
00147 break;
00148 case 1:
00149 edge1_lid = 3;
00150 edge2_lid = 4;
00151 edge3_lid = 5;
00152 break;
00153 case 2:
00154 edge1_lid = 1;
00155 edge2_lid = 2;
00156 edge3_lid = 5;
00157 break;
00158 case 3:
00159 edge1_lid = 0;
00160 edge2_lid = 2;
00161 edge3_lid = 4;
00162 break;
00163 }
00164 }
00165
00175 class CoordinateMatrix : public colarray::Matrix<double> {
00176 public:
00179 CoordinateMatrix(const Tet& tet);
00180 };
00181
00190 class GradientMatrix : public colarray::Matrix<double> {
00191 public:
00195 GradientMatrix(const CoordinateMatrix& X);
00198 GradientMatrix(const Tet& tet);
00199 };
00202 bool is_inside_bounding_box(const Vector3& point) const {
00203 Vector3 node_center, node_extent;
00204 get_bounding_box(node_center, node_extent);
00205 node_center -= point;
00206 node_center.x = fabs(node_center.x);
00207 node_center.y = fabs(node_center.y);
00208 node_center.z = fabs(node_center.z);
00209 return node_center <= node_extent;
00210 }
00213 bool is_inside_bounding_box_gracious(const Vector3& point) const {
00214 const double grace_tolerance = 1e-13;
00215 Vector3 node_center, node_extent;
00216
00217 get_bounding_box(node_center, node_extent);
00218 node_center -= point;
00219 node_center.x = fabs(node_center.x);
00220 node_center.y = fabs(node_center.y);
00221 node_center.z = fabs(node_center.z);
00222 return node_center <= node_extent * (1.0 + grace_tolerance);
00223 }
00224
00225 public:
00228 void get_bounding_box(Vector3& center, Vector3& extent) const;
00229 public:
00233 TetMesh* get_mesh() const;
00234 private:
00235 id_t _corners[4];
00236 id_t _edges[6];
00237 id_t _faces[4];
00238 id_t _material;
00243 unsigned char _edge_orientation;
00244 };
00245
00246 }
00247
00248 #endif