Пример #1
0
        /// <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;
        }
Пример #2
0
        /// <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;
        }
Пример #3
0
        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);
            }
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        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;
        }
Пример #7
0
 public ValuedConflictNode(AvoidElement avoidElement, XYZ conflictLocation, AvoidElement elementConflicted)
 {
     ConflictLocation = conflictLocation;
     ValueNode1       = new ValueNode(this, avoidElement);
     ValueNode2       = new ValueNode(this, elementConflicted);
 }
Пример #8
0
 public ConflictLineSection(AvoidElement startElement)
 {
     AvoidElement     = startElement;
     ElementId        = AvoidElement.MEPCurve.Id;
     ConflictElements = new List <ConflictElement>();
 }
Пример #9
0
        /// <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);
        }
Пример #10
0
 public ValueNode(ValuedConflictNode valuedConflictNode, AvoidElement avoidElement)
 {
     ValuedConflictNode   = valuedConflictNode;
     OrientAvoidElement   = avoidElement;
     ConflictLineSections = new ConflictLineSections();
 }
Пример #11
0
        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;
        }