/// <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()); }
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); } }
/// <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)); }
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()); } }