24 #define DEFAULT_EPS std::numeric_limits<double>::epsilon()*10
31 explicit Approx(
const T& x,
double eps = DEFAULT_EPS)
35 template<
typename OtherDerived>
36 explicit Approx(
const Eigen::MatrixBase<OtherDerived>& x,
double eps = DEFAULT_EPS)
37 : _x(x.eval()), _eps(eps)
40 friend bool operator==(
const T& x1,
const Approx<T>& x2)
42 if constexpr(std::is_same_v<T,double>)
43 return std::fabs(x1-x2._x) < x2._eps;
45 else if(x1.size() != x2._x.size())
51 else if constexpr(std::is_same_v<T,Interval>)
53 if((x1.is_empty() && !x2._x.is_empty()) || (!x1.is_empty() && x2._x.is_empty()))
55 return (x1.lb() == x2._x.lb() || x1.lb() == Approx<double>(x2._x.lb(),x2._eps))
56 && (x1.ub() == x2._x.ub() || x1.ub() == Approx<double>(x2._x.ub(),x2._eps));
59 else if constexpr(std::is_same_v<T,Vector>
60 || std::is_same_v<T,IntervalVector>
61 || std::is_same_v<T,Row>
62 || std::is_same_v<T,IntervalRow>
63 || std::is_same_v<T,Matrix>
64 || std::is_same_v<T,IntervalMatrix>)
66 for(Index i = 0 ; i < x1.rows() ; i++)
67 for(Index j = 0 ; j < x1.cols() ; j++)
68 if(!(x1(i,j) == Approx<typename T::Scalar>(x2._x(i,j), x2._eps)))
75 assert_release_constexpr(
false &&
"Approx::operator== unhandled case");
80 friend std::ostream& operator<<(std::ostream& os,
const Approx<T>& x)
82 os <<
"Approx(" << x._x <<
")";
97 explicit Approx(
const Segment& x,
double eps = DEFAULT_EPS)
101 friend bool operator==(
const Segment& p1,
const Approx<Segment>& p2)
103 return (Approx<IntervalVector>(p1[0], p2._eps) == p2._x[0] && Approx<IntervalVector>(p1[1], p2._eps) == p2._x[1])
104 || (Approx<IntervalVector>(p1[1], p2._eps) == p2._x[0] && Approx<IntervalVector>(p1[0], p2._eps) == p2._x[1]);
107 friend std::ostream& operator<<(std::ostream& os,
const Approx<Segment>& x)
109 os <<
"Approx(" << x._x <<
")";
124 explicit Approx(
const Polygon& x,
double eps = DEFAULT_EPS)
128 friend bool operator==(
const Polygon& p1,
const Approx<Polygon>& p2)
130 size_t n = p1.edges().size();
131 if(p2._x.edges().size() != n)
135 for(i = 0 ; i < n ; i++)
136 if(Approx<Segment>(p1.edges()[0], p2._eps) == p2._x.edges()[i])
141 way = (Approx<Segment>(p1.edges()[1], p2._eps) == p2._x.edges()[(i+1)%n]) ? 1 : -1;
142 assert(way == 1 || (way == -1 && p1.edges()[1] == p2._x.edges()[(i-1+2*n)%n]));
144 for(
size_t j = 0 ; j < n ; j++)
145 if(Approx<Segment>(p1.edges()[j], p2._eps) != p2._x.edges()[(i+way*j+2*n)%n])
151 friend std::ostream& operator<<(std::ostream& os,
const Approx<Polygon>& x)
153 os <<
"Approx(" << x._x <<
")";
164 class Approx<std::pair<T,T>>
168 explicit Approx(
const std::pair<T,T>& x,
double eps = DEFAULT_EPS)
172 friend bool operator==(
const std::pair<T,T>& p1,
const Approx<std::pair<T,T>>& p2)
174 return Approx<T>(p2._x.first,p2._eps) == p1.first && Approx<T>(p2._x.second,p2._eps) == p1.second;
177 friend std::ostream& operator<<(std::ostream& os,
const Approx<std::pair<T,T>>& x)
179 os <<
"Approx(" << x._x.first <<
"," << x._x.second <<
")";
185 const std::pair<T,T> _x;
189 Approx(
const Polygon&,
double) ->
Represents a polygon (convex or non-convex) defined by its vertices enclosed in IntervalVectors.
Definition codac2_Polygon.h:29
Represents a geometric segment defined by two points enclosed in IntervalVectors.
Definition codac2_Segment.h:28
Definition codac2_OctaSym.h:21