Virtual Testbed
Ship dynamics simulator for extreme conditions
line_segment.hh
1 #ifndef VTESTBED_GEOMETRY_LINE_SEGMENT_HH
2 #define VTESTBED_GEOMETRY_LINE_SEGMENT_HH
3 
4 #include <array>
5 #include <iosfwd>
6 
7 #include <vtestbed/geometry/plane.hh>
8 #include <vtestbed/geometry/types.hh>
9 #include <vtestbed/geometry/vertex.hh>
10 
11 namespace vtb {
12 
13  namespace geometry {
14 
15  template <class T, int N>
16  class Line_segment: public std::array<Vertex<T,N>,2> {
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 
38  using base_type::base_type;
39  using base_type::operator=;
40  using base_type::operator[];
41 
42  inline
43  Line_segment(const_reference a, const_reference b):
44  base_type{a,b} {}
45 
46  inline bool
47  border_contains(const_reference v) const {
48  return all(this->front() == v) || all(this->back() == v);
49  }
50 
51  inline bool
52  border_contains(const_reference v, scalar_type eps) const {
53  return near(this->front(), v, eps) || near(this->back(), v, eps);
54  }
55 
56  inline bool
57  interior_contains(const_reference v, T eps) const {
58  return !this->border_contains(v) && this->contains(v, eps);
59  }
60 
61  inline bool
62  degenerate(scalar_type eps) const {
63  return near(this->front(), this->back(), eps);
64  }
65 
66  inline void
67  flip() {
68  using std::swap;
69  swap(this->front(), this->back());
70  }
71 
72  inline scalar_type length() const { return distance(this->front(), this->back()); }
73  inline value_type centre() const { return T{0.5}*(this->front()+this->back()); }
74 
75  bool contains(const_reference c, T eps) const;
76 
77  Plane<T,2> plane() const;
78  inline void invert() { std::swap(this->front(), this->back()); }
79 
80  void gnuplot(std::ostream&) const;
81 
82  };
83 
84  template <class T, int N>
85  inline bool
86  near(const Line_segment<T,N>& lhs, const Line_segment<T,N>& rhs, T eps) {
87  return near(lhs.front(), rhs.front(), eps) &&
88  near(lhs.back(), rhs.back(), eps);
89  }
90 
91  template <class T, int N>
92  inline bool
93  operator<(const Line_segment<T,N>& lhs, const Line_segment<T,N>& rhs) {
94  Compare_vertex<T,N> cmp;
95  return cmp(lhs.back(), rhs.front());
96  }
97 
98  template <class T, int N>
99  inline bool
100  operator==(const Line_segment<T,N>& lhs, const Line_segment<T,N>& rhs) {
101  return all(lhs.front() == rhs.front()) &&
102  all(lhs.back() == rhs.back());
103  }
104 
105  template <class T, int N>
106  inline bool
107  operator!=(const Line_segment<T,N>& lhs, const Line_segment<T,N>& rhs) {
108  return !operator==(lhs, rhs);
109  }
110 
111  template <class T, int N>
112  inline Vertex<Plane_position,2>
113  compare(const Plane<T,N> plane, const Line_segment<T,N>& s, T eps) {
114  return {compare(plane, s[0], eps), compare(plane, s[1], eps)};
115  }
116 
117  template <class T, int N>
118  Vertex<T,N>
119  intersection_point(
120  const Plane<T,N>& plane,
121  const Line_segment<T,N>& segment
122  );
123 
124  template <int dim, class T, int N>
125  Vertex<T,N>
126  intersection_point(const Line_segment<T,N>& segment, T level) {
127  const auto& a = segment.front();
128  const auto& b = segment.back();
129  Vertex<T,N> extent = b - a;
130  T s = (level - a(dim)) / extent(dim);
131  return a + s*extent;
132  }
133 
134  template <class T, int N>
135  struct is_figure<Line_segment<T,N>>: public std::true_type {};
136 
137  template <class T, int N>
138  inline Vertex<T,N>
139  centroid(const Line_segment<T,N>& s) { return s.centre(); }
140 
141  }
142 
143 }
144 
145 #endif // vim:filetype=cpp
T operator!=(T... args)
Main namespace.
Definition: convert.hh:9
Three- and two-dimensional plane.
Definition: plane.hh:28