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