这是几何问题,在GIS里经常会遇到的问题。问题的来由是由于本人在开发室内定位引擎系统。
可以回到数学知识自己解决这个问题,不过有专业的库解决这些几何问题。本人搜到两个办法:
第一个办法通过NuGet添加一个叫NetTopologySuite的库。
直接上代码举例子:
using NetTopologySuite.Geometries;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
LineSegment lineSeg1 = new LineSegment(1, 1, 0, 3);
LineSegment lineSeg2 = new LineSegment(3, 1, 5, 2);
GeoAPI.Geometries.Coordinate cor = lineSeg1.Intersection(lineSeg2); // 线段的交点
cor = lineSeg1.LineIntersection(lineSeg2);// 线条(线段无限延长)的交点
}
}
}
LineSegment代表线段类,它有两个函数,Intersection()和LineIntersection(),前者是求线段的交点,有交点则返回交点的值,如果无交点则返回null;后者是线条(两个线段无线延长)的交点,同样的无交点则返回null。
另外一种方法:通过NuGet添加一个叫MathNet.Spatial的库。
上代码举例:
using System;
using System.Collections.Generic;
using MathNet.Spatial.Euclidean;
namespace ConsoleApplication2
{
public static class myExtendLine2D
{
/// <summary>
/// 判断两个线段(不延长)之间是否相交,如果相交给出相交的点。(使用了MathNet.Spatial库,来自NuGet)
/// </summary>
/// <param name="segmentline1"></param>
/// <param name="segmentline2"></param>
/// <returns></returns>
public static Point2D? IntersecWithSegmentLine(this Line2D segmentline1, Line2D segmentline2)
{
Point2D? intersecPoint = segmentline1.IntersectWith(segmentline2);
if (intersecPoint.Equals(null))
return null;
if (intersecPoint.Value.X > Math.Max(segmentline1.StartPoint.X, segmentline1.EndPoint.X) ||
intersecPoint.Value.X < Math.Min(segmentline1.StartPoint.X, segmentline1.EndPoint.X) ||
intersecPoint.Value.X > Math.Max(segmentline2.StartPoint.X, segmentline2.EndPoint.X) ||
intersecPoint.Value.X < Math.Min(segmentline2.StartPoint.X, segmentline2.EndPoint.X) ||
intersecPoint.Value.Y > Math.Max(segmentline1.StartPoint.Y, segmentline1.EndPoint.Y) ||
intersecPoint.Value.Y < Math.Min(segmentline1.StartPoint.Y, segmentline1.EndPoint.Y) ||
intersecPoint.Value.Y > Math.Max(segmentline2.StartPoint.Y, segmentline2.EndPoint.Y) ||
intersecPoint.Value.Y < Math.Min(segmentline2.StartPoint.Y, segmentline2.EndPoint.Y)
)
{
return null;
}
return intersecPoint;
}
}
class Program
{
static void Main(string[] args)
{
Line2D Line1 = new Line2D(new Point2D(0, 0), new Point2D(2, 2));
Line2D Line2 = new Line2D(new Point2D(1, -9), new Point2D(4, 0));
Point2D? r = Line1.IntersecWithSegmentLine(Line2);
//List<Point2D> points = new List<Point2D>() { new Point2D(1,1),new Point2D(0,3) ,new Point2D(2,5), new Point2D(4,4), new Point2D(5,2), new Point2D(3,1)};
//Point2D p = new Point2D(3,5);
//bool bin1 = Polygon2D.IsPointInPolygon(p, new Polygon2D(points));
//Polygon2D p2d = new Polygon2D(points);
//bool bin2 = p2d.EnclosesPoint(p);
}
}
}
MathNet.Spatial貌似没有计算线段交点的,但是有计算线条(线段无线延长)的交点函数IntersectWith(),因此本人扩展了一个新的函数IntersectWithSegmentLine()函数来计算线段的交点。
(上面代码中注释的是:MathNet.Spatial自带的可以判断一个点是否在某个多边形内部的例子,有两个函数:IsPointInPolygon和EnclosesPoint())
不好意思上面的这个代码有误!
参考下面的文章: