/// <summary>
 /// 連接梁接點
 /// </summary>
 /// <param name="NewBeamGroup"></param>
 private void ConnectedEdge(ref List <List <LINE> > NewBeamGroup)
 {
     foreach (List <LINE> Beams in NewBeamGroup)
     {
         Dictionary <int, LINE> tmpAddLines = new Dictionary <int, LINE>();
         for (int i = 0; i < Beams.Count; i++)
         {
             try
             {
                 LINE L1         = Beams[i];
                 LINE L2         = i + 1 == Beams.Count ? Beams[0] : Beams[i + 1];
                 XYZ  crossPoint = L1.GetCrossPoint(L2);
                 Beams[i].ResetParameters(crossPoint, "EndPoint");
                 if (i + 1 == Beams.Count)
                 {
                     Beams[0].ResetParameters(crossPoint, "StartPoint");
                 }
                 else
                 {
                     Beams[i + 1].ResetParameters(crossPoint, "StartPoint");
                 }
             }
             catch (Exception)
             {
             }
         }
     }
 }
        private XYZ GetNewEndedPoint(XYZ ColTarget_, XYZ EndPoint, LINE Beam)
        {
            XYZ    ColTarget    = new XYZ(ColTarget_.X, ColTarget_.Y, Beam.GetStartPoint().Z);
            XYZ    startPoint   = Beam.GetStartPoint();
            XYZ    oriDir       = Beam.GetDirection();
            XYZ    newDir       = new XYZ(oriDir.Y, -oriDir.X, oriDir.Z);
            LINE   VerticalLINE = new LINE(ColTarget, newDir, 1);
            XYZ    newPoint     = VerticalLINE.GetCrossPoint(Beam);
            double dist         = Math.Sqrt((newPoint.X - EndPoint.X) * (newPoint.X - EndPoint.X) +
                                            (newPoint.Y - EndPoint.Y) * (newPoint.Y - EndPoint.Y));

            if (dist > Beam.GetLength())
            {
                return(EndPoint);
            }
            return(VerticalLINE.GetCrossPoint(Beam));
        }
        /// <summary>
        /// 判斷點是否在封閉曲線內
        /// </summary>
        /// <param name="point"></param>
        /// <param name="boundary"></param>
        /// <returns></returns>
        private bool IsInner(XYZ point, List <LINE> boundary)
        {
            double Len      = boundary.Sum(t => t.GetLength());
            LINE   shotLine = new LINE(point, new XYZ(0, 1, boundary[0].GetStartPoint().Z), Len);
            int    num1     = 0;

            foreach (LINE item in boundary)
            {
                XYZ crossPoint = shotLine.GetCrossPoint(item);
                if (shotLine.IsPointInLine(crossPoint) && item.IsPointInLine(crossPoint))
                {
                    num1++;
                }
            }

            LINE shotLine2 = new LINE(point, new XYZ(0, -1, boundary[0].GetStartPoint().Z), Len);
            int  num2      = 0;

            foreach (LINE item in boundary)
            {
                XYZ crossPoint = shotLine2.GetCrossPoint(item);
                if (shotLine2.IsPointInLine(crossPoint) && item.IsPointInLine(crossPoint))
                {
                    num2++;
                }
            }

            if (num1 % 2 == 1 && num2 % 2 == 1)
            {
                return(true);
            }
            if ((num1 + num2) % 2 == 1)
            {
                return(true);
            }
            //double minX = boundary.Min(m => m.GetStartPoint().X);
            //double maxX = boundary.Max(m => m.GetStartPoint().X);
            //double minY = boundary.Min(m => m.GetStartPoint().Y);
            //double maxY = boundary.Max(m => m.GetStartPoint().Y);

            //if (point.X > minX && point.X < maxX && point.Y > minY && point.Y < maxY)
            //{
            //    return true;
            //}
            return(false);
        }
        private List <List <LINE> > DataPreProcessing(Level targetLevel, Level targetLevelCol, List <LINE> BEAMs)
        {
            ///// 取得所有梁平均寬度
            double SHIFTs_Width_Of_Beam = 0;

            foreach (LINE item in BEAMs)
            {
                SHIFTs_Width_Of_Beam += item.Width;
            }
            SHIFTs_Width_Of_Beam = SHIFTs_Width_Of_Beam / BEAMs.Count;

            ///// 取得目標樓層所有的柱
            Dictionary <string, List <LINE> > columns = GetAllColumnsBoundary(targetLevelCol);
            int        kk              = 0;
            double     SHIFTs          = 0;
            List <XYZ> colCenterPoints = new List <XYZ>();

            foreach (KeyValuePair <string, List <LINE> > item in columns)
            {
                foreach (LINE line in item.Value)
                {
                    SHIFTs += line.GetLength();
                    kk      = kk + 1;
                }

                if (item.Value.Count != 0)
                {
                    double All_X = item.Value.Sum(t => t.GetStartPoint().X) / item.Value.Count;
                    double All_Y = item.Value.Sum(t => t.GetStartPoint().Y) / item.Value.Count;
                    colCenterPoints.Add(new XYZ(All_X, All_Y, 0));
                }
            }
            SHIFTs = SHIFTs / kk;


            ////// 延伸梁的邊緣線至柱中心
            /// 找出subBeam,將不做延伸處理
            List <int> NonePo = new List <int>();

            for (int i = 0; i < BEAMs.Count; i++)
            {
                for (int j = 0; j < BEAMs.Count; j++)
                {
                    if (i == j)
                    {
                        continue;
                    }
                    LINE b1 = BEAMs[i];
                    LINE b2 = BEAMs[j];
                    if (Math.Round(b1.GetSlope(), 3) == Math.Round(b2.GetSlope(), 3))
                    {
                        continue;
                    }
                    try
                    {
                        XYZ crossPoint = b1.GetCrossPoint(b2);
                        if (IsCloseEndsPoint(b1, crossPoint, SHIFTs_Width_Of_Beam) && b2.IsPointInLine(crossPoint))
                        {
                            NonePo.Add(i);
                            break;
                        }
                        ;
                    }
                    catch (Exception)
                    {
                    }
                }
            }
            List <LINE> Beams_Connect = new List <LINE>();

            for (int i = 0; i < BEAMs.Count; i++)
            {
                if (NonePo.Contains(i))
                {
                    Beams_Connect.Add(BEAMs[i]);
                    continue;
                }
                ;

                List <XYZ> col = GetClosedColumn(colCenterPoints, BEAMs[i]);

                XYZ newStartPoint = GetNewEndedPoint(col[0], BEAMs[i].GetStartPoint(), BEAMs[i]);
                XYZ newEndPoint   = GetNewEndedPoint(col[1], BEAMs[i].GetEndPoint(), BEAMs[i]);
                if (newStartPoint.X == newEndPoint.X && newStartPoint.Y == newEndPoint.Y)
                {
                    Beams_Connect.Add(BEAMs[i]);
                    continue;
                }
                LINE newBeam = new LINE(newStartPoint, newEndPoint);
                newBeam.Name      = BEAMs[i].Name;
                newBeam.Width     = BEAMs[i].Width;
                newBeam.LevelName = BEAMs[i].LevelName;
                Beams_Connect.Add(newBeam);
            }



            /// 將所有的梁轉換至各樓板邊緣線
            List <LINE>         nonSelected = new List <LINE>();
            List <List <LINE> > BeamGroup   = GetBeamGroup(Beams_Connect, ref nonSelected, SHIFTs);

            SaveTmp(BeamGroup);
            /// 將樓板邊緣線偏移並連接
            List <List <LINE> > NewBeamGroup = BeamConnectAndShiftProcessing(BeamGroup);

            SaveTmp(NewBeamGroup);

            if (NewBeamGroup.Count == 0)
            {
                return(NewBeamGroup);
            }

            double newHeight = NewBeamGroup[0][0].GetStartPoint().Z;
            ///// 重設目標樓層所有的柱的高度
            Dictionary <string, List <LINE> > columns2 = new Dictionary <string, List <LINE> >();

            foreach (KeyValuePair <string, List <LINE> > item in columns)
            {
                SaveTmp(item.Value);
                List <LINE> newFloor = new List <LINE>();
                foreach (LINE floor in item.Value)
                {
                    XYZ newSt = new XYZ(floor.GetStartPoint().X,
                                        floor.GetStartPoint().Y,
                                        newHeight);
                    XYZ newEn = new XYZ(floor.GetEndPoint().X,
                                        floor.GetEndPoint().Y,
                                        newHeight);
                    newFloor.Add(new LINE(newSt, newEn));
                }
                columns2[item.Key] = newFloor;
            }

            List <List <LINE> > Result = new List <List <LINE> >();

            foreach (List <LINE> item in NewBeamGroup)
            {
                Result.Add(TakeOffColumnEdge(columns2, item));
            }

            SaveTmp(Result);
            Result = ConnectedEdgeFromMiddleColumns(Result);

            SaveTmp(Result);
            /// 拿掉第一輪subBeam
            List <List <LINE> > Res  = TakeOffSubBeams(Result, nonSelected, SHIFTs_Width_Of_Beam);
            List <List <LINE> > Res2 = TakeOffSubBeams(Res, nonSelected, SHIFTs_Width_Of_Beam);

            SaveTmp(Res2);
            return(Res2);
        }
        private List <LINE> TakeOffColumnEdge(Dictionary <string, List <LINE> > columns, List <LINE> floor)
        {
            foreach (KeyValuePair <string, List <LINE> > column in columns)
            {
                List <LINE> newFloor = new List <LINE>();
                Dictionary <int, List <LINE> > tmpData = new Dictionary <int, List <LINE> >();
                for (int ii = 0; ii < column.Value.Count; ii++)
                {
                    LINE columnEdge = column.Value[ii];
                    for (int jj = 0; jj < floor.Count; jj++)
                    {
                        LINE floorEdge = floor[jj];
                        if (Math.Round(floorEdge.GetSlope(), 3) == Math.Round(columnEdge.GetSlope(), 3))
                        {
                            continue;
                        }
                        if (Math.Abs(Math.Round(floorEdge.GetDirection().X, 3)) == Math.Abs(Math.Round(columnEdge.GetDirection().X, 3)) &&
                            Math.Abs(Math.Round(floorEdge.GetDirection().Y, 3)) == Math.Abs(Math.Round(columnEdge.GetDirection().Y, 3)))
                        {
                            continue;
                        }

                        XYZ crossPoint = floorEdge.GetCrossPoint(columnEdge);


                        try
                        {
                            if (floorEdge.IsPointInLine(crossPoint) && columnEdge.IsPointInLine(crossPoint))
                            {
                                XYZ innerPoint = IsInner(columnEdge.GetStartPoint(), floor) ?
                                                 columnEdge.GetStartPoint() : columnEdge.GetEndPoint();

                                double      dis1    = (crossPoint - floorEdge.GetStartPoint()).GetLength();
                                double      dis2    = (crossPoint - floorEdge.GetEndPoint()).GetLength();
                                LINE        newLine = null;
                                List <LINE> newList = new List <LINE>();
                                if (dis1 > dis2)
                                {
                                    floorEdge.ResetParameters(crossPoint, "EndPoint");
                                    newLine = new LINE(crossPoint, innerPoint);
                                    newList.Add(floorEdge);
                                    if (dis2 != 0)
                                    {
                                        newList.Add(newLine);
                                    }
                                }
                                else
                                {
                                    newLine = new LINE(innerPoint, crossPoint);
                                    floorEdge.ResetParameters(crossPoint, "StartPoint");
                                    if (dis1 != 0)
                                    {
                                        newList.Add(newLine);
                                    }
                                    newList.Add(floorEdge);
                                }
                                tmpData[jj] = newList;
                            }
                        }
                        catch (Exception)
                        {
                        }
                    }
                }


                for (int kk = 0; kk < floor.Count; kk++)
                {
                    if (tmpData.ContainsKey(kk))
                    {
                        foreach (LINE item in tmpData[kk])
                        {
                            newFloor.Add(item);
                        }
                    }
                    else
                    {
                        newFloor.Add(floor[kk]);
                    }
                }
                floor = new List <LINE>();
                floor = newFloor;
            }

            return(floor);
        }
