Skip to content

Commit 5b0d470

Browse files
author
Acorn
committed
add shapes::computeShapeBoundingSphere() function
1 parent aa373fc commit 5b0d470

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

include/geometric_shapes/shape_operations.h

+3
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ Eigen::Vector3d computeShapeExtents(const ShapeMsg &shape_msg);
7070
/** \brief Compute the extents of a shape */
7171
Eigen::Vector3d computeShapeExtents(const Shape *shape);
7272

73+
/** \brief Compute a sphere bounding a shape */
74+
void computeShapeBoundingSphere(const Shape *shape, Eigen::Vector3d& center, double& radius);
75+
7376
/** \brief Get the string name of the shape */
7477
const std::string& shapeStringName(const Shape *shape);
7578

src/shape_operations.cpp

+64
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,70 @@ Eigen::Vector3d computeShapeExtents(const Shape *shape)
301301
return Eigen::Vector3d(0.0, 0.0, 0.0);
302302
}
303303

304+
void computeShapeBoundingSphere(const Shape *shape, Eigen::Vector3d& center, double& radius)
305+
{
306+
center.x() = 0.0;
307+
center.y() = 0.0;
308+
center.z() = 0.0;
309+
radius = 0.0;
310+
311+
if (shape->type == SPHERE)
312+
{
313+
radius = static_cast<const Sphere*>(shape)->radius;
314+
}
315+
else if (shape->type == BOX)
316+
{
317+
const double* sz = static_cast<const Box*>(shape)->size;
318+
radius = std::sqrt(sz[0] * sz[0] + sz[1] * sz[1] + sz[2] * sz[2]);
319+
}
320+
else if (shape->type == CYLINDER)
321+
{
322+
double r = static_cast<const Cylinder*>(shape)->radius;
323+
double l = static_cast<const Cylinder*>(shape)->length;
324+
radius = std::sqrt(r * r + l * l);
325+
}
326+
else if (shape->type == CONE)
327+
{
328+
double r = static_cast<const Cone*>(shape)->radius;
329+
double l = static_cast<const Cone*>(shape)->length;
330+
331+
if (l > r)
332+
{
333+
// center of sphere is intersection of perpendicular bisectors:
334+
double z = (l - (r * r / l)) * 0.5;
335+
center.z() = z - (l * 0.5);
336+
radius = l - z;
337+
}
338+
else
339+
{
340+
// short cone. Bounding sphere touches base only.
341+
center.z() = - (l * 0.5);
342+
radius = r;
343+
}
344+
}
345+
else if (shape->type == MESH)
346+
{
347+
const Mesh *mesh = static_cast<const Mesh*>(shape);
348+
if (mesh->vertex_count > 1)
349+
{
350+
double mx = std::numeric_limits<double>::max();
351+
Eigen::Vector3d min( mx, mx, mx);
352+
Eigen::Vector3d max(-mx, -mx, -mx);
353+
unsigned int cnt = mesh->vertex_count * 3;
354+
for (unsigned int i = 0; i < cnt ; i+=3)
355+
{
356+
Eigen::Vector3d v(mesh->vertices[i+0], mesh->vertices[i+1], mesh->vertices[i+2]);
357+
min = min.cwiseMin(v);
358+
max = max.cwiseMax(v);
359+
}
360+
361+
center = (min + max) * 0.5;
362+
radius = (max - min).norm() * 0.5;
363+
}
364+
}
365+
}
366+
367+
304368
bool constructMsgFromShape(const Shape* shape, ShapeMsg &shape_msg)
305369
{
306370
if (shape->type == SPHERE)

0 commit comments

Comments
 (0)