public void ConcaveRoomNeighbours() { var a = _plan.Add(new[] { new Vector2(-100, 20), new Vector2(-100, 75), new Vector2(0, 75), new Vector2(0, 20), }, 5).Single(); var b = _plan.Add(new[] { new Vector2(-100, -75), new Vector2(-100, -20), new Vector2(0, -20), new Vector2(0, -75), }, 5).Single(); var c = _plan.Add(new[] { new Vector2(-50, -75), new Vector2(-50, 75), new Vector2(50, 75), new Vector2(50, -75), }, 5).Single(); Assert.IsNotNull(a); Assert.IsNotNull(b); Assert.IsNotNull(c); Console.WriteLine(SvgRoomVisualiser.FloorplanToSvg(_plan)); }
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_ComplexRoomNeighbours() { var a = _plan.Add(new[] { new Vector2(-70, -75), new Vector2(0, -25), new Vector2(-50, -25), new Vector2(-50, 25), new Vector2(0, 25), new Vector2(0, 75), new Vector2(50, 75), new Vector2(50, -75), }, 1).Single(); var b = _plan.Add(new[] { new Vector2(-90, -75), new Vector2(-90, 0), new Vector2(0, 0), new Vector2(0, -75), }, 1).Single(); Console.WriteLine(SvgRoomVisualiser.FloorplanToSvg(_plan, 3, true)); //This used to throw (index out of range exception due to neighbour calculation assuming inner and outer arrays are the same length) var na = a.GetWalls(); Console.WriteLine(SvgRoomVisualiser.FloorplanToSvg(_plan, 3, false)); Assert.AreEqual(3, a.Neighbours.Count()); }
public void RegressionTest_MissingFacadeStartSections() { // This is a test case found when designing trains // The start of a wall (from wall start -> start of first neighbour) didn't generate, now it does. // This test will fail if that happens again var b = _plan.Add(new[] { new Vector2(-70, -50), new Vector2(-70, -10), new Vector2(-30, -10), new Vector2(-30, -50), }, 5).Single(); var c = _plan.Add(new[] { new Vector2(-69.9f, -50), new Vector2(-69.9f, 50), new Vector2(60, 50), new Vector2(60, -50), }, 5).Single(); Console.WriteLine(SvgRoomVisualiser.FloorplanToSvg(_plan, 4)); Assert.AreEqual(4, b.GetWalls().Count()); Assert.AreEqual(6, c.GetWalls().Count()); }
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 Floorplan_CornerOverlap_GeneratesNoNeighbours() { var roomLeft = _plan.Add(new Vector2[] { new Vector2(-20, -20), new Vector2(-20, 0), new Vector2(0, 0), new Vector2(0, -20) }, 5).Single(); var roomRight = _plan.Add(new Vector2[] { new Vector2(5, -2), new Vector2(5, 20), new Vector2(25, 20), new Vector2(25, -2) }, 5).Single(); Console.WriteLine(SvgRoomVisualiser.FloorplanToSvg(_plan)); Assert.AreEqual(0, roomRight.Neighbours.Count()); Assert.AreEqual(0, roomLeft.Neighbours.Count()); }
public void Floorplan_ClippingRooms_GeneratesNonOverlappingRooms() { var roomLeft = _plan.Add(new Vector2[] { new Vector2(-20, -20), new Vector2(-20, 0), new Vector2(0, 0), new Vector2(0, -20) }, 5).Single(); var roomRight = _plan.Add(new Vector2[] { new Vector2(-5, -5), new Vector2(-5, 20), new Vector2(25, 20), new Vector2(25, -5) }, 5).Single(); _plan.Freeze(); Assert.IsNotNull(roomLeft); Assert.IsNotNull(roomRight); Console.WriteLine(SvgRoomVisualiser.FloorplanToSvg(_plan)); }
public void ExactlyMirroredRoomsAreNeighbours() { var a = _plan.Add(new Vector2[] { new Vector2(-10, -10), new Vector2(-10, 10), new Vector2(0, 10), new Vector2(0, -10) }, 1).Single(); var b = _plan.Add(new Vector2[] { new Vector2(0, -10), new Vector2(0, 10), new Vector2(10, 10), new Vector2(10, -10) }, 1).Single(); Console.WriteLine(SvgRoomVisualiser.FloorplanToSvg(_plan, 3)); var n = a.Neighbours.Single(ne => ne.Other(a) == b); Assert.AreEqual(0, n.At); Assert.AreEqual(1, n.Bt); Assert.AreEqual(0, n.Ct); Assert.AreEqual(1, n.Dt); }
public void TheTest() { var b = _plan.Add(new[] { new Vector2(-99.9f, -50), new Vector2(-99.99f, -10), new Vector2(-30, -10), new Vector2(-30, -50), }, 5).Single(); var c = _plan.Add(new[] { new Vector2(-69.9f, -50), new Vector2(-69.9f, 50), new Vector2(60, 50), new Vector2(60, -50), }, 5).Single(); //B neighbours A, C, ~D var neighboursB = b.Neighbours; Assert.AreEqual(2, neighboursB.Count(x => x.Other(b) == c)); //C neighbours A, B, D var neighboursC = c.Neighbours; Assert.AreEqual(2, neighboursC.Count(x => x.Other(c) == b)); //Check that B has no duplicated facades var facadesB = b.GetWalls().ToArray(); var duplicatesB = facadesB.Where(f => facadesB.Any(g => g != f && g.Section.Matches(f.Section))).ToArray(); Assert.IsFalse(duplicatesB.Any()); //Check that C has no duplicated facades var facadesC = c.GetWalls().ToArray(); var duplicatesC = facadesC.Where(f => facadesC.Any(g => g != f && g.Section.Matches(f.Section))).ToArray(); Assert.IsFalse(duplicatesC.Any()); var svg = SvgRoomVisualiser.FloorplanToSvg(_plan); Console.WriteLine(svg); }
public void InnerWallTurn() { _plan.Add(new[] { new Vector2(-70, -75), new Vector2(0, -25), new Vector2(-50, -25), new Vector2(-50, 25), new Vector2(0, 25), new Vector2(0, 75), new Vector2(50, 75), new Vector2(50, -75), }, 5); Console.WriteLine(SvgRoomVisualiser.FloorplanToSvg(_plan)); }
public void Floorplan_SeparateRooms_HaveNoNeighbours() { var roomA = _plan.Add(new Vector2[] { new Vector2(-100, -100), new Vector2(-100, -80), new Vector2(-80, -80), new Vector2(-80, -100) }, 3f).Single(); var roomB = _plan.Add(new Vector2[] { new Vector2(100, 100), new Vector2(100, 80), new Vector2(80, 80), new Vector2(80, 100) }, 3f).Single(); _plan.Freeze(); DrawPlan(); Assert.AreEqual(0, roomA.Neighbours.Count()); Assert.AreEqual(0, roomB.Neighbours.Count()); //Check all neighbour data is correctly wound AssertAllWindings(); //Check all sections lies on the external footprint of the involved rooms AssertAllSections(); 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 OddlyAngledRoomsAreNotNeighbours() { var a = _plan.Add(new Vector2[] { new Vector2(0, 0), new Vector2(0, 30), new Vector2(30, 30), new Vector2(30, 0), }, 1f).Single(); var b = _plan.Add(new Vector2[] { new Vector2(-30, 30), new Vector2(30, -30), new Vector2(-30, -60), new Vector2(-60, -30), }, 1f).Single(); Console.WriteLine(SvgRoomVisualiser.FloorplanToSvg(_plan, 3)); Assert.AreEqual(0, a.Neighbours.Count()); Assert.AreEqual(0, b.Neighbours.Count()); }
private void DrawPlan(IFloorPlanBuilder plan = null) { Console.WriteLine(SvgRoomVisualiser.FloorplanToSvg(plan ?? _plan, 3)); }
public void TestMethod1() { var rnd = new Random(3); var random = (Func <double>)rnd.NextDouble; var metadata = new NamedBoxCollection(); var designer = FloorDesigner.Deserialize(new StringReader(@" # root node !Floorplan # tags for this floorplan Tags: Type: Residential Style: None # Aliases block is just a list of items, not used by the system. Handy place to define objects which will be used later in the markup Aliases: # A single room, with a set of constraints - &office !Room Id: Office Walkthrough: false Tags: 1: { Office } # Constraints: [] # - { Strength: 1, Req: !ExteriorWindow { } } # - { Strength: 0.5, Req: !ExteriorDoor { Deny: true } } # - { Strength: 0.5, Req: !Area { Min: 11 } } # A group of rooms - &office_group !Group Id: Offices Children: - *office - *office GrowthParameters: SeedSpacing: !NormalValue { Min: 2.5, Mean: 5, Max: 6.5, Vary: true } SeedChance: 0.75 IntersectionContinuationChance: 0.3 ParallelCheck: Length: 1 Width: 3.5 Angle: 15 MergeParameters: AngularDeviation: Weight: 0.4 Threshold: 0.5 Convexity: Weight: 0.3 Threshold: 0.5 Area: Weight: 0.3 Threshold: 45 Cutoff: 5 CorridorParameters: Width: 1 Spaces: - !Repeat Count: !NormalValue { Min: 1, Max: 100 } Space: *office_group ")); Func <IEnumerable <KeyValuePair <string, string> >, Type[], ScriptReference> finder = (tags, types) => { var tagsClean = from tag in tags let k = string.IsNullOrEmpty(tag.Key) let v = string.IsNullOrEmpty(tag.Value) where !k || !v select(!k && !v) ? (tag.Key + ":" + tag.Value) : (k ? tag.Value : tag.Key); return(ScriptReferenceFactory.Create(typeof(TestScript), Guid.NewGuid(), string.Join(",", tagsClean))); }; ////Corner shape //var shape = new[] { // new Vector2(9, 5), new Vector2(9, -6), new Vector2(0, -6), new Vector2(0, 0), new Vector2(-4, 0), new Vector2(-4, 5) //}; //var sections = new[] { // new Subsection[] { new Subsection(0, 1, Subsection.Types.Window) }, // new Subsection[0], // new Subsection[0], // new Subsection[0], // new Subsection[] { new Subsection(0, 1, Subsection.Types.Window) }, // new Subsection[0] //}; //Diagonal bend shape var shape = new[] { new Vector2(10, 10), new Vector2(20, 0), new Vector2(23, 0), new Vector2(33, 10), new Vector2(43, 0), new Vector2(28, -15), new Vector2(15, -15), new Vector2(0, 0) }; var sections = new[] { new Subsection[0], new Subsection[0], new Subsection[0], new Subsection[0], new Subsection[0], new Subsection[0], new Subsection[0], new Subsection[0] }; var verticals = new Vector2[][] { }; ////Actual office floorplan //var shape = new[] { // new Vector2(-25, 17), // new Vector2(0, 17), // new Vector2(3, 15), // new Vector2(33, 15), // new Vector2(38, 0), // new Vector2(-25, -25) //}; //var sections = new[] { // new Subsection[0], // new Subsection[0], // new Subsection[0], // new Subsection[0], // new Subsection[0], // new Subsection[0] //}; //var verticals = new[] { // new[] { // new Vector2(0, 0), // new Vector2(7, 0), // new Vector2(7, -7), // new Vector2(0, -7), // } //}; ////rectangle //var shape = new[] { // new Vector2(9, 0), // new Vector2(9, -6), // new Vector2(0, -6), // new Vector2(0, 0) //}; //var sections = new[] { // new Subsection[0], // new Subsection[0], // new Subsection[0], // new Subsection[0], //}; var plan = new GeometricFloorplan(shape); designer.Design(random, metadata, finder, plan, sections, 0.175f, verticals, new List <ConstrainedVerticalSelection>()); Console.WriteLine(SvgRoomVisualiser.FloorplanToSvg(plan, 55, basic: false)); }