OpenStructure
vec3.hh
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
2 // This file is part of the OpenStructure project <www.openstructure.org>
3 //
4 // Copyright (C) 2008-2020 by the OpenStructure authors
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License as published by the Free
8 // Software Foundation; either version 3.0 of the License, or (at your option)
9 // any later version.
10 // This library is distributed in the hope that it will be useful, but WITHOUT
11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 // details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with this library; if not, write to the Free Software Foundation, Inc.,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 //------------------------------------------------------------------------------
19 #ifndef GEOM_VEC3_H
20 #define GEOM_VEC3_H
21 
22 #include <stdexcept>
23 #include <cassert>
24 #include <cstddef> // for size_t
25 #include <ostream>
26 #include <vector>
27 #include <boost/operators.hpp>
28 
29 
30 #include <ost/config.hh>
32 #include <ost/geom/exc.hh>
33 namespace geom {
34 
35 // fw decl
36 class Vec2;
37 class Vec4;
38 class Line3;
39 class Plane;
40 class Mat4;
41 
44  private boost::equality_comparable<Vec3>,
45  private boost::additive<Vec3>,
46  private boost::additive<Vec3, Real>,
47  private boost::multiplicative<Vec3, Real>
48 {
49 public:
51  Vec3(): x(0), y(0), z(0) {}
52 
54  Vec3(Real px, Real py, Real pz): x(px), y(py), z(pz) {}
55 
57  Vec3(const Vec3& v): x(v.x), y(v.y), z(v.z) { }
58 
60  Vec3(const Vec2& v);
61 
63 
67  explicit Vec3(const Vec4& v);
68 
69  explicit Vec3(Real v): x(v), y(v), z(v) { }
70 
72  explicit Vec3(const double v[3]): x(v[0]), y(v[1]), z(v[2]) { }
73 
75  explicit Vec3(const float v[3]): x(v[0]), y(v[1]), z(v[2]) { }
76 
77  /* The "=" operator for Vec3 gives the "maybe-uninitialize" warning in
78  combination with GenericPropValue with GCC when optimisation is turned on.
79  GenericPropValue is implemented via boost::variant which may confuse GCC
80  tracking variables through the compilation process. As boost::variant is
81  able to search for a "=" operator of different type if no direct match is
82  provided, maybe GCC mixes the Real and Vec3 operators where Real used for
83  Vec3 would indeed lack the y and z component. According to the GCC manual,
84  the "maybe-uninitialize" warnings are prone to produce false positives.
85  There is actually an initiative to get rid of them.
86 
87  We ignore them for this particular case by saving the current diagnostic
88  settings (push), disabling the warning in the diagnostics
89  (ignored "-Wmaybe-uninitialized") and afterwards restoring the old
90  diagnostics context (pop).
91  */
92  #pragma GCC diagnostic push
93  #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
95  Vec3& operator=(const Vec3& v)
96  {
97  x=v.x;
98  y=v.y;
99  z=v.z;
100  return *this;
101  }
102  #pragma GCC diagnostic pop
103 
105  bool operator==(const Vec3& rhs) const
106  {
107  return x==rhs.x && y==rhs.y && z==rhs.z;
108  }
109 
111  Real& operator[](std::size_t indx)
112  {
113  assert(indx<3);
114  return (&x)[indx];
115  }
116 
118  const Real& operator[](std::size_t indx) const
119  {
120  assert(indx<3);
121  return (&x)[indx];
122  }
123 
124  Real& At(size_t indx) {
125  if (indx>2) {
126  throw std::out_of_range("index must be smaller than 3");
127  }
128  return (&x)[indx];
129  }
130 
131  const Real& At(size_t indx) const {
132  if (indx>2) {
133  throw std::out_of_range("index must be smaller than 3");
134  }
135  return (&x)[indx];
136  }
138  Real GetX() const { return x; }
139  Real GetY() const { return y; }
140  Real GetZ() const { return z; }
141  void SetX(Real v) { x=v; }
142  void SetY(Real v) { y=v; }
143  void SetZ(Real v) { z=v; }
144 
146  Vec3& operator+=(const Vec3& rhs)
147  {
148  x+=rhs.x;
149  y+=rhs.y;
150  z+=rhs.z;
151  return *this;
152  }
153 
155  {
156  x+=d;
157  y+=d;
158  z+=d;
159  return *this;
160  }
161 
163  Vec3& operator-=(const Vec3& rhs)
164  {
165  x-=rhs.x;
166  y-=rhs.y;
167  z-=rhs.z;
168  return *this;
169  }
170 
172  {
173  x-=d;
174  y-=d;
175  z-=d;
176  return *this;
177  }
179  Vec3 operator-() const
180  {
181  return Vec3(-x, -y, -z);
182  }
183 
186  {
187  x*=d;
188  y*=d;
189  z*=d;
190  return *this;
191  }
192 
195  {
196  Real one_over_d=Real(1.0)/d;
197  x*=one_over_d;
198  y*=one_over_d;
199  z*=one_over_d;
200  return *this;
201  }
202 
203  Real* Data() {return &x;}
204  const Real* Data() const {return &x;}
205 
209 };
210 
211 inline Vec3 operator/(Real d, const Vec3& v)
212 {
213  Vec3 nrvo(d/v[0],d/v[1],d/v[2]);
214  return nrvo;
215 }
216 
217 // The following operator is among other things used to write vector
218 // data into info files. If its format is changed, the string to
219 // vector type cast in item_type_cast.hh has to be changed
220 // accordingly.
221 inline std::ostream& operator<<(std::ostream& os, const Vec3& v)
222 {
223  os << "[" << v.x << ", " << v.y << ", " << v.z << "]";
224  return os;
225 }
226 } // ns geom
227 
228 namespace geom {
229 
230  // TODO: move to separate file
231  class Mat3;
232 
234  public std::vector<Vec3>,
235  private boost::equality_comparable<Vec3List>,
236  private boost::additive<Vec3List>,
237  private boost::additive<Vec3List, Real>,
238  private boost::multiplicative<Vec3List, Real>
239  {
240 public:
241  typedef std::vector<Vec3> base_type;
243 
244  Vec3List(size_t size, const Vec3& value=Vec3()) : base_type(size, value) {}
245  Vec3List(base_type::iterator b, base_type::iterator e): base_type(b, e) { }
246 
247  Vec3List(const Vec3List& rhs) : base_type(rhs) { }
248  Vec3List(const base_type& rhs) : base_type(rhs) { }
250  {
251  base_type::operator=(rhs);
252  return *this;
253  }
255  bool operator==(const Vec3List& rhs) const
256  {
257  if (this->size()!=rhs.size()){
258  throw std::length_error("Vec3List must have the same size");
259  }
260  for (unsigned int i=0;i!=this->size();++i) {
261  if (((*this)[i])!=((rhs)[i])){
262  return false;
263  }
264  }
265  return true;
266  }
269  {
270  if (this->size()!=rhs.size()){
271  throw std::length_error("Vec3List must have the same size");
272  }
273  for (unsigned int i=0;i!=this->size();++i) {
274  (*this)[i]+=(rhs)[i];
275  }
276  return *this;
277  }
279  {
280  for (unsigned int i=0;i!=this->size();++i) {
281  (*this)[i]+=d;
282  }
283  return *this;
284  }
285 
288  {
289  if (this->size()!=rhs.size()){
290  throw std::length_error("Vec3List must have the same size");
291  }
292  for (unsigned int i=0;i!=this->size();++i) {
293  (*this)[i]-=(rhs)[i];
294  }
295  return *this;
296  }
297 
299  {
300  for (unsigned int i=0;i!=this->size();++i) {
301  (*this)[i]-=d;
302  }
303  return *this;
304  }
306  //Vec3List3 operator-() const
307  //{
308  // geom::Vec3List vl;
309  // for (unsigned int i=0;i!=this->size();++i) {
310  // geom::Vec3 v=(*this)[i];
311  // vl.push_back(-v);
312  // }
313  // return vl;
314  //}
315 
318  {
319  for (unsigned int i=0;i!=this->size();++i) {
320  (*this)[i]*=d;
321  }
322  return *this;
323  }
324 
327  {
328  for (unsigned int i=0;i!=this->size();++i) {
329  (*this)[i]/=d;
330  }
331  return *this;
332  }
333 
334  // TODO: move some or all of these to stand-alone functions
335  Mat3 GetInertia() const;
336  Vec3 GetCenter() const;
338  Line3 GetODRLine() const;
340  void ApplyTransform(const Mat4& m);
342  Real GetRMSD(const Vec3List& other) const;
343  Real GetGDTHA(const Vec3List& other, bool norm=true) const;
344  Real GetGDTTS(const Vec3List& other, bool norm=true) const;
345  Real GetGDT(const Vec3List& other, Real thresh, bool norm=true) const;
346  Real GetMinDist(const Vec3List& other) const;
347  bool IsWithin(const Vec3List& other, Real dist) const;
348 
349  //This function fits a cylinder to the positions in Vec3List
350  //It takes as argument an initial guess for the direction.
351  //The center is set to the geometric centero of the atoms
352  //and is not changed during optimisation as the best fitting cylinder
353  //can be shown to have its axis pass through the geometric center
354  //It returns a pair containing a line3, giving the direction of the Cylinder
355  //and a Real containing the radius.
356  std::pair<Line3, Real> FitCylinder(const Vec3& initial_direction) const;
357 };
358 } // ns geom
359 
360 
361 #include <ost/geom/vec2.hh>
362 #include <ost/geom/vec4.hh>
363 #include <ost/geom/mat3.hh>
364 #include <ost/geom/composite3.hh>
365 
366 namespace geom {
367  inline Vec3::Vec3(const Vec2& v): x(v.x), y(v.y), z(0.0) { }
368 
369  inline Vec3::Vec3(const Vec4& v): x(v.x), y(v.y), z(v.z)
370  {
371  if (std::fabs(v.w)<1e-10) {
372  // it is better to ignore very small w and to simply assume
373  // that this is not a homogeneous coordinate rather than
374  // throwing an exception
375  //throw DivideByZeroException();
376  } else {
377  x/=v.w;
378  y/=v.w;
379  z/=v.w;
380  }
381  }
382 } // namespace geom
383 
384 
385 # endif
Line3.
Definition: composite3.hh:39
Three dimensional vector class, using Real precision.
Definition: vec3.hh:48
Vec3 & operator-=(Real d)
Definition: vec3.hh:171
void SetZ(Real v)
Definition: vec3.hh:143
Real y
Definition: vec3.hh:207
Vec3 & operator+=(Real d)
Definition: vec3.hh:154
Vec3(const float v[3])
explicit initialization with an array of floats
Definition: vec3.hh:75
bool operator==(const Vec3 &rhs) const
comparable
Definition: vec3.hh:105
Real z
Definition: vec3.hh:208
Vec3 operator-() const
negateable
Definition: vec3.hh:179
Vec3(Real v)
Definition: vec3.hh:69
Real & At(size_t indx)
Definition: vec3.hh:124
Vec3 & operator*=(Real d)
multipliable
Definition: vec3.hh:185
Real GetZ() const
Definition: vec3.hh:140
Real GetY() const
Definition: vec3.hh:139
Vec3 & operator-=(const Vec3 &rhs)
subtractable op
Definition: vec3.hh:163
Vec3 & operator/=(Real d)
dividable
Definition: vec3.hh:194
Real & operator[](std::size_t indx)
element access
Definition: vec3.hh:111
void SetY(Real v)
Definition: vec3.hh:142
Vec3(const double v[3])
explicit initialization with an array of doubles
Definition: vec3.hh:72
const Real & operator[](std::size_t indx) const
const element access
Definition: vec3.hh:118
Vec3()
Default initialization, all components are set to zero.
Definition: vec3.hh:51
Vec3 & operator=(const Vec3 &v)
assignement op
Definition: vec3.hh:95
const Real & At(size_t indx) const
Definition: vec3.hh:131
Vec3(const Vec3 &v)
copy ctor
Definition: vec3.hh:57
void SetX(Real v)
Definition: vec3.hh:141
const Real * Data() const
Definition: vec3.hh:204
Real * Data()
Definition: vec3.hh:203
Real x
Definition: vec3.hh:206
Vec3(Real px, Real py, Real pz)
Initialization with x, y and z component.
Definition: vec3.hh:54
Vec3 & operator+=(const Vec3 &rhs)
addable op
Definition: vec3.hh:146
Real GetX() const
element access
Definition: vec3.hh:138
Vec3List(const base_type &rhs)
Definition: vec3.hh:248
Plane GetODRPlane() const
Real GetGDTTS(const Vec3List &other, bool norm=true) const
std::vector< Vec3 > base_type
Definition: vec3.hh:241
Vec3List & operator+=(Real d)
Definition: vec3.hh:278
Vec3List(base_type::iterator b, base_type::iterator e)
Definition: vec3.hh:245
Real GetGDT(const Vec3List &other, Real thresh, bool norm=true) const
Real GetGDTHA(const Vec3List &other, bool norm=true) const
Vec3List(size_t size, const Vec3 &value=Vec3())
Definition: vec3.hh:244
bool IsWithin(const Vec3List &other, Real dist) const
Vec3List & operator-=(Real d)
Definition: vec3.hh:298
Vec3 GetCenter() const
Vec3List(const Vec3List &rhs)
Definition: vec3.hh:247
std::pair< Line3, Real > FitCylinder(const Vec3 &initial_direction) const
Vec3List & operator+=(const Vec3List &rhs)
addable op
Definition: vec3.hh:268
Mat3 GetInertia() const
Vec3List & operator/=(Real d)
dividable
Definition: vec3.hh:326
void ApplyTransform(const Mat4 &m)
Mat3 GetPrincipalAxes() const
Real GetRMSD(const Vec3List &other) const
Line3 GetODRLine() const
bool operator==(const Vec3List &rhs) const
comparable
Definition: vec3.hh:255
Vec3List & operator*=(Real d)
negateable
Definition: vec3.hh:317
Vec3List & operator-=(const Vec3List &rhs)
subtractable op
Definition: vec3.hh:287
Real GetMinDist(const Vec3List &other) const
Real GetSummedSquaredDistances(const Vec3List &other) const
Vec3List & operator=(const Vec3List &rhs)
Definition: vec3.hh:249
Real w
Definition: vec4.hh:193
#define DLLEXPORT_OST_GEOM
float Real
Definition: base.hh:44
Vec2 operator/(Real d, const Vec2 &v)
Definition: vec2.hh:171
std::ostream & operator<<(std::ostream &os, const AlignedCuboid &c)