Beispiel #1
0
        public TDTreeNode <T> buildTree(Sequence <Func.Tuple <Vector3, T> > points, int dim)
        {
            if (points.Count == 0)
            {
                return(null);
            }
            var node = new TDTreeNode <T>();

            Count++;

            float median;
            Func <Func.Tuple <Vector3, T>, int> splitFn = null;

            switch (dim)
            {
            case 0:
                median  = Sequence.Median(Sequence.Unzip(points).car.MapEagerly((Vector3 v) => v.x));
                splitFn = (Func.Tuple <Vector3, T> point) => point.car.x.CompareTo(median);
                break;

            case 1:
                median  = Sequence.Median(Sequence.Unzip(points).car.MapEagerly((Vector3 v) => v.y));
                splitFn = (Func.Tuple <Vector3, T> point) => point.car.y.CompareTo(median);
                break;

            default:
                median  = Sequence.Median(Sequence.Unzip(points).car.MapEagerly((Vector3 v) => v.z));
                splitFn = (Func.Tuple <Vector3, T> point) => point.car.z.CompareTo(median);
                break;
            }


            var tup = points.Partition3(splitFn);

            if (tup.cpr.IsNone())
            {
                throw new Exception("Median not found. Huh?");
            }

            var val = tup.cpr.Value();

            node.value  = val.cdr;
            node.coords = val.car;
            node.left   = null;
            node.right  = null;
            node.parent = null;

            if (tup.car.Count > 0)
            {
                node.left        = buildTree(tup.car, (dim + 1) % 3);
                node.left.parent = node;
            }

            if (tup.cdr.Count > 0)
            {
                node.right        = buildTree(tup.cdr, (dim + 1) % 3);
                node.right.parent = node;
            }
            return(node);
        }
Beispiel #2
0
        TDTreeNode <T> getCurrentBest(Vector3 pos, TDTreeNode <T> node, int dim)
        {
            if (node == null)
            {
                return(null);
            }
            if (node.left == null && node.right == null)
            {
                return(node);
            }

            if (node.left == null && node.right != null)
            {
                return(getCurrentBest(pos, node.right, (dim + 1) % 3));
            }
            if (node.left != null && node.right == null)
            {
                return(getCurrentBest(pos, node.left, (dim + 1) % 3));
            }

            float val;
            Func <Vector3, int> splitFn = null;

            switch (dim)
            {
            case 0:
                val     = node.coords.x;
                splitFn = (Vector3 point) => point.x.CompareTo(val);
                break;

            case 1:
                val     = node.coords.y;
                splitFn = (Vector3 point) => point.y.CompareTo(val);
                break;

            default:
                val     = node.coords.z;
                splitFn = (Vector3 point) => point.z.CompareTo(val);
                break;
            }

            if (splitFn(pos) < 0)
            {
                return(getCurrentBest(pos, node.left, (dim + 1) % 3));
            }

            return(getCurrentBest(pos, node.right, (dim + 1) % 3));
        }
Beispiel #3
0
 public TDTree(Sequence <Func.Tuple <Vector3, T> > points)
 {
     Count = 0;
     root  = buildTree(points, 0);
 }