OpenStructure
vec4.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_VEC4_H
20 #define GEOM_VEC4_H
21 
22 #include <stdexcept>
23 #include <cstddef> // for size_t
24 #include <ostream>
25 
26 #include <boost/operators.hpp>
27 
29 #include <ost/config.hh>
30 
31 namespace geom {
32 
33 // fw decl
34 class Vec2;
35 class Vec3;
36 
37 /*
38  Four dimensional, homogeneous vector class, using Real precision.
39 */
40 class DLLEXPORT Vec4:
41  private boost::equality_comparable<Vec4>,
42  private boost::additive<Vec4>,
43  private boost::additive<Vec4, Real>,
44  private boost::multiplicative<Vec4, Real>
45 {
46 public:
48  Vec4(): x(0), y(0), z(0), w(0) { }
49 
51  Vec4(Real px, Real py, Real pz, Real pw): x(px), y(py), z(pz), w(pw) { }
52 
54  Vec4(const Vec4& v): x(v[0]), y(v[1]), z(v[2]), w(v[3]) { }
55 
57  Vec4(const Vec2& v);
58 
60  Vec4(const Vec3& v);
61 
63  explicit Vec4(const float v[4]): x(v[0]), y(v[1]), z(v[2]), w(v[3]) { }
64 
66  explicit Vec4(const double v[4]): x(v[0]), y(v[1]), z(v[2]), w(v[3]) { }
68  Vec4& operator=(const Vec4& v)
69  {
70  x=v.x;
71  y=v.y;
72  z=v.z;
73  w=v.w;
74  return *this;
75  }
76 
78  bool operator==(const Vec4& rhs) const
79  {
80  return x==rhs.x && y==rhs.y && z==rhs.z && w==rhs.w;
81  }
82 
84  Real& operator[](std::size_t indx)
85  {
86  if (indx>3) {
87  throw std::out_of_range("Index must be in the range [0-3]");
88  }
89  return (&x)[indx];
90  }
91 
93  const Real& operator[](std::size_t indx) const
94  {
95  if (indx>3) {
96  throw std::out_of_range("Index must be in the range [0-3]");
97  }
98  return (&x)[indx];
99  }
101  Real GetX() const { return x; }
102  Real GetY() const { return y; }
103  Real GetZ() const { return z; }
104  Real GetW() const { return w; }
105 
106  void SetX(Real v) { x=v; }
107  void SetY(Real v) { y=v; }
108  void SetZ(Real v) { z=v; }
109  void SetW(Real v) { w=v; }
110 
112  Vec4& operator+=(const Vec4& rhs)
113  {
114  x+=rhs.x;
115  y+=rhs.y;
116  z+=rhs.z;
117  w+=rhs.w;
118  return *this;
119  }
120 
121  Vec4& operator+=(Real d)
122  {
123  x+=d;
124  y+=d;
125  z+=d;
126  w+=d;
127  return *this;
128  }
129 
131  Vec4& operator-=(const Vec4& rhs)
132  {
133  x-=rhs.x;
134  y-=rhs.y;
135  z-=rhs.z;
136  w-=rhs.w;
137  return *this;
138  }
139 
140  Vec4& operator-=(Real d)
141  {
142  x-=d;
143  y-=d;
144  z-=d;
145  w-=d;
146  return *this;
147  }
149  Vec4 operator-() const
150  {
151  return Vec4(-x, -y, -z, -w);
152  }
153 
155  Vec4& operator*=(Real d)
156  {
157  x*=d;
158  y*=d;
159  z*=d;
160  w*=d;
161  return *this;
162  }
163 
165  Vec4& operator/=(Real d)
166  {
167  Real one_over_d=Real(1.0)/d;
168  x*=one_over_d;
169  y*=one_over_d;
170  z*=one_over_d;
171  w*=one_over_d;
172  return *this;
173  }
174 
175  Real* Data() {return &x;}
176  const Real* Data() const {return &x;}
177 
182 };
183 
184 inline Vec4 operator/(Real d, const Vec4& v)
185 {
186  Vec4 nrvo(d/v[0],d/v[1],d/v[2],d/v[3]);
187  return nrvo;
188 }
189 
190 inline std::ostream& operator<<(std::ostream& os, const Vec4& v)
191 {
192  os << "(" << v[0] << "," << v[1] << "," << v[2] << "," << v[3] << ")";
193  return os;
194 }
195 }
196 
197 #include <ost/geom/vec2.hh>
198 #include <ost/geom/vec3.hh>
199 
200 namespace geom {
201 
203 inline Vec4::Vec4(const Vec2& v): x(v.x), y(v.y), z(0), w(1) { }
204 
206 inline Vec4::Vec4(const Vec3& v): x(v.x), y(v.y), z(v.z), w(1.0) { }
207 
208 } // namespace geom
209 
210 # endif