// Use disjoint sets to create the clusters private static SortedDictionary <double, int>[] DerivePointClustersFromRootSets(SortedDictionary <double, Double2>[] curveRootSets) { // First, gather all points and create the disjoint sets data structure var allPoints = curveRootSets.SelectMany(set => set.Values).ToArray(); var disjointSets = new DisjointSets(allPoints.Length); // Now, reunite the clusters for (int i = 0; i < allPoints.Length; i++) { for (int j = i + 1; j < allPoints.Length; j++) { if (DoubleUtils.RoughlyEquals(allPoints[i], allPoints[j])) { disjointSets.UnionSets(i, j); } } } // Finally, attribute the clusters to the original curves int length = curveRootSets.Length; var clusters = new SortedDictionary <double, int> [length]; int k = 0; for (int i = 0; i < length; i++) { clusters[i] = new SortedDictionary <double, int>(); foreach (var kvp in curveRootSets[i]) { clusters[i][kvp.Key] = disjointSets.FindParentOfSets(k++); } } return(clusters); }