using System; using System.Collections; using System.Linq; using Core.Common.Base.Geometry; using NUnit.Framework; namespace Core.Common.Base.Test.Geometry { [TestFixture] public class Math2DTest { #region testcases /// /// Test cases for intersecting segments. The contains pairs of , /// which represent the coordinate of a point. Each pair of coordinates form a segment. /// The last 2 double values are the expected intersection points. /// private static IEnumerable IntersectingSegments() { // \/ // /\ var testCaseDatadata1 = new TestCaseData(new[] { new Point2D(0.0,0.0), new Point2D(1.0,1.0), new Point2D(1.0,0.0), new Point2D(0.0,1.0), new Point2D(0.5,0.5) }, "IntersectingSegments 1"); yield return testCaseDatadata1; // __ // / // / var testCaseDatadata2 = new TestCaseData(new[] { new Point2D(0.0,0.0), new Point2D(1.0,1.0), new Point2D(0.0,1.0), new Point2D(1.0,1.0), new Point2D(1.0,1.0) }, "IntersectingSegments 2"); yield return testCaseDatadata2; // // / // /__ var testCaseDatadata3 = new TestCaseData(new[] { new Point2D(0.0,0.0), new Point2D(1.0,0.0), new Point2D(0.0,0.0), new Point2D(1.0,1.0), new Point2D(0.0,0.0) }, "IntersectingSegments 3"); yield return testCaseDatadata3; } /// /// Test cases for parallel segments. The contains pairs of , /// which represent the coordinate of a point. Each pair of coordinates form a segment. /// private static IEnumerable ParallelSegments() { // __ // __ var testCaseDatadata1 = new TestCaseData(new[] { new Point2D(0.0, 0.0), new Point2D(1.0, 0.0), new Point2D(0.0, 1.0), new Point2D(1.0, 1.0) }, "ParallelSegments"); yield return testCaseDatadata1; // ____ (connected in single point) var testCaseDatadata2 = new TestCaseData(new[] { new Point2D(0.0, 0.0), new Point2D(1.0, 0.0), new Point2D(1.0, 0.0), new Point2D(2.0, 0.0) }, "ParallelSegments, connected in single point"); yield return testCaseDatadata2; // __ (overlap) var testCaseDatadata3 = new TestCaseData(new[] { new Point2D(0.0, 0.0), new Point2D(1.0, 0.0), new Point2D(0.5, 0.0), new Point2D(1.5, 0.0) }, "ParallelSegments, overlap"); yield return testCaseDatadata3; } /// /// Test cases for non intersecting segments. The contains pairs of , /// which represent the coordinate of a point. Each pair of coordinates form a segment. /// private static readonly Point2D[][] NonIntersectingSegments = { // | // ___ new[] { new Point2D(0.0,0.0), new Point2D(1.0,0.0), new Point2D(0.5,1.0), new Point2D(0.5,0.5), new Point2D(0.5,0.0) } }; #endregion [Test] [TestCaseSource("IntersectingSegments")] public void LineIntersectionWithLine_DifferentLineSegmentsWithIntersections_ReturnsPoint(Point2D[] points, string testname = "") { // Call var result = Math2D.LineIntersectionWithLine(points[0], points[1], points[2], points[3]); // Assert Assert.AreEqual(points[4], result); } [Test] [TestCaseSource("ParallelSegments")] // String testname was added because the Teamcity report only counts the unique signatures that were tested public void LineIntersectionWithLine_DifferentParallelLineSegments_ReturnsNoPoint(Point2D[] points, string testname="") { // Call var result = Math2D.LineIntersectionWithLine(points[0], points[1], points[2], points[3]); // Assert Assert.IsNull(result); } [Test] [TestCaseSource("NonIntersectingSegments")] public void LineIntersectionWithLine_DifferentLineSegmentsWithNoIntersection_ReturnsPoint(Point2D[] points) { // Call var result = Math2D.LineIntersectionWithLine(points[0], points[1], points[2], points[3]); // Assert Assert.AreEqual(points[4], result); } [Test] public void LineIntersectionWithLine_WithEqualPoints_ThrowsArgumentException() { // Call TestDelegate testA = () => Math2D.LineIntersectionWithLine(new Point2D(0,0), new Point2D(0,0), new Point2D(1,0), new Point2D(0,1)); TestDelegate testB = () => Math2D.LineIntersectionWithLine(new Point2D(0, 1), new Point2D(0, 0), new Point2D(1, 1), new Point2D(1, 1)); // Assert var exceptionA = Assert.Throws(testA); var exceptionB = Assert.Throws(testB); Assert.AreEqual(Properties.Resources.Math2D_LineIntersectionWithLine_Line_points_are_equal, exceptionA.Message); Assert.AreEqual(Properties.Resources.Math2D_LineIntersectionWithLine_Line_points_are_equal,exceptionB.Message); } [Test] public void LineIntersectionWithLine_InterSectionsHigherUpX_ReturnsIntersectionWithTolerance() { // Setup var y1 = 5.925; var y2 = 5.890; var start = 133; // Call var result = Math2D.LineIntersectionWithLine(new Point2D(start, y1), new Point2D(start + 1, y2), new Point2D(start + 0.5, 0), new Point2D(start + 0.5, 1)); // Assert Assert.AreEqual((y1+y2)/2, result.Y, 1e-8); } [Test] [TestCase(2.5, new [] {3.3})] [TestCase(1.1, new double[0])] [TestCase(5.5, new double[0])] [TestCase(-1.5, new []{1.5, 3.75})] public void SegmentsIntersectionWithVerticalLine_SegmentsCollectionNotIntersecting_ReturnsEmptyCollection(double x, double[] intersectionHeights) { // Setup var segments = new[] { new Segment2D(new Point2D(2.2,3.3), new Point2D(3.3,3.3)), new Segment2D(new Point2D(1.1,5.0), new Point2D(1.1,2.0)), // vertical new Segment2D(new Point2D(5.5,2.0), new Point2D(5.5,2.0)), // no length new Segment2D(new Point2D(-2.0,1.0), new Point2D(-1.0,2.0)), new Segment2D(new Point2D(-1.0,2.0), new Point2D(-2.0,5.5)) }; // Call var result = Math2D.SegmentsIntersectionWithVerticalLine(segments, x); // Assert Assert.AreEqual(intersectionHeights.Select(y => new Point2D(x, y)), result); } } }