Esempio n. 6
0
        private List <FloorEdges> SplitFloorBySubBeam(List <LINE> floor, LINE subbeam)
        {
            List <FloorEdges> Floors = new List <FloorEdges>();
            /////// 檢查subBeam與板邊界是否有兩個交點
            List <int> CrossPo = new List <int>();

            for (int i = 0; i < floor.Count; i++)
            {
                LINE floorEdge = floor[i];
                if (Math.Abs(Math.Round(floorEdge.GetSlope(), 3)) == Math.Abs(Math.Round(subbeam.GetSlope(), 3)))
                {
                    continue;
                }

                XYZ crossPoint = floorEdge.GetCrossPoint(subbeam);

                if (IsCloseEndsPoint(subbeam, crossPoint) && floorEdge.IsPointInLine(crossPoint))
                {
                    CrossPo.Add(i);
                }
            }

            /////// 沒有兩個交點則不處理直接回傳
            if (CrossPo.Count != 2)
            {
                FloorEdges Floor = new FloorEdges(floor);
                Floors.Add(Floor);
                return(Floors);
            }

            /////// 有兩個交點則開始處理梁的分離

            /// 將板轉換成節點
            List <XYZ> nodes = new List <XYZ>();

            foreach (LINE item in floor)
            {
                nodes.Add(item.GetStartPoint());
            }
            nodes.Add(floor[floor.Count - 1].GetEndPoint());

            /// 取的偏移後的交點
            XYZ        targetPoint  = floor[CrossPo[0]].GetStartPoint();
            LINE       offSetLine_1 = subbeam.GetShiftLines(floor[CrossPo[0]].GetStartPoint(), subbeam.Width / 2, "IN")[0];
            LINE       offSetLine_2 = subbeam.GetShiftLines(floor[CrossPo[0]].GetEndPoint(), subbeam.Width / 2, "IN")[0];
            XYZ        crossPoint1  = offSetLine_1.GetCrossPoint(floor[CrossPo[0]]);
            XYZ        crossPoint2  = offSetLine_1.GetCrossPoint(floor[CrossPo[1]]);
            XYZ        crossPoint3  = offSetLine_2.GetCrossPoint(floor[CrossPo[0]]);
            XYZ        crossPoint4  = offSetLine_2.GetCrossPoint(floor[CrossPo[1]]);
            List <XYZ> crossPoint_1 = new List <XYZ>()
            {
                crossPoint1, crossPoint2
            };
            List <XYZ> crossPoint_2 = new List <XYZ>()
            {
                crossPoint3, crossPoint4
            };

            /// Part 1
            int        kk     = 0;
            List <XYZ> part_1 = new List <XYZ>();

            for (int i = 0; i < nodes.Count; i++)
            {
                if (i > CrossPo[0] && i <= CrossPo[1] && kk < 2)
                {
                    part_1.Add(crossPoint_1[kk]);
                    kk = kk + 1;
                }
                else if (i <= CrossPo[0] || i > CrossPo[1])
                {
                    part_1.Add(nodes[i]);
                }
            }

            /// Part 2
            kk = 0;
            List <XYZ> part_2 = new List <XYZ>();

            for (int i = 0; i < nodes.Count; i++)
            {
                if (i > CrossPo[0] && i <= CrossPo[1])
                {
                    part_2.Add(nodes[i]);
                }
                else if ((i == CrossPo[0] || i == CrossPo[1] + 1) && kk < 2)
                {
                    part_2.Add(crossPoint_2[kk]);
                    kk = kk + 1;
                }
            }
            part_2.Add(crossPoint_2[0]);

            try
            {
                /// 將節點轉換成LINE
                List <LINE> newFloor_1 = new List <LINE>();
                for (int i = 0; i < part_1.Count() - 1; i++)
                {
                    newFloor_1.Add(new LINE(part_1[i], part_1[i + 1]));
                }

                List <LINE> newFloor_2 = new List <LINE>();
                for (int i = 0; i < part_2.Count() - 1; i++)
                {
                    newFloor_2.Add(new LINE(part_2[i], part_2[i + 1]));
                }

                Floors.Add(new FloorEdges(newFloor_1));
                Floors.Add(new FloorEdges(newFloor_2));
            }
            catch (Exception)
            {
                return(new List <FloorEdges>()
                {
                    new FloorEdges(floor)
                });
            }

            return(Floors);
        }