コード例 #1
0
ファイル: RoomGroup.cs プロジェクト: vdubya/RoomKit
        /// <summary>
        /// Creates a group of rooms by dividing the supplied Polygon perimeter by the quantity of supplied divisions along the orthogonal x and y axes. Room perimeters conform to fit within the supplied Polygon.
        /// </summary>
        /// <param name="perimeter">The Polygon to divide with a number of Room perimeters.</param>
        /// <param name="xRooms">The quantity of Rooms along the x axis.</param>
        /// <param name="yRooms">The quantity of Rooms along the y axis.</param>
        /// <param name="name">An arbitrary string identifier for this RoomGroup.</param>
        /// <returns>
        /// A new RoomGroup.
        /// </returns>
        public RoomGroup(Polygon perimeter, int xRooms = 1, int yRooms = 1, string name = "")
        {
            Perimeter = new Polygon(perimeter.Vertices);
            Name      = name;
            Box       = new TopoBox(perimeter);
            Rooms     = new List <Room>();

            var sizeX = Box.SizeX / xRooms;
            var sizeY = Box.SizeY / yRooms;
            var count = xRooms * yRooms;

            for (int xIdx = 0; xIdx < xRooms; xIdx++)
            {
                var xCoord = Box.SW.X + (xIdx * sizeX);
                for (int yIdx = 0; yIdx < yRooms; yIdx++)
                {
                    var yCoord  = Box.SW.Y + (yIdx * sizeY);
                    var polygon = Shaper.PolygonBox(sizeX, sizeY);
                    polygon = polygon.MoveFromTo(new Vector3(), new Vector3(xCoord, yCoord)).Intersection(perimeter).First();

                    var room = new Room()
                    {
                        Color     = Palette.Aqua,
                        Perimeter = polygon
                    };
                    Rooms.Add(room);
                }
            }
        }
コード例 #2
0
ファイル: RoomGroup.cs プロジェクト: vdubya/RoomKit
        /// <summary>
        /// Attempts to place a Room perimeter on the next open segment of the Row.
        /// </summary>
        /// <param name="room">The Room from which to derive the Polygon to place.</param>
        /// <returns>
        /// True if the room was successfully placed.
        /// </returns>
        private bool AddToRow(Room room, IList <Polygon> among)
        {
            var polygon = RoomPerimeter(room);
            var box     = new TopoBox(polygon);
            var t       = new Transform();
            var delta   = 0.0;

            if (box.SizeX <= AvailableLength)
            {
                t.Rotate(Vector3.ZAxis, angle);
                delta = box.SizeX;
            }
            else if (box.SizeY <= AvailableLength)
            {
                t.Rotate(Vector3.ZAxis, angle + 90);
                delta = box.SizeY;
            }
            else
            {
                return(false);
            }
            polygon = polygon.Transform(t);
            polygon = polygon.MoveFromTo(new Vector3(), mark);
            if (among != null && polygon.Intersects(among))
            {
                return(false);
            }
            mark           = Row.PointAt((mark.DistanceTo(Row.Start) + delta) / Row.Length);
            room.Perimeter = polygon;
            Rooms.Add(room);
            return(true);
        }
コード例 #3
0
        /// <summary>
        /// Creates an orthogonal 2D grid of Vector3 points from the supplied Polygon and axis intervals.
        /// </summary>
        /// <param name="perimeter">The Polygon boundary of the point grid.</param>
        /// <param name="xInterval">The spacing of the grid along the x-axis.</param>
        /// <param name="yInterval">The spacing of the grid along the y-axis.</param>
        /// <returns>
        /// A new CoordGrid.
        /// </returns>
        public CoordGrid(Polygon polygon, double xInterval = 1, double yInterval = 1, int randomSeed = 1)
        {
            random    = new Random(randomSeed);
            Allocated = new List <Vector3>();
            Available = new List <Vector3>();
            Perimeter = new Polygon(polygon.Vertices);
            var box = new TopoBox(polygon);
            var x   = box.SW.X;
            var y   = box.SW.Y;

            while (y <= box.NW.Y)
            {
                while (x <= box.SE.X)
                {
                    var point = new Vector3(x, y);
                    if (polygon.Contains(point) || polygon.Touches(point))
                    {
                        Available.Add(point);
                    }
                    x += xInterval;
                }
                x  = box.SW.X;
                y += yInterval;
            }
        }
