Skip to content

Commit 6017e7a

Browse files
committed
Add the Triangulation Algorithm for Estimating Your Location
1 parent d3fc4b0 commit 6017e7a

File tree

3 files changed

+123
-0
lines changed

3 files changed

+123
-0
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
using Algorithms.Other;
2+
using NUnit.Framework;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
9+
namespace Algorithms.Tests.Other
10+
{
11+
[TestFixture]
12+
public class TriangulatorTests
13+
{
14+
[Test]
15+
public void CalculatePosition_ValidCoordinatesAndDistances_ReturnsExpectedPosition()
16+
{
17+
var triangulator = new Triangulator();
18+
var baseLocations = new List<(double Latitude, double Longitude)>
19+
{
20+
(16.054407, 108.202167),
21+
(16.049807, 108.218991),
22+
(16.063597, 108.215553)
23+
};
24+
25+
var distances = new List<double> { 0.5, 0.7, 0.6 };
26+
27+
var expectedPosition = (Latitude: 16.054, Longitude: 108.210);
28+
var result = triangulator.CalculatePosition(baseLocations, distances);
29+
30+
Assert.That(result.Latitude, Is.EqualTo(expectedPosition.Latitude).Within(0.01));
31+
Assert.That(result.Longitude, Is.EqualTo(expectedPosition.Longitude).Within(0.01));
32+
}
33+
34+
[Test]
35+
public void CalculatePosition_InvalidBaseLocations_ThrowsArgumentException()
36+
{
37+
var triangulator = new Triangulator();
38+
var baseLocations = new List<(double Latitude, double Longitude)>
39+
{
40+
(10.762622, 106.660172)
41+
};
42+
var distances = new List<double> { 1.0 };
43+
44+
Assert.That(() => triangulator.CalculatePosition(baseLocations, distances), Throws.ArgumentException);
45+
}
46+
47+
[Test]
48+
public void CalculatePosition_InvalidDistances_ThrowsArgumentException()
49+
{
50+
var triangulator = new Triangulator();
51+
var baseLocations = new List<(double Latitude, double Longitude)>
52+
{
53+
(10.762622, 106.660172),
54+
(10.774981, 106.665504),
55+
(10.771817, 106.681179)
56+
};
57+
var distances = new List<double> { 1.0 };
58+
59+
Assert.That(() => triangulator.CalculatePosition(baseLocations, distances), Throws.ArgumentException);
60+
}
61+
}
62+
}

Algorithms/Other/Triangulator.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace Algorithms.Other
8+
{
9+
public class Triangulator
10+
{
11+
public (double Latitude, double Longitude) CalculatePosition(List<(double Latitude, double Longitude)> baseLocations, List<double> distances)
12+
{
13+
if (baseLocations.Count < 3 || distances.Count < 3)
14+
{
15+
throw new ArgumentException("At least three points and corresponding distances are required.");
16+
}
17+
18+
// Convert distances from kilometers to degrees (approximately)
19+
// 1 degree is approximately 111.32 km at the equator
20+
const double kmPerDegree = 111.32;
21+
var distancesInDegrees = distances.Select(d => d / kmPerDegree).ToList();
22+
23+
// Get the coordinates of the three base stations
24+
double lat1 = baseLocations[0].Latitude;
25+
double lon1 = baseLocations[0].Longitude;
26+
double lat2 = baseLocations[1].Latitude;
27+
double lon2 = baseLocations[1].Longitude;
28+
double lat3 = baseLocations[2].Latitude;
29+
double lon3 = baseLocations[2].Longitude;
30+
31+
// Convert coordinates to radians
32+
lat1 = ToRadians(lat1);
33+
lon1 = ToRadians(lon1);
34+
lat2 = ToRadians(lat2);
35+
lon2 = ToRadians(lon2);
36+
lat3 = ToRadians(lat3);
37+
lon3 = ToRadians(lon3);
38+
39+
// Calculate the center point
40+
double centerLat = (lat1 + lat2 + lat3) / 3;
41+
double centerLon = (lon1 + lon2 + lon3) / 3;
42+
43+
// Convert back to degrees
44+
centerLat = ToDegrees(centerLat);
45+
centerLon = ToDegrees(centerLon);
46+
47+
return (centerLat, centerLon);
48+
}
49+
50+
private double ToRadians(double degrees)
51+
{
52+
return degrees * Math.PI / 180;
53+
}
54+
55+
private double ToDegrees(double radians)
56+
{
57+
return radians * 180 / Math.PI;
58+
}
59+
}
60+
}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ find more than one implementation for the same objective but using different alg
224224
* [Pollard's Rho](./Algorithms/Other/PollardsRhoFactorizing.cs)
225225
* [GeoLocation Hash](./Algorithms/Other/Geohash.cs)
226226
* [Geofencing](./Algorithms/Other/Geofence.cs)
227+
* [Triangulation Algorithm](./Algorithms/Other/Triangulator.cs)
227228
* [Problems](./Algorithms/Problems)
228229
* [Stable Marriage](./Algorithms/Problems/StableMarriage)
229230
* [Gale-Shapley](./Algorithms/Problems/StableMarriage/GaleShapley.cs)

0 commit comments

Comments
 (0)