// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*****************************************************************************
* See the file COPYING for full copying permissions. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see . *
*****************************************************************************/
/*!
* \file
* \ingroup Precision
* \brief Defines epsilons to be used for floating point
* arithmetic on geometries, e.g. to determine if
* a point lies on a geometry or for computing the
* intersection of two geometries. The values for
* the epsilons are computed based on the magnitude
* of the provided geometry.
*/
#ifndef FRACKIT_DEFAULT_EPSILON_HH
#define FRACKIT_DEFAULT_EPSILON_HH
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "precision.hh"
namespace Frackit {
/*!
* \ingroup Precision
* \brief Default epsilon for geometries.
* We use the base epsilon here and provide
* overloads for geometries having a magnitude.
*/
template
typename Geometry::ctype defaultEpsilon(const Geometry& geom)
{ return Precision::confusion(); }
/*!
* \ingroup Precision
* \brief Default epsilon for operations on segments.
*/
template
ctype defaultEpsilon(const Segment& seg)
{ return Precision::confusion()*seg.length(); }
/*!
* \ingroup Precision
* \brief Default epsilon for operations on circles.
*/
template
ctype defaultEpsilon(const Circle& circle)
{ return Precision::confusion()*circle.radius(); }
/*!
* \ingroup Precision
* \brief Default epsilon for operations on ellipses.
*/
template
ctype defaultEpsilon(const Ellipse& ellipse)
{
return Precision::confusion()
*0.5*(ellipse.majorAxisLength() + ellipse.minorAxisLength());
}
/*!
* \ingroup Precision
* \brief Default epsilon for operations on disks.
*/
template
ctype defaultEpsilon(const Disk& disk)
{ return defaultEpsilon(disk.boundingEllipse()); }
/*!
* \ingroup Precision
* \brief Default epsilon for operations on quadrilaterals.
*/
template
ctype defaultEpsilon(const Quadrilateral& quad)
{
using std::sqrt;
return 0.5*sqrt(quad.area())*Precision::confusion();
}
/*!
* \ingroup Precision
* \brief Default epsilon for operations on cylinder surfaces.
*/
template
ctype defaultEpsilon(const CylinderSurface& cylSurface)
{
return Precision::confusion()
*0.5*(cylSurface.radius() + cylSurface.height());
}
/*!
* \ingroup Precision
* \brief Default epsilon for operations on boxes.
*/
template
ctype defaultEpsilon(const Box& box)
{
const Segment diagSegment(box.corner(0), box.corner(7));
return Precision::confusion()*diagSegment.length();
}
/*!
* \ingroup Precision
* \brief Default epsilon for operations on shapes.
*/
template
ctype defaultEpsilon(const TopoDS_Shape& shape)
{
const auto bbox = OCCUtilities::getBoundingBox(shape);
const auto diagonalSeg = Segment(bbox.corner(0), bbox.corner(7));
return diagonalSeg.length()*Precision::confusion();
}
} // end namespace Frackit
#endif // FRACKIT_DEFAULT_EPSILON_HH