public void ShouldHaveConsistentDistance(
     [Random(-1000, 1000.0, 5)] double lat,
     [Random(-1000.0, 1000.0, 5)] double lon,
     [Random(-360.0, 360.0, 10)] double bearing,
     [Random(0.0, 1000.0, 10)] double distance)
 {
     var sourceGeo = new Geo(lat, lon);
     var destGeo = sourceGeo.Offset(Geo.KilometersToRadians(distance), Geo.DegreesToRadians(bearing));
     Assert.That(sourceGeo.DistanceKilometers(destGeo), Is.EqualTo(distance).Within(0.0003));
 }
 public static TransmissionLoss ClosestTransmissionLoss(this Scenario scenario, Geo geo, Mode mode)
 {
     var closest = (from ap in scenario.AnalysisPoints
                    from tl in ap.TransmissionLosses
                    where tl.Modes[0].IsAcousticallyEquivalentTo(mode)
                    let d = geo.DistanceKilometers(ap.Geo)
                    orderby d
                    select new { d, tl }).FirstOrDefault();
     return closest != null ? closest.tl : null;
 }
        /// <summary>
        /// Takes a start location and a proposed end location, and returns a reflected end location
        /// If the proposed end location is outside of the current figure, the end location is reflected
        /// by the normal to the intersecting segment, and returned to the caller.  If the proposed end
        /// location is inside the current figure, then it is simply returned to the caller.
        /// </summary>
        /// <param name="startLocation">Start location for the current proposed move</param>
        /// <param name="proposedEndLocation">End location for the current proposed move</param>
        /// <param name="proposedCourse"> </param>
        /// <returns>Actual end location that remains inside the figure, which may be reflected from the
        /// proposed end location provided if the proposed end location lies outside the figure</returns>
        public override Geo Reflect(Geo startLocation, Geo proposedEndLocation, out Course proposedCourse)
        {
            //Geo start = new Geo(StartLocation);
            //Geo end = new Geo(ProposedEndLocation);
#if MATLAB_DEBUG_OUTPUT
            MatlabDumpVertices();
#endif
            proposedCourse = new Course(startLocation, proposedEndLocation);
            if (Contains(proposedEndLocation))
                return proposedEndLocation;

            //start.Move(ProposedCourse.ReciprocalDegrees, 1000);
            //end.Move(ProposedCourse.Degrees, 1000);
#if MATLAB_DEBUG_OUTPUT
            Console.WriteLine("Course=zeros(2,2);\nCourse(1,:)=[{0} {1}];\nCourse(2,:)=[{2} {3}];",
                startLocation.Longitude, startLocation.Latitude, 
                proposedEndLocation.Longitude, proposedEndLocation.Latitude);
#endif
            
            var proposedCourseSegment = new OverlayLineSegment(startLocation, proposedEndLocation);
            for (var i = 0; i < Segments.Count(); i++)
            {
                var intersect = proposedCourseSegment.IntersectionPoint(Segments[i]);
#if MATLAB_DEBUG_OUTPUT
                Console.WriteLine("Intersects({0},:)=[{1} {2}];", i + 1, intersect.Longitude, intersect.Latitude);
#endif
                //if (intersect == null) continue;
                if (!proposedCourseSegment.Contains(intersect) || !Segments[i].Contains(intersect)) continue;
                proposedCourse = proposedCourse.Reflect(Normals[i]);
                var distance = startLocation.DistanceKilometers(proposedEndLocation);
                var result = startLocation.Offset(Geo.KilometersToRadians(distance), proposedCourse.Radians);
                return result;
            }
#if MATLAB_DEBUG_OUTPUT
            Console.WriteLine("figure;");
            Console.WriteLine("plot(Vertices(:, 1), Vertices(:, 2), 'g-*');");
            Console.WriteLine("hold on;");
            Console.WriteLine("plot(Course(:, 1), Course(:, 2), 'r-o');");
            Console.WriteLine("plot(Intersects(:, 1), Intersects(:, 2), 'bx');");
            Console.WriteLine("legend('Area Boundary', 'Course Segment under review', 'Calculated intersection points');");
#endif
            throw new GeometricException("The proposed course didn't intersect with any of the edges of the figure");
        }