/// <summary> /// 构造函数 /// </summary> /// <param name="avoidElement">谁</param> /// <param name="conflictLocation">在哪里</param> /// <param name="conflictElement">跟谁撞了</param> public ConflictElement(AvoidElement avoidElement, XYZ conflictLocation, AvoidElement conflictElement) { AvoidEle = avoidElement; ConflictEle = conflictElement; ConflictLocation = conflictLocation; AvoidHeight = conflictElement.Height; AvoidWidth = conflictElement.Width; }
/// <summary> /// 构造函数 /// </summary> /// <param name="avoidElement">谁</param> /// <param name="conflictLocation">在哪里</param> /// <param name="conflictElement">跟谁撞了</param> public ConflictElement(AvoidElement avoidElement, XYZ conflictLocation, Connector connector, AvoidElement conflictElement) { AvoidEle = avoidElement; ConflictEle = conflictElement; Connector = connector; ConflictLocation = conflictLocation; IsConnector = true; AvoidHeight = conflictElement.Height; AvoidWidth = conflictElement.Width; }
private void TopoConnector(List <ValuedConflictNode> conflictNodes, List <AvoidElement> avoidElements, Connector connector, ConflictElement conflictElement) { var connectorsToMepElement = connector.GetConnectorsToMepElement(); foreach (var connectorToMepElement in connectorsToMepElement) { var startEle = avoidElements.FirstOrDefault(c => c.MEPCurve.Id == connectorToMepElement.Owner.Id); if (startEle == null) { startEle = new AvoidElement(connectorToMepElement.Owner as MEPCurve); avoidElements.Add(startEle); } var conflictEle = startEle.AddConflictElement(connectorToMepElement, conflictElement); SetupGroup(startEle, conflictEle, conflictNodes, avoidElements); } }
public static void GetUpAndDownWidth_2(ConflictElement conflictElement, AvoidElement avoidElement, out double widthUp, out double widthDown, double height = -1) { double angleToTurn = avoidElement.AngleToTurn; double miniConnectHeight = avoidElement.ConnectHeight; double miniConnectWidth = avoidElement.ConnectWidth; double offsetWidth = avoidElement.OffsetWidth; var elementToAvoid = conflictElement.ConflictEle; var elementToAvoidHeight = conflictElement.AvoidHeight; var elementToAvoidWidth = conflictElement.AvoidWidth; //对象信息反填到基础模型中 //点位计算 //max(垂直最短留白距离,最小斜边长度,最短切割距离) if (height == -1) { height = avoidElement.Height / 2 + elementToAvoidHeight / 2 + MiniSpace; height = Math.Max(height, MiniMepLength + miniConnectHeight * 2);//考虑构件的最小高度需求 } //TODO 考虑矩形的最佳方案 //if (avoidElement.Width!= avoidElement.Height|| elementToAvoidWidth!= elementToAvoidHeight) //{ //} widthUp = MiniMepLength / 2 + offsetWidth;//构件最短需求 var diameterAvoid = Math.Max(avoidElement.Width, avoidElement.Height); var diameterToAvoid = Math.Max(elementToAvoidWidth, elementToAvoidHeight); var widthOffset = (angleToTurn - Math.PI / 2).IsMiniValue() ? 0 : height / Math.Tan(angleToTurn); widthUp = (angleToTurn - Math.PI / 2).IsMiniValue() ? widthUp : Math.Max(widthUp, (diameterAvoid / 2 + diameterToAvoid / 2 + MiniSpace) / Math.Sin(angleToTurn) - height * Math.Tan(angleToTurn)); //斜边最短需求 widthUp = Math.Max(widthUp, avoidElement.Width / 2 + elementToAvoidWidth / 2 + MiniSpace); //直径最短需求 widthDown = widthUp + widthOffset; //水平最短距离对应的水平偏移 //相对倾斜修正 var curve = (avoidElement.MEPCurve.Location as LocationCurve).Curve; var direction1 = (curve as Line).Direction; var direction2 = ((conflictElement.ConflictEle.MEPCurve.Location as LocationCurve).Curve as Line).Direction; var faceAngle = direction1.AngleOnPlaneTo(direction2, new XYZ(0, 0, 1)); widthUp = GetFixedJumpLength(widthUp, faceAngle); widthDown = GetFixedJumpLength(widthDown, faceAngle); }
public static double GetUpAndDownWidth(AvoidElement avoidElement, ConflictElement conflictElement, out double height, out double widthUp, out double widthDown) { XYZ verticalDirection = avoidElement.GetVerticalVector(); double angleToTurn = avoidElement.AngleToTurn; double miniConnectHeight = avoidElement.ConnectHeight; double miniConnectWidth = avoidElement.ConnectWidth; double offsetWidth = avoidElement.OffsetWidth; var curve = (avoidElement.MEPCurve.Location as LocationCurve).Curve; XYZ parallelDirection = avoidElement.GetParallelVector(); var elementToAvoid = conflictElement.ConflictEle; var elementToAvoidHeight = conflictElement.AvoidHeight; var elementToAvoidWidth = conflictElement.AvoidWidth; XYZ direction1 = (curve as Line).Direction; double faceAngle = 0; XYZ direction2 = ((elementToAvoid.MEPCurve.Location as LocationCurve).Curve as Line).Direction;//TODO 连接件的ElementToAvoid依旧需要填上 作为溯源数据源 faceAngle = direction1.AngleOnPlaneTo(direction2, new XYZ(0, 0, 1)); //对象信息反填到基础模型中 //点位计算 //max(垂直最短留白距离,最小斜边长度,最短切割距离) height = avoidElement.Height / 2 + elementToAvoidHeight / 2 + MiniSpace; height = Math.Max(height, MiniMepLength + miniConnectHeight * 2);//考虑构件的最小高度需求 //TODO 考虑矩形的最佳方案 //if (avoidElement.Width!= avoidElement.Height|| elementToAvoidWidth!= elementToAvoidHeight) //{ //} widthUp = MiniMepLength / 2 + offsetWidth; var diameterAvoid = Math.Max(avoidElement.Width, avoidElement.Height); var diameterToAvoid = Math.Max(elementToAvoidWidth, elementToAvoidHeight); var widthOffset = (angleToTurn - Math.PI / 2).IsMiniValue() ? 0 : height / Math.Tan(angleToTurn); widthUp = (angleToTurn - Math.PI / 2).IsMiniValue() ? widthUp : Math.Max(widthUp, (diameterAvoid / 2 + diameterToAvoid / 2 + MiniSpace) / Math.Sin(angleToTurn) - height * Math.Tan(angleToTurn)); //斜边最短需求 widthUp = Math.Max(widthUp, avoidElement.Width / 2 + elementToAvoidWidth / 2 + MiniSpace); //直径最短需求 widthDown = widthUp + widthOffset; widthUp = GetFixedJumpLength(widthUp, faceAngle); widthDown = GetFixedJumpLength(widthDown, faceAngle); return(height); }
private static void CalculateLocations(AvoidElement avoidElement, ConflictElement conflictElement) { int id = avoidElement.MEPCurve.Id.IntegerValue; double widthUp, widthDown, height; height = GetUpAndDownWidth(avoidElement, conflictElement, out height, out widthUp, out widthDown); XYZ verticalDirection = avoidElement.GetVerticalVector(); XYZ parallelDirection = avoidElement.GetParallelVector(); XYZ pointStart = avoidElement.StartPoint; XYZ pointEnd = avoidElement.EndPoint; XYZ midPoint = conflictElement.ConflictLocation; if (widthUp.IsMiniValue())//偏移段为0说明偏移不足以实现,作整段偏移 { conflictElement.StartSplit = null; conflictElement.EndSplit = null; conflictElement.MiddleStart = null; conflictElement.MiddleEnd = null; if (!avoidElement.IsHorizontalFixed_StartPoint) { avoidElement.StartPoint += height * verticalDirection; avoidElement.IsHorizontalFixed_StartPoint = true; } if (!avoidElement.IsHorizontalFixed_EndPoint) { avoidElement.EndPoint += height * verticalDirection; avoidElement.IsHorizontalFixed_EndPoint = true; } } else { conflictElement.StartSplit = midPoint + parallelDirection * widthDown; conflictElement.EndSplit = midPoint - parallelDirection * widthDown; midPoint += height * verticalDirection; conflictElement.MiddleStart = midPoint + parallelDirection * widthUp; conflictElement.MiddleEnd = midPoint - parallelDirection * widthUp; //过界修正,过界则做边界的垂直偏移 var comparer = new XYComparer(); if (comparer.Compare(conflictElement.StartSplit, pointStart) > 0) { if (comparer.Compare(conflictElement.MiddleStart, pointStart) > 0) { conflictElement.MiddleStart = null; } conflictElement.StartSplit = null; if (!avoidElement.IsHorizontalFixed_StartPoint) { avoidElement.StartPoint += height * verticalDirection; avoidElement.IsHorizontalFixed_StartPoint = true; } } if (comparer.Compare(conflictElement.EndSplit, pointEnd) < 0) { if (comparer.Compare(conflictElement.MiddleEnd, pointEnd) < 0) { conflictElement.MiddleEnd = null; } conflictElement.EndSplit = null; if (!avoidElement.IsHorizontalFixed_EndPoint) { avoidElement.EndPoint += height * verticalDirection; avoidElement.IsHorizontalFixed_EndPoint = true; } } } conflictElement.OffsetHeight = height; }
public ValuedConflictNode(AvoidElement avoidElement, XYZ conflictLocation, AvoidElement elementConflicted) { ConflictLocation = conflictLocation; ValueNode1 = new ValueNode(this, avoidElement); ValueNode2 = new ValueNode(this, elementConflicted); }
public ConflictLineSection(AvoidElement startElement) { AvoidElement = startElement; ElementId = AvoidElement.MEPCurve.Id; ConflictElements = new List <ConflictElement>(); }
/// <summary> /// 这里形成了源对象上与之碰撞的碰撞元素价值组 /// 价值组的价值越大,自身则越应避让. /// 即 赢退 输不动 /// </summary> /// <param name="startElement">源对象</param> /// <param name="conflictElement"></param> /// <param name="conflictNodes"></param> /// <param name="avoidElements"></param> private void SetupGroup(AvoidElement startElement, ConflictElement conflictElement, List <ValuedConflictNode> conflictNodes, List <AvoidElement> avoidElements) { var currentGroupingDistance = GroupingDistance + startElement.ConnectWidth * 2; XYZ direction1 = ((startElement.MEPCurve.Location as LocationCurve).Curve as Line).Direction; ConflictLineSection conflictLineSection = new ConflictLineSection(startElement); //碰撞点处理 conflictLineSection.ConflictElements.Add(conflictElement); //向后 连续组团处理 var startIndex = startElement.ConflictElements.IndexOf(conflictElement); var currentIndex = startIndex; ConflictElement current = conflictElement; ConflictElement next; for (int i = currentIndex + 1; i < startElement.ConflictElements.Count(); i++) { next = startElement.ConflictElements[i]; if (next.IsConnector) { break; } XYZ direction2 = ((next.ConflictEle.MEPCurve.Location as LocationCurve).Curve as Line).Direction; var faceAngle = direction1.AngleOnPlaneTo(direction2, new XYZ(0, 0, 1)); if (current.GetDistanceTo(next) > ValuedConflictNode.GetFixedJumpLength(currentGroupingDistance, faceAngle)) { break; } conflictLineSection.ConflictElements.Add(next); current = next; currentIndex = i; } //向后 连接件处理 边界连续处理 if (conflictElement.ConflictLocation != startElement.EndPoint && currentIndex == startElement.ConflictElements.Count() - 1) { var connector = startElement.ConnectorEnd; var point = startElement.EndPoint; if (connector != null && current.GetDistanceTo(point) <= currentGroupingDistance) { var continueEle = startElement.AddConflictElement(connector, conflictElement); conflictLineSection.ConflictElements.Add(continueEle); TopoConnector(conflictNodes, avoidElements, connector, conflictElement); } } //重置 current = conflictElement; currentIndex = startIndex; //往前 连续组团处理 for (int i = currentIndex - 1; i >= 0; i--) { next = startElement.ConflictElements[i]; if (next.IsConnector) { break; } XYZ direction2 = ((next.ConflictEle.MEPCurve.Location as LocationCurve).Curve as Line).Direction; var faceAngle = direction1.AngleOnPlaneTo(direction2, new XYZ(0, 0, 1)); if (current.GetDistanceTo(next) > ValuedConflictNode.GetFixedJumpLength(currentGroupingDistance, faceAngle)) { break; } conflictLineSection.ConflictElements.Add(next); current = next; currentIndex = i; } //往前 连接件处理 if (conflictElement.ConflictLocation != startElement.StartPoint && currentIndex == 0) { var connector = startElement.ConnectorStart; var point = startElement.StartPoint; if (connector != null && current.GetDistanceTo(point) <= currentGroupingDistance) { var continueEle = startElement.AddConflictElement(connector, conflictElement); conflictLineSection.ConflictElements.Add(continueEle); TopoConnector(conflictNodes, avoidElements, connector, conflictElement); } } conflictLineSection.ConflictElements = conflictLineSection.ConflictElements.OrderByDescending(c => c.ConflictLocation, new XYZComparer()).ToList(); ConflictLineSections.Add(conflictLineSection); }
public ValueNode(ValuedConflictNode valuedConflictNode, AvoidElement avoidElement) { ValuedConflictNode = valuedConflictNode; OrientAvoidElement = avoidElement; ConflictLineSections = new ConflictLineSections(); }
private static void CalculateLocations(AvoidElement avoidElement, ConflictElement conflictElement, double height = -1) { int id = avoidElement.MEPCurve.Id.IntegerValue; XYZ verticalDirection = avoidElement.GetVerticalVector(); double angleToTurn = avoidElement.AngleToTurn; double miniConnectHeight = avoidElement.ConnectHeight; double miniConnectWidth = avoidElement.ConnectWidth; double offsetWidth = avoidElement.OffsetWidth; var curve = (avoidElement.MEPCurve.Location as LocationCurve).Curve; var pointStart = avoidElement.StartPoint; var pointEnd = avoidElement.EndPoint; XYZ parallelDirection = (pointStart - pointEnd).Normalize(); var elementToAvoid = conflictElement.ConflictEle; var elementToAvoidHeight = conflictElement.AvoidHeight; var elementToAvoidWidth = conflictElement.AvoidWidth; XYZ direction1 = (curve as Line).Direction; double faceAngle = 0; XYZ direction2 = ((elementToAvoid.MEPCurve.Location as LocationCurve).Curve as Line).Direction;//TODO 连接件的ElementToAvoid依旧需要填上 作为溯源数据源 faceAngle = direction1.AngleOnPlaneTo(direction2, new XYZ(0, 0, 1)); if (conflictElement.IsConnector) { conflictElement.ConnectorLocation = conflictElement.ConflictLocation + height * verticalDirection; } #region old //if (conflictElement.IsConnector) //{ // faceAngle = Math.PI / 2;//问题出在 如果连接点作为 // conflictElement.ConnectorLocation = conflictElement.ConflictLocation + height * verticalDirection; //} //else //{ // XYZ direction2 = ((elementToAvoid.MEPCurve.Location as LocationCurve).Curve as Line).Direction; // faceAngle = direction1.AngleOnPlaneTo(direction2, new XYZ(0, 0, 1)); //} #endregion //对象信息反填到基础模型中 //点位计算 var midPoint = conflictElement.ConflictLocation; //max(垂直最短留白距离,最小斜边长度,最短切割距离) if (height == -1) { height = avoidElement.Height / 2 + elementToAvoidHeight / 2 + MiniSpace; height = Math.Max(height, MiniMepLength + miniConnectHeight * 2);//考虑构件的最小高度需求 conflictElement.Height = height; } //TODO 考虑矩形的最佳方案 //if (avoidElement.Width!= avoidElement.Height|| elementToAvoidWidth!= elementToAvoidHeight) //{ //} var widthUp = MiniMepLength / 2 + offsetWidth;//构件最短需求 var diameterAvoid = Math.Max(avoidElement.Width, avoidElement.Height); var diameterToAvoid = Math.Max(elementToAvoidWidth, elementToAvoidHeight); widthUp = Math.Max(widthUp, (diameterAvoid / 2 + diameterToAvoid / 2 + MiniSpace) / Math.Sin(angleToTurn) - height * Math.Tan(angleToTurn)); //斜边最短需求 widthUp = Math.Max(widthUp, avoidElement.Width / 2 + elementToAvoidWidth / 2 + MiniSpace); //直径最短需求 var widthDown = widthUp + height / Math.Tan(angleToTurn); //水平最短距离对应的水平偏移 widthUp = GetFixedJumpLength(widthUp, faceAngle); widthDown = GetFixedJumpLength(widthDown, faceAngle); //double co = Math.Abs(Math.Cos(faceAngle)); //if (!co.IsMiniValue()) //{ // widthUp = widthUp / co; // widthDown = widthDown / co; //} conflictElement.StartSplit = midPoint + parallelDirection * widthDown; conflictElement.EndSplit = midPoint - parallelDirection * widthDown; midPoint += height * verticalDirection; conflictElement.MiddleStart = midPoint + parallelDirection * widthUp; conflictElement.MiddleEnd = midPoint - parallelDirection * widthUp; }