IMP logo
IMP Reference Guide  2.16.0
The Integrative Modeling Platform
Vector3D.h
Go to the documentation of this file.
1 /**
2  * \file IMP/algebra/Vector3D.h \brief Simple 3D vector class.
3  *
4  * Copyright 2007-2021 IMP Inventors. All rights reserved.
5  *
6  */
7 
8 #ifndef IMPALGEBRA_VECTOR_3D_H
9 #define IMPALGEBRA_VECTOR_3D_H
10 
11 #include <IMP/types.h>
12 #include <IMP/base_macros.h>
13 #include <IMP/exception.h>
14 
15 #include <numeric>
16 #include <cmath>
17 
18 #include "VectorD.h"
19 
20 IMPALGEBRA_BEGIN_NAMESPACE
21 
22 /** \name 3D Vectors
23  We provide a specialization of VectorD for 3-space and
24  several additional functions on it.
25  @{
26 */
27 
28 //! Return the vector product (cross product) of two vectors.
29 /** \see Vector3D
30  */
31 inline Vector3D get_vector_product(const Vector3D &p1, const Vector3D &p2) {
32  return Vector3D(p1[1] * p2[2] - p1[2] * p2[1], p1[2] * p2[0] - p1[0] * p2[2],
33  p1[0] * p2[1] - p1[1] * p2[0]);
34 }
35 
36 /* //! Get angle between vectors p1 and p2 (with appropriate sign depending on where */
37 /* //! p2 is in relation to p1) */
38 /* inline Vector3D get_angle(const Vector3D &p1, const Vector3D &p2) { */
39 /* // see wikipedia on great circles - atan formula is numerically more stable */
40 /* // than using acos or asin. */
41 /* double sin_sigma = get_vector_product(p1,p2).get_magnitude(); */
42 /* double cos_sigma = p1*p2; */
43 /* double sigma = atan2(sin_sigma,cos_sigma); */
44 /* return sigma; */
45 /* } */
46 
47 //! Return a vector that is perpendicular to the given vector
48 /** \note This is occasionally referred to in the code as a "vertical" vector.
49  \see Vector3D
50 */
52  unsigned int maxi = 0;
53  if (std::abs(v[1]) > std::abs(v[0])) maxi = 1;
54  if (std::abs(v[2]) > std::abs(v[maxi])) maxi = 2;
55  if (std::abs(v[maxi]) < .0001) {
56  return Vector3D(0.0, 0.0, 0.0);
57  } else {
58  Vector3D ret = get_ones_vector_d<3>();
59  ret[maxi] = (-v[(maxi + 1) % 3] - v[(maxi + 2) % 3]) / v[maxi];
60  IMP_INTERNAL_CHECK(ret * v < .0001, "Vectors are not perpendicular");
61  return ret;
62  }
63 }
64 
65 //! Return the centroid of a set of vectors
66 /** \see Vector3D
67  */
68 inline Vector3D get_centroid(const Vector3Ds &ps) {
69  return std::accumulate(ps.begin(), ps.end(), get_zero_vector_d<3>()) /
70  ps.size();
71 }
72 
73 //! Return the radius of gyration of a set of points
74 /**
75  \see IMP::atom::get_radius_of_gyration()
76  */
77 inline double get_radius_of_gyration(const Vector3Ds &ps) {
78  algebra::Vector3D centroid = get_centroid(ps);
79  double rg = 0;
80  for (unsigned int i = 0; i < ps.size(); i++) {
81  rg += get_squared_distance(ps[i], centroid);
82  }
83  rg /= ps.size();
84  return sqrt(rg);
85 }
86 
87 /** @} */
88 
89 IMPALGEBRA_END_NAMESPACE
90 
91 #endif /* IMPALGEBRA_VECTOR_3D_H */
Basic types used by IMP.
double get_squared_distance(const VectorD< D > &v1, const VectorD< D > &v2)
Compute the squared distance between two vectors.
Definition: VectorD.h:201
Exception definitions and assertions.
A more IMP-like version of the std::vector.
Definition: Vector.h:40
#define IMP_INTERNAL_CHECK(expr, message)
An assertion to check for internal errors in IMP. An IMP::ErrorException will be thrown.
Definition: check_macros.h:139
Vector3D get_vector_product(const Vector3D &p1, const Vector3D &p2)
Return the vector product (cross product) of two vectors.
Definition: Vector3D.h:31
Simple D vector class.
double get_radius_of_gyration(const Vector3Ds &ps)
Return the radius of gyration of a set of points.
Definition: Vector3D.h:77
Vector3D get_centroid(const Vector3Ds &ps)
Return the centroid of a set of vectors.
Definition: Vector3D.h:68
VectorD< 3 > Vector3D
Definition: VectorD.h:421
Vector3D get_orthogonal_vector(const Vector3D &v)
Return a vector that is perpendicular to the given vector.
Definition: Vector3D.h:51
Various general useful macros for IMP.