Revit二次開發-曲線三連:對curves進行排序
日常開發工作中,經常會遇到這樣的場景:
通過手動選擇(或其他手段),獲取到了一些頭尾相連的曲線List<Curves> curves(只限於Line和Arc),現在只知道它們是相連的,但是不知是否沿著一個方向,在集合中是否是按順序排列?
可以根據以下方式對其進行排序,達到真正的首尾相連的結果:
1.首先我們找到第一根線L1,滿足要求:有一端是沒有其他線與其相重合的。並記錄L1與其他線重合的那個端點PL1。
2.然後找下一根線,滿足要求:有一端點與PL1重合,並記錄另一端點P2;
3.重複第二步,直至最後一根線。
如此我們就可以保證所有曲線都是按照次序一根接著一根的。
貼程式碼(經測試,應該沒問題,但很多地方可能有重複過程):
/// <summary>
/// 對目標曲線進行排序(只改變curves的順序)
/// </summary>
/// <param name="curves"></param>
/// <returns></returns>
private List<Curve> OrderCurves(List<Curve> curves)
{
//如果只有1根或者2根,那麼不需要排序
if (curves.Count < 3)
{
return curves;
}
//首先找到第一根線
Curve firstCurve = null;
foreach (var curve in curves)
{
if (IsCurveJoinedBothPoints(curve, curves) == false)
{
firstCurve = curve;
break;
}
}
var orderedCurves = new List<Curve> { firstCurve };
//然後從第二個元素開始,找與第一個元素首尾相連的物件
for (int i = 0; i < orderedCurves.Count; i++)
{
foreach (var item in curves)
{
//首先保證item並不在orderedCurves中
if (orderedCurves.Contains(item) == false)
{
//如果curves存在一根線與orderedCurves[i]的端點重合
if (IsPointJoinedWithCurve(orderedCurves[i].GetEndPoint(0), item, out _)
|| IsPointJoinedWithCurve(orderedCurves[i].GetEndPoint(1), item, out _))
{
orderedCurves.Add(item);
}
}
}
}
return orderedCurves;
}
/// <summary>
/// 判斷這根線的兩個端點,是否與目標curves中的線都相連線
/// </summary>
/// <param name="curve"></param>
/// <param name="curves"></param>
/// <returns></returns>
private bool IsCurveJoinedBothPoints(Curve curve, List<Curve> curves)
{
if (curves.Exists(
x => x.GetHashCode() != curve.GetHashCode()//不是同一根線
&& IsPointJoinedWithCurve(curve.GetEndPoint(0), x, out _)//有線與curve的起點重合
))
{
if (curves.Exists(
y => y.GetHashCode() != curve.GetHashCode()//不是同一根線
&& IsPointJoinedWithCurve(curve.GetEndPoint(1), y, out _)//也有線與curve的終點重合
))
{
//即如果即有與curve起點重合的線,又有與curve重點重合的線
//就判定這跟線收尾都有與之相鄰的線
return true;
}
}
return false;
}
/// <summary>
/// 判斷一個點和一根線的起始點是否重合
/// </summary>
/// <param name="point"></param>
/// <param name="curve"></param>
/// <param name="p">0代表curve與point的起點重合,1代表curve與point的終點重合</param>
/// <returns></returns>
private bool IsPointJoinedWithCurve(XYZ point, Curve curve, out int p)
{
if (curve.GetEndPoint(0).DistanceTo(point)<_presion)
{
p = 0;
return true;
}
else if (curve.GetEndPoint(1).DistanceTo(point) < _presion)
{
p = 1;
return true;
}
p = -1;
return false;
}
/// <summary>
/// 對orderedCurves的第一條線做變向處理,使其開放端為起點
/// </summary>
/// <param name="curves"></param>
private List<Curve> ChangeFirstCurveOrientation(List<Curve> curves)
{
var firstCurve = curves[0];
//如果第一條線的起點,有其他線與之重合,則將第一條線的方向改一下
if (curves.Exists(x=> x.GetHashCode()!= firstCurve.GetHashCode()&&
IsPointJoinedWithCurve(firstCurve.GetEndPoint(0),x,out int _)))
{
var newCurve = firstCurve.CreateReversed();
curves.Remove(firstCurve);
curves.Insert(0, newCurve);
}
return curves;
}
/// <summary>
/// 改變曲線的方向,使其首尾相連
/// </summary>
/// <param name="curves"></param>
/// <returns></returns>
private List<Curve> ChangeOriention(List<Curve> curves)
{
if (curves.Count < 2)
{
return curves;
}
var output = new List<Curve>() { curves[0] };
for (int i = 1; i <curves.Count; i++)
{
var p0 = output[i - 1].GetEndPoint(0);
var p1 = output[i - 1].GetEndPoint(1);
var p10 = curves[i].GetEndPoint(0);
var p11 = curves[i].GetEndPoint(1);
//否則,就是起點與起點重合,終點與終點重合,需要改變其方向
if (p0.DistanceTo(p10) < _presion || p1.DistanceTo(p11) < _presion)
{
var curve = curves[i].CreateReversed();
output.Add(curve);
}
//如果下一根線與上一根線是起點與終點重合,或者終點與起點重合,說明方向一樣
//那就原封不動放進去
else
{
output.Add(curves[i]);
}
}
return output;
}
相關文章
- Error Curves——錯誤曲線Error
- Flutter 動畫曲線Curves 效果一覽Flutter動畫
- 如何對Wormhole進行連線Worm
- 對字典進行排序排序
- Revit二次開發環境配置(Revit 2020 +Visual Studio 2019)開發環境
- 147. 對連結串列進行插入排序排序
- 獲取洞口邊界及在牆上開洞(Revit二次開發)
- 直播app開發,對字串中字元進行自然順序排序APP字串字元排序
- Revit二次開發之“讓物件處於被選擇狀態”物件
- 串列埠屏開發曲線串列埠
- 對 Lotus Notes 郵件模版進行二次開發的最佳實踐
- Python對字典進行排序Python排序
- 對N個數進行排序排序
- java對中文(拼音)進行排序Java排序
- 利用橢圓曲線進行加密通訊加密
- 二次開發連線區域網其它資料庫資料庫
- 力扣 147. 對連結串列進行插入排序力扣排序
- windows 遠端連線Linux進行開發與除錯MySQLWindowsLinux除錯MySql
- 對AlamofireObjectMapper進行二次封裝ObjectAPP封裝
- LeetCode-147-對連結串列進行插入排序LeetCode排序
- 4.10 如何在Java中進行排序開發Java排序
- canvas 二次貝塞爾曲線quadraticCurveTo()Canvas
- SVG <path> Q指令 二次貝塞爾曲線SVG
- 對列進行連線操作會影響索引的使用索引
- vscode連線遠端伺服器docker容器進行開發VSCode伺服器Docker
- 貝塞爾曲線開發的藝術
- 二次開發連線伺服器mysql資料庫問題伺服器MySql資料庫
- Revit二次開發知識分享(八)控制顯示隱藏的圖元按鈕
- python 對字典的值進行排序Python排序
- 一個命令對文字進行高效排序排序
- ORDER對查詢結果進行排序排序
- 使用XPathExpression類對XML進行排序 (轉)ExpressXML排序
- SVG <path>元素Q指令二次貝塞爾曲線SVG
- vscode遠端連線伺服器進行嵌入式開發VSCode伺服器
- 一次對連線過程進行跟蹤處理連線故障問題的案例
- 排序和表連線排序
- VMware Workstation 下進行 橋連線
- 使用Collections對list的內容進行排序排序