Virtual Testbed
Ship dynamics simulator for extreme conditions
curve_segments.hh
1 #ifndef VTESTBED_GEOMETRY_CURVE_SEGMENTS_HH
2 #define VTESTBED_GEOMETRY_CURVE_SEGMENTS_HH
3 
4 #include <vector>
5 
6 #include <vtestbed/geometry/math.hh>
7 #include <vtestbed/geometry/types.hh>
8 
9 namespace vtb {
10 
11  namespace geometry {
12 
13  template <class T, int N>
15 
16  public:
17  using value_type = T;
18  using reference = value_type&;
19  using const_reference = const value_type&;
20  using pointer = value_type*;
21  using const_pointer = const value_type*;
23  using size_type = size_t;
25 
26  private:
27  container_type _segments;
28  T _min{0}, _max{1};
29  T _length{0};
30 
31  public:
32 
33  inline explicit
34  Curve_segments(const vertex_array& points) {
35  this->chord_length(points);
36  }
37 
38  inline void
39  chord_length(const vertex_array& values) {
40  const auto nvalues = values.size();
41  if (nvalues == 0) {
42  return;
43  }
44  auto& result = this->_segments;
45  result.clear();
46  result.reserve(nvalues-1);
47  T sum{0};
48  auto p0 = values.front();
49  for (size_t i=1; i<nvalues; ++i) {
50  const auto& p1 = values[i];
51  auto s = distance(p0,p1);
52  result.emplace_back(s);
53  sum += s;
54  p0 = p1;
55  }
56  this->_length = sum;
57  this->_max = sum;
58  }
59 
60  inline void
61  uniform(size_type npoints) {
62  if (npoints == 0) {
63  return;
64  }
65  auto& result = this->_segments;
66  result.clear();
67  result.reserve(npoints-1);
68  T delta = T{1}/(npoints-1);
69  for (size_t i=1; i<npoints; ++i) {
70  result.emplace_back(delta);
71  }
72  this->_length = 1;
73  this->_max = 1;
74  }
75 
76  inline void
77  projection(const vertex_array& values, int dim, T z_min, T z_max, T eps=T{}) {
78  using std::abs;
79  using std::max;
80  using std::min;
81  const auto nvalues = values.size();
82  if (nvalues == 0) { return; }
83  auto& result = this->_segments;
84  result.clear();
85  result.reserve(nvalues-1);
86  T sum{0};
87  auto p0 = values.front();
88  for (size_t i=1; i<nvalues; ++i) {
89  const auto& p1 = values[i];
90  const auto z0 = max(z_min, min(z_max, p0(dim)));
91  const auto z1 = max(z_min, min(z_max, p1(dim)));
92  auto s = z1-z0;
93  if (s < eps) { s = distance(p0,p1); }
94  result.emplace_back(s);
95  sum += s;
96  p0 = p1;
97  }
98  this->_length = sum;
99  this->_max = sum;
100  }
101 
102  inline void
103  projection(const vertex_array& values, int dim, T eps=T{}) {
104  this->projection(
105  values,
106  dim,
109  eps
110  );
111  }
112 
113  inline void
114  normalise() {
115  auto& length = this->_length;
116  for (auto& s : this->_segments) {
117  s /= length;
118  }
119  this->_min /= length;
120  this->_max /= length;
121  length = 1;
122  }
123 
124  inline void
125  locate(T& t, size_type& i) const {
126  T new_t = _min + (_max - _min)*t;
127  const auto& segments = this->_segments;
128  const auto nsegments = segments.size();
129  T sum = 0;
130  for (; i < nsegments; ++i) {
131  const auto& s = segments[i];
132  T old_sum = sum;
133  sum += s;
134  if (sum > new_t) {
135  t = (new_t - old_sum) / s;
136  break;
137  }
138  }
139  }
140 
141  inline T
142  locate(size_type i) const {
143  i = std::min(i, this->_segments.size());
144  T sum{};
145  for (size_type j=0; j<i; ++j) { sum += this->_segments[j]; }
146  return sum;
147  }
148 
149  inline void
150  range(T min, T max) {
151  this->_min = min;
152  this->_max = max;
153  }
154 
155  inline T
156  length() const {
157  return this->_length;
158  }
159 
160  inline size_type
161  size() const {
162  return this->_segments.size();
163  }
164 
165  inline reference
166  operator[](size_type i) {
167  return this->_segments[i];
168  }
169 
170  inline const_reference
171  operator[](size_type i) const {
172  return this->_segments[i];
173  }
174 
175  inline pointer
176  begin() {
177  return this->_segments.data();
178  }
179 
180  inline const_pointer
181  begin() const {
182  return this->_segments.data();
183  }
184 
185  inline pointer
186  end() {
187  return this->begin() + this->size();
188  }
189 
190  inline const_pointer
191  end() const {
192  return this->begin() + this->size();
193  }
194 
195  private:
196 
197  };
198 
199  }
200 
201 }
202 
203 #endif // vim:filetype=cpp
Main namespace.
Definition: convert.hh:9