環境:
- .net 6.0
- NetTopologySuite 2.5.0
- vs2022
- 平面二維
一、夾角計算
1.1 計算向量與x軸正方向的夾角
方法:
AngleUtility.Angle(Coordinate p)
下圖上的t2即為p,之是以這麼寫是為了和 AngleUtility.AngleBetweenOriented
做比較
注意:
- 結果逆時針為正,順時針為負;
- 相對于x軸;
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLjZTO1IjZ1cDNkVjY2YWN5gTNhRzY5IWYjhTNmVmYhhzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
執行個體:
1.2 計算兩條線段的夾角(區分方向)
方法:
AngleUtility.AngleBetweenOriented(Coordinate tip1, Coordinate tail, Coordinate tip2)
注意:
- 結果逆時針為正,順時針為負;
- ∠t1 tail t2;
執行個體:
1.3 計算兩條線段的夾角(不區分方向)
方法:
AngleUtility.AngleBetween(Coordinate tip1, Coordinate tail, Coordinate tip2)
由于不考慮方向,兩個線段的夾角總是處在 [0,180°) 範圍内。
不在畫圖顯示。
二、檢測一個環是否是簡單的(IsSimple)
2.1 簡單的示例(IsSimple=true):
2.2 複雜的示例(IsSimple=false):
三、多邊形的凹凸(convex/concave) 和 順(Clockwise)/逆(CounterClockwise)時針
3.1 多邊形的凹凸定義:
凸多邊形(convex): 所有的内角都小于180°;
凹多邊形(concave): 至少有一個内角大于180°;
示例:
3.2 多邊形的順逆時針
因為多邊形是一個環狀的東西,是以在平面上可以用順逆時針表示它的方向,這在很多計算方法中有用。
多邊形的方向應該是整體來看,單看局部點位是無法判斷的,如下(僅憑下面三黑點兩個紅線是判斷不出來的):
判斷方法,
NetTopologySuite
已提供,對于上圖判斷示例如下:
3.3 計算多邊形的各個内角值(判斷凹凸性)
計算内角,我們可以使用
NetTopologySuite
的方法:
AngleBetweenOriented
,這裡我們需要按照點位順序計算。
比如:p1、p2、p3、p4、p5
那麼,計算點p2的内角為:∠p1p2p3,再結合多邊形的方向(順逆時針),将它轉為(0,360)範圍内。
下圖為,順逆時針和凹凸組合下的示意圖:
由此可得計算的方法,如下:
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;
}
}
驗證如下圖形: