Skip to content

Commit fc090a1

Browse files
committed
geometry utils
Signed-off-by: silanus23 <[email protected]>
1 parent 190dfc7 commit fc090a1

File tree

1 file changed

+36
-33
lines changed

1 file changed

+36
-33
lines changed

nav2_util/include/nav2_util/geometry_utils.hpp

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -264,42 +264,45 @@ inline double cross_product_2d(
264264
* @param polygon Polygon to check if the point is inside
265265
* @return True if given point is inside polygon, otherwise false
266266
*/
267-
template<class PointT>
268-
inline bool isPointInsidePolygon(
269-
const double px, const double py, const std::vector<PointT> & polygon)
267+
inline double distanceToPoint(const geometry_msgs::msg::PoseStamped &global_pose,
268+
const geometry_msgs::msg::PoseStamped &target)
270269
{
271-
// Adaptation of Shimrat, Moshe. "Algorithm 112: position of point relative to polygon."
272-
// Communications of the ACM 5.8 (1962): 434.
273-
// Implementation of ray crossings algorithm for point in polygon task solving.
274-
// Y coordinate is fixed. Moving the ray on X+ axis starting from given point.
275-
// Odd number of intersections with polygon boundaries means the point is inside polygon.
276-
const int points_num = polygon.size();
277-
int i, j; // Polygon vertex iterators
278-
bool res = false; // Final result, initialized with already inverted value
279-
280-
// Starting from the edge where the last point of polygon is connected to the first
281-
i = points_num - 1;
282-
for (j = 0; j < points_num; j++) {
283-
// Checking the edge only if given point is between edge boundaries by Y coordinates.
284-
// One of the condition should contain equality in order to exclude the edges
285-
// parallel to X+ ray.
286-
if ((py <= polygon[i].y) == (py > polygon[j].y)) {
287-
// Calculating the intersection coordinate of X+ ray
288-
const double x_inter = polygon[i].x +
289-
(py - polygon[i].y) *
290-
(polygon[j].x - polygon[i].x) /
291-
(polygon[j].y - polygon[i].y);
292-
// If intersection with checked edge is greater than point x coordinate,
293-
// inverting the result
294-
if (x_inter > px) {
295-
res = !res;
296-
}
297-
}
298-
i = j;
299-
}
300-
return res;
270+
const double xDist = global_pose.pose.position.x - target.pose.position.x;
271+
const double yDist = global_pose.pose.position.y - target.pose.position.y;
272+
return std::hypot(xDist,yDist);
301273
}
302274

275+
/**
276+
* @brief Find the shortest distance to a vector
277+
* @param global_pose Robot's current or planned position
278+
* @param start Starting point of target vector
279+
* @param finish End point of target vector
280+
* @return int
281+
*/
282+
inline double distanceToSegment(
283+
const geometry_msgs::msg::PoseStamped & point,
284+
const geometry_msgs::msg::PoseStamped & start,
285+
const geometry_msgs::msg::PoseStamped & end)
286+
{
287+
const auto & p = point.pose.position;
288+
const auto & a = start.pose.position;
289+
const auto & b = end.pose.position;
290+
291+
const double seg_len_sq = distanceToPoint(start, end);
292+
if (seg_len_sq <= 1e-8) {
293+
return std::sqrt(distanceToPoint(start, end));
294+
}
295+
296+
const double dot = ((p.x - a.x) * (b.x - a.x)) + ((p.y - a.y) * (b.y - a.y));
297+
const double t = std::clamp(dot / seg_len_sq, 0.0, 1.0);
298+
299+
const double proj_x = a.x + t * (b.x - a.x);
300+
const double proj_y = a.y + t * (b.y - a.y);
301+
302+
const double dx_proj = p.x - proj_x;
303+
const double dy_proj = p.y - proj_y;
304+
return std::hypot(dx_proj,dy_proj);
305+
}
303306
} // namespace geometry_utils
304307
} // namespace nav2_util
305308

0 commit comments

Comments
 (0)