如何在一条曲线上,获取到距离指定点最近的点位置?

与上一篇 C# 曲线上的点(一) 获取指定横坐标对应的纵坐标值 类似,

我们通过曲线上获取的密集点,通过俩点之间连线,获取连线上最近的点。我们能够获取到一系列最近的点集,最近只取距离最小的点即可。

我们这样的算法是否精确呢?不算太精确,但是对于获取曲线上最近点,基本能满足。

斜率变化不大的线段,点不密集;斜率变化较大的线段,点相当密集,所以由此点集得到的最近点,是相对准确的。

实现方案,以下代码可以直接复用:

     public static Point GetClosestPointOnPath(Point p, Geometry geometry)
{
PathGeometry pathGeometry = geometry.GetFlattenedPathGeometry(); var points = pathGeometry.Figures.Select(f => GetClosestPointOnPathFigure(f, p))
.OrderBy(t => t.Item2).FirstOrDefault();
return points?.Item1 ?? new Point(, );
} private static Tuple<Point, double> GetClosestPointOnPathFigure(PathFigure figure, Point p)
{
List<Tuple<Point, double>> closePoints = new List<Tuple<Point, double>>();
Point current = figure.StartPoint;
foreach (PathSegment s in figure.Segments)
{
PolyLineSegment segment = s as PolyLineSegment;
LineSegment line = s as LineSegment;
Point[] points;
if (segment != null)
{
points = segment.Points.ToArray();
}
else if (line != null)
{
points = new[] { line.Point };
}
else
{
throw new InvalidOperationException();
}
foreach (Point next in points)
{
Point closestPoint = GetClosestPointOnLine(current, next, p);
double d = (closestPoint - p).LengthSquared;
closePoints.Add(new Tuple<Point, double>(closestPoint, d));
current = next;
}
}
return closePoints.OrderBy(t => t.Item2).First();
}

俩点之间的连线,如果当前点在此方向的投影为负或者大于当前长度,则取俩侧的点:

     private static Point GetClosestPointOnLine(Point start, Point end, Point p)
{
double length = (start - end).LengthSquared;
if (Math.Abs(length) < 0.01)
{
return start;
}
Vector v = end - start;
double param = (p - start) * v / length;
return (param < 0.0) ? start : (param > 1.0) ? end : (start + param * v);
}

效果图:

最新文章

  1. C#由变量捕获引起对闭包的思考
  2. Oracle 11g导出空表、少表的解决办法
  3. MicroERP软件更新记录2.1
  4. windows dir改成ls
  5. c# tcp备忘及networkstream.length此流不支持查找解决
  6. c#---部分;把数组或者结构体存入集合里,然后再从集合中取出之后,输出;foreach既可以用到提取数组重点额数据,也可以提取集合中的数据(前提是集合中的元素是相同数据类型)
  7. linux下tomcat服务的启动、关闭与错误跟踪
  8. file_operations结构体解析 1
  9. Top 10 Uses of a Message Queue
  10. HTML5之一HTML5简介
  11. 将数据库字段从float修改为decimal
  12. java MD5加密
  13. tinkphp5.0 traits 的引入
  14. Android监听自身卸载,弹出用户反馈调查
  15. vueRouter lazyLoad
  16. 关于矩阵A*b=A*c 中b是否等于c
  17. 1093. Count PAT’s (25)-统计字符串中PAT出现的个数
  18. Flutter学习笔记(四)--Flutter几个小知识点
  19. nginx正确服务react-router应用
  20. Hive学习之路 (二)Hive安装

热门文章

  1. java爬虫,爬取当当网数据
  2. 聊聊真实的 Android TV 开发技术栈
  3. 排序算法——(2)Python实现十大常用排序算法
  4. 工厂方法模式--java代码实现
  5. .net core 注入中的三种模式:Singleton、Scoped 和 Transient
  6. 粮草先行——Android折叠屏开发技术点(二)
  7. css 四周边框角加粗效果
  8. centos7下报错: import requests ImportError: No module named requests
  9. Netty3:分隔符和定长解码器
  10. Nginx 相关介绍