예제 #1
0
        /// <summary>
        /// this function tries to sort lines, but it can throw exception when it fails
        /// </summary>
        public void SortLines()
        {
            List <_Line> orderedLines   = new List <_Line>();
            int          actualIndex    = 0;//the basis of sorting is to loop and keep this actualindex
            int          boundCount     = Lines.Count;
            int          nullLinesCount = 0;

            for (int i = 0; i < boundCount; i++)
            {
                _Line loopLine = Lines[actualIndex];
                if (loopLine.StartPoint.Equals(loopLine.EndPoint))
                {
                    nullLinesCount++;
                    continue; //we remove null lines this way
                }

                orderedLines.Add(loopLine);
                actualIndex = 0;
                for (var j = 0; j < boundCount; j++)
                {
                    _Line innerLoopLine = Lines[j];
                    if (orderedLines.Contains(innerLoopLine))
                    {
                        actualIndex++; //so skip this line
                        continue;
                    }
                    //from these next statments, only one can be true
                    if (Equals(innerLoopLine.StartPoint, loopLine.StartPoint) && !Equals(innerLoopLine.EndPoint, loopLine.EndPoint))
                    {
                        break;
                    }

                    if (Equals(innerLoopLine.StartPoint, loopLine.EndPoint) && !Equals(innerLoopLine.EndPoint, loopLine.StartPoint))
                    {
                        break;
                    }

                    if (Equals(innerLoopLine.EndPoint, loopLine.EndPoint) && !Equals(innerLoopLine.StartPoint, loopLine.StartPoint))
                    {
                        break;
                    }

                    if (Equals(innerLoopLine.EndPoint, loopLine.StartPoint) && !Equals(innerLoopLine.StartPoint, loopLine.EndPoint))
                    {
                        break;
                    }

                    actualIndex++;
                }
            }
            _Point p1 = orderedLines.First().ConnectsPoint(orderedLines.Last());                           //this is where the first and last line joins
            _Point p2 = orderedLines.ElementAt(1).ConnectsPoint(orderedLines.ElementAt(0));                //this is where the first and second line joins
            _Point p3 = orderedLines.Last().ConnectsPoint(orderedLines.ElementAt(orderedLines.Count - 2)); //this is where the last and the line before last joins
            //so this is the point where the first and second line connect
            //so p0 is where it all started. the last line should have p0
            _Point p0 = orderedLines.First().StartPoint.Equals(p2)
                ? orderedLines.First().EndPoint
                : orderedLines.First().StartPoint;

            //to get full circle
            _Point p4 = orderedLines.Last().StartPoint.Equals(p3)
                ? orderedLines.Last().EndPoint
                : orderedLines.Last().StartPoint;

            bool isGoodOrdering = p1 != null && p1.Equals(p0) && p1.Equals(p4);

            bool isGoodCount = (orderedLines.Count + nullLinesCount) == Lines.Count;

            if (!isGoodOrdering)
            {
                throw new Exception("first and last line does not connect");
            }

            if (!isGoodCount)
            {
                throw new Exception("not enough lines");
            }

            Lines = orderedLines;
        }
