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 namespace coal {
45 
46 template <typename PolygonT>
47 Convex<PolygonT>::Convex(std::shared_ptr<std::vector<Vec3s>> points_,
48  unsigned int num_points_,
49  std::shared_ptr<std::vector<PolygonT>> polygons_,
50  unsigned int num_polygons_)
51  : ConvexBase(), polygons(polygons_), num_polygons(num_polygons_) {
52  this->initialize(points_, num_points_);
53  this->fillNeighbors();
54  this->buildSupportWarmStart();
55 }
56 
57 template <typename PolygonT>
59  : ConvexBase(other), num_polygons(other.num_polygons) {
60  if (other.polygons.get()) {
61  polygons.reset(new std::vector<PolygonT>(*(other.polygons)));
62  } else
63  polygons.reset();
64 }
65 
66 template <typename PolygonT>
68 
69 template <typename PolygonT>
70 void Convex<PolygonT>::set(std::shared_ptr<std::vector<Vec3s>> points_,
71  unsigned int num_points_,
72  std::shared_ptr<std::vector<PolygonT>> polygons_,
73  unsigned int num_polygons_) {
74  ConvexBase::set(points_, num_points_);
75 
76  this->num_polygons = num_polygons_;
77  this->polygons = polygons_;
78 
79  this->fillNeighbors();
80  this->buildSupportWarmStart();
81 }
82 
83 template <typename PolygonT>
85  return new Convex(*this);
86 }
87 
88 template <typename PolygonT>
90  typedef typename PolygonT::size_type size_type;
91  typedef typename PolygonT::index_type index_type;
92 
93  Matrix3s C = Matrix3s::Zero();
94 
95  Matrix3s C_canonical;
96  C_canonical << 1 / 60.0, 1 / 120.0, 1 / 120.0, 1 / 120.0, 1 / 60.0, 1 / 120.0,
97  1 / 120.0, 1 / 120.0, 1 / 60.0;
98 
99  if (!(points.get())) {
100  std::cerr
101  << "Error in `Convex::computeMomentofInertia`! Convex has no vertices."
102  << std::endl;
103  return C;
104  }
105  const std::vector<Vec3s>& points_ = *points;
106  if (!(polygons.get())) {
107  std::cerr
108  << "Error in `Convex::computeMomentofInertia`! Convex has no polygons."
109  << std::endl;
110  return C;
111  }
112  const std::vector<PolygonT>& polygons_ = *polygons;
113  for (unsigned int i = 0; i < num_polygons; ++i) {
114  const PolygonT& polygon = polygons_[i];
115 
116  // compute the center of the polygon
117  Vec3s plane_center(0, 0, 0);
118  for (size_type j = 0; j < polygon.size(); ++j)
119  plane_center += points_[polygon[(index_type)j]];
120  plane_center /= polygon.size();
121 
122  // compute the volume of tetrahedron making by neighboring two points, the
123  // plane center and the reference point (zero) of the convex shape
124  const Vec3s& v3 = plane_center;
125  for (size_type j = 0; j < polygon.size(); ++j) {
126  index_type e_first = polygon[static_cast<index_type>(j)];
127  index_type e_second =
128  polygon[static_cast<index_type>((j + 1) % polygon.size())];
129  const Vec3s& v1 = points_[e_first];
130  const Vec3s& v2 = points_[e_second];
131  Matrix3s A;
132  A << v1.transpose(), v2.transpose(),
133  v3.transpose(); // this is A' in the original document
134  C += A.transpose() * C_canonical * A * (v1.cross(v2)).dot(v3);
135  }
136  }
137 
138  return C.trace() * Matrix3s::Identity() - C;
139 }
140 
141 template <typename PolygonT>
143  typedef typename PolygonT::size_type size_type;
144  typedef typename PolygonT::index_type index_type;
145 
146  Vec3s com(0, 0, 0);
147  CoalScalar vol = 0;
148  if (!(points.get())) {
149  std::cerr << "Error in `Convex::computeCOM`! Convex has no vertices."
150  << std::endl;
151  return com;
152  }
153  const std::vector<Vec3s>& points_ = *points;
154  if (!(polygons.get())) {
155  std::cerr << "Error in `Convex::computeCOM`! Convex has no polygons."
156  << std::endl;
157  return com;
158  }
159  const std::vector<PolygonT>& polygons_ = *polygons;
160  for (unsigned int i = 0; i < num_polygons; ++i) {
161  const PolygonT& polygon = polygons_[i];
162  // compute the center of the polygon
163  Vec3s plane_center(0, 0, 0);
164  for (size_type j = 0; j < polygon.size(); ++j)
165  plane_center += points_[polygon[(index_type)j]];
166  plane_center /= polygon.size();
167 
168  // compute the volume of tetrahedron making by neighboring two points, the
169  // plane center and the reference point (zero) of the convex shape
170  const Vec3s& v3 = plane_center;
171  for (size_type j = 0; j < polygon.size(); ++j) {
172  index_type e_first = polygon[static_cast<index_type>(j)];
173  index_type e_second =
174  polygon[static_cast<index_type>((j + 1) % polygon.size())];
175  const Vec3s& v1 = points_[e_first];
176  const Vec3s& v2 = points_[e_second];
177  CoalScalar d_six_vol = (v1.cross(v2)).dot(v3);
178  vol += d_six_vol;
179  com += (points_[e_first] + points_[e_second] + plane_center) * d_six_vol;
180  }
181  }
182 
183  return com / (vol * 4); // here we choose zero as the reference
184 }
185 
186 template <typename PolygonT>
188  typedef typename PolygonT::size_type size_type;
189  typedef typename PolygonT::index_type index_type;
190 
191  CoalScalar vol = 0;
192  if (!(points.get())) {
193  std::cerr << "Error in `Convex::computeVolume`! Convex has no vertices."
194  << std::endl;
195  return vol;
196  }
197  const std::vector<Vec3s>& points_ = *points;
198  if (!(polygons.get())) {
199  std::cerr << "Error in `Convex::computeVolume`! Convex has no polygons."
200  << std::endl;
201  return vol;
202  }
203  const std::vector<PolygonT>& polygons_ = *polygons;
204  for (unsigned int i = 0; i < num_polygons; ++i) {
205  const PolygonT& polygon = polygons_[i];
206 
207  // compute the center of the polygon
208  Vec3s plane_center(0, 0, 0);
209  for (size_type j = 0; j < polygon.size(); ++j)
210  plane_center += points_[polygon[(index_type)j]];
211  plane_center /= polygon.size();
212 
213  // compute the volume of tetrahedron making by neighboring two points, the
214  // plane center and the reference point (zero point) of the convex shape
215  const Vec3s& v3 = plane_center;
216  for (size_type j = 0; j < polygon.size(); ++j) {
217  index_type e_first = polygon[static_cast<index_type>(j)];
218  index_type e_second =
219  polygon[static_cast<index_type>((j + 1) % polygon.size())];
220  const Vec3s& v1 = points_[e_first];
221  const Vec3s& v2 = points_[e_second];
222  CoalScalar d_six_vol = (v1.cross(v2)).dot(v3);
223  vol += d_six_vol;
224  }
225  }
226 
227  return vol / 6;
228 }
229 
230 template <typename PolygonT>
232  neighbors.reset(new std::vector<Neighbors>(num_points));
233 
234  typedef typename PolygonT::size_type size_type;
235  typedef typename PolygonT::index_type index_type;
236  std::vector<std::set<index_type>> nneighbors(num_points);
237  unsigned int c_nneighbors = 0;
238 
239  if (!(polygons.get())) {
240  std::cerr << "Error in `Convex::fillNeighbors`! Convex has no polygons."
241  << std::endl;
242  }
243  const std::vector<PolygonT>& polygons_ = *polygons;
244  for (unsigned int l = 0; l < num_polygons; ++l) {
245  const PolygonT& polygon = polygons_[l];
246  const size_type n = polygon.size();
247 
248  for (size_type j = 0; j < polygon.size(); ++j) {
249  size_type i = (j == 0) ? n - 1 : j - 1;
250  size_type k = (j == n - 1) ? 0 : j + 1;
251  index_type pi = polygon[(index_type)i], pj = polygon[(index_type)j],
252  pk = polygon[(index_type)k];
253  // Update neighbors of pj;
254  if (nneighbors[pj].count(pi) == 0) {
255  c_nneighbors++;
256  nneighbors[pj].insert(pi);
257  }
258  if (nneighbors[pj].count(pk) == 0) {
259  c_nneighbors++;
260  nneighbors[pj].insert(pk);
261  }
262  }
263  }
264 
265  nneighbors_.reset(new std::vector<unsigned int>(c_nneighbors));
266 
267  unsigned int* p_nneighbors = nneighbors_->data();
268  std::vector<Neighbors>& neighbors_ = *neighbors;
269  for (unsigned int i = 0; i < num_points; ++i) {
270  Neighbors& n = neighbors_[i];
271  if (nneighbors[i].size() >= (std::numeric_limits<unsigned char>::max)())
272  COAL_THROW_PRETTY("Too many neighbors.", std::logic_error);
273  n.count_ = (unsigned char)nneighbors[i].size();
274  n.n_ = p_nneighbors;
275  p_nneighbors =
276  std::copy(nneighbors[i].begin(), nneighbors[i].end(), p_nneighbors);
277  }
278  assert(p_nneighbors == nneighbors_->data() + c_nneighbors);
279 }
280 
281 } // namespace coal
282 
283 #endif
Base for convex polytope.
Definition: geometric_shapes.h:645
Convex polytope.
Definition: convex.h:49
virtual Convex< PolygonT > * clone() const
Clone (deep copy)
Definition: convex.hxx:84
Matrix3s computeMomentofInertia() const
based on http://number-none.com/blow/inertia/bb_inertia.doc
Definition: convex.hxx:89
~Convex()
Definition: convex.hxx:67
CoalScalar computeVolume() const
compute the volume
Definition: convex.hxx:187
void fillNeighbors()
Definition: convex.hxx:231
Vec3s computeCOM() const
compute center of mass
Definition: convex.hxx:142
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:101
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:70
Convex()
Construct an uninitialized convex object.
Definition: convex.h:52
#define COAL_THROW_PRETTY(message, exception)
Definition: fwd.hh:64
unsigned int * n_
Definition: geometric_shapes.h:689
void buildSupportWarmStart()
Build the support points warm starts.
void set(std::shared_ptr< std::vector< Vec3s >> points_, unsigned int num_points_)
Set the points of the convex shape.
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.
unsigned char count_
Definition: geometric_shapes.h:688
Main namespace.
Definition: broadphase_bruteforce.h:44
Eigen::Matrix< CoalScalar, 3, 3 > Matrix3s
Definition: data_types.h:81
Eigen::Matrix< CoalScalar, 3, 1 > Vec3s
Definition: data_types.h:77
double CoalScalar
Definition: data_types.h:76
Definition: geometric_shapes.h:687