coal 3.0.2
Coal, The Collision Detection Library. Previously known as HPP-FCL, fork of FCL -- The Flexible Collision Library
Loading...
Searching...
No Matches
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
36
37#ifndef COAL_SHAPE_CONVEX_HXX
38#define COAL_SHAPE_CONVEX_HXX
39
40#include <set>
41#include <vector>
42#include <iostream>
43
44namespace coal {
45
46template <typename PolygonT>
47Convex<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();
55}
56
57template <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
66template <typename PolygonT>
68
69template <typename PolygonT>
70void 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();
81}
82
83template <typename PolygonT>
85 return new Convex(*this);
86}
87
88template <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
141template <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
186template <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
230template <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
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
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()
Definition convex.hxx:67
CoalScalar computeVolume() const
compute the volume
Definition convex.hxx:187
void fillNeighbors()
Definition convex.hxx:231
unsigned int num_polygons
Definition convex.h:102
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
Convex()
Construct an uninitialized convex object.
Definition convex.h:52
#define COAL_THROW_PRETTY(message, exception)
Definition fwd.hh:64
void set(std::shared_ptr< std::vector< Vec3s > > points_, unsigned int num_points_)
Set the points of the convex shape.
std::shared_ptr< std::vector< unsigned int > > nneighbors_
Array of indices of the neighbors of each vertex. Since we don't know a priori the number of neighbor...
Definition geometric_shapes.h:801
unsigned int * n_
Definition geometric_shapes.h:689
unsigned int num_points
Definition geometric_shapes.h:720
void buildSupportWarmStart()
Build the support points warm starts.
std::shared_ptr< std::vector< Neighbors > > neighbors
Neighbors of each vertex. It is an array of size num_points. For each vertex, it contains the number ...
Definition geometric_shapes.h:732
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
ConvexBase()
Construct an uninitialized convex object Initialization is done with ConvexBase::initialize.
Definition geometric_shapes.h:762
std::shared_ptr< std::vector< Vec3s > > points
An array of the points of the polygon.
Definition geometric_shapes.h:719
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