coal 3.0.1
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
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
46namespace coal {
47
48template <typename PolygonT>
49ConvexTpl<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();
57}
58
59template <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
73template <typename PolygonT>
74template <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
100template <typename PolygonT>
101void 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
114template <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
174template <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
219template <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
265template <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
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
ConvexTpl * deepcopy() const override
Deep copy of the ConvexBaseTpl. This method deep copies every field of the class.
Definition convex.h: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 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
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
Base & base()
Cast Convex to ConvexBaseTpl. This method should never be marked as virtual.
Definition convex.h:79
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