47 BoundaryCheck(
bool checkLocal0,
bool checkLocal1,
double tolerance0 = 0,
48 double tolerance1 = 0);
56 operator bool()
const {
return (
m_type != Type::eNone); }
69 template <
typename Vector2Container>
81 const Vector2& upperRight)
const;
94 template <
typename Vector2Container>
107 const Vector2& upperRight)
const;
138 template <
typename Vector2Container>
140 const Vector2Container&
vertices)
const;
145 const Vector2& upperRight)
const;
175 return m_weight.inverse();
181 m_type(check ?
Type::eAbsolute :
Type::eNone) {}
184 double tolerance0,
double tolerance1)
186 m_tolerance(checkLocal0 ? tolerance0 : DBL_MAX,
187 checkLocal1 ? tolerance1 : DBL_MAX),
188 m_type(
Type::eAbsolute) {}
192 : m_weight(localCovariance.inverse()),
193 m_tolerance(sigmaMax, 0),
194 m_type(
Type::eChi2) {}
199 if (m_type == Type::eAbsolute) {
202 bc.
m_tolerance = (jacobian * m_tolerance).cwiseAbs();
205 (jacobian * m_weight.inverse() * jacobian.transpose()).inverse();
210 template <
typename Vector2Container>
213 if (m_type == Type::eNone) {
219 }
else if (m_tolerance ==
Vector2(0., 0.)) {
234 auto closestPoint = computeClosestPointOnPolygon(point, vertices);
235 return isTolerated(closestPoint - point);
241 const Vector2& upperRight)
const {
247 if (m_type == Type::eNone || m_type == Type::eAbsolute) {
250 computeEuclideanClosestPointOnRectangle(point, lowerLeft, upperRight);
255 {upperRight[0], lowerLeft[1]},
256 {upperRight[0], upperRight[1]},
257 {lowerLeft[0], upperRight[1]}};
258 closestPoint = computeClosestPointOnPolygon(point, vertices);
261 return isTolerated(closestPoint - point);
265 template <
typename Vector2Container>
269 double d = squaredNorm(point - computeClosestPointOnPolygon(point, vertices));
276 const Vector2& upperRight)
const {
277 if (m_type == Type::eNone || m_type == Type::eAbsolute) {
279 double d = (point - computeEuclideanClosestPointOnRectangle(
280 point, lowerLeft, upperRight))
289 {upperRight[0], lowerLeft[1]},
290 {upperRight[0], upperRight[1]},
291 {lowerLeft[0], upperRight[1]}};
297 if (m_type == Type::eNone) {
299 }
else if (m_type == Type::eAbsolute) {
300 return (std::abs(delta[0]) <= m_tolerance[0]) &&
301 (std::abs(delta[1]) <= m_tolerance[1]);
304 return (squaredNorm(delta) < (2 * m_tolerance[0]));
309 return (x.transpose() * m_weight *
x).
value();
312 template <
typename Vector2Container>
317 auto closestOnSegment = [&](
auto&& ll0,
auto&& ll1) {
320 auto weighted_n = m_weight *
n;
321 auto f = n.dot(weighted_n);
322 auto u = std::isnormal(
f)
323 ? (point - ll0).dot(weighted_n) /
f
326 return ll0 + std::clamp(
u, 0.0, 1.0) *
n;
333 auto closestDist = squaredNorm(closest - point);
335 for (++iv; iv !=
std::end(vertices); ++iv) {
338 Vector2 current = closestOnSegment(l0, l1);
339 auto currentDist = squaredNorm(current - point);
340 if (currentDist < closestDist) {
342 closestDist = currentDist;
347 if (squaredNorm(last - point) < closestDist) {
356 const Vector2& upperRight)
const {
375 double l0 = point[0],
l1 = point[1];
376 double loc0Min = lowerLeft[0], loc0Max = upperRight[0];
377 double loc1Min = lowerLeft[1], loc1Max = upperRight[1];
380 if (loc0Min <= l0 && l0 < loc0Max && loc1Min <= l1 && l1 < loc1Max) {
382 double dist = std::abs(loc0Max - l0);
385 double test = std::abs(loc0Min - l0);
391 test = std::abs(loc1Max - l1);
397 test = std::abs(loc1Min - l1);
399 return {l0, loc1Min};
406 return {loc0Max, loc1Max};
407 }
else if (l1 <= loc1Min) {
408 return {loc0Max, loc1Min};
410 return {loc0Max, l1};
412 }
else if (l0 < loc0Min) {
414 return {loc0Min, loc1Max};
415 }
else if (l1 <= loc1Min) {
416 return {loc0Min, loc1Min};
418 return {loc0Min, l1};
422 return {l0, loc1Max};
424 return {l0, loc1Min};