コード例 #4
0
ファイル: RoomGroup.cs プロジェクト: vdubya/RoomKit
 public RoomGroup(Polygon perimeter, string name = "")
 {
     Perimeter = new Polygon(perimeter.Vertices);
     Name      = name;
     Box       = new TopoBox(perimeter);
     Rooms     = new List <Room>();
     Row       = null;
 }
コード例 #5
0
        /// <summary>
        /// Returns a list of Vector3 points representig the corners of the Polygon's orthogonal bounding box.
        /// </summary>
        public static List <Vector3> BoxCorners(this Polygon polygon)
        {
            var box = new TopoBox(polygon);

            return(new List <Vector3>
            {
                box.SW,
                box.SE,
                box.NE,
                box.NW
            });
        }
コード例 #6
0
ファイル: PolygonEx.cs プロジェクト: vdubya/RoomKit
        /// <summary>
        /// Creates a rectilinear Polygon in the specified adjacent quadrant to the supplied Polygon.
        /// </summary>
        /// <param name="area">The area of the new Polygon.</param>
        /// <param name="orient">The relative direction in which the new Polygon will be placed.</param>
        /// <returns>
        /// A new Polygon.
        /// </returns>
        public static Polygon AdjacentArea(this Polygon polygon, double area, Orient orient)
        {
            var    box   = new TopoBox(polygon);
            double sizeX = 0.0;
            double sizeY = 0.0;

            if (orient == Orient.N || orient == Orient.S)
            {
                sizeX = box.SizeX;
                sizeY = area / box.SizeX;
            }
            else
            {
                sizeX = area / box.SizeY;
                sizeY = box.SizeY;
            }
            Vector3 origin = null;

            switch (orient)
            {
            case Orient.N:
                origin = box.NW;
                break;

            case Orient.E:
                origin = box.SE;
                break;

            case Orient.S:
                origin = new Vector3(box.SW.X, box.SW.Y - sizeY);
                break;

            case Orient.W:
                origin = new Vector3(box.SW.X - sizeX, box.SW.Y);
                break;
            }
            return
                (new Polygon
                 (
                     new List <Vector3>
            {
                origin,
                new Vector3(origin.X + sizeX, origin.Y),
                new Vector3(origin.X + sizeX, origin.Y + sizeY),
                new Vector3(origin.X, origin.Y + sizeY)
            }
                 ));
        }
コード例 #7
0
ファイル: RoomGroup.cs プロジェクト: vdubya/RoomKit
 public RoomGroup()
 {
     Name      = "";
     Perimeter =
         new Polygon
         (
             new List <Vector3>
     {
         new Vector3(0.0, 0.0),
         new Vector3(0.0, 10.0),
         new Vector3(10.0, 10.0),
         new Vector3(0.0, 10.0)
     }
         );
     Box   = new TopoBox(Perimeter);
     Rooms = new List <Room>();
     Row   = null;
 }
コード例 #8
0
        /// <summary>
        /// Tests if the supplied Polygon resides in a corner of a Polygon perimeter.
        /// </summary>
        /// <param name="polygon">The Polygon to test.</param>
        /// <param name="perimeter">The Polygon to test against.</param>
        /// <returns>
        /// Returns true if exactly three of the polygon bounding box points fall on the Polygon perimeter bounding box.
        /// </returns>
        public static bool AtCorner(this Polygon polygon, Polygon perimeter)
        {
            var count    = 0;
            var box      = new TopoBox(perimeter);
            var boundary = Shaper.PolygonBox(box.SizeX, box.SizeY).MoveFromTo(Vector3.Origin, box.SW);

            foreach (Vector3 vertex in BoxCorners(polygon))
            {
                if (boundary.Touches(vertex))
                {
                    count++;
                }
            }
            if (count != 3)
            {
                return(false);
            }
            return(true);
        }
