/// <summary> /// Transform door line according to a given transformation. /// </summary> /// <param name="doorLine"></param> /// <param name="transformation"></param> /// <returns></returns> public static DoorLine TransformDoorLine(DoorLine doorLine, TransformationGrid2D transformation) { var doorPosition = doorLine.Line; if (doorPosition.GetDirection() == OrthogonalLineGrid2D.Direction.Undefined) { throw new InvalidOperationException("Cannot fix door direction when original direction is undefined"); } switch (transformation) { case TransformationGrid2D.Identity: return(doorLine); case TransformationGrid2D.Rotate90: return(new DoorLine(doorPosition.Rotate(90), doorLine.Length)); case TransformationGrid2D.Rotate180: return(new DoorLine(doorPosition.Rotate(180), doorLine.Length)); case TransformationGrid2D.Rotate270: return(new DoorLine(doorPosition.Rotate(270), doorLine.Length)); } // Other transformations need to switch door directions var firstStartPoint = doorPosition.From.Transform(transformation); var lastStartPoint = doorPosition.To.Transform(transformation); var length = doorLine.Length; var transformedDirection = TransformDirection(doorPosition.GetDirection(), transformation); var transformedLine = new OrthogonalLineGrid2D(firstStartPoint, lastStartPoint, transformedDirection); var lastEndPoint = lastStartPoint + length * transformedLine.GetDirectionVector(); var newDirection = OrthogonalLineGrid2D.GetOppositeDirection(transformedDirection); var newDoorPosition = new OrthogonalLineGrid2D(lastEndPoint, lastEndPoint + transformedLine.Length * transformedLine.SwitchOrientation().GetDirectionVector(), newDirection); if (newDoorPosition.Length != doorPosition.Length) { throw new InvalidOperationException(); } return(new DoorLine(newDoorPosition, doorLine.Length)); }
/// <summary> /// Merges all door lines that are directly next to each other and have the same length. /// </summary> /// <param name="doorLines"></param> /// <returns></returns> public static List <DoorLine> MergeDoorLines(IEnumerable <DoorLine> doorLines) { var doorLinesByDirection = doorLines.GroupBy(x => x.Line.GetDirection()); var result = new List <DoorLine>(); foreach (var grouping in doorLinesByDirection) { if (grouping.Key == OrthogonalLineGrid2D.Direction.Undefined) { throw new ArgumentException("There must be no door lines with undefined direction"); } var sameDirectionDoorLines = new LinkedList <DoorLine>(grouping); while (sameDirectionDoorLines.Count != 0) { var doorLineNode = sameDirectionDoorLines.First; var doorLine = doorLineNode.Value; sameDirectionDoorLines.RemoveFirst(); while (true) { var found = false; var nextDoorLineNode = sameDirectionDoorLines.First; while (nextDoorLineNode != null) { var otherDoorLineNode = nextDoorLineNode; var otherDoorLine = otherDoorLineNode.Value; nextDoorLineNode = otherDoorLineNode.Next; if (otherDoorLine.Length != doorLine.Length) { continue; } if (doorLine.Line.To + doorLine.Line.GetDirectionVector() == otherDoorLine.Line.From) { doorLine = new DoorLine(new OrthogonalLineGrid2D(doorLine.Line.From, otherDoorLine.Line.To), doorLine.Length); found = true; sameDirectionDoorLines.Remove(otherDoorLineNode); } else if (doorLine.Line.From - doorLine.Line.GetDirectionVector() == otherDoorLine.Line.To) { doorLine = new DoorLine(new OrthogonalLineGrid2D(otherDoorLine.Line.From, doorLine.Line.To), doorLine.Length); found = true; sameDirectionDoorLines.Remove(otherDoorLineNode); } } if (!found) { break; } } result.Add(doorLine); } } return(result); }