Ejemplo n.º 1
0
        /// <summary>
        /// Transform door line according to a given transformation.
        /// </summary>
        /// <param name="doorLine"></param>
        /// <param name="transformation"></param>
        /// <returns></returns>
        public static IDoorLine TransformDoorLine(IDoorLine doorLine, Transformation transformation)
        {
            var doorPosition = doorLine.Line;

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

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

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

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

            case Transformation.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 OrthogonalLine(firstStartPoint, lastStartPoint, transformedDirection);

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

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

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

            return(new DoorLine(newDoorPosition, doorLine.Length));
        }
Ejemplo n.º 2
0
        private static OrthogonalLine.Direction TransformDirection(OrthogonalLine.Direction originalDirection, Transformation transformation)
        {
            if (originalDirection == OrthogonalLine.Direction.Undefined)
            {
                throw new InvalidOperationException("Cannot transform direction when original direction is undefined");
            }

            switch (transformation)
            {
            case Transformation.MirrorX:
                if (IsHorizontal(originalDirection))
                {
                    return(originalDirection);
                }

                return(OrthogonalLine.GetOppositeDirection(originalDirection));

            case Transformation.MirrorY:
                if (IsHorizontal(originalDirection))
                {
                    return(OrthogonalLine.GetOppositeDirection(originalDirection));
                }

                return(originalDirection);

            case Transformation.Diagonal13:
                switch (originalDirection)
                {
                case OrthogonalLine.Direction.Top:
                    return(OrthogonalLine.Direction.Right);

                case OrthogonalLine.Direction.Right:
                    return(OrthogonalLine.Direction.Top);

                case OrthogonalLine.Direction.Bottom:
                    return(OrthogonalLine.Direction.Left);

                case OrthogonalLine.Direction.Left:
                    return(OrthogonalLine.Direction.Bottom);

                default:
                    throw new ArgumentException();
                }

            case Transformation.Diagonal24:
                switch (originalDirection)
                {
                case OrthogonalLine.Direction.Top:
                    return(OrthogonalLine.Direction.Left);

                case OrthogonalLine.Direction.Right:
                    return(OrthogonalLine.Direction.Bottom);

                case OrthogonalLine.Direction.Bottom:
                    return(OrthogonalLine.Direction.Right);

                case OrthogonalLine.Direction.Left:
                    return(OrthogonalLine.Direction.Top);

                default:
                    throw new ArgumentException();
                }
            }

            throw new ArgumentException();
        }
        private ConfigurationSpace GetConfigurationSpace(GridPolygon polygon, List <IDoorLine> doorLines, GridPolygon fixedCenter, List <IDoorLine> doorLinesFixed, List <int> offsets = null)
        {
            if (offsets != null && offsets.Count == 0)
            {
                throw new ArgumentException("There must be at least one offset if they are set", nameof(offsets));
            }

            var configurationSpaceLines = new List <OrthogonalLine>();
            var reverseDoor             = new List <Tuple <OrthogonalLine, DoorLine> >();

            doorLines      = DoorUtils.MergeDoorLines(doorLines);
            doorLinesFixed = DoorUtils.MergeDoorLines(doorLinesFixed);

            // One list for every direction
            var lines = new List <IDoorLine> [4];

            // Init array
            for (var i = 0; i < lines.Length; i++)
            {
                lines[i] = new List <IDoorLine>();
            }

            // Populate lists with lines
            foreach (var line in doorLinesFixed)
            {
                lines[(int)line.Line.GetDirection()].Add(line);
            }

            foreach (var doorLine in doorLines)
            {
                var line = doorLine.Line;
                var oppositeDirection  = OrthogonalLine.GetOppositeDirection(line.GetDirection());
                var rotation           = line.ComputeRotation();
                var rotatedLine        = line.Rotate(rotation);
                var correspondingLines = lines[(int)oppositeDirection].Where(x => x.Length == doorLine.Length).Select(x => new DoorLine(x.Line.Rotate(rotation), x.Length));

                foreach (var cDoorLine in correspondingLines)
                {
                    var cline = cDoorLine.Line;
                    var y     = cline.From.Y - rotatedLine.From.Y;
                    var from  = new IntVector2(cline.From.X - rotatedLine.To.X + (rotatedLine.Length - doorLine.Length), y);
                    var to    = new IntVector2(cline.To.X - rotatedLine.From.X - (rotatedLine.Length + doorLine.Length), y);

                    if (from.X < to.X)
                    {
                        continue;
                    }

                    if (offsets == null)
                    {
                        var resultLine = new OrthogonalLine(from, to, OrthogonalLine.Direction.Left).Rotate(-rotation);
                        reverseDoor.Add(Tuple.Create(resultLine, new DoorLine(cDoorLine.Line.Rotate(-rotation), cDoorLine.Length)));
                        configurationSpaceLines.Add(resultLine);
                    }
                    else
                    {
                        foreach (var offset in offsets)
                        {
                            var offsetVector = new IntVector2(0, offset);
                            var resultLine   = new OrthogonalLine(from - offsetVector, to - offsetVector, OrthogonalLine.Direction.Left).Rotate(-rotation);
                            reverseDoor.Add(Tuple.Create(resultLine, new DoorLine(cDoorLine.Line.Rotate(-rotation), cDoorLine.Length)));
                            configurationSpaceLines.Add(resultLine);
                        }
                    }
                }
            }

            // Remove all positions when the two polygons overlap
            configurationSpaceLines = RemoveOverlapping(polygon, fixedCenter, configurationSpaceLines);

            // Remove all non-unique positions
            configurationSpaceLines = RemoveIntersections(configurationSpaceLines);

            return(new ConfigurationSpace()
            {
                Lines = configurationSpaceLines, ReverseDoors = reverseDoor
            });
        }