Skip to content

Commit

Permalink
Add extension method to compute transformed point position from room
Browse files Browse the repository at this point in the history
  • Loading branch information
OndrejNepozitek committed Nov 19, 2019
1 parent 7097cb0 commit c0cf3c5
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 3 deletions.
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="nunit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\MapGeneration\MapGeneration.csproj" />
</ItemGroup>

</Project>
50 changes: 50 additions & 0 deletions MapGeneration.IntegrationTests/Utils/RoomExtensionsTests.cs
@@ -0,0 +1,50 @@
using System.Linq;
using GeneralAlgorithms.DataStructures.Common;
using GeneralAlgorithms.DataStructures.Polygons;
using MapGeneration.Core.Doors.DoorModes;
using MapGeneration.Core.MapDescriptions;
using MapGeneration.Utils;
using NUnit.Framework;

namespace MapGeneration.IntegrationTests.Utils
{
[TestFixture]
public class RoomExtensionsTests
{
[Test]
public void TransformPointToNewPosition_RectanglePoints()
{
// Create a rectangular room shape
// Move it away from (0, 0) so that we can properly test the functionality
var rectangleShape = GridPolygon.GetRectangle(10, 4) + new IntVector2(10, 10);

// Create points to be transformed
// These could be for example traps, spawn points, etc.
// We use points of the rectangle here because it is easy to check that the transformation is correct.
var pointsToTransform = rectangleShape.GetPoints();

var mapDescription = new MapDescription<int>();

// Create simple graph with 2 vertices and 1 edge
mapDescription.AddRoom(0);
mapDescription.AddRoom(1);
mapDescription.AddPassage(0, 1);

// Add the rectangle shape
mapDescription.AddRoomShapes(new RoomDescription(rectangleShape, new OverlapMode(1, 0)));

var layoutGenerator = LayoutGeneratorFactory.GetDefaultChainBasedGenerator<int>();
var layout = layoutGenerator.GetLayouts(mapDescription, 1)[0];

foreach (var room in layout.Rooms)
{
// The points were chosen to be the points of the polygon, so after transforming them, they should
// be equal to the room.Shape + room.Position points
var transformedPoints = pointsToTransform.Select(x => room.TransformPointToNewPosition(x));
var expectedPoints = (room.Shape + room.Position).GetPoints();

Assert.That(transformedPoints, Is.EquivalentTo(expectedPoints));
}
}
}
}
2 changes: 1 addition & 1 deletion MapGeneration.Interfaces/Core/MapLayouts/IRoom.cs
Expand Up @@ -47,7 +47,7 @@ public interface IRoom<TNode>
Transformation Transformation { get; }

/// <summary>
/// All possible transformations of the room room description.
/// All possible transformations of the room description.
/// </summary>
IList<Transformation> Transformations { get; }
}
Expand Down
81 changes: 81 additions & 0 deletions MapGeneration.Tests/Utils/RoomExtensionsTests.cs
@@ -0,0 +1,81 @@
using System.Collections.Generic;
using GeneralAlgorithms.DataStructures.Common;
using GeneralAlgorithms.DataStructures.Polygons;
using MapGeneration.Core.Doors.DoorModes;
using MapGeneration.Core.MapDescriptions;
using MapGeneration.Core.MapLayouts;
using MapGeneration.Utils;
using NUnit.Framework;

