Пример #1
0
        /// <summary>
        /// Transform door line according to a given transformation.
        /// </summary>
        /// <param name="doorLine"></param>
        /// <param name="transformation"></param>
        /// <returns></returns>
        public static DoorLine TransformDoorLine(DoorLine doorLine, TransformationGrid2D transformation)
        {
            var doorPosition = doorLine.Line;

            if (doorPosition.GetDirection() == OrthogonalLineGrid2D.Direction.Undefined)
            {
                throw new InvalidOperationException("Cannot fix door direction when original direction is undefined");
            }

            switch (transformation)
            {
            case TransformationGrid2D.Identity:
                return(doorLine);

            case TransformationGrid2D.Rotate90:
                return(new DoorLine(doorPosition.Rotate(90), doorLine.Length));

            case TransformationGrid2D.Rotate180:
                return(new DoorLine(doorPosition.Rotate(180), doorLine.Length));

            case TransformationGrid2D.Rotate270:
                return(new DoorLine(doorPosition.Rotate(270), doorLine.Length));
            }

            // Other transformations need to switch door directions
            var firstStartPoint      = doorPosition.From.Transform(transformation);
            var lastStartPoint       = doorPosition.To.Transform(transformation);
            var length               = doorLine.Length;
            var transformedDirection = TransformDirection(doorPosition.GetDirection(), transformation);
            var transformedLine      = new OrthogonalLineGrid2D(firstStartPoint, lastStartPoint, transformedDirection);

            var lastEndPoint = lastStartPoint + length * transformedLine.GetDirectionVector();

            var newDirection    = OrthogonalLineGrid2D.GetOppositeDirection(transformedDirection);
            var newDoorPosition = new OrthogonalLineGrid2D(lastEndPoint, lastEndPoint + transformedLine.Length * transformedLine.SwitchOrientation().GetDirectionVector(), newDirection);

            if (newDoorPosition.Length != doorPosition.Length)
            {
                throw new InvalidOperationException();
            }

            return(new DoorLine(newDoorPosition, doorLine.Length));
        }
Пример #2
0
        /// <summary>
        /// Merges all door lines that are directly next to each other and have the same length.
        /// </summary>
        /// <param name="doorLines"></param>
        /// <returns></returns>
        public static List <DoorLine> MergeDoorLines(IEnumerable <DoorLine> doorLines)
        {
            var doorLinesByDirection = doorLines.GroupBy(x => x.Line.GetDirection());
            var result = new List <DoorLine>();

            foreach (var grouping in doorLinesByDirection)
            {
                if (grouping.Key == OrthogonalLineGrid2D.Direction.Undefined)
                {
                    throw new ArgumentException("There must be no door lines with undefined direction");
                }

                var sameDirectionDoorLines = new LinkedList <DoorLine>(grouping);

                while (sameDirectionDoorLines.Count != 0)
                {
                    var doorLineNode = sameDirectionDoorLines.First;
                    var doorLine     = doorLineNode.Value;
                    sameDirectionDoorLines.RemoveFirst();

                    while (true)
                    {
                        var found            = false;
                        var nextDoorLineNode = sameDirectionDoorLines.First;

                        while (nextDoorLineNode != null)
                        {
                            var otherDoorLineNode = nextDoorLineNode;
                            var otherDoorLine     = otherDoorLineNode.Value;
                            nextDoorLineNode = otherDoorLineNode.Next;

                            if (otherDoorLine.Length != doorLine.Length)
                            {
                                continue;
                            }

                            if (doorLine.Line.To + doorLine.Line.GetDirectionVector() == otherDoorLine.Line.From)
                            {
                                doorLine = new DoorLine(new OrthogonalLineGrid2D(doorLine.Line.From, otherDoorLine.Line.To), doorLine.Length);
                                found    = true;
                                sameDirectionDoorLines.Remove(otherDoorLineNode);
                            }
                            else if (doorLine.Line.From - doorLine.Line.GetDirectionVector() == otherDoorLine.Line.To)
                            {
                                doorLine = new DoorLine(new OrthogonalLineGrid2D(otherDoorLine.Line.From, doorLine.Line.To), doorLine.Length);
                                found    = true;
                                sameDirectionDoorLines.Remove(otherDoorLineNode);
                            }
                        }

                        if (!found)
                        {
                            break;
                        }
                    }

                    result.Add(doorLine);
                }
            }

            return(result);
        }