Commit 8926a801 authored by Dennis Gläser's avatar Dennis Gläser
Browse files

Merge branch 'feature/polygon-disk-intersection' into 'master'

Feature/polygon disk intersection

See merge request tools/frackit!150
parents e512a685 8785843e
......@@ -11,6 +11,7 @@ algo_planargeom_line.hh
algo_planargeom_planargeom.hh
algo_plane_line.hh
algo_plane_plane.hh
algo_polygon_disk.hh
algo_polygon_polygon.hh
algo_quadrilateral_disk.hh
algo_quadrilateral_line.hh
......
// -*- 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 <http://www.gnu.org/licenses/>. *
*****************************************************************************/
/*!
* \file
* \brief Contains the intersection algorithm
* between a polygon and a disk.
*/
#ifndef FRACKIT_POLYGON_DISK_INTERSECTION_HH
#define FRACKIT_POLYGON_DISK_INTERSECTION_HH
#include <cmath>
#include <frackit/precision/precision.hh>
#include <frackit/geometry/polygon.hh>
#include <frackit/geometry/disk.hh>
#include <frackit/geometry/segment.hh>
#include <frackit/intersection/intersectiontraits.hh>
#include "algo_planargeom_planargeom.hh"
namespace Frackit {
namespace IntersectionAlgorithms {
//! Intersect a polygon and a disk
//! The result can be:
//! - a surface bounded by segments and/or elliptical arcs
//! - a segment
//! - a point
//! - no intersection
template<class ctype>
Intersection< Polygon<ctype, 3>, Disk<ctype> >
intersect_polygon_disk(const Polygon<ctype, 3>& polygon,
const Disk<ctype>& disk,
ctype eps)
{
using Segment = Segment<ctype, 3>;
ctype charLength = 0.0;
using std::max;
for (unsigned int i = 0; i < polygon.numCorners(); ++i)
charLength = max(charLength, Segment(polygon.center(), polygon.corner(i)).squaredLength());
using std::sqrt;
return intersect_planarGeometry_planarGeometry(polygon, disk,
sqrt(charLength),
eps, eps, eps);
}
} // end namespace IntersectionAlgorithms
} // end namespace Frackit
#endif // FRACKIT_POLYGON_DISK_INTERSECTION_HH
......@@ -49,16 +49,14 @@ intersect_quadrilateral_disk(const Quadrilateral<ctype, 3>& quad,
ctype eps)
{
using std::max;
ctype charLength = disk.majorAxisLength();
ctype charLength = disk.majorAxisLength()*disk.majorAxisLength();
for (unsigned int edgeIdx = 0; edgeIdx < quad.numEdges(); ++edgeIdx)
charLength = max(charLength, quad.edge(edgeIdx).length());
charLength = max(charLength, quad.edge(edgeIdx).squaredLength());
return intersect_planarGeometry_planarGeometry(quad,
disk,
charLength,
eps,
Precision<ctype>::confusion(),
eps);
using std::sqrt;
return intersect_planarGeometry_planarGeometry(quad, disk,
sqrt(charLength),
eps, eps, eps);
}
} // end namespace IntersectionAlgorithms
......
......@@ -56,6 +56,7 @@
#include "algorithms/algo_quadrilateral_line.hh"
#include "algorithms/algo_quadrilateral_quadrilateral.hh"
#include "algorithms/algo_quadrilateral_disk.hh"
#include "algorithms/algo_polygon_disk.hh"
#include "algorithms/algo_polygon_polygon.hh"
#include "algorithms/algo_disk_disk.hh"
#include "algorithms/algo_cylsurface_disk.hh"
......@@ -267,6 +268,34 @@ Intersection< Disk<ctype>, Quadrilateral<ctype, 3> >
intersect(const Disk<ctype>& disk, const Quadrilateral<ctype, 3>& quad, ctype eps)
{ return intersect(quad, disk, eps); }
/*!
* \ingroup Intersection
* \brief Intersect a polygon and a disk in 3d space.
* \param polygon The polygon
* \param disk The disk
* \param eps Tolerance to be used for floating point comparisons
*/
template<class ctype>
Intersection< Polygon<ctype, 3>, Disk<ctype> >
intersect(const Polygon<ctype, 3>& polygon, const Disk<ctype>& disk, ctype eps)
{
if (!doIntersect(getBoundingBox(polygon), getBoundingBox(disk), eps))
return {EmptyIntersection<3, ctype>()};
return IntersectionAlgorithms::intersect_polygon_disk(polygon, disk, eps);
}
/*!
* \ingroup Intersection
* \brief Intersect a disk and a polygon in 3d space.
* \param polygon The polygon
* \param quad The quadrilateral
* \param eps Tolerance to be used for floating point comparisons
*/
template<class ctype>
Intersection< Disk<ctype>, Polygon<ctype, 3> >
intersect(const Disk<ctype>& disk, const Polygon<ctype, 3>& polygon, ctype eps)
{ return intersect(polygon, disk, eps); }
/*!
* \ingroup Intersection
* \brief Intersect a lateral cylinder surface and a disk.
......
......@@ -195,6 +195,22 @@ struct IntersectionTraits< Disk<ctype>, Quadrilateral<ctype, 3> >
: public IntersectionTraits< Quadrilateral<ctype, 3>, Disk<ctype> >
{};
//! Result type of the intersection of a polygon and a disk in 3d space
template<class ctype>
struct IntersectionTraits< Polygon<ctype, 3>, Disk<ctype> >
{
using type = std::variant< Point<ctype, 3>,
Segment<ctype, 3>,
TopoDS_Face,
EmptyIntersection<3> >;
};
//! Result type of the intersection of a disk and a polygon in 3d space
template<class ctype>
struct IntersectionTraits< Disk<ctype>, Polygon<ctype, 3> >
: public IntersectionTraits< Polygon<ctype, 3>, Disk<ctype> >
{};
//! Result type of the intersection of a cylinder surface and a disk
template<class ctype>
struct IntersectionTraits< CylinderSurface<ctype>, Disk<ctype> >
......
......@@ -180,6 +180,9 @@ void registerIntersectionFunctions(py::module& module)
Detail::registerIntersectionFunction<Quad, Disk, ctype>(module, "Quadrilateral", "Disk");
Detail::registerIntersectionFunction<Disk, Quad, ctype>(module, "Disk", "Quadrilateral");
Detail::registerIntersectionFunction<Quad, Disk, ctype>(module, "Polygon", "Disk");
Detail::registerIntersectionFunction<Disk, Quad, ctype>(module, "Disk", "Polygon");
Detail::registerIntersectionFunction<FaceWrapper, Disk, ctype>(module, "TopoDS_Face_Wrapper", "Disk");
Detail::registerIntersectionFunction<Disk, FaceWrapper, ctype>(module, "Disk", "TopoDS_Face_Wrapper");
......
......@@ -52,9 +52,9 @@ frackit_add_test(NAME test_polygon_face_intersection
SOURCES test_polygon_face_intersection.cc
LABELS intersection)
# quadrilateral - disk
frackit_add_test(NAME test_quad_disk_intersection
SOURCES test_quad_disk_intersection.cc
# polygon - disk
frackit_add_test(NAME test_polygon_disk_intersection
SOURCES test_polygon_disk_intersection.cc
LABELS intersection)
# cylinder surface - disk
......
#include <vector>
#include <stdexcept>
#include <type_traits>
#include <frackit/geometry/quadrilateral.hh>
#include <frackit/geometry/polygon.hh>
#include <frackit/geometry/disk.hh>
#include <frackit/magnitude/length.hh>
#include <frackit/intersection/intersect.hh>
......@@ -48,25 +53,40 @@ void checkResultGeometry(const TopoDS_Face& face, IntersectionType expected)
std::cout << "Test passed" << std::endl;
}
//! test quadrilateral-disk intersections
int main()
// make quadrilateral instance
template<class Quad, class Point>
Quad makeQuad(const Point& p1, const Point& p2,
const Point& p3, const Point& p4, std::false_type)
{ return Quad(p1, p2, p3, p4); }
// make polygon instance
template<class Quad, class Point>
Quad makeQuad(const Point& p1, const Point& p2,
const Point& p3, const Point& p4, std::true_type)
{ return Quad(std::vector<Point>({p1, p2, p4, p3})); }
//! test quadrilateral/polygon - disk intersections
template<class QuadGeom>
void doTest()
{
using ctype = double;
using Quad = QuadGeom;
using ctype = typename Quad::ctype;
using Disk = Frackit::Disk<ctype>;
using Quad = Frackit::Quadrilateral<ctype, 3>;
using Point = typename Disk::Point;
using Direction = typename Disk::Direction;
using Vector = typename Direction::Vector;
constexpr bool isPolygonImpl = std::is_same_v<Quad, Frackit::Polygon<ctype, 3>>;
std::vector<ctype> scales({1.0e-5, 1, 1e5});
for (auto f : scales)
{
std::cout << "Checking scale factor " << f << std::endl;
Quad quad(Point(-0.5*f, -0.5*f, 0.0),
Point(0.5*f, -0.5*f, 0.0),
Point(-0.5*f, 0.5*f, 0.0),
Point(0.5*f, 0.5*f, 0.0));
auto quad = makeQuad<Quad>(Point(-0.5*f, -0.5*f, 0.0),
Point(0.5*f, -0.5*f, 0.0),
Point(-0.5*f, 0.5*f, 0.0),
Point(0.5*f, 0.5*f, 0.0),
std::integral_constant<bool, isPolygonImpl>());
// disk that intersects quad in a segment fully in quad
Direction e11(Vector(1.0, 0.0, 0.0));
......@@ -95,5 +115,12 @@ int main()
std::cout << "All tests passed" << std::endl;
}
}
int main()
{
using ctype = double;
doTest<Frackit::Quadrilateral<ctype, 3>>();
doTest<Frackit::Polygon<ctype, 3>>();
return 0;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment