这个算法是去年8-9月份进行“煤矿三维巷道建模”开发中运用到的,总结一下:
这个算法是自己第一次实实在在地进行GIS算法学习开发,从中学习到很多东西。
很多解析几何的知识:象限角、向量、标架坐标系统。
首先是计算向量的象限角
View Code
1 /// <summary>
2 /// 获取由两个点所形成的向量的象限角度
3 /// </summary>
4 /// <param name="preCoord">第一个点的坐标</param>
5 /// <param name="nextCoord">第二个点的坐标</param>
6 /// <returns></returns>
7 public static double GetQuadrantAngle(IPoint preCoord, IPoint nextCoord)
8 {
9 return GetQuadrantAngle(nextCoord.X - preCoord.X, nextCoord.Y - preCoord.Y);
10 }
计算两个向量的夹角
View Code
1 /// <summary>
2 /// 获取由相邻的三个点所形成的两个向量之间的夹角
3 /// </summary>
4 /// <param name="preCoord">左边</param>
5 /// <param name="midCoord">中间点</param>
6 /// <param name="nextCoord">右边</param>
7 /// <returns></returns>
8 public static double GetIncludedAngel(IPoint preCoord, IPoint midCoord, IPoint nextCoord)
9 {
10 double innerProduct = (midCoord.X-preCoord.X ) * (nextCoord.X - midCoord.X) + (midCoord.Y -preCoord.Y ) * (nextCoord.Y - midCoord.Y);
11 double mode1 = Math.Sqrt(Math.Pow((preCoord.X- midCoord.X ), 2.0) + Math.Pow((midCoord.Y - preCoord.Y), 2.0));
12 double mode2 = Math.Sqrt(Math.Pow((midCoord.X-nextCoord.X ), 2.0) + Math.Pow((nextCoord.Y - midCoord.Y), 2.0));
13 return Math.Acos(innerProduct / (mode1 * mode2));
14 }
判断向量的转向
View Code
1 /// <summary>
2 /// 获取相邻三个点所形成的两个向量的交叉乘积
3 /// </summary>
4 /// <param name="preCoord">第一个节点坐标</param>
5 /// <param name="midCoord">第二个节点坐标</param>
6 /// <param name="nextCoord">第三个节点坐标</param>
7 /// <returns>相邻三个点所形成的两个向量的交叉乘积小于0逆时针,大于0顺时针,等于0共线</returns>
8 public static double GetVectorProduct(IPoint P0, IPoint P1, IPoint P2)
9 {
10 return (P2.X - P0.X) * (P1.Y - P0.Y) - (P2.Y - P0.Y)* (P1.X - P0.X) ;
11 }
计算向量的模:
View Code
1 /// <summary>
2 /// 获取由两个点所形成的向量的模(长度)
3 /// </summary>
4 /// <param name="preCoord">第一个点</param>
5 /// <param name="nextCoord">第二个点</param>
6 /// <returns>由两个点所形成的向量的模(长度)</returns>
7 public static double GetDistance(IPoint preCoord, IPoint nextCoord)
8 {
9 return Math.Sqrt(Math.Pow((nextCoord.X - preCoord.X), 2) + Math.Pow((nextCoord.Y - preCoord.Y), 2));
10 }
11 /// <summary>
12 /// 获取由3维空间两个点所形成的向量的模(长度)
13 /// </summary>
14 /// <param name="preCoord">第一个点</param>
15 /// <param name="nextCoord">第二个点</param>
16 /// <returns>由两个点所形成的向量的模(长度)</returns>
17 public static double GetDistance3D(IPoint preCoord, IPoint nextCoord)
18 {
19 return Math.Sqrt(Math.Pow((nextCoord.X - preCoord.X), 2) + Math.Pow((nextCoord.Y - preCoord.Y), 2) + Math.Pow((nextCoord.Z - preCoord.Z), 2));
20 }
根据线的节点计算左右缓冲点坐标,平头和圆头。实现这个算法的关键是节点插入,对于拐点采用圆弧拟合。首先根据矢量叉积判断前后线的转向,开发中根据点,缓冲半径,象限角计算左右缓冲点。在开发中感觉到算法设计很重要的一点就是数据结构的设计。
本文代码参考了网上的一些源码,但是由于有些时间了,原链接找不到了!在此对作者表示感谢!