今日说法联系方式,忘忧草家园,杨一柳
如何在一条曲线上,获取到距离指定点最近的点位置?
与上一篇 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 }
效果图:
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
asp.net搭建博客,使用BlogEngine.NET+MySql搭建博客
网友评论