예제 #2
0
        private List <_Room> roomsContainingTheLineToMove = new List <_Room>();                      //these rooms might need to change

        public void MoveLine(int distance, _Line lineToMove)
        {
            //if (lineToMove.length < 11) //return;

            roomsContainingTheLineToMove.Clear();
            roomsTouchingStartPoint.Clear();
            roomsTouchingEndPoint.Clear();
            roomsTouchingStartPointOnlyAndHaveNoParallelLines.Clear();
            roomsTouchingEndPointOnlyAndHaveNoParalellLines.Clear();

            _Line movedLine = lineToMove.DeepCopy();                             //first we copy the line we need to move

            movedLine.Name = $"Moved_in_step:{moveStepsCount}";                  //this is for debugging
            _Point moveVector = movedLine.GetNV(true) * distance;                //we scale it up

            movedLine.Move(moveVector);                                          //so we moved the copy (why not the actual?)

            _Line l1 = new _Line(lineToMove.StartPoint, lineToMove.StartPoint.Move(moveVector));
            _Line l2 = new _Line(lineToMove.EndPoint, lineToMove.EndPoint.Move(moveVector));

            l1.Name = $"New_Start_Line_{moveStepsCount}";
            l2.Name = $"New_End_Line_{moveStepsCount}";

            fillRelatedRoomListInfomration(lineToMove, ref l1, ref l2);

            List <_Line> linesToRemove = new List <_Line>();

            //this is the big function
            foreach (_Room room in roomsContainingTheLineToMove)
            {
                bool shouldBeTrue       = room.CanGetBoundarySorted();
                int  linetoMoveOriginal = room.Lines.FindIndex(a => a.Equals(lineToMove));
                if (linetoMoveOriginal == -1)
                {
                    linetoMoveOriginal = 0;
                }

                room.Lines.Remove(lineToMove);
                int linesCount = room.Lines.Count;
                for (var index = 0; index < linesCount; index++)
                {
                    _Line  lineInLoop = room.Lines[index];
                    _Point loopAndToMoveCommonPoint = lineInLoop.ConnectsPoint(lineToMove);
                    if (loopAndToMoveCommonPoint != null && loopAndToMoveCommonPoint.Equals(lineToMove.StartPoint)) //there is common point with startpoint, so this line touched the old startpoint
                    {
                        bool areweMovingOnLoopLine = IsOnLineButNotEndPoint(l1.EndPoint, lineInLoop);
                        //if there is a touching room, we need to keep the point. of course, might not in this room.
                        if (!roomsTouchingStartPoint.Any())
                        {
                            _Point loopNormal = lineInLoop.GetNV(true); //we need to either move it, if it is parallel, or keep it if it is merőleges
                            _Point moveNormal = lineToMove.GetNV(true); //THE LINE SHOULD MOVE - BOTH DIRECTIONS - MOVE P WITH MOVEVECTOR

                            bool NOTparallel = AreNotParralel(loopNormal, moveNormal);

                            if (lineInLoop.StartPoint.Equals(loopAndToMoveCommonPoint) && (NOTparallel))
                            {
                                lineInLoop.StartPoint = lineInLoop.StartPoint.Move(moveVector);
                            }

                            if (lineInLoop.EndPoint.Equals(loopAndToMoveCommonPoint) && (NOTparallel))
                            {
                                lineInLoop.EndPoint = lineInLoop.EndPoint.Move(moveVector);
                            }
                            if (lineInLoop.StartPoint.Equals(lineInLoop.EndPoint))
                            {
                                linesToRemove.Add(lineInLoop);
                            }
                            if ((lineInLoop.StartPoint.Equals(loopAndToMoveCommonPoint) || lineInLoop.EndPoint.Equals(loopAndToMoveCommonPoint)) && !NOTparallel && !l1.StartPoint.Equals(l1.EndPoint))
                            {
                                room.Lines.Add(l1);
                            }
                        }
                        //TODO:if there is room, we may move it, if there is no perpendicular line in that room -- but be careful of that other room
                        if (roomsTouchingStartPoint.Any() && !l1.StartPoint.Equals(l1.EndPoint))
                        {
                            if (!areweMovingOnLoopLine && !room.Lines.Contains(l1))
                            {
                                room.Lines.Add(l1);  //this makes it easier to remove the small lines later
                            }
                            foreach (_Room room1 in roomsTouchingStartPoint)
                            {
                                if (!room1.Lines.Contains(l1))
                                {
                                    room1.Lines.Add(l1);
                                }
                            }
                        }
                    }

                    if (loopAndToMoveCommonPoint != null && loopAndToMoveCommonPoint.Equals(lineToMove.EndPoint))
                    {
                        bool areweMovingOnLoopLine = _Model.IsOnLineButNotEndPoint(l2.EndPoint, lineInLoop);
                        if (!roomsTouchingEndPoint.Any())
                        {
                            _Point objA        = lineInLoop.GetNV(true);
                            _Point objB        = lineToMove.GetNV(true);
                            bool   NOTparallel = AreNotParralel(objA, objB);
                            if (lineInLoop.StartPoint.Equals(loopAndToMoveCommonPoint) && (NOTparallel))
                            {
                                lineInLoop.StartPoint = lineInLoop.StartPoint.Move(moveVector);
                            }

                            if (lineInLoop.EndPoint.Equals(loopAndToMoveCommonPoint) && (NOTparallel))
                            {
                                lineInLoop.EndPoint = lineInLoop.EndPoint.Move(moveVector);
                            }
                            if (lineInLoop.StartPoint.Equals(lineInLoop.EndPoint))
                            {
                                linesToRemove.Add(lineInLoop);
                            }
                            if ((lineInLoop.EndPoint.Equals(loopAndToMoveCommonPoint) || lineInLoop.StartPoint.Equals(loopAndToMoveCommonPoint)) && !NOTparallel && !l2.StartPoint.Equals(l2.EndPoint))
                            {
                                room.Lines.Add(l2);
                            }
                        }
                        if (roomsTouchingEndPoint.Any() && !l2.StartPoint.Equals(l2.EndPoint))
                        {
                            if (!areweMovingOnLoopLine && !room.Lines.Contains(l2))
                            {
                                room.Lines.Add(l2);
                            }
                            foreach (_Room room2 in roomsTouchingEndPoint)
                            {
                                if (!room2.Lines.Contains(l2))
                                {
                                    room2.Lines.Add(l2);
                                }
                            }
                        }
                    }
                }

                room.Lines.Insert(linetoMoveOriginal, movedLine);
                foreach (var line in linesToRemove)
                {
                    room.Lines.Remove(line);
                }
                //shouldBeTrue = room.CanGetBoundarySorted();
            }


            foreach (_Room room in roomsContainingTheLineToMove)
            {
                bool shouldBeTrue = room.CanGetBoundarySorted();
                TryToDivideRoomLinesWithL1L2(room, l1, l2);
                TryToCatchIfGlobalCase(room, movedLine);
                shouldBeTrue = room.CanGetBoundarySorted();
                if (!shouldBeTrue)
                {
                    //throw new Exception("should be sortable, if i cant figure it out, mark as invalid state");
                    IsInInvalidState = true;
                }
            }

            foreach (_Room room in roomsTouchingEndPoint)
            {
                TryToDivideRoomLinesWithL1L2(room, l1, l2);
                TryToRemoveRemainderLines(room, l1, l2);
                bool shouldBeTrue = room.CanGetBoundarySorted();
                if (!shouldBeTrue)
                {
                    //throw new Exception("should be sortable, if i cant figure it out, mark as invalid state
                    IsInInvalidState = true;
                }
            }

            foreach (_Room room in roomsTouchingStartPoint)
            {
                TryToDivideRoomLinesWithL1L2(room, l1, l2);
                TryToRemoveRemainderLines(room, l1, l2);
                bool shouldBeTrue = room.CanGetBoundarySorted();
                if (!shouldBeTrue)
                {
                    //throw new Exception("should be sortable, if i cant figure it out, mark as invalid state");
                    IsInInvalidState = true;
                }
            }


            foreach (_Room room in roomsTouchingStartPointOnlyAndHaveNoParallelLines)
            {
                TryToRemoveRemainderLines(room, l1, l2);
                bool shouldBeTrue = room.CanGetBoundarySorted();
                if (!shouldBeTrue)
                {
                    IsInInvalidState = true;
                }
            }
            foreach (_Room room in roomsTouchingEndPointOnlyAndHaveNoParalellLines)
            {
                TryToRemoveRemainderLines(room, l1, l2);
                bool shouldBeTrue = room.CanGetBoundarySorted();
                if (!shouldBeTrue)
                {
                    IsInInvalidState = true;
                }
            }

            List <_Room> sumrooms = new List <_Room>();

            sumrooms.AddRange(roomsContainingTheLineToMove);
            sumrooms.AddRange(roomsTouchingStartPoint);
            sumrooms.AddRange(roomsTouchingEndPoint);
            //this handles null lines, can be removed at any time, probably should do it before sorting
            foreach (_Room room in sumrooms)
            {
                for (var index = 0; index < room.Lines.Count; index++)
                {
                    _Line roomLine = room.Lines[index];
                    if (roomLine.StartPoint.Equals(roomLine.EndPoint))
                    {
                        room.Lines.Remove(roomLine);
                    }
                }
            }
            //GC.Collect();
            //only need to join the same line
            //but why after? we could handle upon creation

            moveStepsCount++;
        }