hpp-fcl  3.0.0
HPP fork of FCL -- The Flexible Collision Library
convex.hxx
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2019, CNRS - LAAS
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of Open Source Robotics Foundation nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34 
37 #ifndef HPP_FCL_SHAPE_CONVEX_HXX
38 #define HPP_FCL_SHAPE_CONVEX_HXX
39 
40 #include <set>
41 #include <vector>
42 #include <iostream>
43 
44 namespace hpp {
45 namespace fcl {
46 
47 template <typename PolygonT>
48 Convex<PolygonT>::Convex(std::shared_ptr<std::vector<Vec3f>> points_,
49  unsigned int num_points_,
50  std::shared_ptr<std::vector<PolygonT>> polygons_,
51  unsigned int num_polygons_)
52  : ConvexBase(), polygons(polygons_), num_polygons(num_polygons_) {
53  this->initialize(points_, num_points_);
54  this->fillNeighbors();
55  this->buildSupportWarmStart();
56 }
57 
58 template <typename PolygonT>
60  : ConvexBase(other), num_polygons(other.num_polygons) {
61  if (other.polygons.get()) {
62  polygons.reset(new std::vector<PolygonT>(*(other.polygons)));
63  } else
64  polygons.reset();
65 }
66 
67 template <typename PolygonT>
69 
70 template <typename PolygonT>
71 void Convex<PolygonT>::set(std::shared_ptr<std::vector<Vec3f>> points_,
72  unsigned int num_points_,
73  std::shared_ptr<std::vector<PolygonT>> polygons_,
74  unsigned int num_polygons_) {
75  ConvexBase::set(points_, num_points_);
76 
77  this->num_polygons = num_polygons_;
78  this->polygons = polygons_;
79 
80  this->fillNeighbors();
81  this->buildSupportWarmStart();
82 }
83 
84 template <typename PolygonT>
86  return new Convex(*this);
87 }
88 
89 template <typename PolygonT>
91  typedef typename PolygonT::size_type size_type;
92  typedef typename PolygonT::index_type index_type;
93 
94  Matrix3f C = Matrix3f::Zero();
95 
96  Matrix3f C_canonical;
97  C_canonical << 1 / 60.0, 1 / 120.0, 1 / 120.0, 1 / 120.0, 1 / 60.0, 1 / 120.0,
98  1 / 120.0, 1 / 120.0, 1 / 60.0;
99 
100  if (!(points.get())) {
101  std::cerr
102  << "Error in `Convex::computeMomentofInertia`! Convex has no vertices."
103  << std::endl;
104  return C;
105  }
106  const std::vector<Vec3f>& points_ = *points;
107  if (!(polygons.get())) {
108  std::cerr
109  << "Error in `Convex::computeMomentofInertia`! Convex has no polygons."
110  << std::endl;
111  return C;
112  }
113  const std::vector<PolygonT>& polygons_ = *polygons;
114  for (unsigned int i = 0; i < num_polygons; ++i) {
115  const PolygonT& polygon = polygons_[i];
116 
117  // compute the center of the polygon
118  Vec3f plane_center(0, 0, 0);
119  for (size_type j = 0; j < polygon.size(); ++j)
120  plane_center += points_[polygon[(index_type)j]];
121  plane_center /= polygon.size();
122 
123  // compute the volume of tetrahedron making by neighboring two points, the
124  // plane center and the reference point (zero) of the convex shape
125  const Vec3f& v3 = plane_center;
126  for (size_type j = 0; j < polygon.size(); ++j) {
127  index_type e_first = polygon[static_cast<index_type>(j)];
128  index_type e_second =
129  polygon[static_cast<index_type>((j + 1) % polygon.size())];
130  const Vec3f& v1 = points_[e_first];
131  const Vec3f& v2 = points_[e_second];
132  Matrix3f A;
133  A << v1.transpose(), v2.transpose(),
134  v3.transpose(); // this is A' in the original document
135  C += A.transpose() * C_canonical * A * (v1.cross(v2)).dot(v3);
136  }
137  }
138 
139  return C.trace() * Matrix3f::Identity() - C;
140 }
141 
142 template <typename PolygonT>
144  typedef typename PolygonT::size_type size_type;
145  typedef typename PolygonT::index_type index_type;
146 
147  Vec3f com(0, 0, 0);
148  FCL_REAL vol = 0;
149  if (!(points.get())) {
150  std::cerr << "Error in `Convex::computeCOM`! Convex has no vertices."
151  << std::endl;
152  return com;
153  }
154  const std::vector<Vec3f>& points_ = *points;
155  if (!(polygons.get())) {
156  std::cerr << "Error in `Convex::computeCOM`! Convex has no polygons."
157  << std::endl;
158  return com;
159  }
160  const std::vector<PolygonT>& polygons_ = *polygons;
161  for (unsigned int i = 0; i < num_polygons; ++i) {
162  const PolygonT& polygon = polygons_[i];
163  // compute the center of the polygon
164  Vec3f plane_center(0, 0, 0);
165  for (size_type j = 0; j < polygon.size(); ++j)
166  plane_center += points_[polygon[(index_type)j]];
167  plane_center /= polygon.size();
168 
169  // compute the volume of tetrahedron making by neighboring two points, the
170  // plane center and the reference point (zero) of the convex shape
171  const Vec3f& v3 = plane_center;
172  for (size_type j = 0; j < polygon.size(); ++j) {
173  index_type e_first = polygon[static_cast<index_type>(j)];
174  index_type e_second =
175  polygon[static_cast<index_type>((j + 1) % polygon.size())];
176  const Vec3f& v1 = points_[e_first];
177  const Vec3f& v2 = points_[e_second];
178  FCL_REAL d_six_vol = (v1.cross(v2)).dot(v3);
179  vol += d_six_vol;
180  com += (points_[e_first] + points_[e_second] + plane_center) * d_six_vol;
181  }
182  }
183 
184  return com / (vol * 4); // here we choose zero as the reference
185 }
186 
187 template <typename PolygonT>
189  typedef typename PolygonT::size_type size_type;
190  typedef typename PolygonT::index_type index_type;
191 
192  FCL_REAL vol = 0;
193  if (!(points.get())) {
194  std::cerr << "Error in `Convex::computeVolume`! Convex has no vertices."
195  << std::endl;
196  return vol;
197  }
198  const std::vector<Vec3f>& points_ = *points;
199  if (!(polygons.get())) {
200  std::cerr << "Error in `Convex::computeVolume`! Convex has no polygons."
201  << std::endl;
202  return vol;
203  }
204  const std::vector<PolygonT>& polygons_ = *polygons;
205  for (unsigned int i = 0; i < num_polygons; ++i) {
206  const PolygonT& polygon = polygons_[i];
207 
208  // compute the center of the polygon
209  Vec3f plane_center(0, 0, 0);
210  for (size_type j = 0; j < polygon.size(); ++j)
211  plane_center += points_[polygon[(index_type)j]];
212  plane_center /= polygon.size();
213 
214  // compute the volume of tetrahedron making by neighboring two points, the
215  // plane center and the reference point (zero point) of the convex shape
216  const Vec3f& v3 = plane_center;
217  for (size_type j = 0; j < polygon.size(); ++j) {
218  index_type e_first = polygon[static_cast<index_type>(j)];
219  index_type e_second =
220  polygon[static_cast<index_type>((j + 1) % polygon.size())];
221  const Vec3f& v1 = points_[e_first];
222  const Vec3f& v2 = points_[e_second];
223  FCL_REAL d_six_vol = (v1.cross(v2)).dot(v3);
224  vol += d_six_vol;
225  }
226  }
227 
228  return vol / 6;
229 }
230 
231 template <typename PolygonT>
233  neighbors.reset(new std::vector<Neighbors>(num_points));
234 
235  typedef typename PolygonT::size_type size_type;
236  typedef typename PolygonT::index_type index_type;
237  std::vector<std::set<index_type>> nneighbors(num_points);
238  unsigned int c_nneighbors = 0;
239 
240  if (!(polygons.get())) {
241  std::cerr << "Error in `Convex::fillNeighbors`! Convex has no polygons."
242  << std::endl;
243  }
244  const std::vector<PolygonT>& polygons_ = *polygons;
245  for (unsigned int l = 0; l < num_polygons; ++l) {
246  const PolygonT& polygon = polygons_[l];
247  const size_type n = polygon.size();
248 
249  for (size_type j = 0; j < polygon.size(); ++j) {
250  size_type i = (j == 0) ? n - 1 : j - 1;
251  size_type k = (j == n - 1) ? 0 : j + 1;
252  index_type pi = polygon[(index_type)i], pj = polygon[(index_type)j],
253  pk = polygon[(index_type)k];
254  // Update neighbors of pj;
255  if (nneighbors[pj].count(pi) == 0) {
256  c_nneighbors++;
257  nneighbors[pj].insert(pi);
258  }
259  if (nneighbors[pj].count(pk) == 0) {
260  c_nneighbors++;
261  nneighbors[pj].insert(pk);
262  }
263  }
264  }
265 
266  nneighbors_.reset(new std::vector<unsigned int>(c_nneighbors));
267 
268  unsigned int* p_nneighbors = nneighbors_->data();
269  std::vector<Neighbors>& neighbors_ = *neighbors;
270  for (unsigned int i = 0; i < num_points; ++i) {
271  Neighbors& n = neighbors_[i];
272  if (nneighbors[i].size() >= (std::numeric_limits<unsigned char>::max)())
273  HPP_FCL_THROW_PRETTY("Too many neighbors.", std::logic_error);
274  n.count_ = (unsigned char)nneighbors[i].size();
275  n.n_ = p_nneighbors;
276  p_nneighbors =
277  std::copy(nneighbors[i].begin(), nneighbors[i].end(), p_nneighbors);
278  }
279  assert(p_nneighbors == nneighbors_->data() + c_nneighbors);
280 }
281 
282 } // namespace fcl
283 
284 } // namespace hpp
285 
286 #endif
Base for convex polytope.
Definition: geometric_shapes.h:638
Convex polytope.
Definition: convex.h:50
virtual Convex< PolygonT > * clone() const
Clone (deep copy)
Definition: convex.hxx:85
Convex()
Construct an uninitialized convex object.
Definition: convex.h:53
~Convex()
Definition: convex.hxx:68
std::shared_ptr< std::vector< PolygonT > > polygons
An array of PolygonT object. PolygonT should contains a list of vertices for each polygon,...
Definition: convex.h:102
void set(std::shared_ptr< std::vector< Vec3f >> points, unsigned int num_points, std::shared_ptr< std::vector< PolygonT >> polygons, unsigned int num_polygons)
Set the current Convex from a list of points and polygons.
Definition: convex.hxx:71
Vec3f computeCOM() const
compute center of mass
Definition: convex.hxx:143
FCL_REAL computeVolume() const
compute the volume
Definition: convex.hxx:188
void fillNeighbors()
Definition: convex.hxx:232
Matrix3f computeMomentofInertia() const
based on http://number-none.com/blow/inertia/bb_inertia.doc
Definition: convex.hxx:90
#define HPP_FCL_THROW_PRETTY(message, exception)
Definition: fwd.hh:64
void set(std::shared_ptr< std::vector< Vec3f >> points_, unsigned int num_points_)
Set the points of the convex shape.
unsigned int * n_
Definition: geometric_shapes.h:682
void buildSupportWarmStart()
Build the support points warm starts.
void initialize(std::shared_ptr< std::vector< Vec3f >> points_, unsigned int num_points_)
Initialize the points of the convex shape This also initializes the ConvexBase::center.
unsigned char count_
Definition: geometric_shapes.h:681
Eigen::Matrix< FCL_REAL, 3, 3 > Matrix3f
Definition: data_types.h:71
Eigen::Matrix< FCL_REAL, 3, 1 > Vec3f
Definition: data_types.h:67
double FCL_REAL
Definition: data_types.h:66
Main namespace.
Definition: broadphase_bruteforce.h:44
Definition: geometric_shapes.h:680