PixelBorderDistance.hpp
Go to the documentation of this file.
1 /*
2  * PixelBorderDistance.h
3  *
4  * Created on: Aug 7, 2020
5  * Author: Ruben Grandia
6  * Institute: ETH Zurich
7  */
8 
9 #pragma once
10 
11 #include <algorithm>
12 #include <cassert>
13 #include <cmath>
14 
15 namespace grid_map {
16 namespace signed_distance_field {
17 
26 inline float pixelBorderDistance(float i, float j) {
27  return std::max(std::abs(i - j) - 0.5F, 0.0F);
28 }
29 
33 inline float squarePixelBorderDistance(float i, float j, float f) {
34  const float d{pixelBorderDistance(i, j)};
35  return d * d + f;
36 }
37 
38 namespace internal {
39 
43 inline float intersectionPointRightSideOfOrigin(float p, float fp) {
44  /*
45  * There are 5 different solutions
46  * In decreasing order:
47  * sol 1 in [p^2, inf]
48  * sol 2 in [bound, p^2]
49  * sol 3 in [-bound, bound]
50  * sol 4 in [-p^2, -bound]
51  * sol 5 in [-inf, -p^2]
52  */
53  const float pSquared{p * p};
54  if (fp > pSquared) {
55  return (pSquared + p + fp) / (2.0F * p); // sol 1
56  } else if (fp < -pSquared) {
57  return (pSquared - p + fp) / (2.0F * p); // sol 5
58  } else {
59  const float bound{pSquared - 2.0F * p + 1.0F}; // Always positive because (p > 0)
60  if (fp > bound) {
61  return 0.5F + std::sqrt(fp); // sol 2
62  } else if (fp < -bound) {
63  return p - 0.5F - std::sqrt(-fp); // sol 4
64  } else {
65  return (pSquared - p + fp) / (2.0F * p - 2.0F); // sol 3
66  }
67  }
68 }
69 
73 inline float intersectionOffsetFromOrigin(float p, float fp) {
74  if (p > 0.0F) {
76  } else {
77  // call with negative p and flip the result
78  return -intersectionPointRightSideOfOrigin(-p, fp);
79  }
80 }
81 
82 } // namespace internal
83 
89 inline float equidistancePoint(float q, float fq, float p, float fp) {
90  assert(q == p ||
91  std::abs(q - p) >= 1.0F); // Check that q and p are proper pixel locations: either the same pixel or non-overlapping pixels
92  assert((q == p) ? fp == fq : true); // Check when q and p are equal, the offsets are also equal
93 
94  if (fp == fq) { // quite common case when both pixels are of the same class (occupied / free)
95  return 0.5F * (p + q);
96  } else {
97  float df{fp - fq};
98  float dr{p - q};
99  return internal::intersectionOffsetFromOrigin(dr, df) + q;
100  }
101 }
102 
103 } // namespace signed_distance_field
104 } // namespace grid_map
float squarePixelBorderDistance(float i, float j, float f)
float intersectionPointRightSideOfOrigin(float p, float fp)
float pixelBorderDistance(float i, float j)
float equidistancePoint(float q, float fq, float p, float fp)
float intersectionOffsetFromOrigin(float p, float fp)


grid_map_sdf
Author(s): Takahiro Miki , Péter Fankhauser
autogenerated on Wed Jul 5 2023 02:23:42