public ConfigurationSpace GetConfigurationSpaceOverCorridor(PolygonGrid2D polygon, List <DoorLineGrid2D> doorLines, PolygonGrid2D fixedPolygon, List <DoorLineGrid2D> fixedDoorLines, PolygonGrid2D corridor, List <DoorLineGrid2D> corridorDoorLines) { var fixedAndCorridorConfigurationSpace = GetConfigurationSpace(corridor, corridorDoorLines, fixedPolygon, fixedDoorLines); var newCorridorDoorLines = new List <DoorLineGrid2D>(); corridorDoorLines = DoorUtils.MergeDoorLines(corridorDoorLines); foreach (var corridorPositionLine in fixedAndCorridorConfigurationSpace.Lines) { foreach (var corridorDoorLine in corridorDoorLines) { var rotation = corridorDoorLine.Line.ComputeRotation(); var rotatedLine = corridorDoorLine.Line.Rotate(rotation); var rotatedCorridorLine = corridorPositionLine.Rotate(rotation).GetNormalized(); if (rotatedCorridorLine.GetDirection() == OrthogonalLineGrid2D.Direction.Right) { var correctPositionLine = (rotatedCorridorLine + rotatedLine.From); var correctLengthLine = new OrthogonalLineGrid2D(correctPositionLine.From, correctPositionLine.To + rotatedLine.Length * rotatedLine.GetDirectionVector(), rotatedCorridorLine.GetDirection()); var correctRotationLine = correctLengthLine.Rotate(-rotation); // TODO: problem with corridors overlapping newCorridorDoorLines.Add(new DoorLineGrid2D(correctRotationLine, corridorDoorLine.Length, corridorDoorLine.DoorSocket)); } else if (rotatedCorridorLine.GetDirection() == OrthogonalLineGrid2D.Direction.Top) { foreach (var corridorPosition in rotatedCorridorLine.GetPoints()) { var transformedDoorLine = rotatedLine + corridorPosition; var newDoorLine = transformedDoorLine.Rotate(-rotation); // TODO: problem with corridors overlapping // TODO: problem with too many small lines instead of bigger lines newCorridorDoorLines.Add(new DoorLineGrid2D(newDoorLine, corridorDoorLine.Length, corridorDoorLine.DoorSocket)); } } } } var configurationSpace = GetConfigurationSpace(polygon, doorLines, fixedPolygon, newCorridorDoorLines); // configurationSpace.ReverseDoors = null; return(new ConfigurationSpace() { Lines = configurationSpace.Lines.ToList() }); }
public List <RoomTemplateInstanceGrid2D> GetRoomTemplateInstances(RoomTemplateGrid2D roomTemplate) { var result = new List <RoomTemplateInstanceGrid2D>(); var doorLines = roomTemplate.Doors.GetDoors(roomTemplate.Outline); var shape = roomTemplate.Outline; foreach (var transformation in roomTemplate.AllowedTransformations) { var transformedShape = shape.Transform(transformation); var smallestPoint = transformedShape.BoundingRectangle.A; // Both the shape and doors are moved so the polygon is in the first quadrant and touches axes transformedShape = transformedShape + (-1 * smallestPoint); transformedShape = polygonUtils.NormalizePolygon(transformedShape); var transformedDoorLines = doorLines .Select(x => DoorUtils.TransformDoorLine(x, transformation)) .Select(x => new DoorLineGrid2D(x.Line + (-1 * smallestPoint), x.Length, x.DoorSocket)) .ToList(); // Check if we already have the same room shape (together with door lines) var sameRoomShapeFound = false; foreach (var roomInfo in result) { if (roomInfo.RoomShape.Equals(transformedShape) && roomInfo.DoorLines.SequenceEqualWithoutOrder(transformedDoorLines)) { roomInfo.Transformations.Add(transformation); sameRoomShapeFound = true; break; } } if (sameRoomShapeFound) { continue; } result.Add(new RoomTemplateInstanceGrid2D(roomTemplate, transformedShape, transformedDoorLines, new List <TransformationGrid2D>() { transformation })); } return(result); }
/// <summary> /// Applies all given transformation to a given room description. /// </summary> /// <remarks> /// Groups room shapes that are equal after transformation. /// </remarks> /// <param name="roomDescription"></param> /// <param name="transformations"></param> /// <returns></returns> private List <RoomInfo> TransformPolygons(RoomDescription roomDescription, IEnumerable <Transformation> transformations) { var result = new List <RoomInfo>(); var doorLines = doorHandler.GetDoorPositions(roomDescription.Shape, roomDescription.DoorsMode); var shape = roomDescription.Shape; foreach (var transformation in transformations) { var transformedShape = shape.Transform(transformation); var smallestPoint = transformedShape.BoundingRectangle.A; // Both the shape and doors are moved so the polygon is in the first quadrant and touches axes transformedShape = transformedShape + (-1 * smallestPoint); transformedShape = polygonUtils.NormalizePolygon(transformedShape); var transformedDoorLines = doorLines .Select(x => DoorUtils.TransformDoorLine(x, transformation)) .Select(x => new DoorLine(x.Line + (-1 * smallestPoint), x.Length)) .Cast <IDoorLine>() .ToList(); // Check if we already have the same room shape (together with door lines) var sameRoomShapeFound = false; foreach (var roomInfo in result) { if (roomInfo.RoomShape.Equals(transformedShape) && roomInfo.DoorLines.SequenceEqualWithoutOrder(transformedDoorLines)) { roomInfo.Transformations.Add(transformation); sameRoomShapeFound = true; break; } } if (sameRoomShapeFound) { continue; } result.Add(new RoomInfo(roomDescription, transformedShape, transformation, transformedDoorLines)); } return(result); }
public void MergeDoorLines_CorrectlyMerges() { var doorLines = new List <IDoorLine>() { new DoorLine(new OrthogonalLine(new IntVector2(1, 0), new IntVector2(2, 0)), 2), new DoorLine(new OrthogonalLine(new IntVector2(3, 0), new IntVector2(5, 0)), 2), new DoorLine(new OrthogonalLine(new IntVector2(-3, 0), new IntVector2(0, 0)), 1), new DoorLine(new OrthogonalLine(new IntVector2(-3, 0), new IntVector2(0, 0)), 2), new DoorLine(new OrthogonalLine(new IntVector2(0, 0), new IntVector2(0, 3)), 2), new DoorLine(new OrthogonalLine(new IntVector2(0, -2), new IntVector2(0, -1)), 2), }; var expectedDoorLines = new List <IDoorLine>() { new DoorLine(new OrthogonalLine(new IntVector2(-3, 0), new IntVector2(0, 0)), 1), new DoorLine(new OrthogonalLine(new IntVector2(-3, 0), new IntVector2(5, 0)), 2), new DoorLine(new OrthogonalLine(new IntVector2(0, -2), new IntVector2(0, 3)), 2), }; var mergedDoorLines = DoorUtils.MergeDoorLines(doorLines); Assert.That(mergedDoorLines, Is.EquivalentTo(expectedDoorLines)); }
private ConfigurationSpace GetConfigurationSpace(GridPolygon polygon, List <IDoorLine> doorLines, GridPolygon fixedCenter, List <IDoorLine> doorLinesFixed, List <int> offsets = null) { if (offsets != null && offsets.Count == 0) { throw new ArgumentException("There must be at least one offset if they are set", nameof(offsets)); } var configurationSpaceLines = new List <OrthogonalLine>(); var reverseDoor = new List <Tuple <OrthogonalLine, DoorLine> >(); doorLines = DoorUtils.MergeDoorLines(doorLines); doorLinesFixed = DoorUtils.MergeDoorLines(doorLinesFixed); // One list for every direction var lines = new List <IDoorLine> [4]; // Init array for (var i = 0; i < lines.Length; i++) { lines[i] = new List <IDoorLine>(); } // Populate lists with lines foreach (var line in doorLinesFixed) { lines[(int)line.Line.GetDirection()].Add(line); } foreach (var doorLine in doorLines) { var line = doorLine.Line; var oppositeDirection = OrthogonalLine.GetOppositeDirection(line.GetDirection()); var rotation = line.ComputeRotation(); var rotatedLine = line.Rotate(rotation); var correspondingLines = lines[(int)oppositeDirection].Where(x => x.Length == doorLine.Length).Select(x => new DoorLine(x.Line.Rotate(rotation), x.Length)); foreach (var cDoorLine in correspondingLines) { var cline = cDoorLine.Line; var y = cline.From.Y - rotatedLine.From.Y; var from = new IntVector2(cline.From.X - rotatedLine.To.X + (rotatedLine.Length - doorLine.Length), y); var to = new IntVector2(cline.To.X - rotatedLine.From.X - (rotatedLine.Length + doorLine.Length), y); if (from.X < to.X) { continue; } if (offsets == null) { var resultLine = new OrthogonalLine(from, to, OrthogonalLine.Direction.Left).Rotate(-rotation); reverseDoor.Add(Tuple.Create(resultLine, new DoorLine(cDoorLine.Line.Rotate(-rotation), cDoorLine.Length))); configurationSpaceLines.Add(resultLine); } else { foreach (var offset in offsets) { var offsetVector = new IntVector2(0, offset); var resultLine = new OrthogonalLine(from - offsetVector, to - offsetVector, OrthogonalLine.Direction.Left).Rotate(-rotation); reverseDoor.Add(Tuple.Create(resultLine, new DoorLine(cDoorLine.Line.Rotate(-rotation), cDoorLine.Length))); configurationSpaceLines.Add(resultLine); } } } } // Remove all positions when the two polygons overlap configurationSpaceLines = RemoveOverlapping(polygon, fixedCenter, configurationSpaceLines); // Remove all non-unique positions configurationSpaceLines = RemoveIntersections(configurationSpaceLines); return(new ConfigurationSpace() { Lines = configurationSpaceLines, ReverseDoors = reverseDoor }); }