vec3.h 4.67 KB
Newer Older
Martin Reinecke's avatar
more    
Martin Reinecke committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*
 *  This file is part of libcxxsupport.
 *
 *  libcxxsupport is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  libcxxsupport is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with libcxxsupport; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

/*
 *  libcxxsupport is being developed at the Max-Planck-Institut fuer Astrophysik
 *  and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
 *  (DLR).
 */

/*! \file vec3.h
 *  Class representing 3D cartesian vectors
 *
28
 *  Copyright (C) 2003-2020 Max-Planck-Society
Martin Reinecke's avatar
more    
Martin Reinecke committed
29
30
31
 *  \author Martin Reinecke
 */

Martin Reinecke's avatar
Martin Reinecke committed
32
33
#ifndef DUCC0_VEC3_H
#define DUCC0_VEC3_H
Martin Reinecke's avatar
more    
Martin Reinecke committed
34
35
36
37

#include <cmath>
#include <iostream>

Martin Reinecke's avatar
Martin Reinecke committed
38
namespace ducc0 {
Martin Reinecke's avatar
more    
Martin Reinecke committed
39
40
41
42
43

/*! \defgroup vec3group 3D vectors */
/*! \{ */

/*! Class representing a 3D cartesian vector. */
44
template<typename T> class vec3_t
Martin Reinecke's avatar
more    
Martin Reinecke committed
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
  {
  public:
    T x, /*!< x-coordinate */
      y, /*!< y-coordinate */
      z; /*!< z-coordinate */

    /*! Default constructor. Does not initialize \a x, \a y, and \a z. */
    vec3_t () {}
    /*! Creates a vector with the coordinates \a xc, \a yc, and \a zc. */
    vec3_t (T xc, T yc, T zc)
      : x(xc), y(yc), z(zc) {}
    template<typename T2> explicit vec3_t (const vec3_t<T2> &orig)
      : x(orig.x), y(orig.y), z(orig.z) {}

    /*! Sets the vector components to \a xc, \a yc, and \a zc. */
    void Set (T xc, T yc, T zc)
      { x=xc; y=yc; z=zc; }
    /*! Creates a unit vector from a z coordinate and an azimuthal angle. */
    void set_z_phi (T z_, T phi)
      {
      T sintheta = std::sqrt((T(1)-z_)*(T(1)+z_));
      x = sintheta*std::cos(phi);
      y = sintheta*std::sin(phi);
      z = z_;
      }

    /*! Normalizes the vector to length 1. */
    void Normalize ()
      {
      T l = T(1)/std::sqrt (x*x + y*y + z*z);
      x*=l; y*=l; z*=l;
      }

    vec3_t Norm() const
      {
      vec3_t res(*this);
      res.Normalize();
      return res;
      }

    /*! Returns the length of the vector. */
    T Length () const
87
      { return std::sqrt (x*x + y*y + z*z); }
Martin Reinecke's avatar
more    
Martin Reinecke committed
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150

    /*! Returns the squared length of the vector. */
    T SquaredLength () const
      { return (x*x + y*y + z*z); }
    /*! Returns the vector with the signs of all coordinates flipped. */
    const vec3_t operator- () const
      { return vec3_t (-x, -y, -z); }
    /*! Flips the signs of all coordinates. */
    void Flip ()
      { x=-x; y=-y; z=-z; }
    /*! Returns (\a *this + \a vec). */
    const vec3_t operator+ (const vec3_t &vec) const
      { return vec3_t (x+vec.x, y+vec.y, z+vec.z); }
    /*! Adds \a vec to \a *this. */
    vec3_t &operator+= (const vec3_t &vec)
      { x+=vec.x; y+=vec.y; z+=vec.z; return *this; }
    /*! Returns (\a *this - \a vec). */
    const vec3_t operator- (const vec3_t &vec) const
      { return vec3_t (x-vec.x, y-vec.y, z-vec.z); }
    /*! Subtracts \a vec from \a *this. */
    vec3_t &operator-= (const vec3_t &vec)
      { x-=vec.x; y-=vec.y; z-=vec.z; return *this; }
    /*! Returns the vector scaled by \a fact. */
    const vec3_t operator* (T fact) const
      { return vec3_t (x*fact, y*fact, z*fact); }
    /*! Returns the vector scaled by \a 1/fact. */
    const vec3_t operator/ (T fact) const
      { T xfact = T(1)/fact; return vec3_t (x*xfact, y*xfact, z*xfact); }
    /*! Scales the vector by \a fact. */
    vec3_t &operator*= (T fact)
      { x*=fact; y*=fact; z*=fact; return *this; }
  };

/*! Returns the dot product of \a v1 and \a v2.
    \relates vec3_t */
template<typename T> inline T dotprod(const vec3_t<T> &v1, const vec3_t<T> &v2)
  { return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z; }

/*! Returns the cross product of \a a and \a b.
    \relates vec3_t */
template<typename T> inline vec3_t<T> crossprod
  (const vec3_t<T> &a, const vec3_t<T> &b)
  { return vec3_t<T>(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x); }

/*! Writes \a v to \a os.
    \relates vec3_t */
template<typename T> inline std::ostream &operator<<
  (std::ostream &os, const vec3_t<T> &v)
  {
  os << v.x << ", " << v.y << ", " << v.z << std::endl;
  return os;
  }

/*! Specialisation of vec3_t for 64-bit floating point components */
using vec3 = vec3_t<double>;
/*! Specialisation of vec3_t for 32-bit floating point components */
using vec3f = vec3_t<float>;

/*! \} */

}

#endif