Exemple #1
0
        /// <inheritdoc />
        public IList <Tuple <IntVector2, bool> > OverlapAlongLine(TShape movingPolygon, TShape fixedPolygon, OrthogonalLine line)
        {
            var reverse = line.GetDirection() == OrthogonalLine.Direction.Bottom || line.GetDirection() == OrthogonalLine.Direction.Left;

            if (reverse)
            {
                line = line.SwitchOrientation();
            }

            var rotation    = line.ComputeRotation();
            var rotatedLine = line.Rotate(rotation);

            var movingDecomposition = GetDecomposition(movingPolygon).Select(x => x.Rotate(rotation)).ToList();
            var fixedDecomposition  = GetDecomposition(fixedPolygon).Select(x => x.Rotate(rotation)).ToList();

            var smallestX = movingDecomposition.Min(x => x.A.X);
            var events    = new List <Tuple <IntVector2, bool> >();

            // Compute the overlap for every rectangle in the decomposition of the moving polygon
            foreach (var movingRectangle in movingDecomposition)
            {
                var newEvents = OverlapAlongLine(movingRectangle, fixedDecomposition, rotatedLine, movingRectangle.A.X - smallestX);
                events = MergeEvents(events, newEvents, rotatedLine);
            }

            if (reverse)
            {
                events = ReverseEvents(events, rotatedLine);
            }

            return(events.Select(x => Tuple.Create(x.Item1.RotateAroundCenter(-rotation), x.Item2)).ToList());
        }
Exemple #2
0
        public void TryGetIntersection_HorizontalAndVertical()
        {
            {
                // No intersection - one above the other
                var line1 = new OrthogonalLine(new IntVector2(1, 1), new IntVector2(5, 1));
                var line2 = new OrthogonalLine(new IntVector2(3, 2), new IntVector2(3, 7));

                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line1, line2, out var intersection1));
                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line1.SwitchOrientation(), line2.SwitchOrientation(), out var intersection2));

                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line2, line1, out var intersection3));
                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line2.SwitchOrientation(), line1.SwitchOrientation(), out var intersection4));
            }

            {
                // No intersection - one next to the other
                var line1 = new OrthogonalLine(new IntVector2(1, 1), new IntVector2(5, 1));
                var line2 = new OrthogonalLine(new IntVector2(6, 2), new IntVector2(6, 7));

                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line1, line2, out var intersection1));
                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line1.SwitchOrientation(), line2.SwitchOrientation(), out var intersection2));

                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line2, line1, out var intersection3));
                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line2.SwitchOrientation(), line1.SwitchOrientation(), out var intersection4));
            }

            {
                // Intersection is one point
                var line1    = new OrthogonalLine(new IntVector2(1, 1), new IntVector2(5, 1));
                var line2    = new OrthogonalLine(new IntVector2(3, -2), new IntVector2(3, 5));
                var expected = new OrthogonalLine(new IntVector2(3, 1), new IntVector2(3, 1));

                Assert.IsTrue(orthogonalLineIntersection.TryGetIntersection(line1, line2, out var intersection1));
                Assert.AreEqual(expected, intersection1);

                Assert.IsTrue(orthogonalLineIntersection.TryGetIntersection(line1.SwitchOrientation(), line2.SwitchOrientation(), out var intersection2));
                Assert.AreEqual(expected, intersection2);

                Assert.IsTrue(orthogonalLineIntersection.TryGetIntersection(line2, line1, out var intersection3));
                Assert.AreEqual(expected, intersection3);

                Assert.IsTrue(orthogonalLineIntersection.TryGetIntersection(line2.SwitchOrientation(), line1.SwitchOrientation(), out var intersection4));
                Assert.AreEqual(expected, intersection4);
            }
        }
Exemple #3
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));
        }
Exemple #4
0
        public void TryGetIntersection_VerticalLines()
        {
            {
                // No intersection - different Y
                var line1 = new OrthogonalLine(new IntVector2(1, 1), new IntVector2(5, 1)).Rotate(90);
                var line2 = new OrthogonalLine(new IntVector2(1, 2), new IntVector2(5, 2)).Rotate(90);

                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line1, line2, out var intersection1));
                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line1.SwitchOrientation(), line2.SwitchOrientation(), out var intersection2));

                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line2, line1, out var intersection3));
                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line2.SwitchOrientation(), line1.SwitchOrientation(), out var intersection4));
            }

            {
                // No intersection - same Y
                var line1 = new OrthogonalLine(new IntVector2(1, 1), new IntVector2(5, 1)).Rotate(90);
                var line2 = new OrthogonalLine(new IntVector2(6, 1), new IntVector2(8, 1)).Rotate(90);

                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line1, line2, out var intersection1));
                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line1.SwitchOrientation(), line2.SwitchOrientation(), out var intersection2));

                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line2, line1, out var intersection3));
                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line2.SwitchOrientation(), line1.SwitchOrientation(), out var intersection4));
            }

            {
                // Intersection is one point
                var line1    = new OrthogonalLine(new IntVector2(1, 1), new IntVector2(5, 1)).Rotate(90);
                var line2    = new OrthogonalLine(new IntVector2(5, 1), new IntVector2(10, 1)).Rotate(90);
                var expected = new OrthogonalLine(new IntVector2(5, 1), new IntVector2(5, 1), OrthogonalLine.Direction.Bottom).Rotate(90);

                Assert.IsTrue(orthogonalLineIntersection.TryGetIntersection(line1, line2, out var intersection1));
                Assert.AreEqual(expected, intersection1);

                Assert.IsTrue(orthogonalLineIntersection.TryGetIntersection(line1.SwitchOrientation(), line2.SwitchOrientation(), out var intersection2));
                Assert.AreEqual(expected, intersection2);

                Assert.IsTrue(orthogonalLineIntersection.TryGetIntersection(line2, line1, out var intersection3));
                Assert.AreEqual(expected, intersection3);

                Assert.IsTrue(orthogonalLineIntersection.TryGetIntersection(line2.SwitchOrientation(), line1.SwitchOrientation(), out var intersection4));
                Assert.AreEqual(expected, intersection4);
            }

            {
                // Intersection is a line
                var line1    = new OrthogonalLine(new IntVector2(3, 2), new IntVector2(10, 2)).Rotate(90);
                var line2    = new OrthogonalLine(new IntVector2(7, 2), new IntVector2(13, 2)).Rotate(90);
                var expected = new OrthogonalLine(new IntVector2(7, 2), new IntVector2(10, 2)).Rotate(90).GetNormalized();

                Assert.IsTrue(orthogonalLineIntersection.TryGetIntersection(line1, line2, out var intersection1));
                Assert.AreEqual(expected, intersection1.GetNormalized());

                Assert.IsTrue(orthogonalLineIntersection.TryGetIntersection(line1.SwitchOrientation(), line2.SwitchOrientation(), out var intersection2));
                Assert.AreEqual(expected, intersection2.GetNormalized());

                Assert.IsTrue(orthogonalLineIntersection.TryGetIntersection(line2, line1, out var intersection3));
                Assert.AreEqual(expected, intersection3.GetNormalized());

                Assert.IsTrue(orthogonalLineIntersection.TryGetIntersection(line2.SwitchOrientation(), line1.SwitchOrientation(), out var intersection4));
                Assert.AreEqual(expected, intersection4.GetNormalized());
            }
        }