// O(k*n) List <XY> RunClusterAlgo() { // put points in buckets int allPointsCount = BaseDataset.Count; var firstPoint = BaseDataset[0]; firstPoint.Color = GetRandomColor(); var firstId = 0.ToString(); var firstBucket = new Bucket(firstId) { Centroid = firstPoint }; BaseBucketsLookup.Add(firstId, firstBucket); for (int i = 1; i < allPointsCount; i++) { var set = new HashSet <string>(); //cluster candidate list var p = BaseDataset[i]; // iterate clusters and collect candidates foreach (var bucket in BaseBucketsLookup.Values) { var isInCluster = MathTool.BoxWithin(p, bucket.Centroid, MARKERCLUSTERER_SIZE); if (!isInCluster) { continue; } set.Add(bucket.Id); //use first, short dist will be calc at last step before returning data break; } // if not within box area, then make new cluster if (set.Count == 0) { var pid = i.ToString(); p.Color = GetRandomColor(); var newbucket = new Bucket(pid) { Centroid = p }; BaseBucketsLookup.Add(pid, newbucket); } } //important, align all points to closest cluster point BaseUpdatePointsByCentroid(); return(BaseGetClusterResult()); }