coal  3.0.1
Coal, The Collision Detection Library. Previously known as HPP-FCL, 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 COAL_SHAPE_CONVEX_HXX
38 #define COAL_SHAPE_CONVEX_HXX
39 
40 #include <set>
41 #include <vector>
42 #include <iostream>
43 
44 #include "coal/shape/convex.h"
45 
46 namespace coal {
47 
48 template <typename PolygonT>
49 ConvexTpl<PolygonT>::ConvexTpl(std::shared_ptr<std::vector<Vec3s>> points_,
50  unsigned int num_points_,
51  std::shared_ptr<std::vector<PolygonT>> polygons_,
52  unsigned int num_polygons_)
53  : Base(), polygons(polygons_), num_polygons(num_polygons_) {
54  this->initialize(points_, num_points_);
55  this->fillNeighbors();
56  this->buildSupportWarmStart();
57 }
58 
59 template <typename PolygonT>
61  if (this != &other) {
62  // Copy the base
63  this->base() = other.base();
64 
65  // Shallow copy the polygons
66  this->num_polygons = other.num_polygons;
67  this->polygons = other.polygons;
68  }
69 
70  return *this;
71 }
72 
73 template <typename PolygonT>
74 template <typename OtherPolygonT>
77  if (source == nullptr || copy == nullptr) {
78  return;
79  }
80 
81  // Deep copy the base
82  Base::deepcopy(source, copy);
83 
84  // Deep copy the polygons
85  typedef typename OtherPolygonT::IndexType OtherIndexType;
86  copy->num_polygons = source->num_polygons;
87  if (source->polygons != nullptr) {
88  const std::vector<PolygonT>& source_polygons = *(source->polygons);
89  copy->polygons.reset(
90  new std::vector<OtherPolygonT>(source_polygons.size()));
91  std::vector<OtherPolygonT>& copy_polygons = *(copy->polygons);
92  for (std::size_t i = 0; i < source_polygons.size(); ++i) {
93  copy_polygons[i] = source_polygons[i].template cast<OtherIndexType>();
94  }
95  } else {
96  copy->polygons.reset();
97  }
98 }
99 
100 template <typename PolygonT>
101 void ConvexTpl<PolygonT>::set(std::shared_ptr<std::vector<Vec3s>> points_,
102  unsigned int num_points_,
103  std::shared_ptr<std::vector<PolygonT>> polygons_,
104  unsigned int num_polygons_) {
105  Base::set(points_, num_points_);
106 
107  this->num_polygons = num_polygons_;
108  this->polygons = polygons_;
109 
110  this->fillNeighbors();
111  this->buildSupportWarmStart();
112 }
113 
114 template <typename PolygonT>
116  typedef typename PolygonT::size_type size_type;
117  typedef typename PolygonT::IndexType IndexType;
118 
119  Matrix3s C = Matrix3s::Zero();
120 
121  Matrix3s C_canonical;
122  C_canonical << Scalar(1 / 60.0), //
123  Scalar(1 / 120.0), //
124  Scalar(1 / 120.0), //
125  Scalar(1 / 120.0), //
126  Scalar(1 / 60.0), //
127  Scalar(1 / 120.0), //
128  Scalar(1 / 120.0), //
129  Scalar(1 / 120.0), //
130  Scalar(1 / 60.0);
131 
132  if (!(points.get())) {
133  std::cerr << "Error in `ConvexTpl::computeMomentofInertia`! ConvexTpl has "
134  "no vertices."
135  << std::endl;
136  return C;
137  }
138  const std::vector<Vec3s>& points_ = *points;
139  if (!(polygons.get())) {
140  std::cerr << "Error in `ConvexTpl::computeMomentofInertia`! ConvexTpl has "
141  "no polygons."
142  << std::endl;
143  return C;
144  }
145  const std::vector<PolygonT>& polygons_ = *polygons;
146  for (unsigned int i = 0; i < num_polygons; ++i) {
147  const PolygonT& polygon = polygons_[i];
148 
149  // compute the center of the polygon
150  Vec3s plane_center(0, 0, 0);
151  for (size_type j = 0; j < polygon.size(); ++j)
152  plane_center += points_[polygon[(IndexType)j]];
153  plane_center /= Scalar(polygon.size());
154 
155  // compute the volume of tetrahedron making by neighboring two points, the
156  // plane center and the reference point (zero) of the convex shape
157  const Vec3s& v3 = plane_center;
158  for (size_type j = 0; j < polygon.size(); ++j) {
159  IndexType e_first = polygon[static_cast<IndexType>(j)];
160  IndexType e_second =
161  polygon[static_cast<IndexType>((j + 1) % polygon.size())];
162  const Vec3s& v1 = points_[e_first];
163  const Vec3s& v2 = points_[e_second];
164  Matrix3s A;
165  A << v1.transpose(), v2.transpose(),
166  v3.transpose(); // this is A' in the original document
167  C += A.transpose() * C_canonical * A * (v1.cross(v2)).dot(v3);
168  }
169  }
170 
171  return C.trace() * Matrix3s::Identity() - C;
172 }
173 
174 template <typename PolygonT>
176  typedef typename PolygonT::size_type size_type;
177  typedef typename PolygonT::IndexType IndexType;
178 
179  Vec3s com(0, 0, 0);
180  Scalar vol = 0;
181  if (!(points.get())) {
182  std::cerr << "Error in `ConvexTpl::computeCOM`! ConvexTpl has no vertices."
183  << std::endl;
184  return com;
185  }
186  const std::vector<Vec3s>& points_ = *points;
187  if (!(polygons.get())) {
188  std::cerr << "Error in `ConvexTpl::computeCOM`! ConvexTpl has no polygons."
189  << std::endl;
190  return com;
191  }
192  const std::vector<PolygonT>& polygons_ = *polygons;
193  for (unsigned int i = 0; i < num_polygons; ++i) {
194  const PolygonT& polygon = polygons_[i];
195  // compute the center of the polygon
196  Vec3s plane_center(0, 0, 0);
197  for (size_type j = 0; j < polygon.size(); ++j)
198  plane_center += points_[polygon[(IndexType)j]];
199  plane_center /= Scalar(polygon.size());
200 
201  // compute the volume of tetrahedron making by neighboring two points, the
202  // plane center and the reference point (zero) of the convex shape
203  const Vec3s& v3 = plane_center;
204  for (size_type j = 0; j < polygon.size(); ++j) {
205  IndexType e_first = polygon[static_cast<IndexType>(j)];
206  IndexType e_second =
207  polygon[static_cast<IndexType>((j + 1) % polygon.size())];
208  const Vec3s& v1 = points_[e_first];
209  const Vec3s& v2 = points_[e_second];
210  Scalar d_six_vol = (v1.cross(v2)).dot(v3);
211  vol += d_six_vol;
212  com += (points_[e_first] + points_[e_second] + plane_center) * d_six_vol;
213  }
214  }
215 
216  return com / (vol * 4); // here we choose zero as the reference
217 }
218 
219 template <typename PolygonT>
221  typedef typename PolygonT::size_type size_type;
222  typedef typename PolygonT::IndexType IndexType;
223 
224  Scalar vol = 0;
225  if (!(points.get())) {
226  std::cerr
227  << "Error in `ConvexTpl::computeVolume`! ConvexTpl has no vertices."
228  << std::endl;
229  return vol;
230  }
231  const std::vector<Vec3s>& points_ = *points;
232  if (!(polygons.get())) {
233  std::cerr
234  << "Error in `ConvexTpl::computeVolume`! ConvexTpl has no polygons."
235  << std::endl;
236  return vol;
237  }
238  const std::vector<PolygonT>& polygons_ = *polygons;
239  for (unsigned int i = 0; i < num_polygons; ++i) {
240  const PolygonT& polygon = polygons_[i];
241 
242  // compute the center of the polygon
243  Vec3s plane_center(0, 0, 0);
244  for (size_type j = 0; j < polygon.size(); ++j)
245  plane_center += points_[polygon[(IndexType)j]];
246  plane_center /= Scalar(polygon.size());
247 
248  // compute the volume of tetrahedron making by neighboring two points, the
249  // plane center and the reference point (zero point) of the convex shape
250  const Vec3s& v3 = plane_center;
251  for (size_type j = 0; j < polygon.size(); ++j) {
252  IndexType e_first = polygon[static_cast<IndexType>(j)];
253  IndexType e_second =
254  polygon[static_cast<IndexType>((j + 1) % polygon.size())];
255  const Vec3s& v1 = points_[e_first];
256  const Vec3s& v2 = points_[e_second];
257  Scalar d_six_vol = (v1.cross(v2)).dot(v3);
258  vol += d_six_vol;
259  }
260  }
261 
262  return vol / 6;
263 }
264 
265 template <typename PolygonT>
267  neighbors.reset(new std::vector<Neighbors>(num_points));
268 
269  typedef typename PolygonT::size_type size_type;
270  typedef typename PolygonT::IndexType IndexType;
271 
272  std::vector<std::set<IndexType>> nneighbors(num_points);
273  unsigned int c_nneighbors = 0;
274 
275  if (!(polygons.get())) {
276  std::cerr
277  << "Error in `ConvexTpl::fillNeighbors`! ConvexTpl has no polygons."
278  << std::endl;
279  }
280  const std::vector<PolygonT>& polygons_ = *polygons;
281  for (unsigned int l = 0; l < num_polygons; ++l) {
282  const PolygonT& polygon = polygons_[l];
283  const size_type n = polygon.size();
284 
285  for (size_type j = 0; j < polygon.size(); ++j) {
286  size_type i = (j == 0) ? n - 1 : j - 1;
287  size_type k = (j == n - 1) ? 0 : j + 1;
288  IndexType pi = polygon[(IndexType)i], pj = polygon[(IndexType)j],
289  pk = polygon[(IndexType)k];
290  // Update neighbors of pj;
291  if (nneighbors[pj].count(pi) == 0) {
292  c_nneighbors++;
293  nneighbors[pj].insert(pi);
294  }
295  if (nneighbors[pj].count(pk) == 0) {
296  c_nneighbors++;
297  nneighbors[pj].insert(pk);
298  }
299  }
300  }
301 
302  nneighbors_.reset(new std::vector<IndexType>(c_nneighbors));
303 
304  std::vector<Neighbors>& neighbors_ = *neighbors;
305  std::vector<IndexType>& nneighbors__ = *(nneighbors_);
306  IndexType begin_id = 0;
307  for (unsigned int i = 0; i < num_points; ++i) {
308  Neighbors& n = neighbors_[i];
309  if (nneighbors[i].size() >= (std::numeric_limits<unsigned char>::max)())
310  COAL_THROW_PRETTY("Too many neighbors.", std::logic_error);
311  n.count = (unsigned char)nneighbors[i].size();
312  n.begin_id = begin_id;
313  IndexType j = 0;
314  for (IndexType idx : nneighbors[i]) {
315  nneighbors__[n.begin_id + j] = idx;
316  j++;
317  }
318  begin_id += n.count;
319  }
320 }
321 
322 } // namespace coal
323 
324 #endif
void buildSupportWarmStart()
Build the support points warm starts.
void initialize(std::shared_ptr< std::vector< Vec3s >> points_, unsigned int num_points_)
Initialize the points of the convex shape This also initializes the ConvexBase::center.
Definition: geometric_shapes.hxx:67
Convex polytope.
Definition: convex.h:50
Base & base()
Cast Convex to ConvexBaseTpl. This method should never be marked as virtual.
Definition: convex.h:79
virtual Matrix3s computeMomentofInertia() const override
based on http://number-none.com/blow/inertia/bb_inertia.doc
Definition: convex.hxx:115
ConvexTpl()
Construct an uninitialized convex object.
Definition: convex.h:61
void set(std::shared_ptr< std::vector< Vec3s >> 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:101
ConvexTpl & operator=(const ConvexTpl &other)
Copy operator. The copy operator only shallow copies the data (it copies the shared pointers but does...
Definition: convex.hxx:60
void fillNeighbors()
Definition: convex.hxx:266
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:139
virtual Scalar computeVolume() const override
compute the volume
Definition: convex.hxx:220
ConvexTpl * deepcopy() const override
Deep copy of the ConvexBaseTpl. This method deep copies every field of the class.
Definition: convex.h:101
PolygonT::IndexType IndexType
Definition: convex.h:52
virtual Vec3s computeCOM() const override
compute center of mass
Definition: convex.hxx:175
unsigned int num_polygons
Definition: convex.h:140
#define COAL_THROW_PRETTY(message, exception)
Definition: fwd.hh:64
Main namespace.
Definition: broadphase_bruteforce.h:44
Eigen::Matrix< Scalar, 3, 1 > Vec3s
Definition: data_types.h:70
double Scalar
Definition: data_types.h:68
Eigen::Matrix< Scalar, 3, 3 > Matrix3s
Definition: data_types.h:74
Definition: geometric_shapes.h:638
unsigned char count
Definition: geometric_shapes.h:641
IndexType begin_id
Definition: geometric_shapes.h:642