/// <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()); }
/// <summary> /// Computes the overlap along a line of a given moving rectangle and a fixed rectangle. /// </summary> /// <param name="movingRectangle"></param> /// <param name="fixedRectangle"></param> /// <param name="line"></param> /// <param name="movingRectangleOffset"></param> /// <returns></returns> protected List <Tuple <IntVector2, bool> > OverlapAlongLine(GridRectangle movingRectangle, GridRectangle fixedRectangle, OrthogonalLine line, int movingRectangleOffset = 0) { if (line.GetDirection() != OrthogonalLine.Direction.Right) { throw new ArgumentException(); } // The smallest rectangle that covers both the first and the last position on the line of the moving rectangle var boundingRectangle = new GridRectangle(movingRectangle.A + line.From, movingRectangle.B + line.To); // They cannot overlap if the bounding rectangle does not overlap with the fixed one if (!DoOverlap(boundingRectangle, fixedRectangle)) { return(new List <Tuple <IntVector2, bool> >()); } var events = new List <Tuple <IntVector2, bool> >(); if (fixedRectangle.A.X - movingRectangle.Width - movingRectangleOffset <= line.From.X) { events.Add(Tuple.Create(line.From, true)); } if (fixedRectangle.A.X > line.From.X + movingRectangle.Width + movingRectangleOffset) { events.Add(Tuple.Create(new IntVector2(fixedRectangle.A.X - movingRectangle.Width + 1 - movingRectangleOffset, line.From.Y), true)); } if (fixedRectangle.B.X - movingRectangleOffset < line.To.X) { events.Add(Tuple.Create(new IntVector2(fixedRectangle.B.X - movingRectangleOffset, line.From.Y), false)); } return(events); }
public void GetDirection_ReturnsDirection() { var top = new OrthogonalLine(new IntVector2(2, 2), new IntVector2(2, 4)); var bottom = new OrthogonalLine(new IntVector2(2, 4), new IntVector2(2, 2)); var right = new OrthogonalLine(new IntVector2(5, 3), new IntVector2(8, 3)); var left = new OrthogonalLine(new IntVector2(8, 3), new IntVector2(5, 3)); Assert.AreEqual(OrthogonalLine.Direction.Top, top.GetDirection()); Assert.AreEqual(OrthogonalLine.Direction.Bottom, bottom.GetDirection()); Assert.AreEqual(OrthogonalLine.Direction.Right, right.GetDirection()); Assert.AreEqual(OrthogonalLine.Direction.Left, left.GetDirection()); }
/// <summary> /// Computes the overlap along a line of a given moving rectangle and a set o fixed rectangles. /// </summary> /// <param name="movingRectangle"></param> /// <param name="fixedRectangles"></param> /// <param name="line"></param> /// <param name="movingRectangleOffset">Specifies the X-axis offset of a given moving rectangle.</param> /// <returns></returns> protected List <Tuple <IntVector2, bool> > OverlapAlongLine(GridRectangle movingRectangle, IList <GridRectangle> fixedRectangles, OrthogonalLine line, int movingRectangleOffset = 0) { if (line.GetDirection() != OrthogonalLine.Direction.Right) { throw new ArgumentException(); } var events = new List <Tuple <IntVector2, bool> >(); foreach (var fixedRectangle in fixedRectangles) { var newEvents = OverlapAlongLine(movingRectangle, fixedRectangle, line, movingRectangleOffset); events = MergeEvents(events, newEvents, line); } return(events); }