Mantid
Loading...
Searching...
No Matches
PolygonEdge.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7//-----------------------------------------------------------------------------
8// Includes
9//-----------------------------------------------------------------------------
12#include <limits>
13
14namespace Mantid::Geometry {
15using Kernel::V2D;
16
17namespace {
18// Smallest possible double value
19const double EPSILON = std::numeric_limits<double>::epsilon();
20} // namespace
21
22//-----------------------------------------------------------------------------
23// Public methods
24//-----------------------------------------------------------------------------
29 : m_start(start), m_end(end), m_dir(m_end - m_start) {}
30
36Kernel::V2D PolygonEdge::point(const double fraction) const { return start() + m_dir * fraction; }
37
38//-------------------------------------------------------------------------
39// Non-member functions
40//-------------------------------------------------------------------------
48 const V2D p2 = pt;
49 const V2D &a = edge.direction();
50 const V2D b = p2 - edge.start();
51 double sa = a.X() * b.Y() - b.X() * a.Y();
52 if (sa > 0.0) {
53 return OnLeft;
54 }
55 if (sa < 0.0) {
56 return OnRight;
57 }
58 if ((a.X() * b.X() < 0.0) || (a.Y() * b.Y() < 0.0)) {
59 return Behind;
60 }
61 if (a.norm() < b.norm()) {
62 return Beyond;
63 }
64 if (edge.start() == p2) {
65 return Origin;
66 }
67 if (edge.end() == p2) {
68 return Destination;
69 }
70 return Between;
71}
72
81PolygonEdge::Orientation orientation(const PolygonEdge &focusEdge, const PolygonEdge &refEdge, double &t) {
82 V2D normalToRef((refEdge.end().Y() - refEdge.start().Y()), (refEdge.start().X() - refEdge.end().X()));
83 double denom = normalToRef.scalar_prod(focusEdge.direction());
84 if (Kernel::equals(denom, 0.0)) {
85 PointClassification edgeClass = classify(focusEdge.start(), refEdge);
86 if (edgeClass == OnLeft || edgeClass == OnRight) {
88 } else {
90 }
91 }
92 V2D startDir = focusEdge.start() - refEdge.start();
93 double numer = normalToRef.scalar_prod(startDir);
94 t = -numer / denom;
95 return PolygonEdge::Skew;
96}
97
104PolygonEdge::Orientation crossingPoint(const PolygonEdge &edgeOne, const PolygonEdge &edgeTwo, V2D &crossPoint) {
105 using Kernel::gtEquals;
106 using Kernel::ltEquals;
107
108 double s(0.0);
109 PolygonEdge::Orientation classe = orientation(edgeOne, edgeTwo, s);
110 if (classe == PolygonEdge::Collinear || classe == PolygonEdge::Parallel) {
111 return classe;
112 }
113 double lene = edgeOne.direction().norm();
114 if ((s < -EPSILON * lene) || (s > 1.0 + EPSILON * lene)) {
116 }
117 double t(0.0);
118 orientation(edgeTwo, edgeOne, t);
119 double lenf = edgeTwo.direction().norm();
120 if (ltEquals(-EPSILON * lenf, t) && ltEquals(t, 1.0 + EPSILON * lenf)) {
121 if (ltEquals(t, EPSILON * lenf)) {
122 crossPoint = edgeTwo.start();
123 } else if (gtEquals(t, 1.0 - EPSILON * lenf)) {
124 crossPoint = edgeTwo.end();
125 } else if (ltEquals(s, EPSILON * lene)) {
126 crossPoint = edgeOne.start();
127 } else if (gtEquals(s, 1.0 - EPSILON * lene)) {
128 crossPoint = edgeOne.end();
129 } else {
130 crossPoint = edgeTwo.point(t);
131 }
133 } else {
135 }
136}
137
146 PolygonEdge::Orientation crossType) {
147 const auto &va = a.direction();
148 const auto &vb = b.direction();
149 if (crossType != PolygonEdge::Collinear) {
150 double ca = va.X() * vb.Y();
151 double cb = vb.X() * va.Y();
152 if (Kernel::gtEquals(ca, cb)) {
153 return (aclass != OnRight);
154 } else {
155 return (aclass != OnLeft);
156 }
157 } else {
158 return (aclass != Beyond);
159 }
160}
161
162} // namespace Mantid::Geometry
const double EPSILON(1.0E-10)
PolygonEdge Defines a directed edge between two points on a polygon.
Definition: PolygonEdge.h:23
const Kernel::V2D & end() const
Access the end point.
Definition: PolygonEdge.h:39
const Kernel::V2D & direction() const
Return the direction.
Definition: PolygonEdge.h:41
PolygonEdge()
Default constructor.
const Kernel::V2D & start() const
Access the start point.
Definition: PolygonEdge.h:37
Kernel::V2D point(const double fraction) const
Create a point a given fraction along this edge.
Definition: PolygonEdge.cpp:36
Orientation
Defines the orientation with respect to another edge.
Definition: PolygonEdge.h:26
@ SkewNoCross
Edges are at an angle and do not intersect.
Definition: PolygonEdge.h:31
@ Parallel
Edges point in the same direction.
Definition: PolygonEdge.h:28
@ Skew
Edges are at an angle to each other.
Definition: PolygonEdge.h:29
@ Collinear
Edges lie on the same line.
Definition: PolygonEdge.h:27
@ SkewCross
Edges are at an angle and intersect.
Definition: PolygonEdge.h:30
const Kernel::V2D m_dir
Direction vector.
Definition: PolygonEdge.h:54
Implements a 2-dimensional vector embedded in a 3D space, i.e.
Definition: V2D.h:29
double Y() const
Y position.
Definition: V2D.h:49
double scalar_prod(const V2D &other) const
Compute the scalar product with another vector.
Definition: V2D.h:133
double X() const
X position.
Definition: V2D.h:44
double norm() const
Compute the norm.
Definition: V2D.h:121
MANTID_GEOMETRY_DLL PolygonEdge::Orientation orientation(const PolygonEdge &focusEdge, const PolygonEdge &refEdge, double &t)
Calculate the orientation type of one edge wrt to another.
Definition: PolygonEdge.cpp:81
MANTID_GEOMETRY_DLL PointClassification classify(const Kernel::V2D &pt, const PolygonEdge &edge)
Helper function for classification.
Definition: PolygonEdge.cpp:47
MANTID_GEOMETRY_DLL bool edgeAimsAt(const PolygonEdge &a, const PolygonEdge &b, PointClassification aclass, PolygonEdge::Orientation crossType)
Return if the edges aim at each other.
MANTID_GEOMETRY_DLL PolygonEdge::Orientation crossingPoint(const PolygonEdge &edgeOne, const PolygonEdge &edgeTwo, Kernel::V2D &crossPoint)
Calculate the crossing point of one edge with wrt another.
PointClassification
Enumeration for point type w.r.t an edge.
Definition: PolygonEdge.h:58
@ Destination
Point equals edge destination.
Definition: PolygonEdge.h:65
@ OnRight
Point is to right of edge.
Definition: PolygonEdge.h:60
@ Between
Point is between edge origin and destination.
Definition: PolygonEdge.h:63
@ OnLeft
Point is to left of edge.
Definition: PolygonEdge.h:59
@ Origin
Point equals edge origin.
Definition: PolygonEdge.h:64
@ Behind
Point is left of edge origin.
Definition: PolygonEdge.h:62
@ Beyond
Point is right of edge destination.
Definition: PolygonEdge.h:61
MANTID_KERNEL_DLL bool equals(const T x, const T y)
Test for equality of doubles using compiler-defined precision.
MANTID_KERNEL_DLL bool ltEquals(const T x, const T y)
Test whether x<=y within machine precision.
MANTID_KERNEL_DLL bool gtEquals(const T x, const T y)
Test whether x>=y within machine precision.