public static List <T> GetClusterCenters(List <T> points, T nilValue, double radius) { try { //var result = new KdTreePointClusters<T>(); Func <T, T, int> xWise = (p1, p2) => p1.X.CompareTo(p2.X); Func <T, T, int> yWise = (p1, p2) => p1.Y.CompareTo(p2.Y); Func <T, T, int>[] funcs = { xWise, yWise }; HashSet <T> set = new HashSet <T>(); var kdtree = new BalancedKdTree <T>(points, funcs.ToList(), nilValue, i => i); if (!(points?.Count > 0)) { return(new List <T>()); } List <T> result = new List <T>(); for (int i = 0; i < points.Count; i++) { try { if (set.Contains(points[i])) { continue; } result.Add(points[i]); var neighbours = kdtree.FindNeighbours(points[i], radius); set.Add(points[i]); set.UnionWith(neighbours); //for (int j = 0; j < neighbours?.Count; j++) //{ // set.Add(neighbours[j]); //} } catch (Exception ex) { return(new List <T>()); } } return(result); } catch (Exception ex) { return(new List <T>()); } }
public void TestNearestNeighbour() { List <Point> points = new List <Point>(); points.Add(new Point(1, 9)); points.Add(new Point(2, 2)); points.Add(new Point(2, 5)); points.Add(new Point(2, 10)); points.Add(new Point(2, 12)); points.Add(new Point(3, 7)); points.Add(new Point(4, 11)); points.Add(new Point(5, 8)); points.Add(new Point(6, 7)); points.Add(new Point(7, 3)); points.Add(new Point(7, 4)); points.Add(new Point(7, 5)); points.Add(new Point(7, 11)); points.Add(new Point(8, 3)); points.Add(new Point(8, 4)); points.Add(new Point(8, 5)); points.Add(new Point(9, 3)); points.Add(new Point(9, 4)); points.Add(new Point(9, 5)); points.Add(new Point(9, 10)); points.Add(new Point(9, 11)); points.Add(new Point(10, 3)); points.Add(new Point(10, 10)); points.Add(new Point(10, 11)); points.Add(new Point(11, 6)); Func <Point, Point, int> xWise = (p1, p2) => p1.X.CompareTo(p2.X); Func <Point, Point, int> yWise = (p1, p2) => p1.Y.CompareTo(p2.Y); Func <Point, Point, int>[] funcs = { xWise, yWise }; var kdtree = new BalancedKdTree <Point>(points.ToArray(), funcs.ToList(), Point.NaN, i => i); Assert.AreEqual(new Point(6, 7), kdtree.FindNearestNeighbour(new Point(7, 7))); Assert.AreEqual(new Point(7, 4), kdtree.FindNearestNeighbour(new Point(7, 4))); Assert.AreEqual(new Point(11, 6), kdtree.FindNearestNeighbour(new Point(10, 6))); Assert.AreEqual(new Point(4, 11), kdtree.FindNearestNeighbour(new Point(3, 11))); for (int i = 0; i < 100; i++) { var point = new Point(Math.Sin(RandomHelper.Get(0, 100)) * 20, Math.Cos(RandomHelper.Get(0, 100)) * 20); System.Diagnostics.Debug.WriteLine(point.ToString()); Assert.AreEqual(kdtree.FindNearestNeighbour(point), FindNearestBruteForce(points, point)); } }
public void GetClusters(Func <T, T, bool> groupLogic) { Func <Group <T>, Group <T>, int> xWise = (p1, p2) => p1.Center.X.CompareTo(p2.Center.X); Func <Group <T>, Group <T>, int> yWise = (p1, p2) => p1.Center.Y.CompareTo(p2.Center.Y); Func <Group <T>, Group <T>, int>[] funcs = { xWise, yWise }; //this.Groups = new List<Group<T>>(); if (_allSingleMembers?.Count > 0) { this.Groups = new BalancedKdTree <Group <T> >(new Group <T>[] { new Group <T>(_allSingleMembers[0]) }, funcs.ToList(), _nilValue, g => g.Center); //Groups.Add(new Group<T>(_allSingleMembers[0])); for (int i = 1; i < _allSingleMembers.Count; i++) { bool hasGroup = false; var tempGroup = new Group <T>(_allSingleMembers[i]); var nearestGroup = Groups.FindNearestNeighbour(tempGroup, ((g1, g2) => g1.Center.DistanceTo(g2.Center))); if (groupLogic(nearestGroup.Center, _allSingleMembers[i])) { nearestGroup.Add(_allSingleMembers[i]); hasGroup = true; } //bool hasGroup = false; //for (int g = 0; g < Groups.Count; g++) //{ //if (groupLogic(Groups[g].Center, _allSingleMembers[i])) //{ // Groups[g].Add(_allSingleMembers[i]); // hasGroup = true; // break; //} //} if (!hasGroup) { MakeNewGroup(_allSingleMembers[i]); } } } }
public void TestBoundingBox() { List <Point> points = new List <Point>(); points.Add(new Point(1, 9)); points.Add(new Point(2, 2)); points.Add(new Point(2, 5)); points.Add(new Point(2, 10)); points.Add(new Point(2, 12)); points.Add(new Point(3, 7)); points.Add(new Point(4, 11)); points.Add(new Point(5, 8)); points.Add(new Point(6, 7)); points.Add(new Point(7, 3)); points.Add(new Point(7, 4)); points.Add(new Point(7, 5)); points.Add(new Point(7, 11)); points.Add(new Point(8, 3)); points.Add(new Point(8, 4)); points.Add(new Point(8, 5)); points.Add(new Point(9, 3)); points.Add(new Point(9, 4)); points.Add(new Point(9, 5)); points.Add(new Point(9, 10)); points.Add(new Point(9, 11)); points.Add(new Point(10, 3)); points.Add(new Point(10, 10)); points.Add(new Point(10, 11)); points.Add(new Point(11, 6)); Func <Point, Point, int> xWise = (p1, p2) => p1.X.CompareTo(p2.X); Func <Point, Point, int> yWise = (p1, p2) => p1.Y.CompareTo(p2.Y); Func <Point, Point, int>[] funcs = { xWise, yWise }; var kdtree = new BalancedKdTree <Point>(points.ToArray(), funcs.ToList(), Point.NaN, i => i); Assert.AreEqual(true, CheckBoundingBox(kdtree.Root)); }