基于双索引从墙体曲线数组生成双向路径列表的技术问询
问题说明
核心不是Revit API的使用,而是要生成行进路径线(PathOfTravel):从房间里的最远点出发,沿着墙体走最短路线,有两种循环方向可选。我已经拿到了构成房间边界的所有墙体曲线列表List<Curve>,也知道门所在墙体的索引doorIndex、最远点所在墙体的索引furthestPointIndex——这两个索引会随房间不同变化。现在需要生成两个遍历列表:一个从doorIndex走到furthestPointIndex,另一个反过来,还要处理列表首尾循环的情况(比如从列表末尾跳转到第一个元素,或者反向跳转),最后用这两个列表找出最短路径。
解决思路与代码实现
核心思路
先处理两种索引场景:正常顺序(doorIndex < furthestPointIndex)和循环场景(doorIndex > furthestPointIndex),分别生成两个方向的墙体曲线列表,计算各自的总长度,选短的那个来生成行进路线。
修正后的代码
// 获取按顺序排列的房间边界墙体曲线列表 List<Curve> edgeLoop = AbcRevitUtils.GeometryUtils.get_Curves(bottomFace); Curve doorCurve; Curve furthestCurve; int doorIndex = edgeLoop.IndexOf(doorCurve); int furthestIndex = edgeLoop.IndexOf(furthestCurve); XYZ furthestPoint = new XYZ(0, 0, 0); int startOrEnd; // 判断最远点是对应墙体曲线的起点还是终点 if (dPoint.DistanceTo(edgeLoop[furthestIndex].GetEndPoint(0)) < dPoint.DistanceTo(edgeLoop[furthestIndex].GetEndPoint(1))) { furthestPoint = edgeLoop[furthestIndex].GetEndPoint(1); startOrEnd = 1; } else { furthestPoint = edgeLoop[furthestIndex].GetEndPoint(0); startOrEnd = 0; } // 创建初始行进路径 Autodesk.Revit.DB.Analysis.PathOfTravel route = Autodesk.Revit.DB.Analysis.PathOfTravel.Create(doc.ActiveView, furthestPoint, dPoint); // 生成两个方向的路径曲线列表并计算长度 List<Curve> pathDir1 = new List<Curve>(); // 从door到furthest的路径 List<Curve> pathDir2 = new List<Curve>(); // 从furthest到door的路径 double lenDir1 = 0; double lenDir2 = 0; // 生成方向1的路径:从doorIndex出发,循环到furthestIndex int current = doorIndex; while (current != furthestIndex) { pathDir1.Add(edgeLoop[current]); lenDir1 += edgeLoop[current].Length; // 处理循环:到列表末尾就跳回第一个元素 current = (current + 1) % edgeLoop.Count; } // 加上最远点所在的墙体曲线 pathDir1.Add(edgeLoop[furthestIndex]); lenDir1 += edgeLoop[furthestIndex].Length; // 生成方向2的路径:从furthestIndex出发,循环到doorIndex current = furthestIndex; while (current != doorIndex) { pathDir2.Add(edgeLoop[current]); lenDir2 += edgeLoop[current].Length; current = (current + 1) % edgeLoop.Count; } pathDir2.Add(edgeLoop[doorIndex]); lenDir2 += edgeLoop[doorIndex].Length; // 选最短的路径 List<Curve> shortestPath = lenDir1 <= lenDir2 ? pathDir1 : pathDir2; // 向路径插入途经点,注意顺序匹配行进方向 int waypointPos = 0; foreach (Curve curve in shortestPath) { // 根据最远点的端点方向,取对应墙体的另一端点作为途经点 XYZ waypoint = startOrEnd == 1 ? curve.GetEndPoint(0) : curve.GetEndPoint(1); route.InsertWaypoint(waypoint, waypointPos); waypointPos++; route.Update(); }
关键细节
- 用
(current + 1) % edgeLoop.Count自动处理列表循环,不用写复杂的if判断 - 两个while循环分别生成完整的双向路径,同时累加长度,直接对比就能选最短的
- 途经点的取点逻辑和最远点的端点方向对应,保证路径沿墙体连续
内容的提问来源于stack exchange,提问作者Dries
相关产品推荐
相关产品推荐

