// Note: // -u can be up to N+i-1 // -l can be down to -N+1+u private void CalculateNeighbourhood(IList<ScanPoint> scan, float eps, FloatMetric<ScanPoint> circularMetric) { //both the scan and feature space are circular which makes implemantation tricky! int N=scan.Count, l = N-1, u = 0; for (int i = 0; i < N; ++i) { for (; u < N + i && circularMetric.Distance(scan[Mod(u, N)], scan[i]) < eps; ++u) ; U[i] = u-1; } for (int i = N-1; i >= 0; --i) { for(; U[i]-l+1<=N && circularMetric.Distance(scan[Mod(l, N)], scan[i]) < eps; --l) ; L[i] = l+1; } }
public List<DBSCANCluster> Cluster(IList<ScanPoint> scan, float eps, int minPoints, Comparer<ScanPoint> comparer, FloatMetric<ScanPoint> circularMetric) { List<DBSCANCluster> clusters = new List<DBSCANCluster>(); int cluster = 0, N=scan.Count; if (N > Capacity) Capacity = N; ArrayList.Adapter((IList)scan).Sort(comparer); CalculateNeighbourhood(scan, eps, circularMetric); for (int i = 0; i < N; ++i) C[i] = NOT_VISITED; for (int i = 0; i < N; ++i) { if (C[i] != NOT_VISITED) continue; if (NeighbourCount(i) < minPoints) C[i] = NOISE; else clusters.Add(ExpandCluster(scan, ++cluster, i, minPoints)); } // DumpScan(scan, C); return clusters; }