文档章节

C# 曲线上的点(二) 获取距离最近的点

o
 osc_a22drz29
发布于 2019/03/26 17:45
字数 459
阅读 8
收藏 0

钉钉、微博极速扩容黑科技,点击观看阿里云弹性计算年度发布会!>>>

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

 

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

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

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

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

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

 1     public static Point GetClosestPointOnPath(Point p, Geometry geometry)
 2     {
 3         PathGeometry pathGeometry = geometry.GetFlattenedPathGeometry();
 4 
 5         var points = pathGeometry.Figures.Select(f => GetClosestPointOnPathFigure(f, p))
 6             .OrderBy(t => t.Item2).FirstOrDefault();
 7         return points?.Item1 ?? new Point(0, 0);
 8     }
 9 
10     private static Tuple<Point, double> GetClosestPointOnPathFigure(PathFigure figure, Point p)
11     {
12         List<Tuple<Point, double>> closePoints = new List<Tuple<Point, double>>();
13         Point current = figure.StartPoint;
14         foreach (PathSegment s in figure.Segments)
15         {
16             PolyLineSegment segment = s as PolyLineSegment;
17             LineSegment line = s as LineSegment;
18             Point[] points;
19             if (segment != null)
20             {
21                 points = segment.Points.ToArray();
22             }
23             else if (line != null)
24             {
25                 points = new[] { line.Point };
26             }
27             else
28             {
29                 throw new InvalidOperationException();
30             }
31             foreach (Point next in points)
32             {
33                 Point closestPoint = GetClosestPointOnLine(current, next, p);
34                 double d = (closestPoint - p).LengthSquared;
35                 closePoints.Add(new Tuple<Point, double>(closestPoint, d));
36                 current = next;
37             }
38         }
39         return closePoints.OrderBy(t => t.Item2).First();
40     }

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

 1     private static Point GetClosestPointOnLine(Point start, Point end, Point p)
 2     {
 3         double length = (start - end).LengthSquared;
 4         if (Math.Abs(length) < 0.01)
 5         {
 6             return start;
 7         }
 8         Vector v = end - start;
 9         double param = (p - start) * v / length;
10         return (param < 0.0) ? start : (param > 1.0) ? end : (start + param * v);
11     }

效果图:

 

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
C# 曲线上的点(二) 获取距离最近的点

原文:C# 曲线上的点(二) 获取距离最近的点 如何在一条曲线上,获取到距离指定点最近的点位置? 与上一篇 C# 曲线上的点(一) 获取指定横坐标对应的纵坐标值 类似, 我们通过曲线上获取的密...

osc_c438keit
2019/04/09
2
0
ZedGraph怎样在双击图形后添加箭头标记

场景 在ZedGraph的曲线图上,双击图时会在图形上生成箭头符号标记。 效果 注: 博客主页: https://blog.csdn.net/badaoliumangqizhi 关注公众号 霸道的程序猿 获取编程相关电子书、教程推送...

osc_lrhgywny
2019/12/27
2
0
Winform中设置ZedGraph鼠标悬浮显示举例最近曲线上的点的坐标值和X轴与Y轴的标题

场景 Winform中设置ZedGraph鼠标双击获取距离最近曲线上的点的坐标值: https://blog.csdn.net/BADAOLIUMANGQIZHI/article/details/102466406 现在要实现鼠标悬浮时显示距离最近曲线上的点的...

osc_z8qxwya5
2019/11/19
3
0
GIS算法基础(八)基于距离变换的栅格骨架提取算法

一、为什么需要骨架提取 简单来说就是用于细化栅格,便于栅格数据转换为矢量数据 栅格格式向矢量格式转换是提取相同编号的栅格集合表示的边界,栅格点转换成矢量点,很简单,在坐标系确定的情...

osc_994n5tsc
2018/12/16
7
0
[原译]WPF绘制圆角多边形

原文:[原译]WPF绘制圆角多边形 介绍 最近,我发现我需要个圆角多边形。而且是需要在运行时从用户界面来绘制。WPF有多边形。但是不支持圆角。我搜索了一下。也没找到可行的现成例子。于是就自...

osc_vg6s3gcq
2018/07/17
2
0

没有更多内容

加载失败,请刷新页面

加载更多

Kubernetes发布SpringBoot项目过程总结

SpringBoot 项目创建完成后,通常会打成 jar 包运行,如果不使用 Kubernetes 可以直接通过 java -jar 或者脚本启动,如果需要发布到 Kubernetes 环境,那么需要编写 Dockerfile、构建镜像、推...

strict_nerd
05/23
0
0
👉 最新推出【Jenkins扩展篇-API实践|监控】教程🎉🎉🎉 助力全方位Jenkins管理!课程详情可添加小助手微信: proc_code。

本文分享自微信公众号 - DevOps云学堂(idevopsvip)。 如有侵权,请联系 support@oschina.cn 删除。 本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。...

泽阳DevOps
02/18
0
0
没错,用三方 Github 做授权登录就是这么简单!(OAuth2.0实战)

本文收录在个人博客:www.chengxy-nds.top,技术资源共享。 上一篇《OAuth2.0 的四种授权方式》文末说过,后续要来一波OAuth2.0实战,耽误了几天今儿终于补上了。 最近在做自己的开源项目(f...

程序员内点事
21分钟前
29
0
Docker可视化工具Portainer

前言 对于新手来说,还是要熟悉并掌握Docker命令,因为它的命令还是非常清晰简单的。随着逐渐熟悉命令后,为了提高工作效率我们可以考虑借助一些工具协助。目前业界对于Docker可视化工具比较...

ville
24分钟前
29
0
从 Git 仓库的 Commit 历史中移除敏感文件

在很多情况,我们由于疏忽会将一些敏感信息误传到 Git 仓库上面去。 尽管我们可以使用git rm将包含敏感信息文件删除掉,然后重新提交上传,文件就不会在仓库文件列表显示。 但是这并不能完全...

A_laoshiren
29分钟前
35
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部