DGtal  1.5.beta
Shapes, Shapers and Digitizers
Author
Jacques-Olivier Lachaud, David Coeurjolly, Jérémy Levallois
See also
shapes/exampleEuclideanShapesDecorator.cpp
Related DGtalTools:
shapeGenerator

Introduction of Concepts

In DGtal, we use the generic terminology shape to describe either explicit objects (e.g. spheres, cubes,...) or implicit ones (from a real valued functions, from a predicate on points,...).

An important usage of these notions in DGtal can be found in the shape factory and shape generators tools (see below). However, they can also be used to describe predicate on points (for example to construct a digital set from an image and a binary predicate to describe the region/pixel of interest).

Hence, shapes can be compact or not (i.e. bounded), oriented or not and finally, defined on either the Euclidean space, or the Digital one. All these cases are formalized in the following concepts:

Note
An orientation predicate is a method with the following interface:
DGtal::Orientation orientation( const Point & aPoint ) //for Digital oriented shape
DGtal::Orientation orientation( const RealPoint & aRealPoint ) //for Euclidean oriented shape
Orientation
Definition: Common.h:141
MyPointD Point
Definition: testClone2.cpp:383
const Point aPoint(3, 4)
PointVector< 3, double > RealPoint
The DGtal::Orientation values can be {INSIDE, ON, OUTSIDE}.

Shapers and Digitizers

Given a bounded and oriented shape, we have several process to construct a digital set: given a domain, we can construct the set of points for which the orientation predicate returns INSIDE (defined in Common.h).

For Digital shapes, the set construction (called a shaper in the following) is quite simple since we just have to define the local domain from the shape upper/lower bounds and to scan all grid points.

Note
A digital shaper helper method is available in the Shapes class, e.g.:
#include <DGtal/shapes/Shapes.h>
...
Shapes<Domain>::digitalShaper( myOutputSet, myInputShape)

When considering an Euclidean shape \(E\), we first need to specify a digitization process. At this point, DGtal contains a GaussDigitizer parametrized by a step grid h and which construct a digital shape which corresponds to the grid points in \(h\cdot{Z}^n\) which are also in \(E\).

For a flexible digitization, here you have all the steps involved in the digitization of an Euclidean shape (aShape of type Shape):

// Creates a digitizer on the window (xLow, xUp).
RealPoint xLow( -5.3, -4.3 );
RealPoint xUp( 7.4, 4.7 );
GaussDigitizer<Space,Shape> dig;
dig.attach( aShape ); // attaches the shape.
dig.init( xLow, xUp, h );
// The domain size is given by the digitizer according to the window
// and the step.
Domain domain = dig.getDomain();
MySet aSet( domain );
// Creates a set from the digitizer.
static void digitalShaper(TDigitalSet &aSet, const TShapeFunctor &aFunctor)
Domain domain
HyperRectDomain< Space > Domain
Note
A simpler (but less flexible) possibility is to use the Euclidean shaper helper method is available in the Shapes class, e.g.:
#include <DGtal/shapes/Shapes.h>
...
Shapes<Domain>::euclideanShaper( myOutputSet, myInputShape, h)
In this case, lower and upper bounds are given from the Euclidean shape characteristics.

The following figures illustrate the digitization of an ellipse with several grid step values.

Digitization of a parametric ellipse h=1
Digitization of a parametric ellipse h=0.5
Digitization of a parametric ellipse h=0.25
Note
A command line tool is available to generate multigrid shapes: shapeGenerator

Shape Factory

DGtal implements many Euclidean shapes to be used in a multigrid analysis of a differential estimator for example. All shapes available in DGtal are models of CEuclideanBoundedShape and CEuclideanOrientedShape.

These shapes are either parametric or implicit ones (see "shapes/parametric" and "shapes/implicit" files). In order to have a simple access to all shapes, just include the "shapes/ShapeFactory.h" header file.

Note
In dimension 2, parametric shapes provide fine approximation of differential quantities (length, tangent, curvature,...). These information can be used to evaluate digital differential estimators.

The following pictures illustrate some of the shapes defined in digital in dimension 2 (note that shapes are defined from a set of parameters which are not specified in the captions).

Flower h=1
Flower h=0.1
Accelerated flower h=1
Accelerated flower h=0.1
Triangle h=1
Triangle h=0.1
Circle h=1
Circle h=0.1
Square h=1
Square h=0.1
Ellipse h=1
Ellipse h=0.1
Astroid h=1
Astroid h=0.1
Lemniscate h=1
Lemniscate h=0.1

Constructive Solid Geometry tree on Shapes

In DGtal, you can also use some CSG operations on Euclidean (resp. Digital) Shapes, using EuclideanShapesCSG (resp. DigitalShapesCSG). See examples in exampleEuclideanShapesDecorator.cpp.

As a root for your CSG tree, you need a shape ShapeA, model of concepts::CEuclideanBoundedShape and concepts::CEuclideanOrientedShape (concepts::CDigitalBoundedShape and concepts::CDigitalOrientedShape). Then, you can add (plus()), remove (minus()), intersect (intersection()) any ShapeB, models of concepts::CEuclideanBoundedShape and concepts::CEuclideanOrientedShape (concepts::CDigitalBoundedShape and concepts::CDigitalOrientedShape) you want. You can combine plus(), minus() and intersection() operations.

Example for minus operation on two Euclidean Shapes :

typedef ImplicitBall< Z2i::Space > MyEuclideanShapeA;
typedef ImplicitBall< Z2i::Space > MyEuclideanShapeB;
MyEuclideanShapeA shapeA( Z2i::RealPoint( 0.0, 0.0 ), 15 );
MyEuclideanShapeB shapeB( Z2i::RealPoint( 0.0, 0.0 ), 10 );
MyEuclideanShapeB shapeC( Z2i::RealPoint( -5.0, 0.0 ), 5 );
typedef EuclideanShapesCSG< MyEuclideanShapeA, MyEuclideanShapeB > Minus;
Minus s_minus ( shapeA );
s_minus.minus( shapeB );
s_minus.plus( shapeC );
Space::RealPoint RealPoint
Definition: StdDefs.h:97

The following images show you binary operations apply on two Ball2D (results are in orange) and in 3D :

Plus operation
Intersection operation
Minus operation
Minus operations
See also
shapes/exampleEuclideanShapesDecorator.cpp