summaryrefslogtreecommitdiff
path: root/matching/include/dual_point.h
diff options
context:
space:
mode:
Diffstat (limited to 'matching/include/dual_point.h')
-rw-r--r--matching/include/dual_point.h107
1 files changed, 107 insertions, 0 deletions
diff --git a/matching/include/dual_point.h b/matching/include/dual_point.h
new file mode 100644
index 0000000..8438860
--- /dev/null
+++ b/matching/include/dual_point.h
@@ -0,0 +1,107 @@
+#ifndef MATCHING_DISTANCE_DUAL_POINT_H
+#define MATCHING_DISTANCE_DUAL_POINT_H
+
+#include <vector>
+#include <ostream>
+#include <tuple>
+
+#include "common_util.h"
+#include "box.h"
+
+namespace md {
+
+ enum class AxisType {
+ x_type, y_type
+ };
+ enum class AngleType {
+ flat, steep
+ };
+
+ // class has two flags of AxisType and AngleType.
+ // ATTENTION. == operator is not overloaded,
+ // so, e.g., line y = x has 4 different non-equal representation.
+ // we are unlikely to ever need this, because 4 cases are
+ // always treated separately.
+ template<class Real_>
+ class DualPoint {
+ public:
+ using Real = Real_;
+
+ DualPoint() = default;
+
+ DualPoint(const DualPoint&) = default;
+
+ DualPoint(DualPoint&&) = default;
+
+ DualPoint& operator=(const DualPoint& other)& = default;
+
+ DualPoint& operator=(DualPoint&& other) = default;
+
+ DualPoint(AxisType axis_type, AngleType angle_type, Real lambda, Real mu);
+
+ Real lambda() const { return lambda_; }
+
+ Real mu() const { return mu_; }
+
+ // angle between line and x-axis
+ Real gamma() const;
+
+ bool is_steep() const { return angle_type_ == AngleType::steep; }
+
+ bool is_flat() const { return angle_type_ == AngleType::flat; }
+
+ bool is_x_type() const { return axis_type_ == AxisType::x_type; }
+
+ bool is_y_type() const { return axis_type_ == AxisType::y_type; }
+
+ bool operator<(const DualPoint& rhs) const;
+
+ AxisType axis_type() const { return axis_type_; }
+ AngleType angle_type() const { return angle_type_; }
+
+ // throw exception, if fields are invalid
+ // return true otherwise
+ bool sanity_check() const;
+
+ Real weighted_push(Point<Real> p) const;
+ Point<Real> push(Point<Real> p) const;
+
+ bool is_horizontal() const;
+ bool is_vertical() const;
+
+ bool goes_below(Point<Real> p) const;
+ bool goes_above(Point<Real> p) const;
+
+ bool contains(Point<Real> p) const;
+
+ Real x_slope() const;
+ Real y_slope() const;
+
+ Real x_intercept() const;
+ Real y_intercept() const;
+
+ Real x_from_y(Real y) const;
+ Real y_from_x(Real x) const;
+
+ Real weight() const;
+
+ bool operator==(const DualPoint& other) const;
+
+ private:
+ AxisType axis_type_ {AxisType::y_type};
+ AngleType angle_type_ {AngleType::flat};
+ // both initial values are invalid: lambda must be between 0 and 1
+ Real lambda_ {-1.0};
+ Real mu_ {-1.0};
+ };
+
+ template<class Real>
+ std::ostream& operator<<(std::ostream& os, const DualPoint<Real>& dp);
+
+ template<class Real>
+ DualPoint<Real> midpoint(DualPoint<Real> x, DualPoint<Real> y);
+};
+
+#include "dual_point.hpp"
+
+#endif //MATCHING_DISTANCE_DUAL_POINT_H