点到折线最短距离所在点距离折线起点的累积距离
2015-07-08 21:08
393 查看
点到折线最短距离所在点 距离 折线起点 的累积距离
using System; using System.Collections.Generic; using System.Linq; using System.Text; using ESRI.ArcGIS.Geometry; using RGeos.Geometry namespace RGeos.Geometry { public class CulmulateDistance { /// <summary> /// 点到折线最短距离处距离折线起点的累积距离 /// </summary> /// <param name="P">任意一点</param> /// <param name="polyline">折线</param> /// <returns></returns> public static double CulmulateDist_Point_to_Polyline(IPoint P, IPolyline polyline) { ISegmentCollection segs = polyline as ISegmentCollection; double min = double.MaxValue; int segIndex = -1;//最短距离所在档的索引 for (int i = 0; i < segs.SegmentCount; i++) { //点到每条线段的最短距离 double dis = Dist_Point_to_Segment(P, segs.get_Segment(i)); if (dis < min) { min = dis; segIndex = i;//取出最小的一个 } } double culmulateDis = 0; for (int i = 0; i < segs.SegmentCount; i++) { if (segIndex != i) { culmulateDis += segs.get_Segment(i).Length; } else { ISegment current = segs.get_Segment(i); Vector3d v = new Vector3d(); v.X = current.ToPoint.X - current.FromPoint.X; v.Y = current.ToPoint.Y - current.FromPoint.Y; Vector3d w = new Vector3d(); w.X = P.X - current.FromPoint.X; w.Y = P.Y - current.FromPoint.Y; double c1 = dot(w, v);//投影长度 if (c1 <= 0)//这种情况最短距离在该线段的起点处 { break; } double c2 = dot(v, v); if (c2 <= c1)//这种情况最短距离在该线段的终点处 { culmulateDis += Math.Sqrt(c2); break; } double b = c1 / c2; culmulateDis += Math.Sqrt(c1); IPoint Pb = new PointClass(); Pb.X = current.FromPoint.X + b * v.X; Pb.Y = current.FromPoint.Y + b * v.Y; break; } } return culmulateDis; } public static IPoint GetCentrePoint(IPolygon polygon) { IArea pArea = polygon as IArea; IPoint pt = new PointClass(); pt.X = pArea.Centroid.X; pt.Y = pArea.Centroid.Y; return pt; } public static double Dist_Point_to_Segment(IPoint P, ISegment S) { Vector3d v = new Vector3d(); v.X = S.ToPoint.X - S.FromPoint.X; v.Y = S.ToPoint.Y - S.FromPoint.Y; Vector3d w = new Vector3d(); w.X = P.X - S.FromPoint.X; w.Y = P.Y - S.FromPoint.Y; double c1 = dot(w, v); if (c1 <= 0) return d(P, S.FromPoint); double c2 = dot(v, v); if (c2 <= c1) return d(P, S.ToPoint); double b = c1 / c2; IPoint Pb = new PointClass(); Pb.X = S.FromPoint.X + b * v.X; Pb.Y = S.FromPoint.Y + b * v.Y; return d(P, Pb); } /// <summary> /// 向量的模 /// </summary> /// <param name="v"></param> /// <returns></returns> public static double norm(Vector3d v) { return Math.Sqrt(dot2(v, v)); // norm = length of vector } /// <summary> /// 2D数量积,点乘 /// </summary> /// <param name="u"></param> /// <param name="v"></param> /// <returns></returns> public static double dot2(Vector3d u, Vector3d v) { return ((u).X * (v).X + (u).Y * (v).Y); } public static double dot(Vector3d u, Vector3d v) { return ((u).X * (v).X + (u).Y * (v).Y + (u).Z * (v).Z); } public static double d(IPoint P, IPoint P1) { return Math.Sqrt((P1.X - P.X) * (P1.X - P.X) + (P1.Y - P.Y) * (P1.Y - P.Y)); } /// <param name="x">增量X</param> /// <param name="y">增量Y</param> /// <returns>象限角</returns> public static double GetQuadrantAngle(double x, double y) { double theta = Math.Atan(y / x); if (x > 0 && y == 0) return 0; if (x == 0 && y > 0) return Math.PI / 2; if (x < 0 && y == 0) return Math.PI; if (x == 0 && y < 0) return 3 * Math.PI / 2; if (x > 0 && y > 0) return theta; if (x > 0 && y < 0) return Math.PI * 2 + theta; if (x < 0 && y > 0) return theta + Math.PI; if (x < 0 && y < 0) return theta + Math.PI; return theta; } } }
相关文章推荐
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法
- 基于C++实现的各种内部排序算法汇总
- C++线性时间的排序算法分析
- C++实现汉诺塔算法经典实例
- PHP实现克鲁斯卡尔算法实例解析
- C#常见算法面试题小结