Virtual Testbed
Ship dynamics simulator for extreme conditions
triangle.hh
1 #ifndef VTESTBED_GEOMETRY_TRIANGLE_HH
2 #define VTESTBED_GEOMETRY_TRIANGLE_HH
3 
4 #include <iosfwd>
5 
6 #include <vtestbed/geometry/math.hh>
7 #include <vtestbed/geometry/plane.hh>
8 #include <vtestbed/geometry/ray.hh>
9 #include <vtestbed/geometry/types.hh>
10 
11 namespace vtb {
12 
13  namespace geometry {
14 
15  template <class T, int N>
16  class Triangle: public std::array<Vertex<T,N>,3> {
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
44  Triangle(const_reference p0, const_reference p1, const_reference p2):
45  base_type{p0,p1,p2} {}
46 
47  inline void flip() { std::swap(this->front(), this->back()); }
48  inline void reverse() { this->flip(); }
49  inline void invert() { this->flip(); }
50 
51  Plane<T,N> plane() const;
52  Polyline<T,N> polyline() const;
53  Polygon<T,N> polygon() const;
54  bool degenerate(scalar_type eps) const;
55 
56  void
57  gnuplot(std::ostream& out) const;
58 
59  };
60 
61  template <class T, int N>
62  struct is_figure<Triangle<T,N>>: public std::true_type {};
63 
69  template <class T>
71  return dot(tr[2], cross(tr[0], tr[1])) / T{6};
72  }
73 
74  template <class T>
75  T tetrahedron_signed_volume(const Triangle<T,2>& tr) {
76  return T{};
77  }
78 
86  template <class T, int N>
87  inline bool
88  intersect(const Ray<T,N>& ray, const Triangle<T,N>& triangle, T eps) {
89  using vec = Vertex<T,N>;
90  vec e1{triangle[1] - triangle[0]}, e2{triangle[2] - triangle[0]};
91  vec n{cross(ray.direction(), e2)};
92  T det = dot(e1, n);
93  if (std::abs(det) < eps) {
94  return false;
95  }
96  T rdet{T{1}/det};
97  vec tvec{ray.origin() - triangle[0]};
98  T u = dot(tvec, n) * rdet;
99  if (u < T{0} || u > T{1}) {
100  return false;
101  }
102  vec qvec{cross(tvec, e1)};
103  T v = dot(ray.direction(), qvec) * rdet;
104  if (v < T{0} || u+v > T{1}) {
105  return false;
106  }
107  return true;
108  }
109 
110  template <class T, int N>
111  inline Vertex<Plane_position,3>
112  compare(const Plane<T,N> plane, const Triangle<T,N>& triangle, T eps) {
113  Vertex<Plane_position,3> order;
114  for (int i=0; i<3; ++i) {
115  order(i) = compare(plane, triangle[i], eps);
116  }
117  return order;
118  }
119 
120  template <class T, int N>
121  void
122  intersect(
123  const Plane<T,N>& plane,
124  const Triangle<T,N>& triangle,
125  const Vertex<Plane_position,3>& positions,
126  Polygon<T,N>& front,
127  Polygon<T,N>& back
128  );
129 
130  template <class T, int N>
131  inline Vertex<T,N>
132  centroid(const Triangle<T,N>& t) {
133  return (t[0]+t[1]+t[2])/T{3};
134  }
135 
136  template <class T, int N>
137  inline T
138  area(const Triangle<T,N>& t) {
139  Vertex<T,N> e1 = t[1] - t[0];
140  Vertex<T,N> e2 = t[2] - t[0];
141  return T{0.5} * length(cross(e1,e2));
142  }
143 
144  template <class T>
145  inline Vertex<T,3>
146  surface_normal(const Triangle<T,3>& t) {
147  return surface_normal(t[0],t[1],t[2]);
148  }
149 
150  }
151 
152 }
153 
154 #endif // vim:filetype=cpp
A polygon composed of line segments.
Definition: polyline.hh:20
bool intersect(const Ray< T, N > &ray, const Triangle< T, N > &triangle, T eps)
Check if ray intersects triangle.
Definition: triangle.hh:88
TinyVector< T, 1 > cross(const TinyVector< T, 2 > &a, const TinyVector< T, 2 > &b)
Two-dimensional cross product.
Definition: blitz.hh:570
T length(const blitz::TinyVector< T, N > &x)
Computes vector length without overflow.
Definition: blitz.hh:471
T tetrahedron_signed_volume(const Triangle< T, 3 > &tr)
Signed volume of a tetrahedron with the origin .
Definition: triangle.hh:70
Main namespace.
Definition: convert.hh:9
Three- and two-dimensional plane.
Definition: plane.hh:28