namespace MapGeneration.Tests.Utils
{
[TestFixture]
public class RoomExtensionsTests
{
[Test]
public void TransformPointToNewPosition_Identity()
{
var room = GetRoom(new IntVector2(0, 0), new IntVector2(0, 0), Transformation.Identity, null);

var point = new IntVector2(5, 5);
var transformedPoint = room.TransformPointToNewPosition(point);

Assert.That(transformedPoint, Is.EqualTo(new IntVector2(5, 5)));
}

[Test]
public void TransformPointToNewPosition_Rotate90()
{
var room = GetRoom(new IntVector2(0, 0), new IntVector2(0, 0), Transformation.Rotate90, null);

var point = new IntVector2(10, 5);
var transformedPoint = room.TransformPointToNewPosition(point);

Assert.That(transformedPoint, Is.EqualTo(new IntVector2(5, 0)));
}

[Test]
public void TransformPointToNewPosition_Identity_WithPosition()
{
var room = GetRoom(new IntVector2(10, 10), new IntVector2(0, 0), Transformation.Identity, null);

var point = new IntVector2(5, 5);
var transformedPoint = room.TransformPointToNewPosition(point);

Assert.That(transformedPoint, Is.EqualTo(new IntVector2(15, 15)));
}

[Test]
public void TransformPointToNewPosition_Rotate180_WithPosition()
{
var room = GetRoom(new IntVector2(10, 10), new IntVector2(0, 0), Transformation.Rotate180, null);

var point = new IntVector2(10, 5);
var transformedPoint = room.TransformPointToNewPosition(point);

Assert.That(transformedPoint, Is.EqualTo(new IntVector2(10, 15)));
}

[Test]
public void TransformPointToNewPosition_Rotate180_WithPosition_WithOrigin()
{
var room = GetRoom(new IntVector2(10, 10), new IntVector2(7, 10), Transformation.Rotate180, null);

var point = new IntVector2(10, 5);
var transformedPoint = room.TransformPointToNewPosition(point);

Assert.That(transformedPoint, Is.EqualTo(new IntVector2(17, 25)));
}

private Room<int> GetRoom(IntVector2 position, IntVector2 roomShapeOrigin, Transformation transformation, List<Transformation> transformations)
{
return new Room<int>(0,
GridPolygon.GetSquare(10),
position,
false,
new RoomDescription(GridPolygon.GetSquare(10) + roomShapeOrigin, new OverlapMode(1, 0)),
transformation,
transformations);
}
}
}
19 changes: 17 additions & 2 deletions MapGeneration.sln
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2010
# Visual Studio Version 16
VisualStudioVersion = 16.0.29409.12
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MapGeneration", "MapGeneration\MapGeneration.csproj", "{8538B30D-B0C5-4BB8-8FA9-C9388E0758E7}"
EndProject
Expand All @@ -19,6 +19,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MapGeneration.Interfaces",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sandbox", "Sandbox\Sandbox.csproj", "{6609983F-B790-4E65-A329-832AFE28BA77}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapGeneration.IntegrationTests", "MapGeneration.IntegrationTests\MapGeneration.IntegrationTests.csproj", "{E72A97FD-3A65-4546-8EBF-2A6A6ECD3115}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -113,13 +115,26 @@ Global
{6609983F-B790-4E65-A329-832AFE28BA77}.Release|x64.Build.0 = Release|Any CPU
{6609983F-B790-4E65-A329-832AFE28BA77}.Release|x86.ActiveCfg = Release|Any CPU
{6609983F-B790-4E65-A329-832AFE28BA77}.Release|x86.Build.0 = Release|Any CPU
{E72A97FD-3A65-4546-8EBF-2A6A6ECD3115}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E72A97FD-3A65-4546-8EBF-2A6A6ECD3115}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E72A97FD-3A65-4546-8EBF-2A6A6ECD3115}.Debug|x64.ActiveCfg = Debug|Any CPU
{E72A97FD-3A65-4546-8EBF-2A6A6ECD3115}.Debug|x64.Build.0 = Debug|Any CPU
{E72A97FD-3A65-4546-8EBF-2A6A6ECD3115}.Debug|x86.ActiveCfg = Debug|Any CPU
{E72A97FD-3A65-4546-8EBF-2A6A6ECD3115}.Debug|x86.Build.0 = Debug|Any CPU
{E72A97FD-3A65-4546-8EBF-2A6A6ECD3115}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E72A97FD-3A65-4546-8EBF-2A6A6ECD3115}.Release|Any CPU.Build.0 = Release|Any CPU
{E72A97FD-3A65-4546-8EBF-2A6A6ECD3115}.Release|x64.ActiveCfg = Release|Any CPU
{E72A97FD-3A65-4546-8EBF-2A6A6ECD3115}.Release|x64.Build.0 = Release|Any CPU
{E72A97FD-3A65-4546-8EBF-2A6A6ECD3115}.Release|x86.ActiveCfg = Release|Any CPU
{E72A97FD-3A65-4546-8EBF-2A6A6ECD3115}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{CD72AFE4-17C9-4F89-892A-1C86127B7466} = {913B8829-7BC1-4627-995B-8ECF6AC15FBA}
{D21972B1-D75A-4ADC-802F-394BD5FFE654} = {913B8829-7BC1-4627-995B-8ECF6AC15FBA}
{E72A97FD-3A65-4546-8EBF-2A6A6ECD3115} = {913B8829-7BC1-4627-995B-8ECF6AC15FBA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6F179471-9336-4BB8-BB31-4035B3D95A9A}
Expand Down
41 changes: 41 additions & 0 deletions MapGeneration/Utils/RoomExtensions.cs
@@ -0,0 +1,41 @@
using System;
using GeneralAlgorithms.DataStructures.Common;
using MapGeneration.Interfaces.Core.MapLayouts;

namespace MapGeneration.Utils
{
public static class RoomExtensions
{
/// <summary>
/// Transforms a given point to a position such that if the point was in some relative position to the
/// RoomShape of the associated MapDescription, the returned point will be in that some relative position
/// with respect to the position and transformation of the RoomShape in the generated layout.
/// </summary>
/// <remarks>
/// This function is useful e.g. if we have some trap or spawn positions defined for our room shapes and
/// then need to know where to place them in the generated layout.
///
/// If the room is invariant to some transformation (e.g. does not change when rotated by 90 degrees), then
/// all such transformations are contained in the room.Transformation collection. All these transformations
/// can be used for the "transformation" parameter if we do not want to use the room.Transformation transformation.
/// </remarks>
/// <typeparam name="TNode"></typeparam>
/// <param name="room"></param>
/// <param name="point">Point to be transformed to the new position</param>
/// <param name="transformation">Transformation to be used. It must be one of the room.Transformations. Defaults to room.Transformation.</param>
/// <returns></returns>
public static IntVector2 TransformPointToNewPosition<TNode>(this IRoom<TNode> room, IntVector2 point, Transformation? transformation = null)
{
if (transformation != null && room.Transformations.Contains(transformation.Value))
{
throw new ArgumentException("Transformation must be one of the possible room transformations", nameof(transformation));
}

transformation = transformation ?? room.Transformation;

var transformedShape = room.RoomDescription.Shape.Transform(transformation.Value);

return (point.Transform(transformation.Value) - transformedShape.BoundingRectangle.A) + room.Position;
}
}
}

0 comments on commit c0cf3c5

Please sign in to comment.