예제 #1
0
        /// <summary>
        /// Tests if a point is contained within this profile. Returns false for points that are outside of the profile (or within voids).
        /// </summary>
        /// <param name="point">The position to test.</param>
        /// <param name="containment">Whether the point is inside, outside, at an edge, or at a vertex.</param>
        /// <returns>True if the point is within the profile.</returns>
        public bool Contains(Vector3 point, out Containment containment)
        {
            IEnumerable <Line> allLines = Perimeter.Segments();

            if (Voids != null)
            {
                allLines = allLines.Union(Voids.SelectMany(v => v.Segments()));
            }
            return(Polygon.Contains(allLines, point, out containment));
        }
예제 #2
0
        /// <summary>
        /// Moves all Rooms along a 3D vector calculated between the supplied Vector3 points.
        /// </summary>
        /// <param name="from">Vector3 base point of the move.</param>
        /// <param name="to">Vector3 target point of the move.</param>
        /// <returns>
        /// None.
        /// </returns>
        public void MoveFromTo(Vector3 from, Vector3 to)
        {
            foreach (Room room in Rooms)
            {
                room.MoveFromTo(from, to);
            }
            Perimeter = Perimeter.MoveFromTo(from, to);
            var ang = Perimeter.Segments().OrderByDescending(s => s.Length()).ToList().First();

            Angle        = Math.Atan2(ang.End.Y - ang.Start.Y, ang.End.X - ang.Start.X) * (180 / Math.PI);
            perimeterJig = Perimeter.Rotate(Vector3.Origin, Angle * -1);
            compass      = perimeterJig.Compass();
            insert.MoveFromTo(from, to);
            Row = new Line(compass.SW, compass.SE).Rotate(Vector3.Origin, Angle);
        }
예제 #3
0
 /// <summary>
 /// Get all segments from a profile's perimeter and internal voids.
 /// </summary>
 public List <Line> Segments()
 {
     return(Perimeter.Segments().Union(Voids?.SelectMany(v => v.Segments()) ?? new Line[0]).ToList());
 }
예제 #4
0
        /// <summary>
        /// Creates a grid network of corridors within the Story and returns a list of spatially sorted RoomRows ready for population.
        /// </summary>
        /// <param name="rowLength">Distance between cross corridors.</param>
        /// <param name="roomDepth">Desired depth of Rooms.</param>
        /// <param name="corridorWidth">Width of all corridors.</param>
        /// <returns>A List of RoomRow</returns>
        public List <RoomRow> PlanGrid(double rowLength, double rowDepth, double corridorWidth = 3.0, bool split = true)
        {
            Corridors.Clear();
            Rooms.Clear();
            rowLength     = rowLength.NearEqual(0.0) ? 1.0 : Math.Abs(rowLength);
            rowDepth      = rowLength.NearEqual(0.0) ? 1.0 : Math.Abs(rowDepth);
            corridorWidth = rowLength.NearEqual(0.0) ? 1.0 : Math.Abs(corridorWidth);

            var row          = Perimeter.Segments().OrderByDescending(s => s.Length()).First();
            var ang          = Math.Atan2(row.End.Y - row.Start.Y, row.End.X - row.Start.X) * (180 / Math.PI);
            var perimeterJig = Perimeter.Rotate(Vector3.Origin, ang * -1);
            var grid         = new Grid2d(perimeterJig);

            grid.U.DivideByFixedLength(rowLength, FixedDivisionMode.RemainderAtBothEnds);
            grid.V.DivideByFixedLength(rowDepth, FixedDivisionMode.RemainderAtBothEnds);
            var uLines   = grid.GetCellSeparators(GridDirection.U).Skip(1).Reverse().Skip(1).Reverse();
            var vLines   = grid.GetCellSeparators(GridDirection.V).Skip(1).Reverse().Skip(1).Reverse();
            var ctrLines = new List <Line>();

            foreach (var curve in uLines)
            {
                ctrLines.Add((Line)curve);
            }
            foreach (var curve in vLines)
            {
                ctrLines.Add((Line)curve);
            }
            foreach (var line in ctrLines)
            {
                var corridor = line.Thicken(corridorWidth);
                if (perimeterJig.Compass().Box.Covers(corridor))
                {
                    AddCorridor(new Room(corridor.Rotate(Vector3.Origin, ang), Height));
                }
            }
            foreach (var cell in grid.CellsFlat)
            {
                var polygon = (Polygon)cell.GetCellGeometry();
                var compass = polygon.Compass();
                if (split)
                {
                    var north = Polygon.Rectangle(compass.W, compass.NE).Rotate(Vector3.Origin, ang);
                    var south = Polygon.Rectangle(compass.SW, compass.E).Rotate(Vector3.Origin, ang);
                    AddRoom(new Room(north, Height));
                    AddRoom(new Room(south, Height));
                    continue;
                }
                else if (Math.Abs(compass.SizeY - rowDepth) <= 0.0001)
                {
                    AddRoom(new Room(polygon.Rotate(Vector3.Origin, ang), Height));
                }
            }
            var roomRows = new List <RoomRow>();

            foreach (var room in Rooms)
            {
                roomRows.Add(new RoomRow(room.Perimeter));
            }
            Rooms.Clear();
            return(roomRows);
        }
