opensurgsim
Vector.h
Go to the documentation of this file.
1 // This file is a part of the OpenSurgSim project.
2 // Copyright 2012-2015, SimQuest Solutions Inc.
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 
18 
19 #ifndef SURGSIM_MATH_VECTOR_H
20 #define SURGSIM_MATH_VECTOR_H
21 
22 #include <array>
23 #include <vector>
24 
25 #include <Eigen/Core>
26 #include <Eigen/Geometry>
27 
29 
30 namespace SurgSim
31 {
32 namespace Math
33 {
34 
37 typedef Eigen::Matrix<float, 2, 1> Vector2f;
38 
41 typedef Eigen::Matrix<float, 3, 1> Vector3f;
42 
45 typedef Eigen::Matrix<float, 4, 1> Vector4f;
46 
49 typedef Eigen::Matrix<float, 6, 1> Vector6f;
50 
53 typedef Eigen::Matrix<double, 2, 1> Vector2d;
54 
57 typedef Eigen::Matrix<double, 3, 1> Vector3d;
58 
61 typedef Eigen::Matrix<double, 4, 1> Vector4d;
62 
65 typedef Eigen::Matrix<double, 6, 1> Vector6d;
66 
68 typedef Eigen::Matrix<double, Eigen::Dynamic, 1> Vector;
69 
77 template <class Vector, class SubVector>
78 void addSubVector(const SubVector& subVector, Eigen::Index blockId, Eigen::Index blockSize, Vector* vector)
79 {
80  vector->segment(blockSize * blockId, blockSize) += subVector;
81 }
82 
89 template <class Vector, class SubVector>
90 void addSubVector(const Eigen::Ref<const SubVector>& subVector,
91  const std::vector<size_t>& blockIds, Eigen::Index blockSize, Vector* vector)
92 {
93  const Eigen::Index numBlocks = static_cast<Eigen::Index>(blockIds.size());
94  for (Eigen::Index block = 0; block < numBlocks; ++block)
95  {
96  vector->segment(blockSize * static_cast<Eigen::Index>(blockIds[block]), blockSize) +=
97  subVector.segment(blockSize * block, blockSize);
98  }
99 }
100 
108 template <class Vector, class SubVector>
109 void setSubVector(const SubVector& subVector, Eigen::Index blockId, Eigen::Index blockSize, Vector* vector)
110 {
111  vector->segment(blockSize * blockId, blockSize) = subVector;
112 }
113 
123 template <class Vector>
124 Eigen::VectorBlock<Vector> getSubVector(Vector& vector, Eigen::Index blockId, Eigen::Index blockSize) // NOLINT
125 {
126  return vector.segment(blockSize * blockId, blockSize);
127 }
128 
136 template <class Vector, class SubVector>
137 void getSubVector(const Vector& vector, const std::vector<size_t>& blockIds, Eigen::Index blockSize,
138  SubVector* subVector)
139 {
140  const Eigen::Index numBlocks = static_cast<Eigen::Index>(blockIds.size());
141  for (Eigen::Index block = 0; block < numBlocks; ++block)
142  {
143  subVector->segment(blockSize * block, blockSize) =
144  vector.segment(blockSize * static_cast<Eigen::Index>(blockIds[block]), blockSize);
145  }
146 }
147 
158 template <typename T, int size, int TOpt>
159 Eigen::Matrix<T, size, 1, TOpt> interpolate(
160  const Eigen::Matrix<T, size, 1, TOpt>& previous,
161  const Eigen::Matrix<T, size, 1, TOpt>& next,
162  T t)
163 {
164  return previous + t * (next - previous);
165 }
166 
174 template <class T, int VOpt>
175 bool buildOrthonormalBasis(Eigen::Matrix<T, 3, 1, VOpt>* i,
176  Eigen::Matrix<T, 3, 1, VOpt>* j,
177  Eigen::Matrix<T, 3, 1, VOpt>* k)
178 {
179  SURGSIM_ASSERT(i != nullptr) << "Parameter [in, out] 'i' is a nullptr";
180  SURGSIM_ASSERT(j != nullptr) << "Parameter [out] 'j' is a nullptr";
181  SURGSIM_ASSERT(k != nullptr) << "Parameter [out] 'k' is a nullptr";
182 
183  if (i->isZero())
184  {
185  return false;
186  }
187 
188  i->normalize();
189  *j = i->unitOrthogonal();
190  *k = i->cross(*j);
191 
192  return true;
193 }
194 
202 template <class T, int VOpt>
203 Eigen::Matrix<T, 3, 1, VOpt> robustCrossProduct(const std::array<Eigen::Matrix<T, 3, 1, VOpt>, 2>& p,
204  const std::array<Eigen::Matrix<T, 3, 1, VOpt>, 2>& q,
205  T epsilon)
206 {
207 
208  auto p0p1 = p[1] - p[0];
209  auto p1q0 = q[0] - p[1];
210  auto p0q0 = q[0] - p[0];
211  auto p1q1 = q[1] - p[1];
212  auto pXq = p0p1.cross(p1q0);
213  auto norm = pXq.norm();
214  if (norm < epsilon)
215  {
216  pXq = p0p1.cross(p0q0);
217  norm = pXq.norm();
218  }
219  if (norm < epsilon)
220  {
221  pXq = p0p1.cross(p1q1);
222  norm = pXq.norm();
223  }
224  pXq *= static_cast<T>(1.0 / norm);
225  return pXq;
226 }
227 
228 }; // namespace Math
229 }; // namespace SurgSim
230 
231 #endif // SURGSIM_MATH_VECTOR_H
Eigen::VectorBlock< Vector > getSubVector(Vector &vector, Eigen::Index blockId, Eigen::Index blockSize)
Helper method to access a sub-vector from a vector, for the sake of clarity.
Definition: Vector.h:124
Wraps glewInit() to separate the glew opengl definitions from the osg opengl definitions only imgui n...
Definition: AddRandomSphereBehavior.cpp:36
Eigen::Matrix< double, 4, 1 > Vector4d
A 4D vector of doubles.
Definition: Vector.h:61
Eigen::Matrix< double, 6, 1 > Vector6d
A 6D matrix of doubles.
Definition: Vector.h:65
Eigen::Matrix< float, 3, 1 > Vector3f
A 3D vector of floats.
Definition: Vector.h:41
Eigen::Matrix< T, 3, 1, VOpt > robustCrossProduct(const std::array< Eigen::Matrix< T, 3, 1, VOpt >, 2 > &p, const std::array< Eigen::Matrix< T, 3, 1, VOpt >, 2 > &q, T epsilon)
Calculate the best unit normal we can find in the direction of pXq for one of the endpoints of q...
Definition: Vector.h:203
#define SURGSIM_ASSERT(condition)
Assert that condition is true.
Definition: Assert.h:77
void setSubVector(const SubVector &subVector, Eigen::Index blockId, Eigen::Index blockSize, Vector *vector)
Helper method to set a sub-vector into a vector, for the sake of clarity.
Definition: Vector.h:109
Eigen::Matrix< double, 3, 1 > Vector3d
A 3D vector of doubles.
Definition: Vector.h:57
Eigen::Matrix< float, 4, 1 > Vector4f
A 4D vector of floats.
Definition: Vector.h:45
Eigen::Matrix< double, 2, 1 > Vector2d
A 2D vector of doubles.
Definition: Vector.h:53
Eigen::Matrix< float, 2, 1 > Vector2f
A 2D vector of floats.
Definition: Vector.h:37
Eigen::Matrix< double, Eigen::Dynamic, 1 > Vector
A dynamic size column vector.
Definition: Vector.h:68
Eigen::Matrix< float, 6, 1 > Vector6f
A 6D vector of floats.
Definition: Vector.h:49
The header that provides the assertion API.
void addSubVector(const SubVector &subVector, Eigen::Index blockId, Eigen::Index blockSize, Vector *vector)
Helper method to add a sub-vector into a vector, for the sake of clarity.
Definition: Vector.h:78
bool buildOrthonormalBasis(Eigen::Matrix< T, 3, 1, VOpt > *i, Eigen::Matrix< T, 3, 1, VOpt > *j, Eigen::Matrix< T, 3, 1, VOpt > *k)
Helper method to construct an orthonormal basis (i, j, k) given the 1st vector direction.
Definition: Vector.h:175