[8516] | 1 | using System;
|
---|
| 2 | using System.Collections.Generic;
|
---|
| 3 |
|
---|
| 4 | namespace HeuristicLab.Problems.RoutePlanning.Utilities {
|
---|
| 5 | public static class Utils {
|
---|
| 6 | public static double Distance(PointD p1, PointD p2) {
|
---|
| 7 | double dx = p2.X - p1.X;
|
---|
| 8 | double dy = p2.Y - p1.Y;
|
---|
| 9 | return Math.Sqrt(dx * dx + dy * dy);
|
---|
| 10 | }
|
---|
| 11 |
|
---|
| 12 | public static double Distance(double startX, double startY, double endX, double endY) {
|
---|
| 13 | double dx = endX - startX;
|
---|
| 14 | double dy = endY - startY;
|
---|
| 15 | return Math.Sqrt(dx * dx + dy * dy);
|
---|
| 16 | }
|
---|
| 17 |
|
---|
| 18 | public static double LocationDistance(PointD p1, PointD p2) {
|
---|
[8520] | 19 | return LocationDistance(p1.X, p1.Y, p2.X, p2.Y);
|
---|
| 20 | }
|
---|
| 21 |
|
---|
| 22 | // calculates the distance of the 2 given locations in kilometers
|
---|
| 23 | public static double LocationDistance(double startX, double startY, double endX, double endY) {
|
---|
[8516] | 24 | // The Haversine formula
|
---|
| 25 | /* dlon = lon2 - lon1
|
---|
| 26 | dlat = lat2 - lat1
|
---|
| 27 | a = (sin(dlat/2))^2 + cos(lat1) * cos(lat2) * (sin(dlon/2))^2
|
---|
| 28 | c = 2 * atan2(sqrt(a), sqrt(1-a))
|
---|
| 29 | d = R * c
|
---|
| 30 | */
|
---|
| 31 |
|
---|
[8520] | 32 | double lat1Rad = startY * (Math.PI / 180.0);
|
---|
| 33 | double long1Rad = startX * (Math.PI / 180.0);
|
---|
| 34 | double lat2Rad = endY * (Math.PI / 180.0);
|
---|
| 35 | double long2Rad = endX * (Math.PI / 180.0);
|
---|
[8516] | 36 |
|
---|
| 37 | double longitude = long2Rad - long1Rad;
|
---|
| 38 | double latitude = lat2Rad - lat1Rad;
|
---|
| 39 |
|
---|
| 40 | double a = Math.Pow(Math.Sin(latitude / 2.0), 2.0) +
|
---|
| 41 | Math.Cos(lat1Rad) * Math.Cos(lat2Rad) *
|
---|
| 42 | Math.Pow(Math.Sin(longitude / 2.0), 2.0);
|
---|
| 43 |
|
---|
| 44 | double c = 2.0 * Math.Asin(Math.Sqrt(a));
|
---|
| 45 |
|
---|
[8520] | 46 | const double earthRadiusKms = 6367.5;
|
---|
[8516] | 47 | double distance = earthRadiusKms * c;
|
---|
| 48 |
|
---|
| 49 | return distance;
|
---|
| 50 | }
|
---|
| 51 |
|
---|
| 52 | public static double PathLength(IList<PointD> points) {
|
---|
| 53 | double length = 0;
|
---|
| 54 | for (int i = 1; i < points.Count; i++) {
|
---|
| 55 | length += Distance((PointD)points[i - 1], (PointD)points[i]);
|
---|
| 56 | }
|
---|
| 57 | return length;
|
---|
| 58 | }
|
---|
| 59 |
|
---|
| 60 | public static RectangleD FindBox(IList<PointD> points) {
|
---|
| 61 | double minX = double.MaxValue;
|
---|
| 62 | double maxX = double.MinValue;
|
---|
| 63 | double minY = double.MaxValue;
|
---|
| 64 | double maxY = double.MinValue;
|
---|
| 65 |
|
---|
| 66 | foreach (PointD p in points) {
|
---|
| 67 | if (p.X < minX)
|
---|
| 68 | minX = p.X;
|
---|
| 69 | if (p.X > maxX)
|
---|
| 70 | maxX = p.X;
|
---|
| 71 |
|
---|
| 72 | if (p.Y < minY)
|
---|
| 73 | minY = p.Y;
|
---|
| 74 | if (p.Y > maxY)
|
---|
| 75 | maxY = p.Y;
|
---|
| 76 | }
|
---|
| 77 | return new RectangleD(minX, minY, maxX - minX, maxY - minY);
|
---|
| 78 | }
|
---|
| 79 |
|
---|
| 80 | public static double PathDistance(IList<PointD> path1, IList<PointD> path2) {
|
---|
| 81 | double distance = 0;
|
---|
| 82 | for (int i = 0; i < path1.Count; i++) {
|
---|
| 83 | distance += Distance((PointD)path1[i], (PointD)path2[i]);
|
---|
| 84 | }
|
---|
| 85 | return distance / path1.Count;
|
---|
| 86 | }
|
---|
| 87 | }
|
---|
| 88 | }
|
---|
| 89 |
|
---|