原理就是,先从梁的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; }