private static void ExpandCluster <XType, YType>(IDbscanPoint <XType, YType>[] points, IDbscanPoint <XType, YType> p, IDbscanPoint <XType, YType>[] neighbors, int cid, int eps, int minimumClusterCount) { p.ClusterId = cid; Queue <IDbscanPoint <XType, YType> > q = new Queue <IDbscanPoint <XType, YType> >(neighbors); while (q.Count > 0) { IDbscanPoint <XType, YType> n = q.Dequeue(); if (!n.IsVisited) { n.IsVisited = true; IDbscanPoint <XType, YType>[] ns = DbscanAlgorithm.GetNeighors(points, n, eps); if (ns.Length >= minimumClusterCount) { foreach (IDbscanPoint <XType, YType> item in ns) { q.Enqueue(item); } } } else if (!n.ClusterId.HasValue) { n.ClusterId = cid; } } }
/// <summary> /// Clusters the specified points using the specified value and minimum points to form a cluster. /// </summary> /// <param name="points">The points to cluster.</param> /// <param name="eps">The value to use to find neighoring points.</param> /// <param name="minimumClusterCount">The minimum number of points to form a cluster.</param> /// <returns>The number of clusters created from the collection.</returns> public static int Dbscan <XType, YType>(IDbscanPoint <XType, YType>[] points, int eps, int minimumClusterCount) { int cid = 0; foreach (IDbscanPoint <XType, YType> p in points) { if (!p.IsVisited) { p.IsVisited = true; IDbscanPoint <XType, YType>[] neighbors = DbscanAlgorithm.GetNeighors(points, p, eps); if (neighbors.Length < minimumClusterCount) { p.IsNoise = true; } else { cid += 1; DbscanAlgorithm.ExpandCluster(points, p, neighbors, cid, eps, minimumClusterCount); } } } return(cid); }
private HighestLowest CalculateTarget(List <DbscanPoint> points, double heightAdjusted) { List <HighestLowest> highestLowestList = new List <HighestLowest>(); var clusterCount = DbscanAlgorithm.Dbscan(points.ToArray(), 45, 2); if (clusterCount == 0) { return(null); } for (var i = 0; i <= clusterCount - 1; i++) { highestLowestList.Add(new HighestLowest { Id = i }); } int clusterIdClosestToMiddle = 0; int clusterClosestToMiddleDistance = int.MaxValue; var castSettings = ((PixelClickerPrototype.Settings)Settings); foreach (var pointLoopVariable in points) { var point = pointLoopVariable; if (point.ClusterId == null || point.IsNoise) { continue; } if (point.X < highestLowestList[(int)(point.ClusterId - 1)].HighestPoint.X) { highestLowestList[(int)(point.ClusterId - 1)].HighestPoint.X = point.X; } if (point.Y < highestLowestList[(int)(point.ClusterId - 1)].HighestPoint.Y) { highestLowestList[(int)(point.ClusterId - 1)].HighestPoint.Y = point.Y; } if (point.X > highestLowestList[(int)(point.ClusterId - 1)].LowestPoint.X) { highestLowestList[(int)(point.ClusterId - 1)].LowestPoint.X = point.X; } if (point.Y > highestLowestList[(int)(point.ClusterId - 1)].LowestPoint.Y) { highestLowestList[(int)(point.ClusterId - 1)].LowestPoint.Y = point.Y; } int dis = DistanceBetween(new Point(Settings.SearchArea.Width / 2, (int)(Settings.SearchArea.Height / 2 * heightAdjusted)), new Point(point.X + castSettings.XOffset, point.Y + castSettings.YOffset)); if (dis < clusterClosestToMiddleDistance) { clusterClosestToMiddleDistance = dis; clusterIdClosestToMiddle = (int)(point.ClusterId - 1); } highestLowestList[(int)(point.ClusterId - 1)].Points.Add(new Point(point.X, point.Y)); } return(highestLowestList[clusterIdClosestToMiddle]); }