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 <cstddef> // for size_t
24 #include <ostream>
25 #include <vector>
26 #include <boost/operators.hpp>
27 
28 
29 #include <ost/config.hh>
31 #include <ost/geom/exc.hh>
32 namespace geom {
33 
34 // fw decl
35 class Vec2;
36 class Vec4;
37 class Line3;
38 class Plane;
39 
42  private boost::equality_comparable<Vec3>,
43  private boost::additive<Vec3>,
44  private boost::additive<Vec3, Real>,
45  private boost::multiplicative<Vec3, Real>
46 {
47 public:
49  Vec3(): x(0), y(0), z(0) {}
50 
52  Vec3(Real px, Real py, Real pz): x(px), y(py), z(pz) {}
53 
55  Vec3(const Vec3& v): x(v.x), y(v.y), z(v.z) { }
56 
58  Vec3(const Vec2& v);
59 
61 
65  explicit Vec3(const Vec4& v);
66 
67  explicit Vec3(Real v): x(v), y(v), z(v) { }
68 
70  explicit Vec3(const double v[3]): x(v[0]), y(v[1]), z(v[2]) { }
71 
73  explicit Vec3(const float v[3]): x(v[0]), y(v[1]), z(v[2]) { }
74 
76  Vec3& operator=(const Vec3& v)
77  {
78  x=v.x;
79  y=v.y;
80  z=v.z;
81  return *this;
82  }
83 
85  bool operator==(const Vec3& rhs) const
86  {
87  return x==rhs.x && y==rhs.y && z==rhs.z;
88  }
89 
91  Real& operator[](std::size_t indx)
92  {
93  if (indx>2) {
94  throw std::out_of_range("Index must be in the range [0-2]");
95  }
96  return (&x)[indx];
97  }
98 
100  const Real& operator[](std::size_t indx) const
101  {
102  if (indx>2) {
103  throw std::out_of_range("Index must be in the range [0-2]");
104  }
105  return (&x)[indx];
106  }
108  Real GetX() const { return x; }
109  Real GetY() const { return y; }
110  Real GetZ() const { return z; }
111  void SetX(Real v) { x=v; }
112  void SetY(Real v) { y=v; }
113  void SetZ(Real v) { z=v; }
114 
116  Vec3& operator+=(const Vec3& rhs)
117  {
118  x+=rhs.x;
119  y+=rhs.y;
120  z+=rhs.z;
121  return *this;
122  }
123 
124  Vec3& operator+=(Real d)
125  {
126  x+=d;
127  y+=d;
128  z+=d;
129  return *this;
130  }
131 
133  Vec3& operator-=(const Vec3& rhs)
134  {
135  x-=rhs.x;
136  y-=rhs.y;
137  z-=rhs.z;
138  return *this;
139  }
140 
141  Vec3& operator-=(Real d)
142  {
143  x-=d;
144  y-=d;
145  z-=d;
146  return *this;
147  }
149  Vec3 operator-() const
150  {
151  return Vec3(-x, -y, -z);
152  }
153 
155  Vec3& operator*=(Real d)
156  {
157  x*=d;
158  y*=d;
159  z*=d;
160  return *this;
161  }
162 
164  Vec3& operator/=(Real d)
165  {
166  Real one_over_d=Real(1.0)/d;
167  x*=one_over_d;
168  y*=one_over_d;
169  z*=one_over_d;
170  return *this;
171  }
172 
173  Real* Data() {return &x;}
174  const Real* Data() const {return &x;}
175 
179 };
180 
181 inline Vec3 operator/(Real d, const Vec3& v)
182 {
183  Vec3 nrvo(d/v[0],d/v[1],d/v[2]);
184  return nrvo;
185 }
186 
187 inline std::ostream& operator<<(std::ostream& os, const Vec3& v)
188 {
189  os << "[" << v.x << ", " << v.y << ", " << v.z << "]";
190  return os;
191 }
192 } // ns geom
193 
194 namespace geom {
195 
196  // TODO: move to separate file
197  class Mat3;
198 
199 class DLLEXPORT_OST_GEOM Vec3List : public std::vector<Vec3> {
200 public:
201  typedef std::vector<Vec3> base_type;
203 
204  Vec3List(size_t size, const Vec3& value=Vec3()) : base_type(size, value) {}
205  Vec3List(base_type::iterator b, base_type::iterator e): base_type(b, e) { }
206 
207  Vec3List(const Vec3List& rhs) : base_type(rhs) { }
208  Vec3List(const base_type& rhs) : base_type(rhs) { }
209  Vec3List& operator=(const Vec3List& rhs)
210  {
211  base_type::operator=(rhs);
212  return *this;
213  }
214 
215  // TODO: move some or all of these to stand-alone functions
216  Mat3 GetInertia() const;
217  Vec3 GetCenter() const;
218  Mat3 GetPrincipalAxes() const;
219  Line3 GetODRLine() const;
220  Plane GetODRPlane() const;
221 
222  //This function fits a cylinder to the positions in Vec3List
223  //It takes as argument an initial guess for the direction and the geometric
224  //center of the atoms. The center is not changed during optimisation as the
225  //best fitting cylinder can be shown to have its axis pass through the geometric center
226  Line3 FitCylinder(const Vec3& initial_direction, const Vec3& center) const;
227 };
228 } // ns geom
229 
230 
231 #include <ost/geom/vec2.hh>
232 #include <ost/geom/vec4.hh>
233 #include <ost/geom/mat3.hh>
234 #include <ost/geom/composite3.hh>
235 
236 namespace geom {
237  inline Vec3::Vec3(const Vec2& v): x(v.x), y(v.y), z(0.0) { }
238 
239  inline Vec3::Vec3(const Vec4& v): x(v.x), y(v.y), z(v.z)
240  {
241  if (std::fabs(v.w)<1e-10) {
242  throw DivideByZeroException();
243  }
244  x/=v.w;
245  y/=v.w;
246  z/=v.w;
247  }
248 } // namespace geom
249 
250 
251 # endif