private IEnumerable <T> EnumerateSphere(ITuple center, double distance, bool tHemisphere) { Node[] stack; int sp; int i; Leaf leaf; double distance2 = distance * distance; double[] centerValues = new double[dimMax]; for (int dim = dimMax; --dim >= 0;) { centerValues[dim] = center.GetDimValue(dim); } stack = new Node[StackDepth]; sp = 0; IElement ele = eleRoot; while (ele is Node) { Node node = (Node)ele; if (center.GetDimValue(node.dim) - distance <= node.splitValue) { if (sp == StackDepth) { throw new ApplicationException("Bspt.EnumerateSphere tree stack overflow"); } stack[sp++] = node; ele = node.eleLE; } else { ele = node.eleGE; } } leaf = (Leaf)ele; i = 0; while (true) { for (; i < leaf.count; ++i) { var lt = leaf.tuples[i]; var distT = lt.GetDimValue(0) - centerValues[0]; if (tHemisphere && distT < 0) { goto Break_Widthin; } double dist2 = distT * distT; if (dist2 > distance2) { goto Break_Widthin; } for (int dim = dimMax; --dim > 0;) { distT = lt.GetDimValue(dim) - centerValues[dim]; dist2 += distT * distT; if (dist2 > distance2) { goto Break_Widthin; } } var ret = leaf.tuples[i++]; ret.Distance2 = dist2; yield return(ret); goto continue_while; Break_Widthin: ; } if (sp == 0) { yield break; } ele = stack[--sp]; while (ele is Node) { Node node = (Node)ele; if (center.GetDimValue(node.dim) + distance < node.splitValue) { if (sp == 0) { yield break; } ele = stack[--sp]; } else { ele = node.eleGE; while (ele is Node) { Node nodeLeft = (Node)ele; stack[sp++] = nodeLeft; ele = nodeLeft.eleLE; } } } leaf = (Leaf)ele; i = 0; continue_while: ; } }
public IEnumerable <T> EnumerateNears(ITuple center, double distance) { Node[] stack = new Node[StackDepth]; int sp = 0; IElement ele = eleRoot; while (ele is Node) { Node node = (Node)ele; if (center.GetDimValue(node.dim) - distance <= node.splitValue) { if (sp == StackDepth) { throw new ApplicationException("Bspt.EnumerateNear tree stack overflow"); } stack[sp++] = node; ele = node.eleLE; } else { ele = node.eleGE; } } Leaf leaf = (Leaf)ele; int i = 0; while (true) { if (i < leaf.count) { yield return(leaf.tuples[i++]); continue; } if (sp == 0) { yield break; } ele = stack[--sp]; while (ele is Node) { Node node = (Node)ele; if (center.GetDimValue(node.dim) + distance < node.splitValue) { if (sp == 0) { yield break; } ele = stack[--sp]; } else { ele = node.eleGE; while (ele is Node) { Node nodeLeft = (Node)ele; stack[sp++] = nodeLeft; ele = nodeLeft.eleLE; } } } leaf = (Leaf)ele; i = 0; yield return(leaf.tuples[i++]); } }