예제 #5
0
        /// <summary>
        /// Creates a Room plan from a Polygon centerline as the double-loaded corridor. Assumes sides of the Story Perimeter are parallel to the centerline.
        /// </summary>
        /// <param name="ctrLine">Polyline centerline of the Corridor.</param>
        /// <param name="roomArea">Desired area of each Room.</param>
        /// <param name="corridorWidth">Width of the Corridor.</param>
        /// <param name="corridorOffset">Offset of the Corridor end from the Perimeter.</param>
        public void PlanByCenterline(Polyline ctrLine,
                                     double roomArea,
                                     double corridorWidth,
                                     double corridorOffset)
        {
            var perLines = Perimeter.Segments();
            var ctrLines = ctrLine.Segments();
            var rows     = new List <Polygon>();

            foreach (var line in ctrLines)
            {
                var sides = new List <Line>();
                foreach (var perLine in perLines)
                {
                    if (perLine.IsParallelTo(line))
                    {
                        sides.Add(perLine);
                    }
                }
                if (sides.Count() < 2)
                {
                    continue;
                }
                sides = sides.OrderBy(s => s.Midpoint().DistanceTo(line.Midpoint())).ToList();
                sides = new List <Line>()
                {
                    sides[0], sides[1]
                };
                foreach (var side in sides)
                {
                    var points = new List <Vector3>();
                    foreach (var vertex in new List <Vector3>()
                    {
                        line.Start, line.End, side.Start, side.End
                    })
                    {
                        points.Add(new Vector3(vertex.X, vertex.Y, 0.0));
                    }
                    Polygon polygon;
                    try
                    {
                        polygon = new Polygon(points);
                    }
                    catch (Exception)
                    {
                        polygon = new Polygon(new[] { points[0], points[1], points[3], points[2] });
                    }
                    rows.Add(polygon);
                }
            }
            foreach (var row in rows)
            {
                var roomRow = new RoomRow(row);
                roomRow.Populate(roomArea, Height);
                foreach (var room in roomRow.Rooms)
                {
                    AddRoom(room);
                }
            }
            var ctrPnts = new List <Vector3>()
            {
                ctrLines.First().PositionAt(corridorOffset)
            };

            foreach (var line in ctrLines)
            {
                ctrPnts.Add(line.End);
            }
            ctrPnts.Reverse();
            ctrPnts = ctrPnts.Skip(1).ToList();
            ctrPnts.Reverse();
            ctrPnts.Add(ctrLines.Last().PositionAt(ctrLines.Last().Length() - corridorOffset));
            var ctrCorridor = new Polyline(ctrPnts);
            var corridor    = new Room(ctrCorridor.Offset(corridorWidth * 0.5, EndType.Square).First(), Height);

            AddCorridor(corridor);
        }