public void Rotate_InvalidDegrees_Throws()
        {
            var line = new OrthogonalLine(new IntVector2(0, 0), new IntVector2(5, 0));

            Assert.Throws <ArgumentException>(() => line.Rotate(1));
            Assert.Throws <ArgumentException>(() => line.Rotate(15));
            Assert.Throws <ArgumentException>(() => line.Rotate(-181));
        }
Beispiel #2
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());
        }
        /// <summary>
        /// Returns a list of lines obtained by removing all the intersections from the original line.
        /// </summary>
        /// <param name="line"></param>
        /// <param name="intersection"></param>
        /// <returns></returns>
        private List <OrthogonalLine> PartitionByIntersection(OrthogonalLine line, IList <OrthogonalLine> intersection)
        {
            var result              = new List <OrthogonalLine>();
            var rotation            = line.ComputeRotation();
            var rotatedLine         = line.Rotate(rotation, true);
            var directionVector     = rotatedLine.GetDirectionVector();
            var rotatedIntersection = intersection.Select(x => x.Rotate(rotation, false).GetNormalized()).ToList();

            rotatedIntersection.Sort((x1, x2) => x1.From.CompareTo(x2.From));

            var lastPoint = rotatedLine.From - directionVector;

            foreach (var intersectionLine in rotatedIntersection)
            {
                if (intersectionLine.From != lastPoint && intersectionLine.From - directionVector != lastPoint)
                {
                    result.Add(new OrthogonalLine(lastPoint + directionVector, intersectionLine.From - directionVector));
                }

                lastPoint = intersectionLine.To;
            }

            if (rotatedLine.To != lastPoint && rotatedLine.To - directionVector != lastPoint)
            {
                result.Add(new OrthogonalLine(lastPoint + directionVector, rotatedLine.To));
            }

            return(result.Select(x => x.Rotate(-rotation, false)).ToList());
        }
        public void Contains_Outside_ReturnsMinusOne()
        {
            {
                var line  = new OrthogonalLine(new IntVector2(4, 2), new IntVector2(10, 2));
                var point = new IntVector2(3, 2);

                // TODO: why is it on the polygon?
                foreach (var rotation in GridPolygon.PossibleRotations)
                {
                    var rotatedLine  = line.Rotate(rotation);
                    var rotatedPoint = point.RotateAroundCenter(rotation);

                    var actualIndex = rotatedLine.Contains(rotatedPoint);

                    Assert.AreEqual(-1, actualIndex);
                }
            }

            {
                var line  = new OrthogonalLine(new IntVector2(4, 2), new IntVector2(10, 2));
                var point = new IntVector2(12, 2);

                // TODO: why is it on the polygon?
                foreach (var rotation in GridPolygon.PossibleRotations)
                {
                    var rotatedLine  = line.Rotate(rotation);
                    var rotatedPoint = point.RotateAroundCenter(rotation);

                    var actualIndex = rotatedLine.Contains(rotatedPoint);

                    Assert.AreEqual(-1, actualIndex);
                }
            }
        }
        public void Rotate_ReturnsRotated()
        {
            {
                var line     = new OrthogonalLine(new IntVector2(0, 0), new IntVector2(5, 0));
                var expected = new OrthogonalLine(new IntVector2(0, 0), new IntVector2(0, -5));
                Assert.AreEqual(expected, line.Rotate(90));
                Assert.AreEqual(expected, line.Rotate(-270));
            }

            {
                var line     = new OrthogonalLine(new IntVector2(-2, -2), new IntVector2(-2, 5));
                var expected = new OrthogonalLine(new IntVector2(2, 2), new IntVector2(2, -5));
                Assert.AreEqual(expected, line.Rotate(180));
                Assert.AreEqual(expected, line.Rotate(-180));
            }
        }