コード例 #9
0
        /// <summary>
        /// Clears the current Rooms list and creates new Rooms defined by orthogonal x- and y-axis divisions of the RoomGroup Perimeter.
        /// </summary>
        /// <param name="xRooms">The quantity of Rooms along orthogonal x-axis. Must be positive.</param>
        /// <param name="yRooms">The quantity of Rooms along orthogonal y-axis. Must be positive.</param>
        /// <returns>
        /// True if the Rooms are created.
        /// </returns>
        public bool RoomsByDivision(int xRooms = 1, int yRooms = 1, double height = 3.0, string name = "")
        {
            if (Perimeter == null || xRooms < 1 || yRooms < 1 || height <= 0.0)
            {
                return(false);
            }
            var sizeX    = SizeX / xRooms;
            var sizeY    = SizeY / yRooms;
            var count    = xRooms * yRooms;
            var box      = new TopoBox(Perimeter);
            var newRooms = new List <Room>();

            for (int xIdx = 0; xIdx < xRooms; xIdx++)
            {
                var xCoord = box.SW.X + (xIdx * sizeX);
                for (int yIdx = 0; yIdx < yRooms; yIdx++)
                {
                    var yCoord  = box.SW.Y + (yIdx * sizeY);
                    var polygon = Shaper.Rectangle(sizeX, sizeY);
                    polygon = polygon.MoveFromTo(Vector3.Origin, new Vector3(xCoord, yCoord)).Intersection(Perimeter).First();
                    var room = new Room()
                    {
                        Height    = height,
                        Name      = name,
                        Perimeter = polygon
                    };
                    newRooms.Add(room);
                }
            }
            if (newRooms.Count == 0)
            {
                return(false);
            }
            Rooms.Clear();
            Rooms.AddRange(newRooms);
            return(true);
        }
コード例 #10
0
        /// <summary>
        /// Attempts to place a Room perimeter on the next open segment of the Row, with optional restrictions of a perimeter within which the Room's perimeter must fit and a list of Polygons which it cannot intersect.
        /// </summary>
        /// <param name="room">The Room from which to derive the Polygon to place.</param>
        /// <param name="within">The optional Polygon perimeter within which a new Room must fit.</param>
        /// <param name="among">The optional list of Polygon perimeters the new Room cannot intersect.</param>
        /// <param name="circ">The optional additional allowance opposite the Row to allow for circulation to the Rooms.</param>
        /// <returns>
        /// True if the room was successfully placed.
        /// </returns>
        public bool AddRoom(Room room, Polygon within = null, IList <Polygon> among = null, double circ = 2.0)
        {
            if (room == null)
            {
                return(false);
            }
            circ = Math.Abs(circ);
            var polygon   = room.MakePerimeter();
            var box       = new TopoBox(polygon);
            var delta     = 0.0;
            var newDepth  = 0.0;
            var circDepth = 0.0;
            var rotation  = angle;

            if (box.SizeX <= AvailableLength)
            {
                delta     = box.SizeX;
                newDepth  = box.SizeY;
                circDepth = box.SizeY + circ;
            }
            else if (box.SizeY <= AvailableLength)
            {
                polygon   = polygon.MoveFromTo(box.NW, box.SW);
                delta     = box.SizeY;
                newDepth  = box.SizeX;
                circDepth = box.SizeX + circ;
                rotation += 90;
            }
            else
            {
                return(false);
            }
            var t = new Transform();

            t.Rotate(Vector3.ZAxis, rotation);
            var chkCirc =
                new Polygon(
                    new []
            {
                new Vector3(),
                new Vector3(delta, 0.0),
                new Vector3(delta, circDepth),
                new Vector3(0.0, circDepth)
            });

            chkCirc = t.OfPolygon(chkCirc).MoveFromTo(new Vector3(), mark);
            if (!chkCirc.Fits(within, among))
            {
                if (Rooms.Count == 0)
                {
                    mark = Row.PointAt(Math.Abs(mark.DistanceTo(Row.Start) + delta) / Row.Length());
                }
                return(false);
            }
            polygon = t.OfPolygon(polygon).MoveFromTo(new Vector3(), mark);
            if (!polygon.Fits(within, among))
            {
                if (Rooms.Count == 0)
                {
                    mark = Row.PointAt(Math.Abs(mark.DistanceTo(Row.Start) + delta) / Row.Length());
                }
                return(false);
            }
            mark = Row.PointAt(Math.Abs(mark.DistanceTo(Row.Start) + delta) / Row.Length());
            if (newDepth > Depth)
            {
                Depth = newDepth;
            }
            var dpt   = Depth + circ;
            var line1 = new Line(box.SW, new Vector3(0.0, dpt));

            line1 = line1.Rotate(box.SW, rotation).MoveFromTo(new Vector3(), Row.Start);
            var line2 = new Line(box.SW, new Vector3(0.0, dpt));

            line2          = line2.Rotate(box.SW, rotation).MoveFromTo(new Vector3(), mark);
            circulation    = new Polygon(new [] { Row.Start, mark, line2.End, line1.End });
            room.Perimeter = polygon;
            Rooms.Add(room);
            return(true);
        }