天天看點

c#: NetTopologySuite凹凸多邊形計算

環境:

  • .net 6.0
  • NetTopologySuite 2.5.0
  • vs2022
  • 平面二維

一、夾角計算

1.1 計算向量與x軸正方向的夾角

方法:

AngleUtility.Angle(Coordinate p)

下圖上的t2即為p,之是以這麼寫是為了和

AngleUtility.AngleBetweenOriented

做比較

注意:

  • 結果逆時針為正,順時針為負;
  • 相對于x軸;
c#: NetTopologySuite凹凸多邊形計算

執行個體:

c#: NetTopologySuite凹凸多邊形計算

1.2 計算兩條線段的夾角(區分方向)

方法:

AngleUtility.AngleBetweenOriented(Coordinate tip1, Coordinate tail, Coordinate tip2)

注意:

  • 結果逆時針為正,順時針為負;
  • ∠t1 tail t2;
c#: NetTopologySuite凹凸多邊形計算

執行個體:

c#: NetTopologySuite凹凸多邊形計算

1.3 計算兩條線段的夾角(不區分方向)

方法:

AngleUtility.AngleBetween(Coordinate tip1, Coordinate tail, Coordinate tip2)

由于不考慮方向,兩個線段的夾角總是處在 [0,180°) 範圍内。

不在畫圖顯示。

二、檢測一個環是否是簡單的(IsSimple)

2.1 簡單的示例(IsSimple=true):

c#: NetTopologySuite凹凸多邊形計算

2.2 複雜的示例(IsSimple=false):

c#: NetTopologySuite凹凸多邊形計算
c#: NetTopologySuite凹凸多邊形計算

三、多邊形的凹凸(convex/concave) 和 順(Clockwise)/逆(CounterClockwise)時針

3.1 多邊形的凹凸定義:

凸多邊形(convex): 所有的内角都小于180°;

凹多邊形(concave): 至少有一個内角大于180°;

示例:

c#: NetTopologySuite凹凸多邊形計算
c#: NetTopologySuite凹凸多邊形計算
c#: NetTopologySuite凹凸多邊形計算

3.2 多邊形的順逆時針

因為多邊形是一個環狀的東西,是以在平面上可以用順逆時針表示它的方向,這在很多計算方法中有用。

多邊形的方向應該是整體來看,單看局部點位是無法判斷的,如下(僅憑下面三黑點兩個紅線是判斷不出來的):

c#: NetTopologySuite凹凸多邊形計算

判斷方法,

NetTopologySuite

已提供,對于上圖判斷示例如下:

c#: NetTopologySuite凹凸多邊形計算

3.3 計算多邊形的各個内角值(判斷凹凸性)

計算内角,我們可以使用

NetTopologySuite

的方法:

AngleBetweenOriented

,這裡我們需要按照點位順序計算。

比如:p1、p2、p3、p4、p5

那麼,計算點p2的内角為:∠p1p2p3,再結合多邊形的方向(順逆時針),将它轉為(0,360)範圍内。

下圖為,順逆時針和凹凸組合下的示意圖:

c#: NetTopologySuite凹凸多邊形計算

由此可得計算的方法,如下:

public static class FuncLib
{
	public static List<double> AnalysisAngles(LinearRing ring)
	{
		if (ring == null || !ring.IsSimple) throw new Exception($"資料錯誤!");
		var angels = new List<double>();
		for (int i = 0, len = ring.Coordinates.Length - 1; i < len; i++)
		{
			var tail = ring[i];
			var t2 = ring[(i + 1) % len];
			var t1 = ring[(i - 1 + len) % len];

			var angle = AngleUtility.AngleBetweenOriented(t1, tail, t2);
			var angleDegree = AngleUtility.ToDegrees(angle);
			if (ring.IsCCW)
			{
				//逆時針
				if (angle > 0)
				{
					//concave
					angleDegree = 360 - angleDegree;
				}
				else if (angle < 0)
				{
					//convex
					angleDegree = -angleDegree;
				}
				else
				{
					//等于0 平行
					angleDegree = 180;
				}
			}
			else
			{
				//順時針
				if (angle < 0)
				{
					//concave
					angleDegree = angleDegree + 360;
				}
				else if (angle > 0)
				{
					//convex
				}
				else
				{
					//等于0 平行
					angleDegree = 180;
				}
			}
			angels.Add(angleDegree);
		}
		return angels;
	}
}
           

驗證如下圖形:

c#: NetTopologySuite凹凸多邊形計算

繼續閱讀