/// <inheritdoc /> public bool UpdateEnergyData(ILayout <TNode, TConfiguration> oldLayout, ILayout <TNode, TConfiguration> newLayout, TNode node, ref TEnergyData energyData) { if (mapDescription.GetRoomDescription(node).IsCorridor) { return(true); } oldLayout.GetConfiguration(node, out var oldConfiguration); var newDistance = oldConfiguration.EnergyData.CorridorConstraintData.CorridorDistance; foreach (var vertex in oldLayout.Graph.Vertices) { if (vertex.Equals(node)) { continue; } if (!oldLayout.GetConfiguration(vertex, out var nodeConfiguration)) { continue; } newLayout.GetConfiguration(vertex, out var newNodeConfiguration); newDistance += newNodeConfiguration.EnergyData.CorridorConstraintData.CorridorDistance - nodeConfiguration.EnergyData.CorridorConstraintData.CorridorDistance; } var constraintData = new CorridorConstraintData { CorridorDistance = newDistance }; energyData.CorridorConstraintData = constraintData; return(newDistance == 0); }
public bool UpdateEnergyData(ILayout <TNode, TConfiguration> oldLayout, ILayout <TNode, TConfiguration> newLayout, TNode node, ref TEnergyData energyData) { oldLayout.GetConfiguration(node, out var oldConfiguration); var newOverlap = oldConfiguration.EnergyData.BasicConstraintData.Overlap; var newDistance = oldConfiguration.EnergyData.BasicConstraintData.MoveDistance; foreach (var vertex in oldLayout.Graph.Vertices) { if (vertex.Equals(node)) { continue; } if (!oldLayout.GetConfiguration(vertex, out var nodeConfiguration)) { continue; } newLayout.GetConfiguration(vertex, out var newNodeConfiguration); newOverlap += newNodeConfiguration.EnergyData.BasicConstraintData.Overlap - nodeConfiguration.EnergyData.BasicConstraintData.Overlap; newDistance += newNodeConfiguration.EnergyData.BasicConstraintData.MoveDistance - nodeConfiguration.EnergyData.BasicConstraintData.MoveDistance; } var constraintData = energyData.BasicConstraintData; constraintData.MoveDistance = newDistance; constraintData.Overlap = newOverlap; energyData.BasicConstraintData = constraintData; return(newOverlap == 0 && newDistance == 0); }
/// <inheritdoc /> public bool UpdateEnergyData(ILayout <TNode, TConfiguration> oldLayout, ILayout <TNode, TConfiguration> newLayout, TNode node, ref TEnergyData energyData) { if (mapDescription.GetRoomDescription(node).IsCorridor) { return(true); } oldLayout.GetConfiguration(node, out var oldConfiguration); var wrongDistanceNew = oldConfiguration.EnergyData.MinimumDistanceConstraintData.WrongDistanceCount; foreach (var vertex in oldLayout.Graph.Vertices) { if (vertex.Equals(node)) { continue; } if (!oldLayout.GetConfiguration(vertex, out var nodeConfiguration)) { continue; } newLayout.GetConfiguration(vertex, out var newNodeConfiguration); wrongDistanceNew += newNodeConfiguration.EnergyData.MinimumDistanceConstraintData.WrongDistanceCount - nodeConfiguration.EnergyData.MinimumDistanceConstraintData.WrongDistanceCount; } var constraintData = new MinimumDistanceConstraintData() { WrongDistanceCount = wrongDistanceNew }; energyData.MinimumDistanceConstraintData = constraintData; return(wrongDistanceNew == 0); }
/// <inheritdoc /> public bool ComputeEnergyData(ILayout <TNode, TConfiguration> layout, TNode node, TConfiguration configuration, ref TEnergyData energyData) { // TODO: why this? if (mapDescription.GetRoomDescription(node).IsCorridor) { return(true); } var wrongDistanceCount = 0; foreach (var vertex in layout.Graph.Vertices) { if (vertex.Equals(node)) { continue; } if (!layout.GetConfiguration(vertex, out var c)) { continue; } if (mapDescription.GetRoomDescription(vertex).IsCorridor) { continue; } if (AreNeighbours(node, vertex)) { continue; } if (!HaveMinimumDistance(configuration, c)) { wrongDistanceCount++; } } var constraintData = new MinimumDistanceConstraintData() { WrongDistanceCount = wrongDistanceCount }; energyData.MinimumDistanceConstraintData = constraintData; return(wrongDistanceCount == 0); }
public bool ComputeEnergyData(ILayout <TNode, TConfiguration> layout, TNode node, TConfiguration configuration, ref TEnergyData energyData) { var isCorridor = optimizeCorridors && mapDescription.GetRoomDescription(node).IsCorridor; var overlap = 0; var distance = 0; var neighbors = layout.Graph.GetNeighbours(node).ToList(); foreach (var vertex in layout.Graph.Vertices) { if (vertex.Equals(node)) { continue; } if (!layout.GetConfiguration(vertex, out var c)) { continue; } var area = ComputeOverlap(configuration, c); if (area != 0) { overlap += area; } else if (!isCorridor && neighbors.Contains(vertex)) { if (!configurationSpaces.HaveValidPosition(configuration, c)) { // TODO: this is not really accurate when there are more sophisticated door positions (as smaller distance is not always better) distance += ComputeDistance(configuration, c); } } } var constraintData = new BasicConstraintData { Overlap = overlap, MoveDistance = distance }; energyData.BasicConstraintData = constraintData; return(overlap == 0 && distance == 0); }
/// <inheritdoc /> public bool ComputeEnergyData(ILayout <TNode, TConfiguration> layout, TNode node, TConfiguration configuration, ref TEnergyData energyData) { if (mapDescription.GetRoomDescription(node).IsCorridor) { return(true); } var distance = 0; var neighbours = graphWithoutCorridors.GetNeighbours(node).ToList(); foreach (var vertex in neighbours) { if (vertex.Equals(node)) { continue; } if (!layout.GetConfiguration(vertex, out var c)) { continue; } // TODO: why wasn't this here? if (!AreNeighboursWithoutCorridors(vertex, node)) { continue; } if (!configurationSpaces.HaveValidPosition(configuration, c)) { distance += ComputeDistance(configuration, c); } } var constraintData = new CorridorConstraintData { CorridorDistance = distance }; energyData.CorridorConstraintData = constraintData; return(distance == 0); }
/// <summary> /// Computes updated energy data of the node that was perturbed. /// </summary> /// <param name="node"></param> /// <param name="oldLayout"></param> /// <param name="newLayout"></param> /// <returns></returns> public TEnergyData UpdateNodeEnergy(TNode node, ILayout <TNode, TConfiguration> oldLayout, ILayout <TNode, TConfiguration> newLayout) { var energyData = new TEnergyData(); var valid = true; foreach (var constraint in constraints) { if (!constraint.UpdateEnergyData(oldLayout, newLayout, node, ref energyData)) { valid = false; } } energyData.IsValid = valid; // TODO: weird newLayout.GetConfiguration(node, out var configuration); energyUpdater.UpdateEnergy(newLayout, configuration, ref energyData); return(energyData); }
/// <inheritdoc /> public LayoutGrid2D <TNode> Convert(ILayout <RoomNode <TNode>, TConfiguration> layout, bool addDoors) { var rooms = new List <LayoutRoomGrid2D <TNode> >(); var roomsDict = new Dictionary <TNode, LayoutRoomGrid2D <TNode> >(); foreach (var vertexAlias in layout.Graph.Vertices) { if (layout.GetConfiguration(vertexAlias, out var configuration)) { var vertex = vertexAlias.Room; var roomTemplateInstance = configuration.RoomShape; // Make sure that the returned shape has the same position as the original room template shape and is not moved to (0,0) // TODO: maybe make a unit/integration test? var transformation = roomTemplateInstance.Transformations.GetRandom(Random); var shape = configuration.RoomShape.RoomShape; var originalShape = roomTemplateInstance.RoomTemplate.Outline; var transformedShape = originalShape.Transform(transformation); var offset = transformedShape.BoundingRectangle.A - shape.BoundingRectangle.A; var room = new LayoutRoomGrid2D <TNode>(vertex, transformedShape, configuration.Position - offset, MapDescription.GetRoomDescription(vertexAlias.Room).IsCorridor, roomTemplateInstance.RoomTemplate, MapDescription.GetRoomDescription(vertexAlias.Room), transformation); rooms.Add(room); if (!addDoors) { continue; } var doors = new List <LayoutDoorGrid2D <TNode> >(); room.Doors = doors; roomsDict[vertex] = room; } } if (addDoors) { var generatedDoors = new HashSet <Tuple <TNode, TNode> >(); foreach (var vertexAlias in layout.Graph.Vertices) { var vertex = vertexAlias.Room; if (layout.GetConfiguration(vertexAlias, out var configuration)) { var neighbours = layout.Graph.GetNeighbours(vertexAlias); foreach (var neighbourAlias in neighbours) { var neighbour = neighbourAlias.Room; if (layout.GetConfiguration(neighbourAlias, out var neighbourConfiguration) && !generatedDoors.Contains(Tuple.Create(neighbour, vertex))) { var doorChoices = GetDoors(configuration, neighbourConfiguration); var randomChoice = doorChoices.GetRandom(Random); roomsDict[vertex].Doors.Add(new LayoutDoorGrid2D <TNode>(vertex, neighbour, randomChoice + -1 * roomsDict[vertex].Position)); roomsDict[neighbour].Doors.Add(new LayoutDoorGrid2D <TNode>(neighbour, vertex, randomChoice + -1 * roomsDict[neighbour].Position)); generatedDoors.Add(Tuple.Create(vertex, neighbour)); } } } } } return(new LayoutGrid2D <TNode>(rooms)); }