1 
2 module kdtree.point;
3 
4 import std.algorithm;
5 import std.array;
6 import std.range;
7 
8 struct KDPoint(size_t k, T) if(k > 0)
9 {
10     T[k] state;
11 
12     this(T[k] state...)
13     {
14         this.state = state;
15     }
16 
17     static KDPoint!(k, T)[] build(T[k][] points...)
18     {
19         return points.map!(p => KDPoint!(k, T)(p)).array;
20     }
21 
22     double distanceSq(KDPoint!(k, T) other) const
23     {
24         return iota(0, k)
25             .map!(i => state[i] - other.state[i])
26             .map!"a ^^ 2"
27             .sum;
28     }
29 
30     @property
31     enum size_t length = k;
32 
33     T opIndex(size_t axis)
34     {
35         return state[axis];
36     }
37 
38     T[] opSlice(size_t start, size_t stop)
39     {
40         return state[start .. stop];
41     }
42 
43     bool opEquals(KDPoint!(k, T) other) const
44     {
45         return state == other.state;
46     }
47 }
48 
49 @property
50 KDPoint!(k, T) kdPoint(size_t k, T)(T[k] point) if(k > 0)
51 {
52     return KDPoint!(k, T)(point);
53 }
54 
55 @property
56 KDPoint!(k, T) kdPoint(size_t k, T)(T[] point) if(k > 0)
57 {
58     return KDPoint!(k, T)(point[0 .. k]);
59 }
60 
61 @property
62 KDPoint!(k, T)[] sortedOn(size_t k, T)(KDPoint!(k, T)[] points, size_t axis) if(k > 0)
63 {
64     return points.sort!((a, b) => a[axis] < b[axis]).array;
65 }