Shiokaze Framework
A research-oriented fluid solver for computer graphics
vec.h
Go to the documentation of this file.
1 /*
2 ** vec.h
3 **
4 ** This is part of Shiokaze, a research-oriented fluid solver for computer graphics.
5 ** Created by Ryoichi Ando <rand@nii.ac.jp> on Dec 29, 2017.
6 **
7 ** Permission is hereby granted, free of charge, to any person obtaining a copy of
8 ** this software and associated documentation files (the "Software"), to deal in
9 ** the Software without restriction, including without limitation the rights to use,
10 ** copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
11 ** Software, and to permit persons to whom the Software is furnished to do so,
12 ** subject to the following conditions:
13 **
14 ** The above copyright notice and this permission notice shall be included in all copies
15 ** or substantial portions of the Software.
16 **
17 ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
18 ** INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
19 ** PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 ** HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
21 ** CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
22 ** OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24 //
25 #ifndef SHKZ_VEC_H
26 #define SHKZ_VEC_H
27 //
28 #include <cmath>
29 #include <ostream>
30 #include <cassert>
31 #include <shiokaze/core/common.h>
32 //
34 //
36 template <class T, unsigned D> struct vec {
39  //
44  T v[D];
49  vec() {
50  for( unsigned dim=0; dim<D; ++dim ) this->v[dim] = T();
51  }
58  template<class Y> vec( const Y *v ) {
59  for( unsigned dim=0; dim<D; ++dim ) this->v[dim] = v[dim];
60  }
67  template<class Y> vec( const vec<Y,D> &v) {
68  for( unsigned dim=0; dim<D; ++dim ) this->v[dim] = v.v[dim];
69  }
76  vec( T v ) {
77  for( unsigned dim=0; dim<D; ++dim ) this->v[dim] = v;
78  }
87  vec( T x, T y ) {
88  assert( D == 2 );
89  v[0] = x; v[1] = y;
90  }
101  vec( T x, T y, T z ) {
102  assert( D == 3 );
103  v[0] = x; v[1] = y; v[2] = z;
104  }
113  const T &operator[](unsigned idx) const {
114  return v[idx];
115  }
124  T &operator[](unsigned idx) {
125  return v[idx];
126  }
133  bool empty() const {
134  for( unsigned dim=0; dim<D; ++dim ) if( v[dim] ) return false;
135  return true;
136  }
143  bool operator==(const vec &v) const {
144  for( unsigned dim=0; dim<D; ++dim ) if( this->v[dim] != v[dim]) return false;
145  return true;
146  }
153  bool operator!=(const vec &v) const {
154  return ! (*this == v);
155  }
164  template<class Y> vec<T,D> operator+(const vec<Y,D> &v) const {
165  struct vec result(*this);
166  for( unsigned dim=0; dim<D; ++dim ) result[dim] += v[dim];
167  return result;
168  }
177  template<class Y> vec<T,D> operator-(const vec<Y,D> &v) const {
178  struct vec result(*this);
179  for( unsigned dim=0; dim<D; ++dim ) result[dim] -= v[dim];
180  return result;
181  }
188  template<class Y> void operator+=(const vec<Y,D> &v) {
189  for( unsigned dim=0; dim<D; ++dim ) this->v[dim] += v[dim];
190  }
197  template<class Y> void operator-=(const vec<Y,D> &v) {
198  for( unsigned dim=0; dim<D; ++dim ) this->v[dim] -= v[dim];
199  }
208  template<class Y> vec operator*(Y s) const {
209  struct vec result(*this);
210  for( unsigned dim=0; dim<D; ++dim ) result[dim] *= s;
211  return result;
212  }
221  template<class Y> vec operator/(Y s) const {
222  struct vec result(*this);
223  for( unsigned dim=0; dim<D; ++dim ) result[dim] /= s;
224  return result;
225  }
232  template<class Y> void operator*=(Y s) {
233  for( unsigned dim=0; dim<D; ++dim ) v[dim] *= s;
234  }
241  template<class Y> void operator/=(Y s) {
242  for( unsigned dim=0; dim<D; ++dim ) v[dim] /= s;
243  }
252  template<class Y> T operator*(vec<Y,D> v) const {
253  T result = T();
254  for( unsigned dim=0; dim<D; ++dim ) result += this->v[dim]*v[dim];
255  return result;
256  }
263  double norm2() const {
264  double result = T();
265  for( unsigned dim=0; dim<D; ++dim ) result += this->v[dim]*this->v[dim];
266  return result;
267  }
274  double norm_inf() const {
275  double result = T();
276  for( unsigned dim=0; dim<D; ++dim ) result = std::max(result,(double)std::abs(this->v[dim]));
277  return result;
278  }
285  double len() const {
286  return sqrt(norm2());
287  }
294  vec normal() const {
295  vec copy = *this;
296  copy.normalize();
297  return copy;
298  }
303  bool normalize() {
304  T length = len();
305  if( length ) {
306  for( unsigned dim=0; dim<D; ++dim ) v[dim] /= length;
307  }
308  return length > 0.0;
309  }
316  vec rotate90() const {
317  assert( D == 2 );
318  struct vec result;
319  result[0] = -v[1];
320  result[1] = v[0];
321  return result;
322  }
331  template<class Y=double> T cross2(const vec<Y,2> &r) const {
332  assert( D == 2 );
333  return v[0]*r[1]-v[1]*r[0];
334  }
343  template<class Y=double> vec<T,3> cross(const vec<Y,3> &r) const {
344  assert( D == 3 );
345  return vec<T,3>(v[1]*r[2]-v[2]*r[1],v[2]*r[0]-v[0]*r[2],v[0]*r[1]-v[1]*r[0]);
346  }
353  template<class Y=double> vec<Y,D> cell() const {
354  vec<Y,D> result;
355  for( int dim=0; dim<D; ++dim ) result[dim] = v[dim]+0.5;
356  return result;
357  }
364  template<class Y=double> vec<Y,D> nodal() const {
365  vec<Y,D> result;
366  for( int dim=0; dim<D; ++dim ) result[dim] = v[dim];
367  return result;
368  }
377  template<class Y=double> vec<Y,D> face( int dim ) const {
378  vec<Y,D> result;
379  for( int _dim=0; _dim<D; ++_dim ) result[_dim] = v[_dim]+0.5*(dim!=_dim);
380  return result;
381  }
390  template<class Y=double> vec<Y,D> edge( int dim ) const {
391  assert( D == 3 );
392  return vec<Y,3>(v[0]+0.5*(dim==0),v[1]+0.5*(dim==1),v[2]+0.5*(dim==2));
393  }
394 };
395 template <class T, class Y> static inline T operator^(const vec<T,2> &l, const vec<Y,2> &r) {
396  return l.cross2(r);
397 }
398 template <class T, class Y> static inline vec<T,3> operator^(const vec<T,3> &l, const vec<Y,3> &r) {
399  return l.cross(r);
400 }
401 template <class Y, class T, unsigned D> static inline vec<T,D> operator*(Y s, const vec<T,D> &vec) {
402  return vec*s;
403 }
404 template <class T, unsigned D> static inline vec<T,D> operator-(const vec<T,D> &v) {
405  return -1.0 * v;
406 }
407 //
408 template <class T> using vec2 = vec<T,2>;
409 template <class T> using vec3 = vec<T,3>;
410 //
411 using vec2r = vec2<Real>;
412 using vec2f = vec2<float>;
413 using vec2d = vec2<double>;
414 using vec2i = vec2<int>;
415 using vec3r = vec3<Real>;
416 using vec3f = vec3<float>;
417 using vec3d = vec3<double>;
418 using vec3i = vec3<int>;
419 //
421 #endif
vec::operator==
bool operator==(const vec &v) const
Get if the vector is equal to the input vector.
Definition: vec.h:143
vec::cross
vec< T, 3 > cross(const vec< Y, 3 > &r) const
Compute the cross product for three dimensions.
Definition: vec.h:343
vec::cross2
T cross2(const vec< Y, 2 > &r) const
Compute the cross product for two dimensions.
Definition: vec.h:331
vec::operator[]
const T & operator[](unsigned idx) const
Get the value at a specified dimension.
Definition: vec.h:113
vec::empty
bool empty() const
Get if all the elements in the vector is empty.
Definition: vec.h:133
vec::operator-
vec< T, D > operator-(const vec< Y, D > &v) const
Subtract a vector.
Definition: vec.h:177
vec::operator-=
void operator-=(const vec< Y, D > &v)
Subtract a vector.
Definition: vec.h:197
vec::edge
vec< Y, D > edge(int dim) const
Compute the position of the center of edge position from the index space.
Definition: vec.h:390
vec::vec
vec(T x, T y, T z)
Constructor for three dimensional vector.
Definition: vec.h:101
vec::v
T v[D]
Vector value array.
Definition: vec.h:44
vec::operator*
vec operator*(Y s) const
Multiply a value.
Definition: vec.h:208
vec::rotate90
vec rotate90() const
Rotate vector 90 degrees counterclockwise.
Definition: vec.h:316
vec::norm_inf
double norm_inf() const
Compute L-inf norm.
Definition: vec.h:274
vec::len
double len() const
Compute L1 norm.
Definition: vec.h:285
vec::operator[]
T & operator[](unsigned idx)
Get the reference to the value at a specified dimension.
Definition: vec.h:124
vec::normal
vec normal() const
Compute normalized vector.
Definition: vec.h:294
SHKZ_BEGIN_NAMESPACE
#define SHKZ_BEGIN_NAMESPACE
Name space beggining definition for shiokaze.
Definition: common.h:39
vec::vec
vec(T x, T y)
Constructor for two dimensional vector.
Definition: vec.h:87
vec::normalize
bool normalize()
Normaliz vector.
Definition: vec.h:303
vec::vec
vec(T v)
Constructor.
Definition: vec.h:76
vec::face
vec< Y, D > face(int dim) const
Compute the position of the center of face position from the index space.
Definition: vec.h:377
vec::nodal
vec< Y, D > nodal() const
Compute the position of the nodal position from the index space.
Definition: vec.h:364
vec::operator+
vec< T, D > operator+(const vec< Y, D > &v) const
Add a vector.
Definition: vec.h:164
vec::operator!=
bool operator!=(const vec &v) const
Get if the vector is not equal to the input vector.
Definition: vec.h:153
vec::vec
vec(const vec< Y, D > &v)
Copy constructor.
Definition: vec.h:67
common.h
vec::operator/
vec operator/(Y s) const
Divide by a value.
Definition: vec.h:221
vec::norm2
double norm2() const
Compute L2 norm.
Definition: vec.h:263
vec
Fixed sized vector structure.
Definition: vec.h:38
vec::operator*=
void operator*=(Y s)
Multiply a value.
Definition: vec.h:232
SHKZ_END_NAMESPACE
#define SHKZ_END_NAMESPACE
Name space end definition for shiokaze.
Definition: common.h:44
vec::vec
vec()
Default constructor.
Definition: vec.h:49
vec::operator+=
void operator+=(const vec< Y, D > &v)
Add a vector.
Definition: vec.h:188
vec::operator/=
void operator/=(Y s)
Divide by a value.
Definition: vec.h:241
vec::cell
vec< Y, D > cell() const
Compute the position of the center of a cell from the index space.
Definition: vec.h:353
vec::vec
vec(const Y *v)
Copy constructor.
Definition: vec.h:58
vec::operator*
T operator*(vec< Y, D > v) const
Compute the dot product.
Definition: vec.h:252