OpenStructure
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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-2011 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 
43  private boost::equality_comparable<Vec3>,
44  private boost::additive<Vec3>,
45  private boost::additive<Vec3, Real>,
46  private boost::multiplicative<Vec3, Real>
47 {
48 public:
50  Vec3(): x(0), y(0), z(0) {}
51 
53  Vec3(Real px, Real py, Real pz): x(px), y(py), z(pz) {}
54 
56  Vec3(const Vec3& v): x(v.x), y(v.y), z(v.z) { }
57 
59  Vec3(const Vec2& v);
60 
62 
66  explicit Vec3(const Vec4& v);
67 
68  explicit Vec3(Real v): x(v), y(v), z(v) { }
69 
71  explicit Vec3(const double v[3]): x(v[0]), y(v[1]), z(v[2]) { }
72 
74  explicit Vec3(const float v[3]): x(v[0]), y(v[1]), z(v[2]) { }
75 
77  Vec3& operator=(const Vec3& v)
78  {
79  x=v.x;
80  y=v.y;
81  z=v.z;
82  return *this;
83  }
84 
86  bool operator==(const Vec3& rhs) const
87  {
88  return x==rhs.x && y==rhs.y && z==rhs.z;
89  }
90 
92  Real& operator[](std::size_t indx)
93  {
94  assert(indx<3);
95  return (&x)[indx];
96  }
97 
99  const Real& operator[](std::size_t indx) const
100  {
101  assert(indx<3);
102  return (&x)[indx];
103  }
104 
105  Real& At(size_t indx) {
106  if (indx>2) {
107  throw std::out_of_range("index must be smaller than 3");
108  }
109  return (&x)[indx];
110  }
111 
112  const Real& At(size_t indx) const {
113  if (indx>2) {
114  throw std::out_of_range("index must be smaller than 3");
115  }
116  return (&x)[indx];
117  }
119  Real GetX() const { return x; }
120  Real GetY() const { return y; }
121  Real GetZ() const { return z; }
122  void SetX(Real v) { x=v; }
123  void SetY(Real v) { y=v; }
124  void SetZ(Real v) { z=v; }
125 
127  Vec3& operator+=(const Vec3& rhs)
128  {
129  x+=rhs.x;
130  y+=rhs.y;
131  z+=rhs.z;
132  return *this;
133  }
134 
135  Vec3& operator+=(Real d)
136  {
137  x+=d;
138  y+=d;
139  z+=d;
140  return *this;
141  }
142 
144  Vec3& operator-=(const Vec3& rhs)
145  {
146  x-=rhs.x;
147  y-=rhs.y;
148  z-=rhs.z;
149  return *this;
150  }
151 
152  Vec3& operator-=(Real d)
153  {
154  x-=d;
155  y-=d;
156  z-=d;
157  return *this;
158  }
160  Vec3 operator-() const
161  {
162  return Vec3(-x, -y, -z);
163  }
164 
166  Vec3& operator*=(Real d)
167  {
168  x*=d;
169  y*=d;
170  z*=d;
171  return *this;
172  }
173 
175  Vec3& operator/=(Real d)
176  {
177  Real one_over_d=Real(1.0)/d;
178  x*=one_over_d;
179  y*=one_over_d;
180  z*=one_over_d;
181  return *this;
182  }
183 
184  Real* Data() {return &x;}
185  const Real* Data() const {return &x;}
186 
190 };
191 
192 inline Vec3 operator/(Real d, const Vec3& v)
193 {
194  Vec3 nrvo(d/v[0],d/v[1],d/v[2]);
195  return nrvo;
196 }
197 
198 inline std::ostream& operator<<(std::ostream& os, const Vec3& v)
199 {
200  os << "[" << v.x << ", " << v.y << ", " << v.z << "]";
201  return os;
202 }
203 } // ns geom
204 
205 namespace geom {
206 
207  // TODO: move to separate file
208  class Mat3;
209 
211  public std::vector<Vec3>,
212  private boost::equality_comparable<Vec3List>,
213  private boost::additive<Vec3List>,
214  private boost::additive<Vec3List, Real>,
215  private boost::multiplicative<Vec3List, Real>
216  {
217 public:
218  typedef std::vector<Vec3> base_type;
220 
221  Vec3List(size_t size, const Vec3& value=Vec3()) : base_type(size, value) {}
222  Vec3List(base_type::iterator b, base_type::iterator e): base_type(b, e) { }
223 
224  Vec3List(const Vec3List& rhs) : base_type(rhs) { }
225  Vec3List(const base_type& rhs) : base_type(rhs) { }
226  Vec3List& operator=(const Vec3List& rhs)
227  {
228  base_type::operator=(rhs);
229  return *this;
230  }
232  bool operator==(const Vec3List& rhs) const
233  {
234  if (this->size()!=rhs.size()){
235  throw std::length_error("Vec3List must have the same size");
236  }
237  for (unsigned int i=0;i!=this->size();++i) {
238  if (((*this)[i])!=((rhs)[i])){
239  return false;
240  }
241  }
242  return true;
243  }
245  Vec3List& operator+=(const Vec3List& rhs)
246  {
247  if (this->size()!=rhs.size()){
248  throw std::length_error("Vec3List must have the same size");
249  }
250  for (unsigned int i=0;i!=this->size();++i) {
251  (*this)[i]+=(rhs)[i];
252  }
253  return *this;
254  }
255  Vec3List& operator+=(Real d)
256  {
257  for (unsigned int i=0;i!=this->size();++i) {
258  (*this)[i]+=d;
259  }
260  return *this;
261  }
262 
264  Vec3List& operator-=(const Vec3List& rhs)
265  {
266  if (this->size()!=rhs.size()){
267  throw std::length_error("Vec3List must have the same size");
268  }
269  for (unsigned int i=0;i!=this->size();++i) {
270  (*this)[i]-=(rhs)[i];
271  }
272  return *this;
273  }
274 
275  Vec3List& operator-=(Real d)
276  {
277  for (unsigned int i=0;i!=this->size();++i) {
278  (*this)[i]-=d;
279  }
280  return *this;
281  }
283  //Vec3List3 operator-() const
284  //{
285  // geom::Vec3List vl;
286  // for (unsigned int i=0;i!=this->size();++i) {
287  // geom::Vec3 v=(*this)[i];
288  // vl.push_back(-v);
289  // }
290  // return vl;
291  //}
292 
294  Vec3List& operator*=(Real d)
295  {
296  for (unsigned int i=0;i!=this->size();++i) {
297  (*this)[i]*=d;
298  }
299  return *this;
300  }
301 
303  Vec3List& operator/=(Real d)
304  {
305  for (unsigned int i=0;i!=this->size();++i) {
306  (*this)[i]/=d;
307  }
308  return *this;
309  }
310 
311  // TODO: move some or all of these to stand-alone functions
312  Mat3 GetInertia() const;
313  Vec3 GetCenter() const;
314  Mat3 GetPrincipalAxes() const;
315  Line3 GetODRLine() const;
316  Plane GetODRPlane() const;
317 
318  //This function fits a cylinder to the positions in Vec3List
319  //It takes as argument an initial guess for the direction and the geometric
320  //center of the atoms. The center is not changed during optimisation as the
321  //best fitting cylinder can be shown to have its axis pass through the geometric center
322  Line3 FitCylinder(const Vec3& initial_direction, const Vec3& center) const;
323 };
324 } // ns geom
325 
326 
327 #include <ost/geom/vec2.hh>
328 #include <ost/geom/vec4.hh>
329 #include <ost/geom/mat3.hh>
330 #include <ost/geom/composite3.hh>
331 
332 namespace geom {
333  inline Vec3::Vec3(const Vec2& v): x(v.x), y(v.y), z(0.0) { }
334 
335  inline Vec3::Vec3(const Vec4& v): x(v.x), y(v.y), z(v.z)
336  {
337  if (std::fabs(v.w)<1e-10) {
338  // it is better to ignore very small w and to simply assume
339  // that this is not a homogeneous coordinate rather than
340  // throwing an exception
341  //throw DivideByZeroException();
342  } else {
343  x/=v.w;
344  y/=v.w;
345  z/=v.w;
346  }
347  }
348 } // namespace geom
349 
350 
351 # endif