private void TryToRemoveRemainderLines(_Room room, _Line l1, _Line l2) { bool isComplete; try { if (room.Lines.Contains(l1)) { room.Lines.Remove(l1); isComplete = room.CanGetBoundarySorted(); if (!isComplete) { room.Lines.Add(l1); } } } catch (Exception e) { } try { if (room.Lines.Contains(l2)) { room.Lines.Remove(l2); isComplete = room.CanGetBoundarySorted(); if (!isComplete) { room.Lines.Add(l2); } } } catch (Exception e) { } try { if (room.Lines.Contains(l1) && room.Lines.Contains(l2)) { room.Lines.Remove(l1); room.Lines.Remove(l2); isComplete = room.CanGetBoundarySorted(); if (!isComplete) { room.Lines.Add(l1); } if (!isComplete) { room.Lines.Add(l2); } } } catch (Exception e) { } }
public _Line Normalize(_Line _Line) { _Point sMyPoint = _Line.StartPoint; _Point eMyPoint = _Line.EndPoint; double length = _Line.GetLength(); _Point neweMyPoint = new _Point(((-sMyPoint.X + eMyPoint.X) / length), ((-sMyPoint.Y + eMyPoint.Y) / length)); _Line line2 = new _Line(new _Point(0, 0), neweMyPoint); return(line2); }
private void TryToDivideRoomLinesWithL1L2(_Room room, _Line l1, _Line l2) { bool isComplete = room.CanGetBoundarySorted(); //this might be bad if (!isComplete) { for (int i = 0; i < room.Lines.Count; i++) { _Line chosenLine = room.Lines.ElementAt(i); if (chosenLine.Equals(l1) || chosenLine.Equals(l2)) { continue; } var connectsPoint = chosenLine.ConnectsPoint(l1); if (connectsPoint != null) { _Point otherPoint = l1.EndPoint.Equals(connectsPoint) ? l1.StartPoint : l1.EndPoint; if (IsOnLine(otherPoint, chosenLine)) { if (chosenLine.EndPoint.Equals(connectsPoint)) { chosenLine.EndPoint = otherPoint; } else { chosenLine.StartPoint = otherPoint; } } } connectsPoint = chosenLine.ConnectsPoint(l2); if (connectsPoint != null) { _Point otherPoint = l2.EndPoint.Equals(connectsPoint) ? l2.StartPoint : l2.EndPoint; if (IsOnLine(otherPoint, chosenLine)) { if (chosenLine.EndPoint.Equals(connectsPoint)) { chosenLine.EndPoint = otherPoint; } else { chosenLine.StartPoint = otherPoint; } } } } } isComplete = room.CanGetBoundarySorted(); //we need to check it after the split }
public override bool Equals(object obj) { //Check for null and compare RunSteps-time types. if ((obj == null) || !this.GetType().Equals(obj.GetType())) { return(false); } else { _Line l = (_Line)obj; return((StartPoint.Equals(l.StartPoint) && (EndPoint.Equals(l.EndPoint))) || (StartPoint.Equals(l.EndPoint) && (EndPoint.Equals(l.StartPoint)))); } }
/// <summary> /// This calls sortlines, too /// and overrides Points /// </summary> public void SortPoints() { SortLines(); Points = new List <_Point>(); for (var index = 0; index < lines.Count; index++) { _Line firstMyLine = lines.ElementAt(index); _Line nextMyLine = lines.ElementAt((index + 1) % lines.Count); _Point commonMyPoint = FindCommonPointOnTwoLines(firstMyLine, nextMyLine); Points.Add(commonMyPoint); } }
public _Model DeepCopy(_Line oldMyLine, out _Line newMyLine) { _Model copy = this.DeepCopy(true); //then only need to find the needed line newMyLine = oldNewLines[oldMyLine]; if (newMyLine.StartPoint == null || newMyLine.EndPoint == null) { throw new Exception("bad"); } return(copy); }
public bool IsTheSame(_Line lineToMove) { if (lineToMove.StartPoint.Equals(this.StartPoint) && lineToMove.EndPoint.Equals(this.EndPoint)) { return(true); } if (lineToMove.StartPoint.Equals(this.EndPoint) && lineToMove.EndPoint.Equals(this.StartPoint)) { return(true); } return(false); }
public _Model DeepCopy(bool isTagNeeded = false) { if (isTagNeeded) { oldNewLines.Clear(); oldNewPoints.Clear(); oldNewRooms.Clear(); } List <_Room> newRooms = new List <_Room>(); foreach (_Room room in rooms) { _Room deepCopy = room.DeepCopy(); if (isTagNeeded) { bool isroomthere = oldNewRooms.ContainsKey(deepCopy); if (!isroomthere) { oldNewRooms.Add(room, deepCopy); } for (var index = 0; index < room.Lines.Count; index++) { _Line i = room.Lines[index]; _Line iCopy = deepCopy.Lines[index]; bool ifs = oldNewLines.ContainsKey(i); if (!ifs) { oldNewLines.Add(i, iCopy); } } } //this storage type is duplicate this way newRooms.Add(deepCopy); } _Model m = new _Model(newRooms); //RemoveRedundancy(m); m.OutlinePolygonPoints = OutlinePolygonPoints; m.AvailableOutlinePolygon = AvailableOutlinePolygon; m.AdjacencyMatrix = AdjacencyMatrix; m.TransparencyMatrix = TransparencyMatrix; m.DepthMatrix = DepthMatrix; m.IsInInvalidState = IsInInvalidState; return(m); }
//this is important only when the room contained the original line, only then is it possible //TODO: here I only solve it for one line, if two lines are overlapped, we have a problem. private void TryToCatchIfGlobalCase(_Room room, _Line movedLine) { List <_Line> overlappedlistinroom = new List <_Line>(); //overlappedlistinroom.Add(movedLine); foreach (_Line roomLine in room.Lines) { if (roomLine.Overlaps(movedLine)) { overlappedlistinroom.Add(roomLine); } } if (overlappedlistinroom.Count > 1) { DoSomething(ref room, overlappedlistinroom); //until we know how to fix it, mark as invalid //IsInInvalidState = true; } }
public _Point ConnectsPoint(_Line lineToMove) { if (lineToMove.StartPoint.Equals(this.StartPoint)) { return(lineToMove.StartPoint); } if (lineToMove.StartPoint.Equals(this.EndPoint)) { return(lineToMove.StartPoint); } if (lineToMove.EndPoint.Equals(this.StartPoint)) { return(lineToMove.EndPoint); } if (lineToMove.EndPoint.Equals(this.EndPoint)) { return(lineToMove.EndPoint); } return(null); }
public bool Connects(_Line lineToMove) { if (lineToMove.StartPoint.Equals(this.StartPoint)) { return(true); } if (lineToMove.StartPoint.Equals(this.EndPoint)) { return(true); } if (lineToMove.EndPoint.Equals(this.StartPoint)) { return(true); } if (lineToMove.EndPoint.Equals(this.EndPoint)) { return(true); } return(false); }
//TODO: implement public void SplitLine(double percentage, _Line lineToSplit) { }
/// <summary> /// this is extremely inefficient, avoid this if possible /// supposedly complete, should time it /// </summary> /// <param name="m"></param> private void RemoveRedundancy(_Model m) { ObservableCollection <_Room> rooms = m.rooms; //List<List<_Line>> lines = m.AllLines(); //List<List<List<_Point>>> points = m.AllPoints(); List <_Point> uniquePoints = new List <_Point>(); List <_Line> uniqueLines = new List <_Line>(); //clean points first //TODO: might need to override equals for the contains filter foreach (_Room room in rooms) { foreach (_Line line in room.Lines) { if (uniquePoints.Contains(line.StartPoint)) { line.StartPoint = uniquePoints.Find(i => i.XY == line.StartPoint.XY); } else { uniquePoints.Add(line.StartPoint); } if (uniquePoints.Contains(line.EndPoint)) { line.EndPoint = uniquePoints.Find(i => i.XY == line.EndPoint.XY); } else { uniquePoints.Add(line.EndPoint); } } } //TODO: might need to override equals for the contains filter //clean lines foreach (_Room room in rooms) { foreach (_Line line in room.Lines) { if (uniqueLines.Contains(line)) { //if (oldNewLines.ContainsKey(line)) //{ //} //else { room.Lines.Remove(line); _Line @where = uniqueLines.FirstOrDefault(i => i.IsTheSame(line)) as _Line; if (@where == null || @where.Number == -1) { room.Lines.Add(line); } else { room.Lines.Add(@where); } } } else { uniqueLines.Add(line); } } } }
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++; }
private void fillRelatedRoomListInfomration(_Line lineToMove, ref _Line l1, ref _Line l2) { foreach (_Room room in rooms) { // the lines are movedline, l1, l2 already existed, then find them foreach (_Line line in room.Lines) { if (line.IsTheSame(l1)) { l1 = line; } if (line.IsTheSame(l2)) { l2 = line; } if (line.Equals(lineToMove) && !roomsContainingTheLineToMove.Contains(room)) { roomsContainingTheLineToMove.Add(room); // roomsContainingTheLineToMove = rooms.Where(i => i.Lines.Contains(lineToMove)).ToList(); } if (line.Equals(lineToMove)) { continue; } if ((line.StartPoint.Equals(lineToMove.StartPoint) || line.EndPoint.Equals(lineToMove.StartPoint)) && !roomsTouchingStartPoint.Contains(room) && !roomsContainingTheLineToMove.Contains(room)) { if (!AreNotParralel(line, lineToMove) && !roomsTouchingStartPointOnlyAndHaveNoParallelLines.Contains(room)) { roomsTouchingStartPointOnlyAndHaveNoParallelLines.Add(room); //unused currently } roomsTouchingStartPoint.Add(room); //this might cause redundancy } if ((line.StartPoint.Equals(lineToMove.EndPoint) || line.EndPoint.Equals(lineToMove.EndPoint)) && !roomsTouchingEndPoint.Contains(room) && !roomsContainingTheLineToMove.Contains(room)) { if (!AreNotParralel(line, lineToMove) && !roomsTouchingEndPointOnlyAndHaveNoParalellLines.Contains(room)) { roomsTouchingEndPointOnlyAndHaveNoParalellLines.Add(room); //this might cause redundancy } roomsTouchingEndPoint.Add(room); //this might cause redundancy } } } foreach (_Room room in roomsContainingTheLineToMove) { if (roomsTouchingStartPoint.Contains(room)) { roomsTouchingStartPoint.Remove(room); } if (roomsTouchingEndPoint.Contains(room)) { roomsTouchingEndPoint.Remove(room); } } if (!roomsContainingTheLineToMove.Any()) { throw new Exception("LineIsMissing"); //if there are no rooms, inconsistent state } }
/// <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; }
public static bool IsOnLine(_Point myPoint, _Line myLine) { return(PointOnLine2D(myPoint, myLine.StartPoint, myLine.EndPoint)); }