原理就是,先從梁的LocationCurve上取點,然後向板的上錶面投影。如果有投影點,再從投影點(板上)向梁的底面投影,這時候如果有投影點的話就能得到距離了。 運用該分析的第一條件是梁是在板的上方,勿忘哈! LocationCurve的延伸: 在Curve上按PointRange選取點位: 獲取距 ...
原理就是,先從梁的LocationCurve上取點,然後向板的上錶面投影。如果有投影點,再從投影點(板上)向梁的底面投影,這時候如果有投影點的話就能得到距離了。
運用該分析的第一條件是梁是在板的上方,勿忘哈!
var beamBottomFaces = FaceUtils.GetBottomFaces(beam); //這個方法是自己封裝的 if (null != beamBottomFaces && beamBottomFaces.Any()) { var beamLocationCurve = beam.Location as LocationCurve; var beamCurve = beamLocationCurve.Curve; if (beamCurve != null) { if (beamCurve is Line) { beamCurve = GetExtLocationCurve(beamCurve); //如果LocationCurve是Line,最好做個延伸演算法來延長,不然有些梁因為扣減的話,locationCurve容易缺少一部分 } var beamPoints = GetPoints(beamCurve, pointRange); //pointRange是取點間隔 if (beamPoints != null && beamPoints.Any()) { var floorDataList = GetBeamFloorsPairCore(beamBottomFaces, beamPoints, floors); //floors為建築板 } } }
LocationCurve的延伸:
private Curve GetExtLocationCurve(Curve curve) { XYZ dir0 = XYZ.Zero; XYZ dir1 = XYZ.Zero; if (curve is Line) { dir0 = (curve as Line).Direction.Negate(); dir1 = (curve as Line).Direction; } Curve extCurve = Line.CreateBound(curve.GetEndPoint(0) + 1E3 * dir0, curve.GetEndPoint(1) + 1E3 * dir1); return extCurve; }
在Curve上按PointRange選取點位:
private List<XYZ> GetPoints(Curve curve, double pointRange) { var points = new List<XYZ>(); var beamLength = curve.Length; var pointsNumber = beamLength % pointRange == 0 ? ((beamLength / pointRange) - 1) : Math.Floor((beamLength / pointRange)); for(var i = 1; i <= pointsNumber; i++) { var point = curve.Evaluate(pointRange * i, false); points.Add(point); } return points; }
獲取距離:
private List<KeyValuePair<Element, List<KeyValuePair<XYZ, double>>>> GetBeamFloorsPairCore(List<PlanarFace> beamBottomFaces, IEnumerable<XYZ> beamPoints, List<Element> floors) { var floorDataList = new List<KeyValuePair<Element, List<KeyValuePair<XYZ, double>>>>(); //尋找每一塊結構梁下的板 foreach (var floor in constructionFloors) { //獲取該板的最上點坐標 var floorTopFaces = FaceUtils.GetTopFaces(floor); if (null != floorTopFaces && floorTopFaces.Any()) { var defaultFloorOriginZ = floorTopFaces.FirstOrDefault().Origin.Z; foreach (var tf in floorTopFaces) { var originZ = tf.Origin.Z; if (defaultFloorOriginZ <= originZ) { defaultFloorOriginZ = originZ; } } var defaultBeamOriginZ = beamBottomFaces.FirstOrDefault().Origin.Z; foreach (var bf in beamBottomFaces) { var originZ = bf.Origin.Z; if (defaultBeamOriginZ >= originZ) { defaultBeamOriginZ = originZ; } } //板在梁下麵 var isLower = defaultFloorOriginZ < defaultBeamOriginZ; if (isLower) { var datalist = new List<KeyValuePair<XYZ, double>>(); //梁上一點能投影到板上 foreach (var point in beamPoints) { foreach (var tf in floorTopFaces) { var isProject = tf.Project(point); if (null != isProject) { //投影到板上點的坐標 var projectPoint = isProject.XYZPoint; //投影點到梁上點的距離 foreach (var bf in beamBottomFaces) { var bp = bf.Project(projectPoint); if (null != bp) { var distance = bp.Distance; distance = UnitUtils.ConvertFromInternalUnits(distance, DisplayUnitType.DUT_MILLIMETERS); distance = Math.Floor(distance); var pointAndDistance = new KeyValuePair<XYZ, double>(projectPoint, distance); datalist.Add(pointAndDistance); break; } } } } } if (datalist != null && datalist.Any()) { var floorAndData = new KeyValuePair<Element, List<KeyValuePair<XYZ, double>>>(floor, datalist); floorDataList.Add(floorAndData); } } } } return floorDataList; }