cgal/Frechet_distance/include/CGAL/Frechet_distance.h

103 lines
4.2 KiB
C++

// Copyright (c) 2024 Max-Planck-Institute Saarbruecken (Germany), GeometryFactory (France)
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : André Nusser <anusser@mpi-inf.mpg.de>
// Marvin Künnemann <marvin@mpi-inf.mpg.de>
// Karl Bringmann <kbringma@mpi-inf.mpg.de>
// Andreas Fabri
// =============================================================================
#ifndef CGAL_FRECHET_DISTANCE_H
#define CGAL_FRECHET_DISTANCE_H
#include <CGAL/license/Frechet_distance.h>
#include <CGAL/basic.h>
#include <CGAL/Frechet_distance/internal/Frechet_distance.h>
#include <iterator>
namespace CGAL
{
/**
* \ingroup PkgFrechetDistanceFunctions
* determines if the Frechet distance between two polylines is larger than a given distance.
*
* \param polyline1 the first polyline defined by a sequence of consecutive points
* \param polyline2 the second polyline defined by a sequence of consecutive points
* \param distance the distance to compare against
* \param traits the geometric traits object
*
* \tparam Traits a model of `FrechetDistanceTraits`
* \tparam force_filtering if `true`, interval arithmetic combined with exact rational will be used internally
* \tparam PointRange a model of the concept `RandomAccessContainer`
* with `Traits::Point_d` as value type.
*
* \pre the polylines must not be empty
*/
template < class Traits, bool force_filtering = false, class PointRange>
bool is_Frechet_distance_larger(const PointRange& polyline1,
const PointRange& polyline2,
const double distance,
const Traits& traits = Traits())
{
constexpr bool filtered = force_filtering ||
std::is_same_v<typename decltype(Frechet_distance_::internal::toCurve<force_filtering>(polyline1, traits))::IFT,
Interval_nt<false>>;
Protect_FPU_rounding<filtered> p;
auto icurve1 = Frechet_distance_::internal::toCurve<force_filtering>(polyline1, traits);
auto icurve2 = Frechet_distance_::internal::toCurve<force_filtering>(polyline2, traits);
using distance_t = const typename decltype(icurve1)::distance_t;
return ! Frechet_distance_::internal::lessThan(icurve1, icurve2, distance_t(distance));
}
/**
* \ingroup PkgFrechetDistanceFunctions
* approximates the Fréchet distance between two polylines up to an additive error
* of `precision`.
*
* \param polyline1 the first polyline defined by a sequence of consecutive points
* \param polyline2 the second polyline defined by a sequence of consecutive points
* \param precision the precision of the approximation
* \param traits the geometric traits object
*
* \tparam Traits a model of `FrechetDistanceTraits`
* \tparam force_filtering if `true`, interval arithmetic combined with exact rational will be used internally
* \tparam PointRange a model of the concept `RandomAccessContainer`
* with `Traits::Point_d` as value type.
*
* \pre the polylines must not be empty
*
* @return an interval enclosing the exact result, the difference between the upper and
* the lower bound being less than `precision`.
*/
template <class Traits, bool force_filtering = false, class PointRange>
std::pair<double,double> approximate_Frechet_distance(const PointRange& polyline1,
const PointRange& polyline2,
const double precision,
const Traits& traits = Traits())
{
constexpr bool filtered = force_filtering ||
std::is_same_v<typename decltype(Frechet_distance_::internal::toCurve<force_filtering>(polyline1, traits))::IFT,
Interval_nt<false>>;
Protect_FPU_rounding<filtered> p;
auto icurve1 = Frechet_distance_::internal::toCurve<force_filtering>(polyline1, traits);
auto icurve2 = Frechet_distance_::internal::toCurve<force_filtering>(polyline2, traits);
return Frechet_distance_::internal::calcDistance(icurve1, icurve2, precision);
}
} // end of namespace CGAL
#endif // CGAL_FRECHET_DISTANCE_H