public void SvgFloorplan() { var r = new Random(23523); const int FLOOR_COUNT = 1; for (int i = 0; i < FLOOR_COUNT; i++) { var plan = new GeometricFloorplan(new ReadOnlyCollection <Vector2>(new[] { new Vector2(-25, -25), new Vector2(-25, 25), new Vector2(25, 25), new Vector2(25, -25) })); for (int j = 0; j < 3; j++) { var minX = r.Next(-25, 20); var minY = r.Next(-25, 20); var width = r.Next(10, 20); var height = r.Next(10, 20); plan.Add(new[] { new Vector2(minX, minY), new Vector2(minX, minY + height), new Vector2(minX + width, minY + height), new Vector2(minX + width, minY) }, r.Next(1, 5) ); } plan.Freeze(); //Console.WriteLine(FloorplanToSvg(plan, 500, 0, 0, (i * floorHeight - floorCount * floorHeight))); } }
public void RegressionTest_UnmatchedWallSections() { // This is a case generated from fuzz testing (i.e. generate random data, see what breaks). // Sometimes matching up inner and outer sections of wall data used to fail (fixed in EpimetheusPlugins). // This test will fail in that case var r = new Random(189); var plan = new GeometricFloorplan(new ReadOnlyCollection <Vector2>(new[] { new Vector2(-25, -25), new Vector2(-25, 25), new Vector2(25, 25), new Vector2(25, -25) })); for (int j = 0; j < 3; j++) { var minX = r.Next(-25, 20); var minY = r.Next(-25, 20); var width = r.Next(10, 20); var height = r.Next(10, 20); plan.Add(new[] { new Vector2(minX, minY), new Vector2(minX, minY + height), new Vector2(minX + width, minY + height), new Vector2(minX + width, minY) }, 1 ); } plan.Freeze(); Console.WriteLine(SvgRoomVisualiser.FloorplanToSvg(_plan)); }
public void RegressionTest_ShrinkingSplitsFootprint() { // This is a case generated from fuzz testing (i.e. generate random data, see what breaks). // Shrinking a shape can generate *several* separate shapes if the original shape was convex. // This used to fail, now shrinking discards all the generated shapes except the largest (fixed with a change in EpimetheusPlugins). var r = new Random(738); var plan = new GeometricFloorplan(new ReadOnlyCollection <Vector2>(new[] { new Vector2(-25, -25), new Vector2(-25, 25), new Vector2(25, 25), new Vector2(25, -25) })); for (int j = 0; j < 3; j++) { var minX = r.Next(-25, 20); var minY = r.Next(-25, 20); var width = r.Next(10, 20); var height = r.Next(10, 20); plan.Add(new[] { new Vector2(minX, minY), new Vector2(minX, minY + height), new Vector2(minX + width, minY + height), new Vector2(minX + width, minY) }, 1 ); } plan.Freeze(); Console.WriteLine(SvgRoomVisualiser.FloorplanToSvg(_plan)); }
public void FuzzTest() { Action <int, bool> iterate = (seed, catchit) => { Random r = new Random(seed); try { var plan = new GeometricFloorplan(new ReadOnlyCollection <Vector2>(new[] { new Vector2(-25, -25), new Vector2(-25, 25), new Vector2(25, 25), new Vector2(25, -25) })); for (int j = 0; j < 3; j++) { var minX = r.Next(-25, 20); var minY = r.Next(-25, 20); var width = r.Next(10, 20); var height = r.Next(10, 20); plan.Add(new[] { new Vector2(minX, minY), new Vector2(minX, minY + height), new Vector2(minX + width, minY + height), new Vector2(minX + width, minY) }, 1); } plan.Freeze(); Console.WriteLine(SvgRoomVisualiser.FloorplanToSvg(_plan).ToString()); } catch { if (!catchit) { throw; } else { Assert.Fail(string.Format("Failing seed = {0}", seed.ToString())); } } }; for (var s = 0; s < 100; s++) { iterate(s * 2389, true); } }
public void TrainCarriageTest2() { // ReSharper disable InconsistentNaming var r = new Random(); Func <double> Random = r.NextDouble; const int Length = 20; const int Width = 10; Func <Vector2, float, float, Vector2> Offset = (start, length, width) => start + new Vector2(Length * length, -Width * width); Func <IFloorPlanBuilder, bool, float, IEnumerable <IRoomPlan> > CreateBalcony = (pl, start, bl) => { var p = pl.ExternalFootprint.First(); const float wt = 0.11f; if (start) { return(pl.Add(new Vector2[] { Offset(p, 0, 0.01f), Offset(p, bl / Length, 0.01f), Offset(p, bl / Length, 0.99f), Offset(p, 0, 0.99f), }, wt)); } else { return(pl.Add(new Vector2[] { Offset(p, 1 - (bl / Length), 0.01f), Offset(p, 1, 0.01f), Offset(p, 1, 0.99f), Offset(p, 1 - bl / Length, 0.99f), }, wt)); } }; var plan = new GeometricFloorplan(new ReadOnlyCollection <Vector2>(new Vector2[] { new Vector2(-Length / 2f, Width / 2f), new Vector2(Length / 2f, Width / 2f), new Vector2(Length / 2f, -Width / 2f), new Vector2(-Length / 2f, -Width / 2f), })); // ReSharper restore InconsistentNaming //Create balconies on either end float balconyLength = Math.Min(3, Length / 10f); CreateBalcony(plan, true, balconyLength); CreateBalcony(plan, false, balconyLength); //Reference point to create rooms relative to var point = plan.ExternalFootprint.First(); //Create corridor section along entire train (along one side) const float CORRIDOR_WIDTH = 3; plan.Add(new Vector2[] { Offset(point, (balconyLength + 0.05f) / Length, 0), Offset(point, (Length - balconyLength - 0.05f) / Length, 0), Offset(point, (Length - balconyLength - 0.05f) / Length, CORRIDOR_WIDTH / Width), Offset(point, (balconyLength + 0.05f) / Length, CORRIDOR_WIDTH / Width), }, 0.55f); //Create compartments var compartmentAreaLength = Length - (balconyLength + 0.05f) * 2; var compartmentCount = Random.CompartmentalizeSpace(compartmentAreaLength, 1, int.MaxValue, 6, 10); var compartmentLength = compartmentAreaLength / compartmentCount; var compartments = new IRoomPlan[compartmentCount]; for (var i = 0; i < compartmentCount; i++) { var xStart = balconyLength + 0.05f + i * compartmentLength; var xEnd = xStart + compartmentLength - 0.05f; const float Y_START = CORRIDOR_WIDTH; compartments[i] = plan.Add(new Vector2[] { Offset(point, xStart / Length, Y_START / Width), Offset(point, xEnd / Length, Y_START / Width), Offset(point, xEnd / Length, 1), Offset(point, xStart / Length, 1), }, 0.55f).Single(); } plan.Freeze(); DrawPlan(plan); }
public void TrainCarriageTest() { // ReSharper disable InconsistentNaming var HierarchicalParameters = new NamedBoxCollection(); var r = new Random(); Func <double> Random = r.NextDouble; const float Length = 60; const float Width = 20; Func <Vector2, float, float, Vector2> Offset = (start, length, width) => start + new Vector2(Length * length, -Width * width); Func <IFloorPlanBuilder, bool, float, IEnumerable <IRoomPlan> > CreateBalcony = (pl, start, bl) => { var p = pl.ExternalFootprint.First(); var wt = HierarchicalParameters.InternalWallThickness(Random); if (start) { return(pl.Add(new Vector2[] { Offset(p, 0, 0.01f), Offset(p, bl / Length, 0.01f), Offset(p, bl / Length, 0.99f), Offset(p, 0, 0.99f), }, wt)); } else { return(pl.Add(new Vector2[] { Offset(p, 1 - (bl / Length), 0.01f), Offset(p, 1, 0.01f), Offset(p, 1, 0.99f), Offset(p, 1 - bl / Length, 0.99f), }, wt)); } }; var plan = new GeometricFloorplan(new ReadOnlyCollection <Vector2>(new Vector2[] { new Vector2(-Length / 2f, Width / 2f), new Vector2(Length / 2f, Width / 2f), new Vector2(Length / 2f, -Width / 2f), new Vector2(-Length / 2f, -Width / 2f), })); // ReSharper restore InconsistentNaming //Get some style values var wallThickness = HierarchicalParameters.InternalWallThickness(Random); var doorWidth = HierarchicalParameters.StandardDoorWidth(Random); //Create balconies on either end float balconyLength = Math.Min(3, Length / 10f); var balcony1 = CreateBalcony(plan, true, balconyLength).Single(); var balcony2 = CreateBalcony(plan, false, balconyLength).Single(); //Reference point to create rooms relative to var point = plan.ExternalFootprint.First(); //Add toilets at one end of the carriage float toiletLength = balconyLength; //Left of the corridor var toiletLeft = plan.Add(new Vector2[] { Offset(point, balconyLength / Length, 0), Offset(point, (balconyLength + toiletLength) / Length, 0), Offset(point, (balconyLength + toiletLength) / Length, (Width / 2 - doorWidth / 2) / Width), Offset(point, balconyLength / Length, (Width / 2 - doorWidth / 2) / Width), }, wallThickness).Single(); //Right of the corridor var toiletRight = plan.Add(new Vector2[] { Offset(point, balconyLength / Length, (Width / 2 + doorWidth / 2) / Width), Offset(point, (balconyLength + toiletLength) / Length, (Width / 2 + doorWidth / 2) / Width), Offset(point, (balconyLength + toiletLength) / Length, 1), Offset(point, balconyLength / Length, 1), }, wallThickness).Single(); //Corridor var corridorL = (Width / 2 - doorWidth / 2 + 0.01f) / Width; var corridorR = (Width / 2 + doorWidth / 2 - 0.01f) / Width; var corridor = plan.Add(new Vector2[] { Offset(point, balconyLength / Length, corridorL), Offset(point, (balconyLength + toiletLength) / Length, corridorL), Offset(point, (balconyLength + toiletLength) / Length, corridorR), Offset(point, balconyLength / Length, corridorR), }, wallThickness).Single(); //Add dining room var diningRoom = plan.Add(new Vector2[] { Offset(point, (balconyLength + toiletLength + 0.05f) / Length, 0), Offset(point, (Length - balconyLength - 0.05f) / Length, 0), Offset(point, (Length - balconyLength - 0.05f) / Length, 1), Offset(point, (balconyLength + toiletLength + 0.05f) / Length, 1), }, wallThickness).Single(); plan.Freeze(); DrawPlan(plan); Assert.IsFalse(balcony2.Neighbours.Any(a => a.Other(balcony2) != diningRoom)); Assert.IsNotNull(balcony1); Assert.IsNotNull(balcony2); Assert.IsNotNull(toiletLeft); Assert.IsNotNull(toiletRight); Assert.IsNotNull(corridor); Assert.IsNotNull(diningRoom); }