/// <summary>
        /// Computes the outline of a given polygon and its door lines.
        /// </summary>
        /// <param name="polygon"></param>
        /// <param name="doorLines"></param>
        /// <returns></returns>
        protected List <Tuple <IntVector2, bool> > GetOutline(GridPolygon polygon, List <IDoorInfo <TNode> > doorLines)
        {
            var outline = new List <Tuple <IntVector2, bool> >();

            foreach (var line in polygon.GetLines())
            {
                AddToOutline(Tuple.Create(line.From, true));

                if (doorLines == null)
                {
                    continue;
                }

                var doorDistances = doorLines.Select(x =>
                                                     new Tuple <IDoorInfo <TNode>, int>(x, Math.Min(line.Contains(x.DoorLine.From), line.Contains(x.DoorLine.To)))).ToList();
                doorDistances.Sort((x1, x2) => x1.Item2.CompareTo(x2.Item2));

                foreach (var pair in doorDistances)
                {
                    if (pair.Item2 == -1)
                    {
                        continue;
                    }

                    var doorLine = pair.Item1.DoorLine;

                    if (line.Contains(doorLine.From) != pair.Item2)
                    {
                        doorLine = doorLine.SwitchOrientation();
                    }

                    doorLines.Remove(pair.Item1);

                    AddToOutline(Tuple.Create(doorLine.From, true));
                    AddToOutline(Tuple.Create(doorLine.To, false));
                }
            }

            return(outline);

            void AddToOutline(Tuple <IntVector2, bool> point)
            {
                if (outline.Count == 0)
                {
                    outline.Add(point);
                    return;
                }

                var lastPoint = outline[outline.Count - 1];

                if (!lastPoint.Item2 && point.Item2 && lastPoint.Item1 == point.Item1)
                {
                    return;
                }

                outline.Add(point);
            }
        }
        /// <inheritdoc />
        public List <IDoorLine> GetDoorPositions(GridPolygon polygon, IDoorMode doorModeRaw)
        {
            if (!(doorModeRaw is OverlapMode doorMode))
            {
                throw new InvalidOperationException("Invalid door mode supplied");
            }

            var lines = new List <IDoorLine>();

            foreach (var line in polygon.GetLines())
            {
                if (line.Length < 2 * doorMode.CornerDistance + doorMode.DoorLength)
                {
                    continue;
                }

                lines.Add(new DoorLine(line.Shrink(doorMode.CornerDistance, doorMode.CornerDistance + doorMode.DoorLength), doorMode.DoorLength));
            }

            return(lines);
        }
Example #3
0
        private DoorLine GetDoorLine(GridPolygon polygon, OrthogonalLine doorPosition)
        {
            if (doorPosition.Length == 0)
            {
                throw new InvalidOperationException();
            }

            foreach (var side in polygon.GetLines())
            {
                if (side.Contains(doorPosition.From) == -1 || side.Contains(doorPosition.To) == -1)
                {
                    continue;
                }

                var isGoodDirection = doorPosition.From + doorPosition.Length * side.GetDirectionVector() == doorPosition.To;
                var from            = isGoodDirection ? doorPosition.From : doorPosition.To;

                return(new DoorLine(new OrthogonalLine(from, from, side.GetDirection()), doorPosition.Length));
            }

            throw new InvalidOperationException("Given door position is not on any side of the polygon");
        }
        private IEnumerable <IDoorLine> GetDoorLine(GridPolygon polygon, OrthogonalLine doorPosition)
        {
            var found = false;

            foreach (var side in polygon.GetLines())
            {
                if (side.Contains(doorPosition.From) == -1 || side.Contains(doorPosition.To) == -1)
                {
                    continue;
                }

                var isGoodDirection = doorPosition.From + doorPosition.Length * side.GetDirectionVector() == doorPosition.To;
                var from            = isGoodDirection ? doorPosition.From : doorPosition.To;

                found = true;
                yield return(new DoorLine(new OrthogonalLine(from, from, side.GetDirection()), doorPosition.Length));
            }

            if (found == false)
            {
                throw new InvalidOperationException("Given door position is not on any side of the polygon");
            }
        }