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動畫
- Revit二次開發環境配置(Revit 2020 +Visual Studio 2019)開發環境
- 如何對Wormhole進行連線Worm
- 147. 對連結串列進行插入排序排序
- 對字典進行排序排序
- LeetCode-147-對連結串列進行插入排序LeetCode排序
- 直播app開發,對字串中字元進行自然順序排序APP字串字元排序
- Python對字典進行排序Python排序
- 力扣 147. 對連結串列進行插入排序力扣排序
- 獲取洞口邊界及在牆上開洞(Revit二次開發)
- vscode連線遠端伺服器docker容器進行開發VSCode伺服器Docker
- windows 遠端連線Linux進行開發與除錯MySQLWindowsLinux除錯MySql
- 串列埠屏開發曲線串列埠
- 利用橢圓曲線進行加密通訊加密
- python 對字典的值進行排序Python排序
- 二次開發連線區域網其它資料庫資料庫
- vscode遠端連線伺服器進行嵌入式開發VSCode伺服器
- canvas 二次貝塞爾曲線quadraticCurveTo()Canvas
- 一個命令對文字進行高效排序排序
- ORDER對查詢結果進行排序排序
- 二次開發連線伺服器mysql資料庫問題伺服器MySql資料庫
- 使用Collections對list的內容進行排序排序
- 如何在Python中對dicts列表進行排序Python排序
- Revit二次開發知識分享(八)控制顯示隱藏的圖元按鈕
- 在ArcGIS Pro中對Revit的bim資料進行地理配準(平移、旋轉等)
- 如何在dhtmlxGantt網格中對任務進行排序和重新排序HTML排序
- 用xgboost模型對特徵重要性進行排序模型特徵排序
- Django(76)isort工具對import匯入進行排序DjangoImport排序
- 對N個數進行從大到小排序排序
- mysql三表連線查詢以及百分數排序MySql排序
- 還在用ABAP進行SAP產品的二次開發?來了解下這種全新的二次開發理念吧
- revit對電腦配置要求高嗎 2022年revit對電腦推薦配置怎樣
- 如何透過連線資料庫的方式對線下應用進行線上擴充套件資料庫套件
- Qt QTcpSocket 對連線伺服器中斷的不同情況進行判定QTTCP伺服器
- 考研大資料爬取與分析工具二次開發進行中。。。大資料
- FTP,FTP該如何進行連線,如何配置FTP
- websocket 建立連線時如何進行授權?Web