vector.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /*
  2. * Copyright 2019 Google Inc. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef CARDBOARD_SDK_UTIL_VECTOR_H_
  17. #define CARDBOARD_SDK_UTIL_VECTOR_H_
  18. #include <array>
  19. namespace cardboard {
  20. // Geometric N-dimensional Vector class.
  21. template <int Dimension> class Vector {
  22. public:
  23. // The default constructor zero-initializes all elements.
  24. Vector();
  25. // Dimension-specific constructors that are passed individual element values.
  26. constexpr Vector(double e0, double e1, double e2);
  27. constexpr Vector(double e0, double e1, double e2, double e3);
  28. // Constructor for a Vector of dimension N from a Vector of dimension N-1 and
  29. // a scalar of the correct type, assuming N is at least 2.
  30. // constexpr Vector(const Vector<Dimension - 1>& v, double s);
  31. void Set(double e0, double e1, double e2); // Only when Dimension == 3.
  32. void Set(double e0, double e1, double e2,
  33. double e3); // Only when Dimension == 4.
  34. // Mutable element accessor.
  35. double& operator[](int index) { return elem_[index]; }
  36. // Element accessor.
  37. double operator[](int index) const { return elem_[index]; }
  38. // Returns a Vector containing all zeroes.
  39. static Vector Zero();
  40. // Self-modifying operators.
  41. void operator+=(const Vector& v) { Add(v); }
  42. void operator-=(const Vector& v) { Subtract(v); }
  43. void operator*=(double s) { Multiply(s); }
  44. void operator/=(double s) { Divide(s); }
  45. // Unary negation operator.
  46. Vector operator-() const { return Negation(); }
  47. // Binary operators.
  48. friend Vector operator+(const Vector& v0, const Vector& v1) { return Sum(v0, v1); }
  49. friend Vector operator-(const Vector& v0, const Vector& v1) { return Difference(v0, v1); }
  50. friend Vector operator*(const Vector& v, double s) { return Scale(v, s); }
  51. friend Vector operator*(double s, const Vector& v) { return Scale(v, s); }
  52. friend Vector operator*(const Vector& v, const Vector& s) { return Product(v, s); }
  53. friend Vector operator/(const Vector& v, double s) { return Divide(v, s); }
  54. // Self-modifying addition.
  55. void Add(const Vector& v);
  56. // Self-modifying subtraction.
  57. void Subtract(const Vector& v);
  58. // Self-modifying multiplication by a scalar.
  59. void Multiply(double s);
  60. // Self-modifying division by a scalar.
  61. void Divide(double s);
  62. // Unary negation.
  63. Vector Negation() const;
  64. // Binary component-wise multiplication.
  65. static Vector Product(const Vector& v0, const Vector& v1);
  66. // Binary component-wise addition.
  67. static Vector Sum(const Vector& v0, const Vector& v1);
  68. // Binary component-wise subtraction.
  69. static Vector Difference(const Vector& v0, const Vector& v1);
  70. // Binary multiplication by a scalar.
  71. static Vector Scale(const Vector& v, double s);
  72. // Binary division by a scalar.
  73. static Vector Divide(const Vector& v, double s);
  74. private:
  75. std::array<double, Dimension> elem_;
  76. };
  77. //------------------------------------------------------------------------------
  78. template <int Dimension> Vector<Dimension>::Vector()
  79. {
  80. for (int i = 0; i < Dimension; i++) {
  81. elem_[i] = 0;
  82. }
  83. }
  84. template <int Dimension>
  85. constexpr Vector<Dimension>::Vector(double e0, double e1, double e2)
  86. : elem_ { e0, e1, e2 }
  87. {
  88. }
  89. template <int Dimension>
  90. constexpr Vector<Dimension>::Vector(double e0, double e1, double e2, double e3)
  91. : elem_ { e0, e1, e2, e3 }
  92. {
  93. }
  94. /*
  95. template <>
  96. constexpr Vector<4>::Vector(const Vector<3>& v, double s)
  97. : elem_{v[0], v[1], v[2], s} {}
  98. */
  99. template <int Dimension> void Vector<Dimension>::Set(double e0, double e1, double e2)
  100. {
  101. elem_[0] = e0;
  102. elem_[1] = e1;
  103. elem_[2] = e2;
  104. }
  105. template <int Dimension> void Vector<Dimension>::Set(double e0, double e1, double e2, double e3)
  106. {
  107. elem_[0] = e0;
  108. elem_[1] = e1;
  109. elem_[2] = e2;
  110. elem_[3] = e3;
  111. }
  112. template <int Dimension> Vector<Dimension> Vector<Dimension>::Zero()
  113. {
  114. Vector<Dimension> v;
  115. return v;
  116. }
  117. template <int Dimension> void Vector<Dimension>::Add(const Vector& v)
  118. {
  119. for (int i = 0; i < Dimension; i++) {
  120. elem_[i] += v[i];
  121. }
  122. }
  123. template <int Dimension> void Vector<Dimension>::Subtract(const Vector& v)
  124. {
  125. for (int i = 0; i < Dimension; i++) {
  126. elem_[i] -= v[i];
  127. }
  128. }
  129. template <int Dimension> void Vector<Dimension>::Multiply(double s)
  130. {
  131. for (int i = 0; i < Dimension; i++) {
  132. elem_[i] *= s;
  133. }
  134. }
  135. template <int Dimension> void Vector<Dimension>::Divide(double s)
  136. {
  137. for (int i = 0; i < Dimension; i++) {
  138. elem_[i] /= s;
  139. }
  140. }
  141. template <int Dimension> Vector<Dimension> Vector<Dimension>::Negation() const
  142. {
  143. Vector<Dimension> ret;
  144. for (int i = 0; i < Dimension; i++) {
  145. ret.elem_[i] = -elem_[i];
  146. }
  147. return ret;
  148. }
  149. template <int Dimension>
  150. Vector<Dimension> Vector<Dimension>::Product(const Vector& v0, const Vector& v1)
  151. {
  152. Vector<Dimension> ret;
  153. for (int i = 0; i < Dimension; i++) {
  154. ret.elem_[i] = v0[i] * v1[i];
  155. }
  156. return ret;
  157. }
  158. template <int Dimension>
  159. Vector<Dimension> Vector<Dimension>::Sum(const Vector& v0, const Vector& v1)
  160. {
  161. Vector<Dimension> ret;
  162. for (int i = 0; i < Dimension; i++) {
  163. ret.elem_[i] = v0[i] + v1[i];
  164. }
  165. return ret;
  166. }
  167. template <int Dimension>
  168. Vector<Dimension> Vector<Dimension>::Difference(const Vector& v0, const Vector& v1)
  169. {
  170. Vector<Dimension> ret;
  171. for (int i = 0; i < Dimension; i++) {
  172. ret.elem_[i] = v0[i] - v1[i];
  173. }
  174. return ret;
  175. }
  176. template <int Dimension> Vector<Dimension> Vector<Dimension>::Scale(const Vector& v, double s)
  177. {
  178. Vector<Dimension> ret;
  179. for (int i = 0; i < Dimension; i++) {
  180. ret.elem_[i] = v[i] * s;
  181. }
  182. return ret;
  183. }
  184. template <int Dimension> Vector<Dimension> Vector<Dimension>::Divide(const Vector& v, double s)
  185. {
  186. Vector<Dimension> ret;
  187. for (int i = 0; i < Dimension; i++) {
  188. ret.elem_[i] = v[i] / s;
  189. }
  190. return ret;
  191. }
  192. typedef Vector<3> Vector3;
  193. typedef Vector<4> Vector4;
  194. } // namespace cardboard
  195. #endif // CARDBOARD_SDK_UTIL_VECTOR_H_