void RecursiveDistanceClusteringEco(Point3DExd obj, IList <Point3Di> cld) { //クラスタに点追加 cld.Add(new Point3Di(obj.X, obj.Y, obj.Z)); //クラスタリング済み にフラグを変える obj.SetFlag(); //26近傍のボクセルに再帰 foreach (var item in obj.cobj) { if (item.Distance == obj.Distance && !item.flag) { RecursiveDistanceClusteringEco(item, cld); } } }
uint SSDTLoopEco(IList <Point3DExd> scluster, Point3Dd rootPoint = null) { if (rootPoint == null) { // use double sweep algorithm. Point3DExd p = scluster[0]; uint maxDistance = 0; // とりあえず何かセットしておかないとunassigned variableと言われてしまうので for (int i = 0; i < 2; i++) { foreach (var q in scluster) { q.ResetFlag(); } var que = new Queue <Point3DExd>(); p.SetFlag(); p.Distance = 0; que.Enqueue(p); maxDistance = 0; while (que.Count > 0) { var q = que.Dequeue(); foreach (var next in q.cobj) { if (next.flag == false) { next.SetFlag(); next.Distance = q.Distance + 1; que.Enqueue(next); maxDistance = Math.Max(maxDistance, next.Distance); // set final node to p p = next; } } } } foreach (var q in scluster) { q.ResetFlag(); } return(maxDistance); } else { // let p is root node. // p is node that argmin~p (distance(p, rootPoint)) Point3DExd p = scluster[0]; foreach (var q in scluster) { q.ResetFlag(); double dp = Math.Pow(p.X - rootPoint.X, 2) + Math.Pow(p.Y - rootPoint.Y, 2) + Math.Pow(p.Z - rootPoint.Z, 2); double dq = Math.Pow(q.X - rootPoint.X, 2) + Math.Pow(q.Y - rootPoint.Y, 2) + Math.Pow(q.Z - rootPoint.Z, 2); if (dq < dp) { p = q; } } var que = new Queue <Point3DExd>(); p.Distance = 0; que.Enqueue(p); uint maxDistance = 0; while (que.Count > 0) { var q = que.Dequeue(); foreach (var next in q.cobj) { if (next.flag == false) { next.Distance = q.Distance + 1; maxDistance = Math.Max(maxDistance, next.Distance); que.Enqueue(next); } } } foreach (var q in scluster) { q.ResetFlag(); } return(maxDistance); } }