GIS 二维常见算法-入门篇
来源:互联网 发布:远视 眼镜 知乎 编辑:程序博客网 时间:2024/06/10 00:03
处理点与线的关系,线与线的关系的算法等等,如有错误,欢迎指正。
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace PointLinePositionRelation{ #region Entity /// <summary> /// Entity Point /// </summary> public class Point { public Point(double x, double y) { this.x = x; this.y = y; } private double x; public double X { get { return x; } set { x = value; } } private double y; public double Y { get { return y; } set { y = value; } } } /// <summary> /// Entity of line /// </summary> public class Line { public Line() { } public Line(List<Point> _points) { this.points = _points; } private List<Point> points = new List<Point>(); public List<Point> Points { get { return points; } } public bool AddPoint(Point p) { bool success = false; if (!points.Contains(p)) { points.Add(p); success = true; } return success; } public bool RemovePoint(Point p) { bool success = false; if (points.Contains(p)) { points.Remove(p); success = true; } return success; } public bool UpdatePoint(Point src_p, Point tar_p) { bool success = false; if (points.Contains(src_p)) { src_p.X = tar_p.X; src_p.Y = tar_p.Y; success = true; } return success; } } /// <summary> /// Position Status /// </summary> enum Position { LEFT = 0, RIGHT = 1, ON_K = 2, UP = 3, DOWN = 4, ON = 5, ERROE = 6 } #endregion #region Function public static class PointLineAlgorithems { #region Algorithems /// <summary> /// return the traingle degree /// </summary> /// <param name="tupe"></param> /// tuple item1:the first point /// tuple item2:the last point /// tuple item3:the middle point /// <returns></returns> public static double GetTraingleDegree(Tuple<Point, Point, Point> tupe) { double distance1 = GetDistance(tupe.Item1, tupe.Item2); double distance2 = GetDistance(tupe.Item1, tupe.Item3); double distance3 = GetDistance(tupe.Item2, tupe.Item3); return Math.Acos(Math.Pow(distance1,2)+Math.Pow(distance2,2)-Math.Pow(distance3,2)/2*distance1*distance2); } /// <summary> /// to judage point and line position /// </summary> /// <param name="l"></param> /// <param name="p"></param> /// <returns></returns> public static string JudgePointLineRelation(Line l, Point p) { //y = kx + b //the k of line combine with two points double k; //the b of line double b; //the result string POSITION = string.Empty; //this function is to deal with one point with a line with two points //if line point is not 2,you should split to two or more lines with //two points,so here we return string.Empty if (l.Points.Count != 2 || p == null) return string.Empty; //if the X value of two points are the same //wo can not get k,then we can deal it as follows if (l.Points[0].X == l.Points[1].X) { if (p.X > l.Points[0].X) POSITION = "LEFT"; else if (p.X < l.Points[0].X) POSITION = "RIGHT"; else if (p.X == l.Points[0].X) POSITION = "ON"; //else POSITION = "ERROR_K"; } //if the k is not zero,we can deal it as follows else { k = (l.Points[0].Y - l.Points[1].Y) / (l.Points[0].X - l.Points[1].X); b = ((l.Points[0].X * l.Points[1].Y) - (l.Points[0].Y * l.Points[1].X)) / (l.Points[0].X - l.Points[1].X); if (p.Y > k * p.X + b) POSITION = "UP"; else if (p.Y < k * p.X + b) POSITION = "DOWN"; else if (p.Y == k * p.X + b) POSITION = "ON"; //else POSITION = "ERROR_N"; } return POSITION; } /// <summary> /// to judage if two line clips /// </summary> /// <param name="src"></param> /// <param name="tar"></param> /// <returns></returns> public static int? JudageLinesRelation(Line src, Line tar) { //if point count of line is less then 2,we do not //deal with this if (src.Points.Count < 2 || tar.Points.Count < 2) return null; Point p = null; Line l = null; string flag = string.Empty; //falg of clip,if not clip 1,else 0 int? clip = 1; for (int i = 0; i < src.Points.Count; i++) { //the first loop point p = new Point(src.Points[i].X, src.Points[i].Y); //the loop for tar line for (int j = 0; j + 1 < tar.Points.Count; j++) { //temp line with two points l = new Line(); l.AddPoint(tar.Points[j]); l.AddPoint(tar.Points[j + 1]); //if the value of flag is Null or Empty,means flag has not been given value if (string.IsNullOrEmpty(flag)) flag = JudgePointLineRelation(l, p); else { //if the new point position is not the same as the old point,the two line cliped //there is no need to contine the loop,we change the flag value to 0(means two line cliped) if (flag != JudgePointLineRelation(l, p)) { clip = 0; break; } } } } return clip; } /// <summary> /// get distance of two points /// </summary> /// <param name="src"></param> /// <param name="tar"></param> /// <returns></returns> public static double GetDistance(Point src, Point tar) { if (src.X == tar.X && src.Y == tar.Y) return 0; return Math.Sqrt(Math.Pow(Math.Abs(src.X - tar.X), 2) + Math.Pow(Math.Abs(src.Y - tar.Y), 2)); } /// <summary> /// To get min distance of two lines /// </summary> /// <param name="src"></param> /// <param name="tar"></param> /// <returns></returns> public static Tuple<double?, int?, int?> CalcMinDistance(Line src, Line tar) { //if the point count less than 2,we do not think it is a line. if (src.Points.Count < 2 || tar.Points.Count < 2) return null; //if the two line cliped,we do not deal with this situation if (0 == JudageLinesRelation(src, tar)) return null; #region Params //the min distance point src_index int? src_index = null; //the min distance point tar_index int? tar_index = null; //the temp value to keep the distance double? temp = null; //the min distance double dist = 0; #endregion //loop for the src line for (int i = 0; i < src.Points.Count; i++) { //loop for tar line for (int j = 0; j < tar.Points.Count; j++) { //the distance dist = GetDistance(src.Points[i], tar.Points[j]); //if the temp has not been given value if (null == temp) { temp = dist; src_index = i; tar_index = j; } else { //if the new value < temp,then keep the min value if (temp > dist) { temp = dist; src_index = i; tar_index = j; } } } } return new Tuple<double?, int?, int?>(temp, src_index, tar_index); } /// <summary> /// to judage the two line direction /// </summary> /// <param name="src_line"></param> /// <param name="tar_line"></param> /// <returns></returns> public static bool? JudageLineDirection(Line src_line, Line tar_line) { //if the point count of line less than 2,we do not deal with this if (src_line.Points.Count < 2 || tar_line.Points.Count < 2) return null; //the boolean flag,if the two line are the same direction,then true //else the flag will be false.Note:if the exception has occoured //the value null will be returned bool flag = false; //the line temp value. //Note:this line is not always represent the min distance line Line line = null; //the temp value to recored the result that the position of point on //src_line position and temp line(mostly min distance line) string src_temp = string.Empty; //the temp value to recored the result that the position of point on //tar_line position and temp line(mostly min distance line) string tar_temp = string.Empty; //the temp tuple value that recored the min distance line information //item1:min distance value //item2:the index of the point on src_line //item3:the index of the point on tar_line Tuple<double?, int?, int?> tuple = CalcMinDistance(src_line, tar_line); //if the min diatance information is not null if (tuple != null) { //the index of src_line or tar_line type is int?,if index has not been given value //the value will be null,else will be the index of point,which combine the min distance line if (tuple.Item2.HasValue && tuple.Item3.HasValue) { #region different situation //if the index of point which combine the min distance line is less than count if ((tuple.Item2.Value < src_line.Points.Count - 1) && (tuple.Item2.Value < tar_line.Points.Count - 1)) { line = new Line(new List<Point> { src_line.Points[tuple.Item2.Value], tar_line.Points[tuple.Item3.Value] }); src_temp = JudgePointLineRelation(line, src_line.Points[tuple.Item2.Value + 1]); tar_temp = JudgePointLineRelation(line, tar_line.Points[tuple.Item3.Value + 1]); } //if the index of point of src_line equals count-1 else if (tuple.Item2.Value == src_line.Points.Count - 1) { line = new Line(new List<Point> { src_line.Points[tuple.Item2.Value - 1], tar_line.Points[tuple.Item3.Value] }); src_temp = JudgePointLineRelation(line, src_line.Points[tuple.Item2.Value]); tar_temp = JudgePointLineRelation(line, tar_line.Points[tuple.Item3.Value + 1]); } //if the index of point of tar_line equals count-1 else if (tuple.Item3.Value == tar_line.Points.Count - 1) { line = new Line(new List<Point> { src_line.Points[tuple.Item2.Value], tar_line.Points[tuple.Item3.Value - 1] }); src_temp = JudgePointLineRelation(line, src_line.Points[tuple.Item2.Value + 1]); tar_temp = JudgePointLineRelation(line, tar_line.Points[tuple.Item3.Value]); } //both of them are equals count - 1 else { line = new Line(new List<Point> { src_line.Points[tuple.Item2.Value], tar_line.Points[tuple.Item3.Value] }); src_temp = JudgePointLineRelation(line, src_line.Points[tuple.Item2.Value - 1]); tar_temp = JudgePointLineRelation(line, tar_line.Points[tuple.Item3.Value - 1]); } #endregion } else { //if did not get min distance information,return null return null; } //if the result are different,different direction //else the same direction if ((src_temp != tar_temp) && (src_temp != "ON" && tar_temp != "ON")) { flag = false; } else { flag = true; } } return flag; } #endregion } #endregion}
0 0
- GIS 二维常见算法-入门篇
- Java二维数组及常见相关算法讲解
- GIS算法源码集合
- GIS 算法,计算箭头
- GIS算法资料
- GIS基本算法基础
- gis矢量切片算法
- GIS源码下载与GIS经典算法
- GIS源码下载与GIS经典算法
- GIS从二维到三维有多远
- 【GIS】GDAL之OGR入门
- GIS开发-地图接入入门
- GIS空间分析算法 内容简介
- GIS的几个算法理论
- GIS算法的一点理解
- GIS常用的几何算法
- GIS算法-底层开发使用
- GIS常用的几何算法
- TS流解析-提取PSI信息
- Iterator迭代器及增强FOR(for-each)
- BSON C 学习笔记
- Srping 注解注入
- android log你不知道的小技巧
- GIS 二维常见算法-入门篇
- 从RDA平台HX8357D屏驱动分析platform_driver_register、platform_device_register
- Spring配置文件的
- 黑马程序员-c语言学习之指针的心得
- 这是一个杨辉三角形
- Android Fragment 真正的完全解析(上)
- 查找最大元素
- JIRA的快捷键一览
- VC中获得当前日期和时间