Virtual Testbed
Ship dynamics simulator for extreme conditions
tetrahedron.hh
1 #ifndef VTESTBED_GEOMETRY_TETRAHEDRON_HH
2 #define VTESTBED_GEOMETRY_TETRAHEDRON_HH
3 
4 #include <array>
5 #include <iosfwd>
6 
7 #include <vtestbed/geometry/math.hh>
8 #include <vtestbed/geometry/triangle.hh>
9 #include <vtestbed/geometry/types.hh>
10 
11 namespace vtb {
12 
13  namespace geometry {
14 
15  template <class T, int N>
16  class Tetrahedron: public std::array<Vertex<T,N>,4> {
17 
18  private:
20 
21  public:
22  static constexpr const int dimensions = N;
23  using scalar_type = T;
24  using value_type = typename base_type::value_type;
25  using pointer = typename base_type::pointer;
26  using const_pointer = typename base_type::const_pointer;
27  using reference = typename base_type::reference;
28  using const_reference = typename base_type::const_reference;
29  using iterator = typename base_type::iterator;
30  using const_iterator = typename base_type::const_iterator;
31  using size_type = typename base_type::size_type;
32  using difference_type = typename base_type::difference_type;
33  using reverse_iterator = typename base_type::reverse_iterator;
34  using const_reverse_iterator = typename base_type::const_reverse_iterator;
35 
36  public:
37  using base_type::base_type;
38  using base_type::operator=;
39  using base_type::operator[];
40 
41  public:
42 
43  inline explicit
45  const_reference p0,
46  const_reference p1,
47  const_reference p2,
48  const_reference p3
49  ): base_type{p0,p1,p2,p3} {}
50 
51  inline explicit
52  Tetrahedron(const_reference origin, const Triangle<T,N>& base):
53  base_type{origin,base[0],base[1],base[2]} {}
54 
55  };
56 
57  template <class T, int N>
58  struct is_figure<Tetrahedron<T,N>>: public std::true_type {};
59 
60  template <class T, int N>
61  inline Vertex<T,N>
62  centroid(const Tetrahedron<T,N>& t) {
63  return (t[0]+t[1]+t[2]+t[3])*T{0.25};
64  }
65 
66  template <class T, int N>
67  inline T
68  signed_volume(const Tetrahedron<T,N>& t) {
69  Vertex<T,N> e1 = t[1]-t[0];
70  Vertex<T,N> e2 = t[2]-t[0];
71  Vertex<T,N> e3 = t[3]-t[0];
72  return dot(e3, cross(e1,e2)) / T{6};
73  }
74 
75  template <class T, int N>
76  inline T
77  volume(const Tetrahedron<T,N>& t) {
78  return std::abs(signed_volume(t));
79  }
80 
81  template <class T>
82  inline T
83  solid_angle(const Tetrahedron<T,3>& t) {
84  using std::atan2;
85  Vertex<T,3> A = t[1]-t[0];
86  Vertex<T,3> B = t[2]-t[0];
87  Vertex<T,3> C = t[3]-t[0];
88  auto a = length(A);
89  auto b = length(B);
90  auto c = length(C);
91  return 2*atan2(det(A,B,C), a*b*c + c*dot(A,B) + a*dot(B,C) + b*dot(C,A));
92  }
93 
94  }
95 
96 }
97 
98 #endif // vim:filetype=cpp
T atan2(T... args)
T length(const blitz::TinyVector< T, N > &x)
Computes vector length without overflow.
Definition: blitz.hh:471
Main namespace.
Definition: convert.hh:9