Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
SutherlandHodgman.h
Go to the documentation of this file.
1/* This file is part of MoDELib, the Mechanics Of Defects Evolution Library.
2 *
3 *
4 * MoDELib is distributed without any warranty under the
5 * GNU General Public License (GPL) v2 <http://www.gnu.org/licenses/>.
6 */
7
8#ifndef model_SutherlandHodgman_H_
9#define model_SutherlandHodgman_H_
10
11#include <algorithm>
12#include <vector>
13#include <Eigen/Dense>
14
15namespace model
16{
18 {
19 public:
20 // The clipping polygon is convex and counterclockwise. The subject
21 // may be concave or self-intersecting; preserve its directed contour.
22 template<typename PointType>
23 constexpr static std::vector<PointType> clip(const std::vector<PointType>& subject,
24 const std::vector<PointType>& boundary)
25 {
26 if(boundary.empty() || subject.empty())
27 {
28 return {};
29 }
30 std::vector<PointType> ring=subject;
31 PointType a=boundary.back();
32 for(const auto& b : boundary)
33 {
34 if(ring.empty())
35 {
36 return {};
37 }
38 const PointType edge=b-a;
39 if(edge.squaredNorm()==0.0)
40 {
41 a=b;
42 continue;
43 }
44 const auto distance=[&](const PointType& point)
45 {
46 const PointType relative=point-a;
47 return edge(0)*relative(1)-edge(1)*relative(0);
48 };
49 std::vector<PointType> input;
50 input.swap(ring);
51 PointType start=input.back();
52 double startDistance=distance(start);
53 for(const auto& end : input)
54 {
55 const double endDistance=distance(end);
56 const bool startInside=startDistance>=0.0;
57 const bool endInside=endDistance>=0.0;
58 if(startInside!=endInside)
59 {
60 // Use the same signed distances for classification and
61 // interpolation. Opposite signs guarantee t in [0,1],
62 // even for an edge nearly coincident with the boundary.
63 // Intersecting infinite lines using absolute-coordinate
64 // determinants can instead extrapolate far beyond it.
65 const double t=std::clamp(startDistance/(startDistance-endDistance),0.0,1.0);
66 ring.push_back(start+t*(end-start));
67 }
68 if(endInside)
69 {
70 ring.push_back(end);
71 }
72 start=end;
73 startDistance=endDistance;
74 }
75 a=b;
76 }
77 return ring;
78 }
79 };
80}
81#endif
static constexpr std::vector< PointType > clip(const std::vector< PointType > &subject, const std::vector< PointType > &boundary)
final point of the source segment t
a
Definition int_R.m:14
b
Definition int_R.m:16
int end[2]