Exemplo n.º 1
0
        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)));
            }
        }
Exemplo n.º 2
0
        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));
        }
Exemplo n.º 3
0
        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));
        }
Exemplo n.º 4
0
        public IFloorPlanBuilder Design(Func <double> random, INamedDataCollection metadata, Func <KeyValuePair <string, string>[], Type[], ScriptReference> finder, IReadOnlyList <Vector2> footprint, IReadOnlyList <IReadOnlyList <Subsection> > sections, float wallThickness, IReadOnlyList <IReadOnlyList <Vector2> > overlappingVerticals, IReadOnlyList <ConstrainedVerticalSelection> startingVerticals)
        {
            Contract.Requires(random != null);
            Contract.Requires(metadata != null);
            Contract.Requires(finder != null);
            Contract.Requires(footprint != null && footprint.Count >= 3);
            Contract.Requires(sections != null && sections.Count == footprint.Count);
            Contract.Requires(overlappingVerticals != null && Contract.ForAll(overlappingVerticals, o => o != null));
            Contract.Requires(startingVerticals != null && Contract.ForAll(startingVerticals, s => s != null));
            Contract.Ensures(Contract.Result <IFloorPlanBuilder>() != null);

            var plan = new GeometricFloorplan(footprint);

            Design(random, metadata, finder, plan, sections, wallThickness, overlappingVerticals, startingVerticals);

            return(plan);
        }
Exemplo n.º 5
0
        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);
            }
        }
Exemplo n.º 6
0
        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);
        }
Exemplo n.º 7
0
        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);
        }
Exemplo n.º 8
0
        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));
        }