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 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 }); }