├── plot2.png
├── plot3.png
├── README.md
├── dbscan.hpp
├── LICENSE
├── dbscan.cpp
├── example.cpp
├── sample2d.csv
├── sample3d.csv
└── vendor
└── nanoflann
└── nanoflann.hpp
/plot2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Eleobert/dbscan/HEAD/plot2.png
--------------------------------------------------------------------------------
/plot3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Eleobert/dbscan/HEAD/plot3.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Density-based spatial clustering of applications with noise (DBSCAN)
2 |
3 | This is a fast C++ implementation of dbscan clustering algorithm.
4 |
5 | Compiling and running the example:
6 |
7 | ```bash
8 | g++ example.cpp dbscan.cpp -I vendor/ -std=c++20 -o example
9 | ./example sample2d.csv 0.2 10 > output.csv
10 | ```
11 |
12 |
13 |
14 |
15 |
16 | Or run with three dimensional data:
17 | ```
18 | ./example sample3d.csv 1 10 > output.csv
19 | ```
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/dbscan.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | struct point2
11 | {
12 | float x, y;
13 | };
14 |
15 | struct point3
16 | {
17 | float x, y, z;
18 | };
19 |
20 | auto dbscan(const std::span& data, float eps, int min_pts) -> std::vector>;
21 | auto dbscan(const std::span& data, float eps, int min_pts) -> std::vector>;
22 |
23 | // template
24 | // auto dbscan(const std::span& data, float eps, int min_pts)
25 | // {
26 | // static_assert(dim == 2 or dim == 3, "This only supports either 2D or 3D points");
27 | // assert(data.size() % dim == 0);
28 |
29 | // if(dim == 2)
30 | // {
31 | // auto * const ptr = reinterpret_cast (data.data());
32 | // auto points = std::span
33 | // }
34 | // }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Eleobert do Espírito Santo
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/dbscan.cpp:
--------------------------------------------------------------------------------
1 | #include "dbscan.hpp"
2 |
3 | #include
4 | #include
5 |
6 | #include
7 | #include
8 |
9 | // And this is the "dataset to kd-tree" adaptor class:
10 |
11 | inline auto get_pt(const point2& p, std::size_t dim)
12 | {
13 | if(dim == 0) return p.x;
14 | return p.y;
15 | }
16 |
17 |
18 | inline auto get_pt(const point3& p, std::size_t dim)
19 | {
20 | if(dim == 0) return p.x;
21 | if(dim == 1) return p.y;
22 | return p.z;
23 | }
24 |
25 |
26 | template
27 | struct adaptor
28 | {
29 | const std::span& points;
30 | adaptor(const std::span& points) : points(points) { }
31 |
32 | /// CRTP helper method
33 | //inline const Derived& derived() const { return obj; }
34 |
35 | // Must return the number of data points
36 | inline std::size_t kdtree_get_point_count() const { return points.size(); }
37 |
38 | // Returns the dim'th component of the idx'th point in the class:
39 | // Since this is inlined and the "dim" argument is typically an immediate value, the
40 | // "if/else's" are actually solved at compile time.
41 | inline float kdtree_get_pt(const std::size_t idx, const std::size_t dim) const
42 | {
43 | return get_pt(points[idx], dim);
44 | }
45 |
46 | // Optional bounding-box computation: return false to default to a standard bbox computation loop.
47 | // Return true if the BBOX was already computed by the class and returned in "bb" so it can be avoided to redo it again.
48 | // Look at bb.size() to find out the expected dimensionality (e.g. 2 or 3 for point clouds)
49 | template
50 | bool kdtree_get_bbox(BBOX& /*bb*/) const { return false; }
51 |
52 | auto const * elem_ptr(const std::size_t idx) const
53 | {
54 | return &points[idx].x;
55 | }
56 | };
57 |
58 |
59 |
60 | auto sort_clusters(std::vector>& clusters)
61 | {
62 | for(auto& cluster: clusters)
63 | {
64 | std::sort(cluster.begin(), cluster.end());
65 | }
66 | }
67 |
68 |
69 | template
70 | auto dbscan(const Adaptor& adapt, float eps, int min_pts)
71 | {
72 | eps *= eps;
73 | using namespace nanoflann;
74 | using my_kd_tree_t = KDTreeSingleIndexAdaptor, decltype(adapt), n_cols>;
75 |
76 | auto index = my_kd_tree_t(n_cols, adapt, KDTreeSingleIndexAdaptorParams(10));
77 | index.buildIndex();
78 |
79 | const auto n_points = adapt.kdtree_get_point_count();
80 | auto visited = std::vector(n_points);
81 | auto clusters = std::vector>();
82 | auto matches = std::vector>();
83 | auto sub_matches = std::vector>();
84 |
85 | for(size_t i = 0; i < n_points; i++)
86 | {
87 | if (visited[i]) continue;
88 |
89 | index.radiusSearch(adapt.elem_ptr(i), eps, matches, SearchParams(32, 0.f, false));
90 | if (matches.size() < static_cast(min_pts)) continue;
91 | visited[i] = true;
92 |
93 | auto cluster = std::vector({i});
94 |
95 | while (matches.empty() == false)
96 | {
97 | auto nb_idx = matches.back().first;
98 | matches.pop_back();
99 | if (visited[nb_idx]) continue;
100 | visited[nb_idx] = true;
101 |
102 | index.radiusSearch(adapt.elem_ptr(nb_idx), eps, sub_matches, SearchParams(32, 0.f, false));
103 |
104 | if (sub_matches.size() >= static_cast(min_pts))
105 | {
106 | std::copy(sub_matches.begin(), sub_matches.end(), std::back_inserter(matches));
107 | }
108 | cluster.push_back(nb_idx);
109 | }
110 | clusters.emplace_back(std::move(cluster));
111 | }
112 | sort_clusters(clusters);
113 | return clusters;
114 | }
115 |
116 |
117 | auto dbscan(const std::span& data, float eps, int min_pts) -> std::vector>
118 | {
119 | const auto adapt = adaptor(data);
120 |
121 | return dbscan<2>(adapt, eps, min_pts);
122 | }
123 |
124 |
125 | auto dbscan(const std::span& data, float eps, int min_pts) -> std::vector>
126 | {
127 | const auto adapt = adaptor(data);
128 |
129 | return dbscan<3>(adapt, eps, min_pts);
130 | }
--------------------------------------------------------------------------------
/example.cpp:
--------------------------------------------------------------------------------
1 | #include "dbscan.hpp"
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 |
14 | auto check_from_chars_error(std::errc err, const std::string_view& line, int line_counter)
15 | {
16 | if(err == std::errc())
17 | return;
18 |
19 | if(err == std::errc::invalid_argument)
20 | {
21 | std::cerr << "Error: Invalid value \"" << line
22 | << "\" at line " << line_counter << "\n";
23 | std::exit(1);
24 | }
25 |
26 | if(err == std::errc::result_out_of_range)
27 | {
28 | std::cerr << "Error: Value \"" << line << "\"out of range at line "
29 | << line_counter << "\n";
30 | std::exit(1);
31 | }
32 |
33 | }
34 |
35 |
36 | auto push_values(std::vector& store, const std::string_view& line, int line_counter)
37 | {
38 | auto ptr = line.data();
39 | auto ec = std::errc();
40 | auto n_pushed = 0;
41 |
42 | do
43 | {
44 | float value;
45 | auto [p, ec] = std::from_chars(ptr, line.data() + line.size(), value);
46 | ptr = p + 1;
47 | check_from_chars_error(ec, line, line_counter);
48 | n_pushed++;
49 | store.push_back(value);
50 |
51 | }while(ptr < line.data() + line.size());
52 |
53 | return n_pushed;
54 | }
55 |
56 |
57 | auto read_values(const std::string& filename)
58 | {
59 | std::ifstream file(filename);
60 |
61 | if(not file.good())
62 | {
63 | std::perror(filename.c_str());
64 | std::exit(2);
65 | }
66 |
67 | auto count = 0;
68 |
69 | auto points = std::vector();
70 | auto dim = 0;
71 |
72 | while(not file.eof())
73 | {
74 | count++;
75 | auto line = std::string();
76 | std::getline(file, line);
77 |
78 | if(not line.empty())
79 | {
80 | auto n_pushed = push_values(points, line, count);
81 |
82 | if(count != 1)
83 | {
84 | if(n_pushed != dim)
85 | {
86 | std::cerr << "Inconsistent number of dimensions at line '" << count << "'\n";
87 | std::exit(1);
88 | }
89 | }
90 | dim = n_pushed;
91 | }
92 | }
93 |
94 | return std::tuple(points, dim);
95 | }
96 |
97 |
98 | template
99 | auto to_num(const std::string& str)
100 | {
101 | T value = 0;
102 | auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value);
103 |
104 | if(ec != std::errc())
105 | {
106 | std::cerr << "Error converting value '" << str << "'\n";
107 | std::exit(1);
108 | }
109 | return value;
110 | }
111 |
112 |
113 | // noise will be labelled as 0
114 | auto label(const std::vector>& clusters, size_t n)
115 | {
116 | auto flat_clusters = std::vector(n);
117 |
118 | for(size_t i = 0; i < clusters.size(); i++)
119 | {
120 | for(auto p: clusters[i])
121 | {
122 | flat_clusters[p] = i + 1;
123 | }
124 | }
125 |
126 | return flat_clusters;
127 | }
128 |
129 |
130 | auto dbscan2d(const std::span& data, float eps, int min_pts)
131 | {
132 | auto points = std::vector(data.size() / 2);
133 |
134 | std::memcpy(points.data(), data.data(), sizeof(float) * data.size());
135 |
136 | auto clusters = dbscan(points, eps, min_pts);
137 | auto flat = label (clusters, points.size());
138 |
139 | for(size_t i = 0; i < points.size(); i++)
140 | {
141 | std::cout << points[i].x << ',' << points[i].y << ',' << flat[i] << '\n';
142 | }
143 | }
144 |
145 |
146 | auto dbscan3d(const std::span& data, float eps, int min_pts)
147 | {
148 | auto points = std::vector(data.size() / 3);
149 |
150 | std::memcpy(points.data(), data.data(), sizeof(float) * data.size());
151 |
152 | auto clusters = dbscan(points, eps, min_pts);
153 | auto flat = label (clusters, points.size());
154 |
155 | for(size_t i = 0; i < points.size(); i++)
156 | {
157 | std::cout << points[i].x << ',' << points[i].y << ',' << points[i].z << ',' << flat[i] << '\n';
158 | }
159 | }
160 |
161 |
162 |
163 | int main(int argc, char** argv)
164 | {
165 | if(argc != 4)
166 | {
167 | std::cerr << "usage: example \n";
168 | return 1;
169 | }
170 |
171 | auto epsilon = to_num(argv[2]);
172 | auto min_pts = to_num (argv[3]);
173 | auto [values, dim] = read_values(argv[1]);
174 |
175 | if(dim == 2)
176 | {
177 | dbscan2d(values, epsilon, min_pts);
178 | }
179 | else if (dim == 3)
180 | {
181 | dbscan3d(values, epsilon, min_pts);
182 | }
183 | }
--------------------------------------------------------------------------------
/sample2d.csv:
--------------------------------------------------------------------------------
1 | -1.3303058582391545,-0.434325580615089
2 | -0.5924972261074593,-0.46453047635748296
3 | -1.1514663829680862,0.41611224001806546
4 | -1.5492485381753465,0.8027038296916662
5 | -0.029999384901909565,0.16778807157434542
6 | -2.550898666403688,0.8951192208886832
7 | -1.204236560105029,0.5776550847730018
8 | -2.0076783977997246,0.3298131705764211
9 | -2.3929007725439684,1.0023550116130524
10 | -0.43406313639471383,-0.37119599704158546
11 | -1.0243161051435994,0.09476345784093444
12 | -1.7303188927974933,-0.04281514187958224
13 | -2.835142083623058,0.7128372359333114
14 | -2.6237108800255813,0.7176294993959645
15 | -1.8602891561940256,0.9923774293633051
16 | -1.1314973855494095,-0.5159850609542471
17 | -0.5818103680025788,-0.4266784189158561
18 | -3.0441854407425044,0.03707690902891613
19 | -1.2125651724538922,0.7102035888785216
20 | -0.9991949806876501,0.009184374561152328
21 | -1.6080788691091472,0.8890972913187793
22 | -0.9952721569244962,-0.59617144409241
23 | -1.700705861626605,0.896771448707588
24 | -2.780827136834604,0.64280336743606
25 | -1.292603276247485,0.6652461841800765
26 | -1.9778544183194762,0.21589716727848582
27 | -2.819583871326087,0.678417100150437
28 | -1.8993123929673383,-0.053849421809319176
29 | -1.2189033205776099,-0.4286013002108381
30 | -0.791744427377514,-0.4854203504851642
31 | -0.31077175947557456,-0.07167431749980765
32 | -1.6522549541506881,-0.335223381072491
33 | -0.9334505907294359,0.07029505658828776
34 | -0.6034725585008933,-0.43058689893087404
35 | -1.6457197324606816,-0.11112708156685057
36 | -0.36047101280325355,-0.18269465497515341
37 | -1.4938865126045393,-0.4398130341163262
38 | -3.034666824636589,0.20236356974545477
39 | -1.3440397545722442,-0.4046411760875248
40 | -1.4777054900584912,-0.3469778397153196
41 | -1.9730268101343804,0.5019435746007844
42 | -2.284838566790355,0.8864313268451619
43 | -2.2635042328486987,0.906075562674943
44 | -0.6207677698554193,-0.43493124092621654
45 | -1.1206294210437668,0.3915235866807588
46 | -2.869880629393536,0.5878038966453305
47 | -0.9603324957002513,-0.4835181035237305
48 | -2.6600544513649687,0.7523609815657362
49 | -0.7082954505693906,-0.48389049147922564
50 | -1.6587685318184242,-0.23097527506769672
51 | -1.7664280399920893,0.9507262140096867
52 | -1.382793764162855,-0.34735213125302
53 | -1.4606504849560245,-0.34443633479666663
54 | -1.360691046650401,-0.33879176678426665
55 | -0.17343079564010422,0.013909120584047604
56 | -1.005888834231635,0.3481366079223894
57 | -1.5741493172377918,-0.30535184355842604
58 | -3.083667027635564,0.07189553239242846
59 | -1.8946527382845548,0.34084585183535554
60 | -1.8038959736437525,1.0253440939282148
61 | -0.5250567188318576,-0.39020059732201506
62 | -2.9966427851291253,0.26876779562932385
63 | -1.9242671872756456,0.06620605431200255
64 | -1.5447276482796466,-0.2792445266194328
65 | -0.8458140333713551,-0.5546887857745991
66 | -1.4148076997192787,0.8998170624488967
67 | -1.9623801598227377,1.011897967383911
68 | -2.0433269197174453,0.41390496702516066
69 | -2.8649384926100865,0.3987656310127547
70 | -2.9243982483176434,0.2859219039943523
71 | -1.1089383314541403,0.4943017968113612
72 | -0.9787775377547561,-0.5039453939797348
73 | -1.7249032773441928,0.9719415828148369
74 | -0.7151734059746804,-0.45672915184754076
75 | -0.05512974495953005,0.34836109749389754
76 | -1.971727820572869,0.44497730614213055
77 | -0.9664395204260849,0.23231255176290683
78 | -1.1817996593933504,0.41723508842136503
79 | -2.6598983141035637,0.800168503912098
80 | -1.5790951472500931,1.0219877766834784
81 | -2.639682248700582,0.7757867503297922
82 | -0.4102140095240072,-0.28212055223875143
83 | -1.0109050094585987,0.37152033696252557
84 | -2.65010299586981,0.9107456739257127
85 | -0.10016997429064389,0.3851235381662591
86 | -0.9458097258682938,0.29010430624643
87 | -1.3236673325509019,-0.5138027801494128
88 | -0.03560587643006463,0.2565636413631235
89 | -3.0151680401528385,0.021461296424950278
90 | -1.275447100658896,-0.37951270796055864
91 | -0.9275542859419348,0.18722089256514687
92 | -2.859455970166303,0.5215984184159529
93 | -0.3029046982396666,-0.24758601457005835
94 | -2.0667133262101403,1.0281110882606044
95 | -1.2077389663388478,0.6480408030712447
96 | -2.765738935134479,0.7891044927150201
97 | -2.4839390493774207,0.8568448838299919
98 | -1.9940235702836244,0.9378924426902338
99 | -2.7324673390909666,0.7662733937107853
100 | -0.2197196637994383,-0.2667177160837247
101 | -0.9752241934754586,0.35158102809799996
102 | -0.03876059428566858,0.2591861540827761
103 | -0.05032023376267447,0.18198546315953743
104 | -1.845743365427094,1.0261961062551863
105 | -1.373027775956463,-0.4315942011348258
106 | -1.9072554662358465,0.2954772666223846
107 | -1.884592724972176,1.015399644194677
108 | -0.5370146104486488,-0.35075887853296966
109 | -1.0858385889735804,-0.5279030212913971
110 | -1.9502435864191046,0.39759090321350254
111 | -1.212392490145117,0.6262918930812117
112 | -1.2168164360026172,-0.5165586839812111
113 | -0.9923093685212152,0.090116852417676
114 | -2.965519831050109,0.272941198921126
115 | -1.0182390343260224,0.28136510577915197
116 | -2.683655147205113,0.6824550143155623
117 | -0.17089899776848005,-0.02720349273039014
118 | -2.419067684312586,0.9099576369701589
119 | -0.009737035306594644,0.456223424336874
120 | -1.0951523053165524,0.3022485966331948
121 | -2.0248796472169937,0.961121522125862
122 | -2.2215065722567626,1.0222314776631556
123 | -1.0800915642045268,0.5545308333497937
124 | -2.6612414385647214,0.703067228199621
125 | -1.7568334996757489,0.9508451843917397
126 | -0.25591685636279093,0.061472424964867683
127 | -0.04674055545263922,0.1579668461498365
128 | -1.0403703848002221,0.3153383340022235
129 | -0.25838830899941456,-0.08506499583670192
130 | -1.6207725768073418,-0.3191036206016011
131 | -0.18037443163505396,0.05592226249813386
132 | -2.8634038861919984,0.4500159893984662
133 | -0.05505351129998637,0.3860393186291424
134 | -1.5382002327780209,-0.33603530533492243
135 | -0.7742709674046657,-0.4534819940717547
136 | -1.9344193266399903,-0.07404505645711607
137 | -2.0649913953396934,0.9478102271147403
138 | -1.9946095824950445,1.009980388432674
139 | -0.6893235783338314,-0.48562808580221545
140 | -0.10365243461042506,0.4927217855399866
141 | -2.920449193972943,0.3814571187216646
142 | -1.5760619170011114,0.8564796286034261
143 | -1.2581359097769376,0.6814844184108857
144 | -1.6362260047525874,0.9681066868205848
145 | -2.961394269878884,0.39316075003012596
146 | -2.3249633893925012,0.8062272882733228
147 | -1.2173776550879958,0.470618878746892
148 | -0.9447901651504267,-0.497433085942137
149 | -2.9913746631645832,0.28528773726285145
150 | -2.7070842245049063,0.6710402337532062
151 | -1.6120464640766123,-0.16001527143944694
152 | -0.128568833657148,0.05167934733837576
153 | -2.783542910378854,0.37918096673532853
154 | -2.746560213317074,0.7642284172608577
155 | -0.0677910021485344,0.14014156631202668
156 | -0.7213175132647316,-0.3990229749893371
157 | -1.9569219806307259,0.09743238873240784
158 | -1.8910037622473292,1.0340066516912434
159 | -2.9977006762686376,0.2142057816306897
160 | -0.4658708211347682,-0.4204756343945776
161 | -1.187344005006889,-0.5320504774489625
162 | -1.434051129982276,-0.4389701996617654
163 | -1.6083860520802693,-0.3130567791802665
164 | -2.589602702634253,0.7553115494401924
165 | -1.3578733491526425,0.7836471777576147
166 | -1.0288780886387399,0.09141697106216339
167 | -1.0206711212684254,0.39810435897603796
168 | -1.1943136606815845,0.5762043878513502
169 | -0.2153356482365354,-0.2207925530079735
170 | -0.20188048137990222,-0.10625918095251864
171 | -1.838450095615389,1.0559051893368212
172 | -1.2147571817857767,-0.4976419732024298
173 | 0.028102192771448653,0.24975711577324525
174 | -2.1770283908206634,0.9618976209877378
175 | -1.4152217884333913,-0.31457543146910466
176 | -1.028298503923746,0.10025302119095444
177 | -2.547334584688949,0.8697766005920244
178 | -1.52891220415545,0.886926328850353
179 | -1.6511506590892095,0.9770059274002476
180 | -1.427439233674651,0.808125572144148
181 | -0.15604891540740584,0.003786551714911171
182 | -1.1068980199749008,0.5708266919962527
183 | -1.1143634109592777,0.22594123619004483
184 | -1.8004598169346109,-0.14179201637197109
185 | -1.019877093519437,0.054061151250768796
186 | -2.4521778784413493,0.9359840508001291
187 | -0.26028072386906675,-0.17717733793494186
188 | -2.1382036851849757,1.0193638290195854
189 | -0.5617672767548061,-0.43168152637311014
190 | -1.5706237277936428,-0.3142142354166646
191 | -1.7937136120116424,-0.09427411399840896
192 | -0.2845984833796571,-0.20719782926785768
193 | -1.4338512187513073,-0.3186862493472428
194 | 0.03892383919069964,0.5546427264670343
195 | -0.056470612955844546,0.3522629219095279
196 | -1.58213967134395,0.9830878857616129
197 | -2.9265180605649994,0.29557855239044595
198 | -1.5941630824512463,0.8809462873857095
199 | -0.07784309848863469,0.05187257158259116
200 | -0.06609617834389936,0.2629452157711026
201 | -2.774703956246765,0.5876289569863236
202 | -0.0399379427962645,0.41624914024250625
203 | -3.0342458474429526,-0.0055521902454389385
204 | -1.4122268686976915,0.838052140064761
205 | -1.928922912191897,0.1250815482902315
206 | -1.7904774727790165,0.04077328996821911
207 | -2.279878057817754,0.9092981747547306
208 | -0.9479795835929299,-0.5469735641203588
209 | -0.057275988481214624,0.18000707273216923
210 | -1.1295397546957258,0.6390144910171083
211 | -0.0842977955518811,0.2967864145889766
212 | -1.7623376853745478,-0.009991992918270146
213 | -2.5478467907693374,0.915327584345221
214 | -1.7358810858070965,-0.3392694269126897
215 | -1.55164279288666,-0.24435898854610485
216 | -1.1715538494378923,-0.5530799782487916
217 | -2.0092407522329516,0.29663485372807297
218 | -1.129713143153003,0.4659559565458078
219 | -1.1620205737182059,0.4365813140354934
220 | -2.9223813500837696,0.5471954419535701
221 | -1.8883579501950252,-0.09323178916862604
222 | -1.840553320643013,0.9894729846158716
223 | -1.8946258442045907,0.12294821185350004
224 | -1.935828344247839,0.9151085482477033
225 | -0.08832237042461388,0.3095585523691082
226 | -0.9725400835024778,-0.4745105434626775
227 | -2.62092115723364,0.8939166091302845
228 | -1.6980184640272131,-0.17040424948479252
229 | -1.313567440586144,0.7221931320770447
230 | -1.81010967110202,-0.19971485266623762
231 | -0.8233478400854841,-0.4330274193506428
232 | -1.6587204274119602,0.885850322669374
233 | -1.8177099438119695,-0.0407858309954903
234 | -3.018488994280959,0.02514752956281836
235 | -1.3842319358988993,0.7985646879628805
236 | -1.838308148896411,-0.03272669403447534
237 | -1.5417605766970828,0.9440244530114985
238 | -1.9776984536339033,0.3602893426493772
239 | -2.2156112006393283,1.034088940436064
240 | -1.5312322335650164,-0.43090330523588954
241 | -1.1023178860207001,0.42098217902438906
242 | -1.0957196719144038,-0.09500671668273612
243 | -1.0175898048952563,-0.4931753280981043
244 | -1.119577139597721,0.14358762691171045
245 | -0.9835036600162825,0.29005022722988927
246 | -1.9911623031083798,0.09006848225111322
247 | -2.561165370650842,0.8658192012428642
248 | -2.0984112491367535,1.044105930168259
249 | -1.6803764157254824,0.96777828224891
250 | -1.7827371846552227,-0.14865622788218041
251 | -1.9315856421415025,0.11338270171069595
252 | -0.9956576895287998,0.12284317336128679
253 | -2.8646272946312346,0.4108816276694249
254 | -1.3276661134885765,0.7686402186139859
255 | -0.10340529681131705,0.09139886858953626
256 | -1.3713863055875708,-0.4750452453835319
257 | -3.0569715421706136,0.14401070527924117
258 | -0.6913650756053837,-0.5203744466393696
259 | -0.07360479428124611,0.34001680292303244
260 | -1.654576470860143,-0.19003085570581552
261 | -0.41220816136881866,-0.20926060482937864
262 | -1.9423759274443775,0.20942190079848583
263 | -1.404947558457767,0.7704362834196857
264 | -1.2508447739310808,-0.447804280161926
265 | -1.4790625586389043,0.8650510937800265
266 | -0.8799725179342051,-0.5399336795861742
267 | -3.0030850720745783,0.29375365816557153
268 | -2.0348009155921654,0.09775973277538091
269 | -0.748685159550933,-0.4843367139399721
270 | -1.8448950497911172,0.015463076434006434
271 | -0.04707131962841227,0.2672546000977345
272 | -0.7798777198985898,-0.5109116574964637
273 | -1.8057111510482917,-0.1718452452271556
274 | -2.0671114067398624,1.0283866997668891
275 | -0.8148962783022449,-0.48254536250107827
276 | -0.2871024452915263,-0.21406217417718498
277 | -2.5604817120128973,0.9104707134423655
278 | -2.6498020217324716,0.7351789956264818
279 | -1.9551080358980826,1.0656513362732054
280 | -1.9816526334341185,0.3494650410836357
281 | -1.2611937047759274,0.822489858151773
282 | -1.2465984467521947,-0.4584478210778391
283 | -2.646011201854898,0.8132227029989629
284 | -1.1729234017765255,0.5706319527441479
285 | -1.169333868339593,0.5417296455091855
286 | -2.8521666658788067,0.5320215129416813
287 | -2.8148521957552863,0.5351631893635644
288 | -3.0069898235335657,0.26486899307294154
289 | -2.465541048718975,0.8623246045111138
290 | -1.323023914449378,-0.4592662060887773
291 | -1.5344103339943804,-0.33436832106567604
292 | -2.955803287598572,0.2616474124252995
293 | -1.912181007626615,0.34743012850440863
294 | -2.7505284071679723,0.7290454577463904
295 | -2.1125813279192065,0.985690747250452
296 | 0.00444438693489646,0.48298088281293894
297 | -1.2770880059445582,0.708049724850664
298 | -3.016493672290941,0.08444662354994087
299 | -0.005715784242641853,0.16392979834326235
300 | -0.990165481731055,-0.5493320922748383
301 | -1.1724373686314866,-0.5180121246729897
302 | -1.1230599048710073,-0.46797496361851687
303 | -0.5684622962882262,-0.39119526520847864
304 | -1.6642678877902728,-0.19271909955546848
305 | -2.0738618986946364,0.49188930403672676
306 | -2.3000845211374155,0.976068327459238
307 | -0.4901344503558558,-0.4707326551827808
308 | -0.10239719493283128,-0.10956045419270206
309 | -1.9512467973685963,0.20004511501019742
310 | -1.0141977194728122,0.13876625703668952
311 | -1.8834048837013437,1.048235640004648
312 | 0.08388920961627022,0.4048564570987999
313 | -2.8256557836416185,0.5272193612270875
314 | -0.4214511877493847,-0.21744161752032473
315 | -2.3835084676882095,0.9383728643963218
316 | -2.2045937113597116,0.9525327876114404
317 | -1.7612289631182765,-0.233986946241868
318 | -0.863815079980448,-0.4038238193934742
319 | -1.7622523938677626,0.965839247618968
320 | -0.769487014728623,-0.44389704834721727
321 | -0.10472786563756498,0.11920925466924044
322 | -0.03235849513483702,0.09380663231524827
323 | -0.9463926187246585,-0.49694899389365377
324 | -2.027414665849706,0.9284475425031758
325 | -1.440868649191871,0.8139232933294703
326 | -0.9333222327394333,-0.46490937448041775
327 | -2.2874168252728673,0.8429656163791928
328 | -1.0498944489920525,0.19135498935535564
329 | -0.10249218317379172,0.01056948254293335
330 | -2.8275267432560014,0.5051041624911904
331 | -0.831047620936572,-0.6429080987068904
332 | -0.4145380718391569,-0.40922899831952364
333 | -2.800088857917638,0.5280072845984589
334 | -0.3711910100235032,-0.29395015418323056
335 | -1.347776571363154,0.7451160628437952
336 | -2.1938526547664874,0.9730812504595999
337 | -2.063350162671239,0.4016847079349769
338 | -0.017127708432950195,0.31045874300431375
339 | -2.5891072310648546,0.7976840495631978
340 | -2.652544481657235,0.8228393293759243
341 | -3.025771243123462,0.10138468195334645
342 | -0.23450174656484024,-0.07527171734053854
343 | -0.10120662226750943,0.10841175558537197
344 | -1.6302077270519075,-0.28381372053955656
345 | -2.850697003911889,0.38564972881636816
346 | -1.1140686839535476,-0.483780376969181
347 | -2.8395237201467856,0.5262651154601811
348 | -2.9491666988651044,0.18583917446922157
349 | -1.0118788111146966,0.32434668946233497
350 | -0.06294626066048536,-0.016440650804748116
351 | -2.898229005419747,0.10151300469753727
352 | -2.0536021533279287,0.1456130653214633
353 | -0.40882895462123026,-0.3147825097498772
354 | -2.2655769179400753,0.9493400508949118
355 | -2.932060232395215,0.5624302175942028
356 | -0.8207859028343891,-0.4373904368674212
357 | -1.195259965396834,0.5337774911457596
358 | -1.342506151780106,-0.48655878239421746
359 | -0.995648693058452,0.22939525705232267
360 | -0.19557376612114052,-0.1516928460376192
361 | -1.8969394053038862,0.08222188499380562
362 | -0.5743852379469281,-0.47328079760235225
363 | -1.5927807132736826,0.9708518478923873
364 | -2.8657660645089473,0.4299669257571747
365 | -1.1772278822826592,-0.4920824933879314
366 | -2.130601497044785,1.0623197368425898
367 | -1.8612826813074985,0.08965191221699671
368 | -1.4960128203914755,-0.39502196997213257
369 | -1.1835080200294064,0.6022694993796934
370 | -0.41197344070935027,-0.38445828760122785
371 | -1.957625998715637,1.048451735116386
372 | -1.64426311617742,0.9669969796425252
373 | 0.031100421351953678,0.4700594673390975
374 | -1.0174484521327134,-0.45499789486702574
375 | -0.7096691550263963,-0.5231803011830302
376 | -2.4730585051102416,0.8444070497184237
377 | -0.03470295995349715,0.1491384608613015
378 | -2.028613057004177,0.4905909462665313
379 | -1.0432801312981794,-0.4419822305861525
380 | -1.8533275025536327,0.1105383373678087
381 | -2.818064603103667,0.3817178068194046
382 | -1.4318004454189521,0.8116970527712951
383 | -1.9592932730324915,0.26129457552947283
384 | -2.894341883227184,0.16736697539928633
385 | -1.4040646756670019,0.8283757971289871
386 | -1.1040541456368445,0.07345853005886999
387 | -1.4725764205248977,0.8858510930158033
388 | -1.7363949484526768,-0.19999800595525688
389 | -0.38332968915379184,-0.28463330410627613
390 | -1.1279101297977325,0.48635379404284784
391 | -0.3094359378253715,-0.17329054439434724
392 | -0.581823051953104,-0.38848139955541294
393 | -0.09948921542907718,0.1931957097214178
394 | -0.2484141598839329,-0.10930879189822526
395 | -2.001076842872787,0.2503990404309993
396 | -0.5165176616484017,-0.3698329326948771
397 | -2.1776234836835613,1.0010324785253524
398 | -1.7505871257405994,-0.15929420878471123
399 | -1.1542325848593762,0.568241843740042
400 | -1.6680916825818084,-0.31942523275363865
401 | -1.5159685250049137,0.8748638196563275
402 | -0.25869882256269316,-0.18668920349064827
403 | -1.506646378484724,-0.3441846707032457
404 | -0.2031788278471358,-0.23225066122767396
405 | -2.964187080561441,0.34981762986403997
406 | -2.36139183567404,0.9748552229048203
407 | -0.00909708061961223,0.37482256990879
408 | -1.1108902560032248,-0.5018590678348256
409 | -3.0531165323947422,0.1422929330781143
410 | -1.1170822541962724,0.4566763359574635
411 | -2.9107976697230873,0.2425870236279298
412 | -1.3568349586177013,-0.3876708277156068
413 | -2.320136126850727,0.8874151861387104
414 | -0.14834999955662354,0.0006077266550730716
415 | -2.505508678804239,0.8365750982075574
416 | -2.9006364185623528,0.4180687566228986
417 | -2.00094163444402,0.36619031696876303
418 | -1.7526406083325246,-0.11753941952270941
419 | 0.026213384847641574,0.4725076547069784
420 | -2.000638326096388,1.0368113901524414
421 | -2.6993730272241767,0.6396734169162216
422 | -2.8295048539238086,0.6417938435093801
423 | -1.20748691677972,-0.5018607136048476
424 | -0.9982394002745643,0.1482740850071686
425 | -1.9595674905340257,0.9997091909634408
426 | -1.0401594520982074,0.017877867212002845
427 | -2.7074525563502014,0.652580120492074
428 | -2.617619209591482,0.7844629819509386
429 | -1.9902883702017153,-0.055073761083357375
430 | -2.954420947995634,0.2537242117932924
431 | -1.9992396733605047,0.42052560909627323
432 | -1.3301807651376114,-0.3987620683304959
433 | -1.3385785335600577,-0.467357726735834
434 | -2.2759588422022876,0.9719138630540386
435 | -1.3326376688856305,0.7266565743042506
436 | -0.7985447027211192,-0.42457885161301473
437 | -1.3169860042111612,0.9290462005710205
438 | -2.0345249292687253,0.5359458200001928
439 | -0.3845332315711891,-0.2740296763210419
440 | -1.668112719802882,-0.3493928792342428
441 | -1.2306980391522684,0.5891803643354819
442 | -1.9201883155439705,0.24324476300255152
443 | -1.0018994593780863,0.30037666407369557
444 | -1.7780319206452952,-0.1102884482284764
445 | -1.6909216425025972,-0.3188806445156344
446 | -1.7921265627379481,0.9310768868930452
447 | -0.6426352737634042,-0.41504434902043075
448 | -0.329367831693252,-0.28224214666388125
449 | -1.8459450924178982,-0.06922474753824864
450 | -1.3091565036631108,0.6652464345574525
451 | -1.2735596702149405,0.6936118660096489
452 | -3.0247306984675637,0.4356613694370174
453 | -0.17803701474232092,-0.08657476353706746
454 | -1.025499313554207,0.0653421749664487
455 | -1.8648275080018912,0.17167948760519353
456 | -3.018406607107652,0.12460364335261154
457 | -2.444273462018608,0.8750051950337625
458 | -2.0795604721706518,0.9583131682102826
459 | -1.98158594869186,1.0565407817968315
460 | -0.11920173437549586,0.11978903419352266
461 | -0.6454438580683746,-0.3732182762774229
462 | -1.707457222997958,0.8303319912796052
463 | -0.5276386495400853,-0.40520540245689807
464 | -2.6410737279318015,0.7575937759125884
465 | -0.9565212320327814,-0.6004869892307175
466 | -1.4208509123879907,0.8703717964066674
467 | -2.4962290936442515,0.9697593145350379
468 | -1.699045340751306,-0.23278892369501858
469 | -0.14591481724859046,-0.041386869459403446
470 | -2.1499020472562003,1.0918247818235298
471 | -1.4895208983500445,0.8737876388762393
472 | -0.75022616295522,-0.495351834423986
473 | -2.7645226207306584,0.5142584607823864
474 | -2.8370041770722425,0.7550288462656409
475 | -1.9534612827495592,0.9508675369665703
476 | -2.885386224511284,0.288928757792501
477 | -0.33475790962955876,-0.1865916583360132
478 | -3.0456659912623296,0.13832044766428322
479 | -2.9939179949137373,0.0842278198211963
480 | -0.25310392249955704,-0.3127494351435451
481 | -1.5749504521166733,0.8803998138456213
482 | -1.2367782150324498,0.6983371437105936
483 | -0.43837841253069665,-0.34965015926430076
484 | -1.9287343786824438,-0.02992948624205022
485 | -1.9629224413949529,0.2048745525993244
486 | -1.0032628433336248,-0.42077662619191264
487 | -2.4696385780385945,0.9416014584236351
488 | -2.1949035287919214,0.9988242672047002
489 | -1.2928379716644405,0.7152031375025273
490 | -1.493494826316391,1.0147784640768471
491 | -1.0894180875271102,0.39729600671784576
492 | -1.8111204134710341,0.9655818543787543
493 | -1.5658011433549797,-0.37052437833046237
494 | -1.251556802561157,0.6279571405666167
495 | 0.07089777845177414,0.2655256763956694
496 | -1.9307637205304424,0.1853887761306248
497 | -1.1663333975334587,0.5099329077245889
498 | -0.388222979098074,-0.3353914900124973
499 | -1.9036962436018598,0.05056284686132628
500 | -0.060065311896446705,0.13698251253102978
501 | 1.332760308328785,0.767884877962312
502 | 2.4006615181983246,0.059619787265298874
503 | 2.3638609552522225,0.37317766303132005
504 | 2.078146348707939,-0.48627361705090516
505 | 2.2983901255261006,-0.5539275874192388
506 | 3.027572101300786,0.3876292188190743
507 | 1.9234539726052775,0.4785191358122062
508 | 2.5057009246605024,-0.1422811647103809
509 | 1.2418800208579688,-0.6510267376681378
510 | 1.2320304561269286,-0.5960473259836544
511 | 2.9399243803973576,-0.1474519082370908
512 | 2.514317184444614,0.03044219172377254
513 | 1.4828490887485266,-0.12350501185820392
514 | 2.312928716470833,0.48039026107615623
515 | 1.5656891863042581,-0.939292528543957
516 | 1.9137426170273657,0.4046197951743814
517 | 2.3400291678724865,-0.30330994431381864
518 | 1.5667329083638109,0.27002452103852226
519 | 1.2340864031126744,-0.6475090730418759
520 | 2.532578640470753,0.8844735188517859
521 | 2.419871089308644,-0.9388359626658621
522 | 1.546055717708307,0.08909939110526284
523 | 2.9018702375584935,-0.31602576245473224
524 | 1.1245826869495108,0.40639690908597054
525 | 2.419094213581651,0.9587142427648327
526 | 1.949941729503839,-0.5364944097451493
527 | 2.8446794267337716,0.5083407811016145
528 | 1.5079639012433477,0.08551063063770814
529 | 1.2509775344710357,0.660646603619693
530 | 2.874125751257406,-0.4550252304209883
531 | 1.895476319374335,-0.5303616206071134
532 | 0.9575679025112518,0.1594084464189912
533 | 0.9924324599085093,0.13796627030824785
534 | 2.052616182757931,-0.9489705728946978
535 | 1.5375173220685816,-0.046882200038518125
536 | 2.5285901750622535,-0.15904902226686948
537 | 1.8858864794351302,0.5299607125382636
538 | 2.078615243089607,-0.44894854485613644
539 | 1.5403022142157932,0.34556485479014143
540 | 3.0082900147124434,-0.31971087176960444
541 | 1.8473586209367037,0.42511199630263097
542 | 2.3808603040990333,0.901223397861692
543 | 1.6005440672746918,-0.31569278802110395
544 | 2.774867220310626,-0.6485291445845931
545 | 1.628973259281691,0.8711009622027854
546 | 3.0679107816884237,-0.009342363784159407
547 | 2.5652903030607677,-0.8276264504859322
548 | 1.7533380253046937,0.45162955794555243
549 | 1.7406652432169363,-0.41012769830030105
550 | 1.1973948174132252,0.5465828911885827
551 | 1.5691601463323936,0.16551903997858056
552 | 1.5734366028547992,-0.8967806440511082
553 | 1.6436406724145274,0.3404120367422808
554 | 1.098476874341757,-0.5159804271949882
555 | 1.0294577507366096,-0.22467923952175511
556 | 2.9969461079503246,0.2845686525689875
557 | 1.8242688097258792,0.4918563100423538
558 | 1.675753844539896,-1.0128601128882848
559 | 2.783645214839637,-0.5639213520905659
560 | 1.577428304967875,0.3881205824488401
561 | 1.5074426930080893,0.8739518646526778
562 | 2.398926726915927,0.221129393731205
563 | 1.473292190742471,-0.22211254116169687
564 | 1.9278982494229042,-0.46731687037321007
565 | 2.1708741451276214,0.46812713948293017
566 | 2.1943355224841947,-1.0580918330007452
567 | 2.9539912929912377,0.21061527657427362
568 | 2.3986640348192596,-0.2942698915665458
569 | 2.5052906443751266,0.294439197790942
570 | 1.6610503087789033,0.8952616669971338
571 | 1.1282271883972586,-0.39656094011966964
572 | 1.848782557936835,1.01580081806546
573 | 1.7220139962500485,0.3882029008469761
574 | 2.450863240132468,-0.23606925779941904
575 | 1.618656270646883,-0.9110416188281522
576 | 1.5109951252640423,0.14879847182642
577 | 2.5560029881728936,0.20654651693021805
578 | 1.2095242556891077,0.594888342551835
579 | 2.563263179431577,-0.026155915103880614
580 | 2.2593649013565127,0.481524755802906
581 | 2.0497783436271666,0.4817143538592521
582 | 2.923271138178566,-0.36342689121539945
583 | 2.4516608015535994,-0.4308764845057145
584 | 2.6830700745357765,-0.6891547520518109
585 | 1.7637680769148254,0.38156822057669676
586 | 1.8770384020833464,0.4853388632387386
587 | 1.7499915536209443,-0.4418797260846676
588 | 1.3474259797896848,-0.7200443925729388
589 | 1.6507970893880382,0.3177586894034334
590 | 2.192245660789337,0.9192970977481978
591 | 2.7246720890728313,-0.6748324590263997
592 | 1.6545604872958548,-0.3196010540697117
593 | 1.5253952718203996,-0.09841145811229401
594 | 2.269885536583571,-0.956575981246498
595 | 1.7352614668786943,-0.9362557317019593
596 | 1.5245770663356235,0.05161819098358897
597 | 2.179582371455681,1.0877381222821079
598 | 2.007952050366317,-0.6090854284891637
599 | 2.0727555293741364,0.9954965513801882
600 | 2.466851389422771,-0.9191252476374643
601 | 1.0786352723435215,0.44618268811182393
602 | 1.696421356723779,0.5359206335750938
603 | 1.739967670996288,0.9376122554328099
604 | 2.2825641973231914,-0.2913909280962257
605 | 2.887831413347926,0.12325285745203199
606 | 1.6872639817432127,-0.4362698907277826
607 | 1.1320790891260826,0.3467613011428099
608 | 3.0046907014689532,-0.38876386410201264
609 | 2.2228394754872216,0.4962953152636303
610 | 1.3096016700124307,-0.6330751644895504
611 | 2.3800590785993934,0.24137143393175278
612 | 3.027694135095628,0.04224210432652942
613 | 1.1208018593820173,-0.26938497836665587
614 | 2.977569854351235,0.2107353633022657
615 | 2.2474557273633105,-0.41828066066489356
616 | 1.9861190715686998,-0.4303296142320146
617 | 1.6348112026281791,-0.003696233314020696
618 | 2.295365229536228,0.35141399207105245
619 | 2.4849247012146285,-0.8482206632990575
620 | 2.031702661383966,-1.0016331582304139
621 | 1.9611266849904276,-0.5028544154315712
622 | 2.3154470118980583,0.9139271120498481
623 | 0.943841400901698,-0.3026591471648039
624 | 1.4567505229038,0.18941634716566547
625 | 1.7559766619333628,-0.3394214220389425
626 | 2.8954170888563606,-0.3713831700066262
627 | 2.0548483805440387,1.0049245568079739
628 | 1.6691666751408487,-0.29892637710102204
629 | 1.5540980598574257,-0.10855339438581973
630 | 1.679939909407417,-0.4387981769703994
631 | 2.380827332169404,-0.22851084424711143
632 | 2.876029315242091,-0.5480592145034425
633 | 2.2367266709376636,0.5331549887191012
634 | 2.0689019693243944,1.0254898657535712
635 | 2.123371763149579,0.461220565971991
636 | 2.545535108773999,-0.12110213826524843
637 | 2.1823792121139336,-0.4643634375486515
638 | 2.2222696937971214,-0.4502578524069737
639 | 2.1797447057225674,-0.46803274238269466
640 | 1.9729838197755742,-1.0597181553272503
641 | 2.150536173701373,-0.9107728856900827
642 | 2.241609235132771,0.9431898341755139
643 | 1.7688906027157358,0.8305625557001711
644 | 2.8530593287122494,0.576335109794347
645 | 2.485628700995951,-0.14370472299245768
646 | 3.04207442294232,0.0869819775394475
647 | 1.8972035655794586,0.5601230023808805
648 | 1.6575997010979249,0.4479374211608941
649 | 2.924718430183022,-0.16341190297713173
650 | 3.092677535387635,0.1231034622415114
651 | 1.089521637491699,-0.4804518096224822
652 | 1.4736202408681418,-0.09002712022076438
653 | 1.04915472352703,-0.21784555944519107
654 | 2.4927135622104815,-0.06116131906490502
655 | 1.0255301953711702,-0.016160215022293978
656 | 2.8528447678901996,0.5635697503479309
657 | 1.891703700352088,0.9722684851981117
658 | 2.836025354666895,0.4258380778856337
659 | 1.5011651321583268,-0.03085753550965195
660 | 2.841143652579794,0.31164833668804215
661 | 2.3242311327343854,0.3627758568467472
662 | 2.7813015130463823,-0.6113171352002129
663 | 1.951462338833233,1.021559135185329
664 | 1.486054677723561,-0.227419947300375
665 | 2.9153020433829204,-0.4376277127378856
666 | 1.5406397324934074,0.8396395931176671
667 | 1.6205938062101501,-0.2850033721705234
668 | 2.1069191090099046,0.47185424588786
669 | 2.453334269515434,-0.021494502326034982
670 | 2.2954491054579167,-0.3121399926655341
671 | 2.165671221241322,-0.44050836884139416
672 | 1.2922778644379154,-0.8000161250692663
673 | 2.4199727706440495,-0.3456223055741109
674 | 1.5247435578639617,0.11751858961466638
675 | 2.4103576986001887,-0.11534299513122333
676 | 2.4786392202941405,-0.8490636248736975
677 | 1.91208598541356,0.5135810627059589
678 | 2.2962114406356218,0.9750029381237627
679 | 2.145617782951456,0.4179930521932204
680 | 2.2120289759747065,-0.48626491900719704
681 | 1.7534350872047517,0.42603312669472315
682 | 1.424367027678748,-0.8919057087849638
683 | 1.1210305111493355,0.5431270122609309
684 | 2.4412615733843346,-0.22985918244749864
685 | 1.9530690082588142,0.9940473168829106
686 | 1.6675404826970588,0.33281286286420747
687 | 1.8468890448024515,-0.46252759240847463
688 | 1.972944852844015,-0.487019904966451
689 | 1.9473254325702087,0.5591410524483186
690 | 1.3776212865458182,0.8546682941269544
691 | 2.058003514265752,0.45014989008335476
692 | 2.093611571607816,-0.49077644004029786
693 | 1.3577934688169375,0.7166946745099064
694 | 2.1481730614737358,0.5447766302307341
695 | 2.2715649912909206,-0.5447930418863632
696 | 2.0722862237513753,0.5228076859885475
697 | 1.5731270927016234,-0.21839123203925806
698 | 1.3213034114328264,0.6715933238759372
699 | 2.8808700514053482,0.3898349768731183
700 | 2.2142044607501785,-1.0285350562883875
701 | 1.1463177745881188,-0.476858866831084
702 | 1.3022589237449402,-0.7699800137446935
703 | 1.1898118503739803,-0.5338255158868489
704 | 2.3317509228214717,-0.23296777477533587
705 | 1.4799870597508193,-0.9644130469184979
706 | 2.398772196499041,0.017027442075387533
707 | 2.887282157833516,-0.46210052740271074
708 | 1.76316137360521,-0.4116875538465668
709 | 1.9832979782750622,1.0159379383910006
710 | 2.014355464884966,0.5542877637971046
711 | 2.536349234913474,0.08103377333171226
712 | 1.0374003303631718,-0.509852277948413
713 | 1.2823069534457563,0.48672502895425973
714 | 1.941783403970248,-0.37776838769901666
715 | 3.015265794419736,0.09770664185768134
716 | 1.587213767470402,-0.45763990641577235
717 | 2.8834708310860178,0.4689130677150092
718 | 1.1187641104247992,-0.5433550176893357
719 | 3.0095825537805485,0.028966665480526215
720 | 2.4013021425437033,0.09994465519743716
721 | 2.6895351646959433,0.7392790246642933
722 | 1.0497134047113508,0.37955960604584726
723 | 3.0439811865521698,-0.07708156437141624
724 | 1.2122594101097464,0.5357494805978895
725 | 1.600269618663922,-0.30827481075208923
726 | 1.9965789270716026,0.48449350917394246
727 | 1.781369872327923,-0.9635858633282459
728 | 2.9547939476142187,-0.12357859942298967
729 | 1.0765626564928565,0.19664372727854454
730 | 1.5099525254921353,-0.9078058634166348
731 | 1.7412828772275173,-0.44143845076978805
732 | 0.9277934962368952,0.08097418647205207
733 | 2.434374383717721,0.19864193698142035
734 | 1.0935353971107078,0.35030657877720056
735 | 1.5098438411926538,0.1432726992426403
736 | 1.9432288601524756,-0.5516073693417195
737 | 2.471686672485753,0.24788843002538336
738 | 1.0661727551676046,-0.3371795504169516
739 | 2.057573344954579,-1.0474268255529582
740 | 1.5598972963701445,0.26651816573797404
741 | 1.9251121424922195,-0.9933353653233478
742 | 0.9620307009927958,0.002659252760806082
743 | 2.3562853043329577,0.38732667286650724
744 | 2.4081556455061173,0.04030235431298485
745 | 1.6918080889487166,-0.44323442699968163
746 | 1.57270713843798,-0.13374880468405848
747 | 1.5672954062358473,0.29288189766912104
748 | 2.9329337740819166,-0.47249105152646137
749 | 1.0221332843450779,-0.27805971605748736
750 | 2.6527676562658984,0.7507975161064857
751 | 2.4479213235011037,-0.2824038683009827
752 | 1.4380942034496393,-0.8567122955186449
753 | 2.6515008920252128,0.7552153499617577
754 | 2.540862778424014,0.8831330913412596
755 | 1.212606657088843,0.6481235227616217
756 | 1.4182175327775064,0.853965617955276
757 | 2.0194374218426216,0.90972309523853
758 | 2.2820899349132837,-0.9743989437138857
759 | 2.3680814606797864,0.21520117559474036
760 | 2.768121103916529,-0.6942438374741211
761 | 1.769754853346661,0.8983068025541218
762 | 2.661268908194801,0.7779357218447932
763 | 2.144701760428584,0.5069472975427782
764 | 2.6779521091489915,0.6639418268563533
765 | 1.4927395281518048,0.16981725687301744
766 | 1.5000769683124107,-0.14156427213959222
767 | 2.025946525920102,-0.5401778206716024
768 | 2.679062128448202,-0.7913680708283738
769 | 2.75722913644538,0.5861931314138025
770 | 1.6587923043802668,-0.2443442832218196
771 | 1.5010691734194914,-0.08222746939085296
772 | 1.3355102035194706,-0.682389765782705
773 | 1.9188990652731155,-0.4899436736513092
774 | 1.5511041849007225,0.3366502538363666
775 | 1.0262771990448023,-0.28869084613421564
776 | 2.628164825071977,-0.8492368029552426
777 | 1.1594958445210173,0.5904171515200466
778 | 1.5621058667839984,0.3779887131498935
779 | 1.5844001349293766,0.33415392149752343
780 | 1.5876764205936942,0.28420941955688134
781 | 2.595540087653293,-0.8000723979640105
782 | 1.4823224051177144,-0.10799681381220463
783 | 2.05419193839545,-0.8879922560536763
784 | 2.6864090634048905,-0.8117805942435428
785 | 2.4191499165034718,-0.8653852735813297
786 | 2.9217619385827964,-0.39485574575954924
787 | 2.489842183531783,0.15549921191511198
788 | 1.8447275889862567,0.9773278370789997
789 | 2.8470542548707516,0.5828413027044643
790 | 2.6685648937457764,-0.7727414390512936
791 | 2.8270890910241504,-0.5209979489304734
792 | 1.02536975770251,-0.11002054992870716
793 | 1.099053156790853,0.31768629133686754
794 | 1.4480759489833486,-0.8558862188129664
795 | 1.6244964975773568,-0.4927893955173633
796 | 1.5385336827971854,-0.29745937321812954
797 | 2.48419463988439,0.8224905086291147
798 | 2.3296180341376833,0.2633308847503867
799 | 1.5235338659901723,0.21982814374471724
800 | 1.6548027658110382,0.9238663934455609
801 | 1.9947700811254268,0.5049332449534436
802 | 1.9799743789913997,0.4481764317836473
803 | 2.9413595387562044,0.33638117189904015
804 | 2.2304144924016063,0.4440661385762309
805 | 1.7257759238464314,-0.4086944897905213
806 | 2.482258982796302,-0.11902231170088205
807 | 2.885963505974083,-0.5782357443335908
808 | 1.37101653639752,-0.8292344275270027
809 | 1.509820372302273,0.7804722910950397
810 | 2.564902532248592,-0.08589372397427956
811 | 2.3922258849393256,-0.3244718328838656
812 | 1.0321177885156236,0.323735545852881
813 | 1.2232873295491955,-0.5935509787818535
814 | 1.2350962076648422,-0.6677662055604194
815 | 2.8878727757734826,0.4149860243415949
816 | 1.7375906182603886,0.3843783959519584
817 | 1.0086721590521077,0.4912714708247026
818 | 1.5384085145672186,0.19611780338354523
819 | 1.1909873717345336,-0.36484453786706406
820 | 2.874011670581674,-0.35511559814664306
821 | 2.5026688253654292,0.13386052146212438
822 | 1.7332219320923046,-0.355784532069234
823 | 1.9174928236635904,0.4375713257394266
824 | 2.5440920205802717,0.00378652554483222
825 | 1.554616847931715,-0.3639599907982022
826 | 3.0502588699767976,-0.15261049883266745
827 | 1.4576550812371263,-0.08810366025615085
828 | 2.885368821412425,0.4463829931918535
829 | 1.8277512825638182,0.4548998822399586
830 | 2.136518881748677,0.5214243536107681
831 | 2.510318927051113,0.24005655849964191
832 | 2.825789298400028,-0.45028770882575364
833 | 1.7077405495051141,-0.4282767986896084
834 | 3.015382962722639,0.14889290333504962
835 | 1.5810590875905672,-0.05059203434780496
836 | 1.0154165622979674,-0.06890417335320373
837 | 2.348885508314895,0.30025903319037905
838 | 2.258588218930218,0.47722305188167585
839 | 1.603973788196442,0.9077486470560393
840 | 1.9304412428450997,-0.9312423457944933
841 | 1.8576459840579487,-0.3335275122453532
842 | 2.4150306211085133,-0.26026135135564715
843 | 2.4182885308866764,0.3656450954856943
844 | 2.249553555600497,0.4411092270562744
845 | 1.9337804789196888,-0.487422563522213
846 | 1.9322769508799604,-1.0109805153795448
847 | 2.1446966794326916,-0.4735084770230948
848 | 1.617396691353993,0.864589365434126
849 | 2.1862274968686473,0.4312726574969127
850 | 2.4716499716928215,0.1467596173024858
851 | 2.9768643302107916,0.31445124347138037
852 | 1.4777193748102218,0.046440608291590434
853 | 1.4437359826937528,0.9090588799226079
854 | 2.4946373749020876,0.2355204388368348
855 | 2.5849633084634944,0.8347325640647715
856 | 2.449432423200372,-0.17141957126696128
857 | 2.213559392619405,0.9782730217186582
858 | 2.4941243772592534,0.8143244066385338
859 | 2.430974364436116,0.22177556460333847
860 | 2.326992214353498,0.9438281754484668
861 | 2.4963595697424257,-0.8042973993872597
862 | 1.5276087475450815,-0.24093191732308072
863 | 1.660990918766231,-0.34903819614439646
864 | 1.8120433104453582,-0.44391824076802966
865 | 1.02331468875764,0.05918396146642865
866 | 2.722471391034293,-0.6350165860823475
867 | 2.027022065147293,1.020564585226125
868 | 1.4907115768559889,-0.02041254407437738
869 | 0.9505047514433653,-0.14323893733829712
870 | 2.015232094102137,-0.9552973498372396
871 | 2.8164122988358784,0.5516300482059333
872 | 2.482106598421536,0.8923652237701749
873 | 2.070964277540391,-0.5889706860907648
874 | 2.9975337964926214,0.011951680062338245
875 | 2.2828030270753015,-0.8592912505423289
876 | 1.5157957960973056,0.1656817667390844
877 | 1.8179642176733581,-0.5246259005849543
878 | 1.2327503094812609,0.5437569431492677
879 | 1.613753080207387,0.30882611044744857
880 | 2.1567868190381323,0.5236861288423516
881 | 2.4526752850031204,-0.21534663764211673
882 | 1.8491162640434406,-1.0112374839429317
883 | 1.4533978997775696,0.0208699915873063
884 | 2.5501911381457902,0.04916778433913593
885 | 1.2507790994816848,0.7095344610940165
886 | 2.3083647593464804,-0.41916139442720685
887 | 1.3087309459275123,0.7378128805335883
888 | 2.105694067883734,-0.45845967177694424
889 | 1.5717480604664698,-0.9826358241493554
890 | 1.9208253751239648,1.0017854047257457
891 | 2.1240984786728943,0.5468917415117145
892 | 2.4280795038573504,0.9552488430220717
893 | 1.6934844300883043,0.3471644764950659
894 | 1.5022860092539294,-0.017585903950832895
895 | 2.434706905558238,-0.9269699465506627
896 | 2.3651693781622267,0.38546059311312636
897 | 2.9960767787066507,-0.5369193648568732
898 | 1.0950513055700521,-0.4831451802414562
899 | 1.0855555546098277,-0.47014619634978266
900 | 1.7532727070053995,0.36673209811901475
901 | 1.8237418436147057,-0.9867060268886465
902 | 1.5608506709340015,0.24886074302120254
903 | 1.0147228681241263,-0.1494086849151127
904 | 2.3030020776610307,-0.38739959405003577
905 | 2.447794355287246,-0.0966217220241571
906 | 2.4743503697647107,0.07688401629181206
907 | 1.8618669423110954,0.5261982382928034
908 | 2.4101346791176037,-0.9774857271757316
909 | 1.4425473436206175,0.8739417209436899
910 | 0.9849840927620244,0.08452895009860963
911 | 2.4795479498455832,-0.2679222179983489
912 | 1.9360126662290693,-0.5380709283758163
913 | 2.2157569225877305,-0.4650178721845657
914 | 2.235326326324152,-0.4550295668363377
915 | 1.4687785321649578,-0.12369046085434043
916 | 1.2614738788909343,0.7175857403569204
917 | 1.6367747945780318,0.8777790339516658
918 | 2.4916359316940175,0.20391337173941793
919 | 1.0287567170241765,0.18338849360471582
920 | 1.4897161847811786,0.20564097763294398
921 | 2.336163026611578,0.3889883005941616
922 | 2.109468297998027,0.9750768618283011
923 | 1.907447648697785,0.5148799549663908
924 | 2.5556527500055353,0.11248644116107101
925 | 1.4970552490684335,0.050393308758871914
926 | 2.141209106068106,-0.5634180375969475
927 | 2.6190457535660916,0.9586798240793624
928 | 1.1152826088177827,0.5006491791886389
929 | 1.5926687850024197,-0.16908184453844888
930 | 2.374183993579363,-0.31352763500051317
931 | 2.368022724634349,0.24308058068799146
932 | 2.127389002487971,-0.47030224824649247
933 | 2.623762531437965,0.809710849984498
934 | 1.5161828106253514,-0.27225343536642727
935 | 2.1791989756983527,0.9739850376475986
936 | 1.8283382151956753,-0.4258546079062249
937 | 1.9873048813569385,-0.5135491004264429
938 | 1.0137000813713,-0.07141624647332519
939 | 2.338140673236484,0.42948600127492004
940 | 2.688380212901583,0.5834280548178284
941 | 1.9630815819746972,-1.0521693335925124
942 | 1.5421675219944377,0.049247980021682985
943 | 1.4139393818826083,-0.8230458898556049
944 | 1.2670788493251246,-0.6175723891218037
945 | 2.9869857805956563,-0.22676576399073142
946 | 2.366746404298651,-0.9077768171077091
947 | 2.7234929562419747,0.772544782853186
948 | 2.6964118735518166,0.7352578976938579
949 | 1.0836882439073916,-0.1277450276476768
950 | 1.9144182130807184,-0.9267187908273082
951 | 2.41129077112626,-0.30835454802232065
952 | 2.1841421682082123,-0.46290758405263677
953 | 2.370366223087747,0.4270575838451279
954 | 1.8337874159381387,-0.4592165375220239
955 | 1.5908791777564484,-0.3310480374079279
956 | 2.2627252607681836,-0.4534426987647982
957 | 1.2401012730983285,-0.5289571534907169
958 | 2.3397579090831275,0.39758673070096134
959 | 2.2970150261210156,-0.3275188489421264
960 | 1.8344116757381042,-0.9661204998162662
961 | 1.1909856620728934,0.5901788611418366
962 | 1.6064294138053734,0.3918928352502876
963 | 2.142970658945365,-0.42995292315762274
964 | 1.9666838044600548,-0.5141679262257687
965 | 1.7182454527718074,0.47835922803172953
966 | 2.2278258021700807,-0.9971332099024548
967 | 3.054190257000919,-0.12314377562274431
968 | 2.3098693961338803,-0.42283308845724277
969 | 0.9308228229091335,0.278175067443591
970 | 1.5822109411603,-0.4311425341741635
971 | 2.5441292693115765,0.21646066589283341
972 | 1.706550593320427,0.9109116637667111
973 | 1.7971844183344352,0.39119334650796933
974 | 2.8738244877513415,0.6186082179237808
975 | 1.491003031049345,-0.8240931527213002
976 | 1.7207861918900615,0.45219518531744746
977 | 2.4323489672167176,-0.202890191824923
978 | 1.7047777848608736,-0.9148410499635582
979 | 2.409617588563504,-0.19734194495247157
980 | 2.569515791759146,0.8101951637438178
981 | 2.2265232187333046,-1.010119085434357
982 | 1.9730439862861981,0.5381162452291598
983 | 1.584564928565328,-0.25907532367811886
984 | 1.3642703404984435,0.8166426877407148
985 | 2.4331760775246436,-0.29957321957981076
986 | 1.7737095093414692,1.0691259985775243
987 | 1.3500984020759375,0.7372049686270443
988 | 2.2943915319970074,0.44638390126489735
989 | 2.9523801250690447,-0.25463851689217365
990 | 2.5052711427475267,0.3197002242531224
991 | 2.583585675030477,-0.8147016443339034
992 | 2.996267270673135,0.2512754839756215
993 | 1.5765052768048087,0.17692571338056756
994 | 2.172799215268133,-1.0693383911466336
995 | 2.460826874316573,0.026120687544004484
996 | 1.9218304156301862,0.5126427957354461
997 | 2.095821767679585,-1.056769956124266
998 | 0.8812769903443816,0.257296679253447
999 | 2.350317646196294,0.9026539565242551
1000 | 1.6267996028736023,-0.9953552092040525
1001 | 3.3989696696610556,-0.7832338621877653
1002 | 0.22800590749390537,-0.8284746284781987
1003 | -0.6649259723156158,0.36238922127097517
1004 | 2.0956865771529642,-1.9677119212076568
1005 | -2.289032208990289,1.212452294804054
1006 | -1.8826417644228304,-1.550400887566688
1007 | -1.3438155001073433,0.719594498238727
1008 | 1.2172442329062907,1.3961942753607337
1009 | 3.5261163928099597,0.6920919923318438
1010 | 2.8817886948056355,-0.9492515164033044
1011 | -0.4597857728632908,-0.7284413287682212
1012 | 2.154349931173768,0.9922216692297772
1013 | -0.7894322197277166,0.6659132251293576
1014 | -3.895536556962096,1.626306533314923
1015 | -0.6174173000214536,1.6251689515242767
1016 | -3.635706421033861,-1.6657818760112715
1017 | -0.0009350549647777484,-1.111562043313191
1018 | 1.8414206411053478,0.7315524062091039
1019 | 1.0453403589551256,1.3639733756824413
1020 | 2.772641390608329,-0.9170567802471483
1021 | -2.233087461319447,0.7098907918738155
1022 | -3.1255289238569164,-1.1910145418226659
1023 | 3.119259541134313,0.5695653392928737
1024 | -2.4280376242563477,0.7388670978109042
1025 | -2.5064927708240985,0.5510016650407104
1026 | -2.264223802713727,0.8545791486068537
1027 | 3.8577216621212145,-0.034000929586839757
1028 | 1.2946824730724193,1.9972588201736863
1029 | -0.788270607648105,1.2456139520200917
1030 | -3.182342942790001,-1.9530538494126137
1031 | 3.7256836823902244,0.43068630718669265
1032 | -1.0419141803007985,-0.17363440652541628
1033 | -3.156022914235793,-1.8862026482095793
1034 | 2.0525692074043844,0.14350272826317445
1035 | 3.192895041061978,0.44651862895828165
1036 | -0.25458724919873443,0.3855719142339624
1037 | 1.1306635359947759,-0.6501169490061676
1038 | 1.0458289046612803,-0.6426684733486043
1039 | 3.2625955237783346,-1.1093475166185884
1040 | -2.050056115231225,0.9605676841009738
1041 | 2.219186954877694,0.05911218130417417
1042 | 1.4776588930156098,-0.6592939118889656
1043 | -2.1497321018933633,0.5697361405386068
1044 | 0.2007088309668701,1.5670803112692502
1045 | -0.09759462435397204,-1.5644806237324613
1046 | 2.3267299324214665,-0.5191218727015796
1047 | -1.9904109214103824,0.16104163573481634
1048 | -3.1591842553792855,-1.7877705689154255
1049 | 0.9450537843871105,-1.8461819561818573
1050 | 0.8264444248777423,-0.9635222993345156
1051 |
--------------------------------------------------------------------------------
/sample3d.csv:
--------------------------------------------------------------------------------
1 | -0.3303707857536943,7.536620597158648,8.669944087353482
2 | -1.2925539632828866,8.600897824060738,8.306406109066085
3 | 0.5894524718495632,-1.9348475386556683,3.5199991651491493
4 | 0.7142509135062736,2.7021774441735333,1.312545379185153
5 | -0.11593029494313645,7.231813076936937,7.950138927657477
6 | 1.8165383715076513,-2.7093400997010244,1.418363542507336
7 | -1.0199196964423463,-1.4069116402843098,2.9624983478066587
8 | -1.7768128204121378,6.40436701413216,10.241538028932295
9 | 0.12738615296772715,6.036768273268347,9.665988496602761
10 | -0.949267300874044,7.942617082331774,9.227413375639761
11 | -0.3603431211673789,3.962115050514679,3.4748708282669827
12 | 1.392402610749318,-0.4812870521096906,1.8753928554367796
13 | 0.09487390910948446,-1.3132884156331628,4.56346793307918
14 | -2.4942312273399088,8.074607137001239,8.851022572787045
15 | -1.2600072253221652,7.567110389454105,10.075395955646783
16 | 1.4596468259243573,5.300526791475164,1.505465563349321
17 | 1.5342454387775812,0.6484094501984985,3.0226897317063623
18 | 1.7486330801697445,-1.672137469632936,3.5047101356766697
19 | 0.8168432355434565,-1.9348655552256937,2.3456081973170475
20 | 0.8629946366057156,5.642235377241478,2.401058482962208
21 | 1.1748765916023223,4.157980074855077,1.8361530702544302
22 | 1.6516686576360717,-1.7329488762788172,2.0665648560036383
23 | 2.0894684347376664,4.298262333722471,0.7557959065337314
24 | 0.8145206588531905,-0.6656661840593543,2.7806725655986204
25 | 2.17653320726639,-3.071980343266479,1.9706523819720871
26 | -0.9748810771439846,8.51492411464001,8.53144990588736
27 | 1.630768203779938,4.765118374033277,0.4006762949620577
28 | 0.846024912368164,-0.001642917389998555,1.615308624709875
29 | 1.1150109407213769,-0.6485218277126037,3.182948147560719
30 | -1.6178879593314195,7.537454036678453,11.023048152589862
31 | -1.070470812802588,7.6863191432233355,9.794861518080722
32 | 0.03646464480548939,4.860131484801619,0.5930972041607037
33 | -1.014778698170024,9.399579782495433,8.97136299980374
34 | 2.950265211714207,-0.08233963498651775,3.11600663629979
35 | -3.3241256085674036,8.337885708142407,9.778088845476223
36 | 0.6989271294443895,3.8316510594439497,1.86993788473958
37 | 1.6084714927069508,3.754131426568567,2.5763932609418148
38 | 0.23188450047161258,7.931445463671733,9.577933350018474
39 | 0.6156751339991162,8.442002109892053,9.652790134983231
40 | -1.659297211514306,8.26132375513173,8.755427156058717
41 | -1.903172977372908,7.85137449132016,7.840143879830855
42 | 0.7145980115541462,4.124407634565124,1.362496944857809
43 | -3.8978467191186312,7.573907303684681,10.715789480892106
44 | 2.3580146061393013,-0.03388254273245761,2.1602192267445033
45 | -0.841787016630857,-1.497310953634878,0.8642063784874323
46 | -1.8680500635236172,7.778241085716392,9.034358893838146
47 | 1.9427514315947332,4.16989509285715,1.479499619563076
48 | 1.049127061383935,4.285233082305548,2.155304806243535
49 | -1.4308459337712358,8.663865999216908,8.410888545123187
50 | 2.262398789919716,5.175560817888997,1.0693075579352376
51 | -1.2153223594317013,9.315739059039533,8.58993306114643
52 | 0.15804911721780346,4.3864972632463015,0.7642090660859009
53 | -1.7722165129232588,7.6919137468864625,9.878141354895988
54 | -0.8747307309182996,8.041136564847172,10.243383786806417
55 | 0.9291406377390402,3.407860273888988,3.2573417274069323
56 | 2.999225136320893,-2.1470705102922722,3.0741860966176144
57 | 0.6672063774658278,-2.076927110059674,3.3977459039202325
58 | 2.0970170597140054,-2.5289123018657196,2.552930358650987
59 | 0.9144847446482237,-1.7841102510723563,3.083087808101795
60 | -0.37772526420414687,-3.1648818106220737,2.228043075681773
61 | -1.9173760232253392,9.156946555137335,6.824737975962103
62 | 1.0097090070551236,4.984354571803511,0.49177083133293586
63 | 1.2247441390273726,-4.749030835995678,3.478130968563987
64 | 0.6442396820807903,4.007686924544846,-0.16309323513103546
65 | 2.819961608574454,5.829294566110954,0.6097319398156849
66 | -2.11751889647898,9.43033617892088,8.942394524699962
67 | 0.7062265549583334,-1.69930258195263,2.9753994808837643
68 | 1.794705582441005,4.705937143013303,2.173323079759186
69 | -1.6727620492075963,8.460722264053532,10.043078920740639
70 | -0.9189565624726499,7.611420514417604,10.156061767728726
71 | 1.8102286474594569,3.6613777101811786,1.9552472661404285
72 | -1.7020620391889265,8.849468919754068,9.768942592776577
73 | 1.381205448455034,-1.0176787933511138,2.8748921033810277
74 | -0.3071526824502676,10.182507327282025,9.707164847392466
75 | 0.6352598880801085,-2.3685938289291695,3.5300721294281185
76 | -2.974122762469715,6.209391945720917,8.540083670960062
77 | 2.0222780466150887,4.405429309188346,2.6154308643213584
78 | -0.7819872049356255,7.602731457807167,8.691037615697857
79 | 1.2887498218998945,-2.1263931322299974,2.4702215821705495
80 | 1.3748558053793418,3.2506129475013084,1.4157912547382105
81 | 2.0084150568371113,4.843739759615133,-0.19599366594710776
82 | 0.7786781056426271,-2.466967879617492,2.487244141987521
83 | -0.19529614661476047,-3.7783645912728057,2.9330835426589763
84 | 2.0238554159643094,3.8798910938476396,-1.4595005976690572
85 | 0.9380053492695007,0.14415784323843983,1.9149567536648917
86 | -3.37038340302513,6.96882204013796,9.108284184758158
87 | -1.5644201246910048,9.24982454064188,7.87671761602605
88 | -0.619563727980001,7.731148518274843,9.638931332781725
89 | -1.9611670344407268,7.219577159548412,10.372581133835554
90 | 1.9755980502397656,4.343955525463904,2.563741510348608
91 | 0.05287892733704025,7.180403405661178,10.175291454766956
92 | -1.318901828319603,8.054643160832713,9.026295595780088
93 | -1.016526973742939,7.6502002661872,9.100222899297503
94 | 0.6416583312875379,-0.9841955695829803,3.2535179577948172
95 | -3.450406625027817,6.2695795597117385,8.873575816437588
96 | 0.1425917013529827,-0.5903384948363506,3.5843005315762984
97 | 1.9161670593444988,4.910176328190176,2.057028362147149
98 | -2.1722791374722834,7.20661808275209,11.302746589940973
99 | 1.055248381186757,5.109869659305214,2.574372440381179
100 | -0.8985100043565366,9.622223709956025,8.66194905831662
101 | -0.5889388505343169,6.464970748449763,9.908565144217327
102 | 0.7924731267390457,-1.1974337138227924,2.736687202242597
103 | -0.7491156430093182,4.66303691609052,2.937202475502567
104 | -2.175903529631451,7.036352472986836,10.18320851602305
105 | 1.224800705976186,4.272541992024439,1.9157935589432058
106 | 1.9234559844165944,-0.989430450579608,3.403293702633766
107 | -0.5303077322197348,8.33654915946697,10.325355891674226
108 | -0.2746161375108169,5.229038079198721,1.1504813632642419
109 | 0.3466281694574824,3.831528923273671,0.5419064841827865
110 | 0.9477303547566096,-2.006920390515294,4.318354016634489
111 | -0.1726194454422918,6.054177987733906,3.241685839140759
112 | 0.4051679931556015,2.3358591258155315,2.116150721832211
113 | 0.7503304228550661,2.649216560936163,1.4155448837206734
114 | -2.585379238368233,7.580801712108434,9.279368591166435
115 | 0.1094805102948957,3.7375966530924707,1.7788147730358463
116 | -2.8479591836874,8.14304864266637,8.378841855437411
117 | 0.9408385887864559,3.992626328818771,-0.5536741271497192
118 | -0.8298366101277269,7.967765761058856,9.399408014606413
119 | -1.4248188682647835,6.244936963298686,9.257465472851594
120 | -1.3161352625231288,8.110842130091271,9.736773698982093
121 | -2.9043217882953156,7.741809457445994,7.9721981853406385
122 | 0.6638285996814582,-1.5556928323790253,3.5489192249178214
123 | 0.7607427365817268,-2.1901193205507807,1.9837282527264768
124 | -0.2118722448668462,4.154373045208542,1.751938606327612
125 | -0.38342696072849836,2.1657699780908133,2.4562046202646446
126 | 0.4572611524719217,7.348880767266533,7.603823438687417
127 | 0.42940251544673247,8.332097206569195,10.261108790918545
128 | 0.8029981073645969,5.3843885776594815,-0.8375267742915238
129 | -1.884355609254409,8.496922370257167,9.70577340533238
130 | -0.7823307070343649,7.541821812038274,8.839046346827532
131 | 1.8549686744120522,4.3117536010982125,3.14384044054143
132 | -0.1774314060901203,6.299594605408973,8.452503819341805
133 | 0.15353115204640566,-2.849360683622859,2.9932111199499873
134 | 1.4646965459991084,3.4654563619162797,2.436431265868252
135 | 1.0352794810780583,-0.567632346837252,3.992916271051304
136 | 0.29421774609002305,-0.4973316546694395,1.832720094858206
137 | 0.8241549195007423,-2.3227903958162077,1.9296330522892284
138 | 4.033594412174223,4.6293273581171865,2.440397262864544
139 | 1.0589631678415363,5.326355731568167,0.5762158122920324
140 | -0.1755279875342992,4.458969923354654,1.4232584651283007
141 | 0.2974926890917142,3.9501594709675083,1.3145200507712316
142 | -0.3837812088422319,9.031469104750801,9.624742444076034
143 | 1.3047462061515702,-2.6126840625896377,3.9961728917545036
144 | -1.9510300080888676,7.090013902401646,8.944317139860699
145 | 0.5509615029592708,-2.21446920535745,3.792974766539392
146 | -0.2754075587179433,7.248481787952962,8.351564530531958
147 | -0.5387450715044277,3.4101155150863085,1.3750238939772768
148 | 0.9686284985634834,-1.629434021871046,2.9441782481764767
149 | -0.4272659396493452,7.4805763067664985,8.96459842373593
150 | 0.3998617108091488,-0.44595156780308587,2.526127774515849
151 | -3.664652896922203,9.192783505708952,9.531431111444567
152 | 1.8058411721908874,4.096469330275536,3.1732661288277795
153 | -0.043489194450377244,7.826828329702187,9.29172713502014
154 | 0.4803789115713654,-0.9345798061369439,2.925181730111897
155 | 0.3905806503470536,-3.4046017272287132,3.497100537759586
156 | -0.8968765291067338,3.2975343049454917,1.8431040078364087
157 | 0.1800842393817469,2.9032460600988257,1.8709169447918481
158 | 1.7495164086465587,5.815859777699744,3.360249991301389
159 | -0.14960338428974618,-0.5317920311959629,3.748256022973364
160 | 0.7269988025096902,3.1449010044582,2.1068645283543996
161 | -1.9914473247355522,8.409942986117997,8.567975240865964
162 | -0.9243141826968058,3.1662081304172522,0.29322863639395047
163 | 1.463757598014388,-0.9801478697783343,3.6242628128076064
164 | 2.8176534150727788,-2.8007937328846233,3.3507578626240813
165 | 1.4981991172207303,-0.8463400966343875,3.317838828093218
166 | 0.4095724581145378,4.061637813205786,3.5696588051568896
167 | 0.6326528222841117,4.235843795620355,3.2318547513255016
168 | 0.7601828430153499,-0.9362335541098414,2.70894172276226
169 | 0.700225855206989,-1.7981370859895653,2.7594152323667
170 | -2.3060338249692744,7.950965160043816,10.120529757185487
171 | 0.03860831970178846,3.740477289076253,2.9485309479891235
172 | 1.4753631333081714,-0.7985753711273326,2.8740151037169492
173 | 1.5201912282700272,3.1991008278491284,1.331546156690223
174 | 0.7907975689006222,-3.0735625133702644,3.4525820937360923
175 | 0.4112424973213681,-0.5494300610588706,2.361948994171063
176 | 0.791036122171172,4.177659156655466,1.80668095653056
177 | -2.849170521386199,6.958546548047151,8.812509397569068
178 | 1.3996331481545061,-0.9438268678708389,3.9576687520066844
179 | 0.29374517163027847,-0.8086006025289532,3.6302762224237037
180 | 1.069729543514279,2.684145981863803,0.42984143332280866
181 | 0.29221082653049,5.566109513655447,0.04971093046942476
182 | 0.674962872754437,4.206679687530852,2.2487461498593926
183 | 0.7582531948725934,4.76344444497002,1.7569762226571106
184 | 2.738767848905081,3.021547860886111,2.3250943159139363
185 | -1.5795428371538636,6.6086155682720085,10.146661960618271
186 | -1.2070167707131647,8.302434014806323,9.207110206684018
187 | 0.49800130637130535,-1.340567289167367,1.0730115334273442
188 | -2.699553729917217,6.822582464091697,8.334921971144546
189 | 0.31137535352536627,6.298493311462159,9.72837572680627
190 | 0.12860166047963317,-0.5614178636840833,4.827968623827218
191 | 0.8013266948521517,-1.9028876363135223,1.7026301734196636
192 | 1.8345078639012518,4.398121617424582,0.5693636627850887
193 | -3.121706593323025,8.893936547247078,8.38821961220561
194 | -1.420788851037896,6.882511104765531,11.245445039963295
195 | 1.3485905027273133,-3.356953734691674,2.9237340551284507
196 | 0.29891212548941726,-0.820986408483163,4.403636465632861
197 | 0.09499169254850326,8.366823856093795,10.486904747636517
198 | 2.350296695920589,-3.2574888338834156,2.7860076695859246
199 | 0.1314980264061829,7.622326755019991,10.88136744604889
200 | 1.362370732498983,3.838767280460583,2.1749647354707977
201 | 1.5429070069102586,2.5439601077378797,0.7992982408102889
202 | 1.0846196273096742,4.565455804335784,1.1405121913340186
203 | -1.8993108278337587,8.185097669635391,7.3588469794148
204 | 1.2393036889622764,-2.1140230962924367,2.386703100355935
205 | 0.7017800250442883,5.6756737568103475,1.7591624389835905
206 | 1.193730083670001,-2.2988901920765454,3.4428442703715176
207 | 0.9537222167261744,-1.9731496138512916,3.3002593027287612
208 | 0.6412490392970898,2.5868157925763935,0.5934019908910451
209 | 1.9058644069396904,3.2409924066678606,1.1688612534657272
210 | 1.1002813564618914,5.214183156268539,2.600437566252151
211 | -1.4280033195931159,5.943251481173632,11.368792579385826
212 | 0.430312377366263,-0.9607412360391601,3.696549142024418
213 | 0.41106502996774785,0.04154121178954129,3.534897995234884
214 | 0.4029828872189354,6.556969217578923,9.69427048868698
215 | -1.507037121977519,7.083336275327278,9.50604672065979
216 | 0.5740452614029787,2.770771814948116,3.601513078037514
217 | 0.9535641272186767,-3.144793103550146,4.0775572061324885
218 | 1.9823430003281228,3.266672457923636,0.24999989347077145
219 | 2.14081780998505,-2.143684689165016,2.8241453709550752
220 | 0.37984688524206756,-1.7448544233189178,3.365852534709752
221 | 2.1879685374207147,3.5615180397775568,3.1538141918277725
222 | 3.053026448847789,-2.1173337975101916,3.2172693324064885
223 | 1.8157865365874095,5.542808306454826,0.2704636346811591
224 | 0.9048196589997308,-2.4312728637388967,1.569386383413886
225 | -0.648277216088951,7.981303472501245,8.833977966883804
226 | 0.8788400387608959,4.942660825734546,3.116654204837603
227 | -1.4634564499934832,8.44887638427782,7.972341701677041
228 | 1.1212047130821499,4.659792922002852,2.630139373541999
229 | -2.387728485214195,8.060196025238525,8.770922786633964
230 | -1.574683415625401,7.275964098798226,8.309766159267053
231 | 1.3600702387132317,7.796554068050605,9.98406926881626
232 | -2.338735695331404,8.329696911402737,7.8886669338710895
233 | -0.8405025875602266,4.11577242838843,2.1443342358276554
234 | -2.7212779764353314,7.094518849210974,9.931953795338005
235 | -0.10938477294918525,3.0352703364801314,1.2805403541296507
236 | -0.8775353390622502,7.529636459751664,9.684382528065862
237 | -0.9293929930395072,7.959768022794711,8.217396126882754
238 | -1.1614123906946485,7.78152987030031,8.480132957927706
239 | 1.724798622496392,0.08139552272959882,3.757799764595709
240 | 0.9176440833807311,5.560358727736694,2.352014717829062
241 | -0.7660670414428237,3.2353129483426386,3.710616921420937
242 | 1.9603873716492584,3.144581002675552,1.6187304287901312
243 | -3.304736118792465,7.436673688427054,9.09972704098344
244 | -0.027814016978902067,8.465367905054464,11.542440956707932
245 | -0.7805373099386221,-2.1198517004193036,3.9685151459382233
246 | 0.8807344268261531,-2.3255648657344707,3.8954639925525862
247 | 0.2502663839230159,-1.352673662558092,2.7355848265607774
248 | 1.1161693252296268,2.9570560287534438,0.8555203473334974
249 | -2.336706741765804,8.574112675155517,8.887621400151811
250 | 2.24865621329461,3.5007925854609256,3.077570724516251
251 | 0.3151658467306455,3.1235963118224737,2.252910159579021
252 | 2.3405218157764534,5.403376232934715,1.4275330803351611
253 | 0.39459708145910677,3.765953374350066,0.4992438437375706
254 | -1.2730558716425264,8.450310117845875,10.370014901786817
255 | 0.9105360079837095,-2.18290211478207,3.247568303195949
256 | 2.703836774280832,4.353844579936617,2.089772529984387
257 | -0.36047275484267116,-3.037725505900264,1.6838259012548276
258 | 0.2681229744170497,-0.40181813428805824,3.938570093606422
259 | -2.0187212428373575,-1.0952403438890304,2.188831968840545
260 | 1.7662348919877002,4.503126706170622,1.9152725868337859
261 | -1.6195362960126323,6.769457833274537,10.03110440022912
262 | -1.6943319414886706,7.58042533563363,9.040279395795647
263 | 1.1704767226339161,3.336289929209526,3.1235272117099537
264 | 1.621327605410504,3.001551364731845,2.330117810271436
265 | -1.6993299135381275,7.85528390214895,10.208802287831668
266 | 1.2491252421188135,2.3465991290018176,1.6032761633039605
267 | -0.6695109544162929,6.983072548784713,8.706823416908414
268 | 1.1986042273820865,4.099140841425413,2.008823998413242
269 | 1.046129348632881,-0.5156870557320932,3.763028588698214
270 | -1.5070338949087052,7.085586091994789,9.012109932871894
271 | 1.1985299802852034,4.738970295009764,2.009519422333256
272 | -0.06514505347413402,6.738766790055047,10.3149279493252
273 | 4.077800662643146,5.162541480440308,0.9004919940259262
274 | 0.06190674379152861,-1.9483923396683789,1.8615828065771556
275 | 1.396413832745878,-1.574401240209456,3.236639729527991
276 | 2.421105788564587,4.4966481906579245,1.6344027010105897
277 | -1.3972780755584586,0.6275531296227785,2.238707494683621
278 | 0.9392703195751407,-0.3849586249546353,3.7762952893046378
279 | 0.6778797240441318,-1.3071720811561556,2.2627983866379413
280 | 3.8092800550069645,-0.627334207091206,2.376952072214779
281 | -0.3605081914193933,5.475167867318703,8.990413816190147
282 | 1.1413507654703985,4.9004751061713065,2.8160501212290288
283 | 0.13595371828383052,-0.9520516514865488,1.8142457902966684
284 | -1.0002736859426316,7.8285944946572625,10.017266168665744
285 | 0.2820970625575592,-3.5755411422650636,4.01103995541626
286 | 1.860922254669902,-3.897751724346603,5.050069764460588
287 | 0.047801869815354836,-2.7362687937880583,3.8396886344227066
288 | 0.14285349794915958,7.3901579871531915,11.382105021769352
289 | 2.649917557269463,6.279179111692256,0.8782554674689658
290 | 1.224654484305808,5.628515368213721,2.762305034198371
291 | 1.011386090259414,-2.1563017932401323,3.2573811527189527
292 | 0.5545642000996411,2.0527590350003226,0.3695434106489093
293 | 0.26106651428685446,7.294938045597636,8.465308661029392
294 | 2.120702703552371,-0.7045658281940249,1.9250436232399166
295 | 0.2933080914702576,3.6506608217028997,2.485034170952309
296 | -1.9693846577912644,7.70472830009652,9.74249568263342
297 | -0.9030655408666204,7.3626250546620895,9.039805110600355
298 | 0.5113254975670425,-2.216317335083324,4.528659833191936
299 | -1.1616945088608588,6.982410767874805,9.51701080145611
300 | -3.23769715601812,7.277976218294719,8.880691209852458
301 | 1.9366362174765779,-1.5719884220696583,2.699870757115424
302 | 0.6310582264298517,-0.8417230997039997,3.865756867553363
303 | 1.69049389892617,6.588120681918735,3.6193701011615023
304 | 0.7450833689665202,2.6935438674326924,3.485869419405092
305 | 1.4330720538779649,-2.0269937032697007,4.120733973290429
306 | 1.2116037473680572,3.449282455754828,2.612043653975748
307 | 2.463879888212735,3.7155325101227317,0.655005614281176
308 | 1.50562306583056,-2.9708206168159763,3.5947243260015913
309 | 1.3203116425315131,3.19447230991688,2.3973250342020824
310 | 3.0238009694248955,-0.643392255691783,2.249076426249098
311 | 0.6186598517473181,0.9299250414010687,2.9438614074626193
312 | -0.8489882332214906,7.619152166061161,11.004450168631848
313 | -1.4153864380414083,7.760690034271519,10.672795485084958
314 | -1.5863611831599158,8.167701575823312,10.06391092153819
315 | -0.31855125480319724,2.002730674761051,4.70708066265949
316 | 0.5010928994383306,-1.8158649230148307,1.1873713113833866
317 | -1.0916606312898485,7.050826346100312,11.005508335367686
318 | 2.0541775546230103,4.281762212137872,1.5892209286584191
319 | -0.4795976288254328,9.344702865713652,8.700643924641879
320 | -0.9918759065883775,8.971938708925743,9.182742983009899
321 | -1.1171458652759567,7.459409194820042,9.097415166866398
322 | 2.1481649955279076,4.2928524460808655,1.727842133405301
323 | -0.8114254778999381,8.722096951891015,7.757756463373921
324 | -0.010133588459775744,-0.9982419963322843,4.161804035939783
325 | 0.45895872730978304,4.359454290161829,2.2449029130165012
326 | 2.0922085326695736,5.643240343996315,0.28783387004372885
327 | -0.08153446560244926,7.358239278679317,9.69665692891568
328 | -1.5494957268869773,8.68706195599781,10.585928223040186
329 | 1.6428947497808166,-3.2832573163086813,1.781111294120189
330 | -1.5044420370640346,6.387920620619962,8.870219491695337
331 | 1.1008167231803423,4.510337175595402,1.1502729750634824
332 | -1.1690133084863372,7.5357563469318185,6.351837833339943
333 | 0.1626715807166974,-1.8127684435585611,1.9913405350568976
334 | -2.2737579791586446,7.107393398273791,8.96969248062753
335 | -1.6119539328877766,8.477518812538282,9.3447998233315
336 | 2.1101363883313278,-1.3067047011778508,3.285836325421323
337 | 1.136928618894617,3.444802006818348,1.848846579107399
338 | 1.8621421963062266,-2.288538973575088,3.7553566642691854
339 | -1.6493313987961056,9.313061790726806,8.574852632727962
340 | -0.8552975937777452,8.052507210283743,8.925210191482671
341 | 0.9233362940057523,4.63679306935443,1.4062857585318018
342 | 1.5983960436080489,-0.710921196362642,1.9957856599723796
343 | 1.3534306896547361,4.233230098264765,2.659427228549253
344 | 0.10650441700499025,7.527613472014557,9.068063894030885
345 | 0.991029556915577,3.9127367483650835,1.6668479434629853
346 | 1.0911239580910168,3.717972145028695,2.354039559794797
347 | 0.3745358532277412,8.97810737613502,11.526508615558775
348 | 0.2400446863514698,8.125892560872286,8.990762204853569
349 | 1.1716903043063664,5.792170264543875,2.380111088424387
350 | 0.5761507456053083,6.880803796196492,9.433402487991758
351 | 0.21479935010730855,-2.00046065768093,1.8122875024438987
352 | 0.49685027733285503,4.615150830725181,1.279247054509337
353 | -2.227508934750667,8.086368687060213,8.136056702956843
354 | -2.8928847990934905,8.27317559395171,8.843139537045355
355 | 1.0127630865494002,-1.2125633099064173,2.9542077368668824
356 | 1.448419076063081,5.123704620500348,2.9627871385397166
357 | -0.6762750168078687,4.781129538503242,7.438679687563124
358 | -2.3811579909521936,7.881196804279395,10.211789068228942
359 | -0.0850904985676122,4.978920631066815,2.96915785151427
360 | 0.8493751312501212,-0.1912080660488542,4.500838648080607
361 | -1.4636538785203528,7.120741917440421,8.475534328340048
362 | -0.3120127057347215,4.313358617806922,2.4729308642420342
363 | -1.9816952063612652,9.518228739353424,10.538574470862068
364 | -0.27629526184989794,-0.36774380262616235,3.508656424042164
365 | -0.08719562134843883,-1.9456283613283414,3.6292480556291524
366 | -2.0848679221659423,8.19698858688919,7.348035375019271
367 | -2.5201088131581684,8.260843042704838,9.118758970117335
368 | 0.9317744571536908,8.544934238813141,10.197597555711278
369 | 0.4614511750194365,-1.495055881753982,1.477614438397519
370 | 1.3298101851531805,5.334129558872794,1.5523269675422073
371 | 2.877321466649993,3.430469603613478,1.9734073892509503
372 | -0.22191663458064514,5.070556094025001,2.2727930659682234
373 | -2.372350052166173,8.235022632484624,9.698516300017785
374 | 1.4043510296034716,3.2639994738944678,2.346495901300198
375 | 2.7589158836097907,-1.2308433106275638,3.0339291172008287
376 | 1.4832248082150428,4.446969591193786,1.549704213489928
377 | 0.5529058863898335,8.431865005088522,9.099091580690393
378 | 0.008841707405453869,7.279116951878392,9.532291312063538
379 | 1.8149915326204185,-0.9728094531348569,3.571668143227801
380 | 1.0723296154820854,-0.3873877745989287,4.289927472248913
381 | 1.1796207517259487,-2.5496315188920704,2.935657105276487
382 | 1.952101670915066,-0.49548289900669773,3.143911691758482
383 | 0.06391636633277364,-1.5213904780369372,2.9986955032845284
384 | 1.3405895555767435,-2.238798325726276,3.9462834195180436
385 | 2.1905136524938538,3.729572105264102,-0.0676831765020034
386 | 2.3852096985704954,-0.7806742295985258,2.9666741142361865
387 | -1.903278925367028,9.070915248370923,8.991479956643358
388 | 0.9020705517460879,-1.5226347759994783,1.1306735611836143
389 | 0.9042880407470808,4.372440305744145,3.2208371166960346
390 | 1.0703844347841003,4.685825647765513,0.254466405563317
391 | 2.0957299908461913,3.335207723369856,3.288496250369609
392 | -1.082848934808109,7.907212415973196,7.805816973269164
393 | 0.5299055850019312,-2.821582583928019,2.3125571352834537
394 | 0.08128071236428636,-2.4706337083117678,1.763849308311366
395 | 1.4452478330284544,-1.7830004247293807,1.6823345284244962
396 | -2.1570438348293983,8.972277685922485,8.367917136962486
397 | 0.4027261570204278,3.920110141603935,2.3469015615669333
398 | 0.3202758986626346,5.545915822454848,0.5867110603267167
399 | -2.3765392108781587,7.833789462667706,10.162440673396137
400 | -0.36578010571694053,0.7329487405599227,4.213064429919129
401 | -2.3726727739365527,8.68422083995873,9.652985743823592
402 | 1.8139898436914228,2.8136759150833655,0.9850525182688414
403 | -0.12592600836915357,5.382366428912042,1.5365334559268193
404 | 1.5083062111194674,-0.8351905922016325,3.2871796410453036
405 | 0.29198663816561765,-1.4741759895345095,4.8616031552091705
406 | 1.1662927749551968,-2.0987104787586524,3.4035378625299426
407 | 2.044103653817844,4.575383068248353,2.6745692877365586
408 | -0.5535989222575817,3.598451322159989,-0.13585601791312918
409 | -1.4052801546523797,6.592292686777514,9.682543273521437
410 | 1.0655281752505634,-2.453813150385579,2.041723815371371
411 | 1.361203425166177,-1.2884233783411676,1.239438083311013
412 | -0.26374803069419805,7.993407446623278,10.14135504813239
413 | -0.11347233400127843,-1.3052935724359371,3.2539060777436806
414 | 0.21486874699186498,6.278925167766663,3.161201640397703
415 | 0.5784402758217033,-1.8249141169182472,3.040570501088224
416 | 2.1010261312714436,4.4158481186650675,2.5744087473019346
417 | 0.7653252743973845,3.3289302805200798,2.754477646907653
418 | 2.5458234782696203,-0.8873039399731957,0.6046194178850248
419 | 2.7537872636402247,4.807266451896594,2.0621870772393773
420 | -1.4734011346009466,6.913827624860822,8.203405200015323
421 | 1.287012989093467,-0.7905454728590671,4.246168376768488
422 | 1.077595860452083,-2.2726562017773353,2.4206826036821223
423 | -1.4485762328591436,4.556522698351665,2.10131240251492
424 | -0.3668866517580558,5.729293454061137,2.283849532455782
425 | 0.9398800041640198,-1.3570704797454585,3.7411354966756982
426 | -2.4161384783368955,8.522409762301821,9.961583887838263
427 | 0.186306443066118,3.832947701845831,1.022213807860603
428 | -0.8886436515669465,9.671239835807292,8.092493258102115
429 | -3.21940705455484,7.281693604118967,9.138680660963542
430 | 0.39044720388714116,5.241346169685137,1.8006594296478375
431 | 0.4388343105064797,4.616122222595506,2.0990415286344217
432 | -0.57478765785241,8.315247865743185,9.249483036914574
433 | 0.7709864036488312,-2.093853848323657,2.2366293954636967
434 | -1.6707993631551064,8.260391576695419,11.584311023524247
435 | -0.3968677483000491,-2.362717887209535,4.071142648629738
436 | -0.14781712555311488,-2.3334688020842203,4.934095678774456
437 | 0.29045078119347756,4.522510638972915,2.6203146001590842
438 | 0.962642569357341,4.027595320178339,2.110614379912839
439 | -0.3173642005475459,4.980814138978239,2.4793227198758445
440 | 1.0649380402509188,-0.4134897449286208,4.72433257960283
441 | 0.45930227533432266,3.6429535844152534,2.360666843035896
442 | -1.048713898321201,7.322079517303738,8.86299510882841
443 | -2.2372560276144524,8.632277084823032,8.915947599339628
444 | 2.683053796500298,-1.1698617536516869,1.8082701703608361
445 | 2.2837549992794615,-1.8213291222523151,1.411306615675756
446 | 3.577149250867844,3.999050846613482,1.4721328974718104
447 | 1.8835500413429829,-2.0582465017427847,4.82831192580065
448 | 2.0264120354782986,4.271717940233877,2.0075336558623387
449 | 0.38627407063796027,0.5349946597051156,2.82083257943172
450 | 0.4781969759386693,3.9408962135846735,2.31922783038867
451 | 0.2026833085701979,3.6077718898478306,1.642911081445916
452 | 1.5530034276679427,3.357856998317992,1.7439645340031946
453 | 1.6524020100234944,-3.5430303671485643,4.558545595206411
454 | -0.16273878930439456,9.708049531083502,10.283917743510138
455 | -1.9379152183333086,8.984045022670198,8.045571195749845
456 | -0.36843135141617656,7.150035668537281,8.42896761977839
457 | 1.4751146695213073,-1.9976590980517335,2.214102636812178
458 | -0.5421232784041539,7.752893748385611,8.058200981877492
459 | 3.076198460498296,-3.3774789730547075,3.36704962685906
460 | -0.8896013907627545,7.470762310810798,8.395742310482035
461 | 2.71652353948443,3.9397005516669106,3.39922194101781
462 | 1.634043609289443,-0.788142887664456,3.359416270379987
463 | 1.8930637713954257,-0.9074567385240213,1.0445932240338995
464 | 0.8613712245186961,6.0468260475177145,1.7333883305492221
465 | -0.3330925445468824,-3.3246145315503988,1.7808118296441762
466 | 0.23019888713536407,2.92043795475589,1.7678770123517826
467 | -1.0966934925281073,-3.101233596542755,2.397750251299823
468 | 0.48227573266456364,4.318423985870831,0.4488010626850454
469 | 2.2423886084042737,3.7979107876878784,4.600468299903932
470 | -0.18181370416154574,7.706169513330787,8.968515903140585
471 | 1.7907176699123484,-1.5432308732752744,0.9456836040284291
472 | 1.1740290752432694,-1.534147164202384,1.5090461193071718
473 | -0.49834174924515695,-0.7721044982310777,2.4978571940506678
474 | -0.20662396920006376,-0.8662300416690338,5.049014370933994
475 | 1.556068874567874,2.950054488366205,1.335740855853829
476 | 1.1589346743827615,-2.5862754796002028,2.370255401906767
477 | 2.6727397323006947,-0.8505721564273746,3.808500135333407
478 | 0.08092938882510392,8.255888806929569,10.483589705496723
479 | -2.1956059837775803,7.610428097021023,7.643237959343871
480 | 0.0481108939762821,5.794509244407413,2.2507668567082058
481 | 2.410337101107561,-2.6160091377105257,4.791635730013821
482 | 1.394934631771551,-2.5290255040220817,2.857470594902552
483 | 1.4874894294607222,2.8254670644486453,1.2486606651523402
484 | 3.100459758828731,-1.831486352333272,4.293553646099481
485 | 1.3956237528671394,-1.7846222542106216,2.144529774284388
486 | 0.46182458062877696,4.616574399843332,3.619780126040376
487 | 1.214419117731786,5.9348385768663245,8.50832553651453
488 | 2.1529305696027903,-1.6581246747704965,3.277137146111565
489 | 0.4773808004486962,-3.86954041244228,2.243379146389897
490 | -2.29344454134831,7.898393891410908,11.45429778550384
491 | 0.787498181470353,2.3148126402624056,1.783584119409643
492 | 0.13618642169950101,3.323816333779105,2.327469716074169
493 | 1.209538923943021,4.574472186291728,1.8108601254307783
494 | 0.08881976432206962,8.088791315284176,10.116306485470272
495 | -0.9682981054043232,6.231207197083285,10.136620052674926
496 | -0.9276242097190089,8.223023441727609,9.745266128944472
497 | -1.3113698474110955,3.7523132022557286,3.262888186461746
498 | 1.3366973456605145,4.711935446744988,0.1145518454112977
499 | -1.4067414822705173,7.667662929648222,10.410533876911936
500 | -3.047453209314147,7.14893271676445,9.274628140221605
501 | 0.6162181941176603,7.2331869569706475,8.189864142338234
502 | 0.7927671995443388,4.696095383104264,2.296902327987819
503 | 1.6197145650318803,-3.2887942841215336,3.929590652745313
504 | -0.04410154927998744,-1.406768756474107,4.120223989224655
505 | -0.8277756741451905,-2.4626825436747577,2.126074853021455
506 | 2.0477350794054425,-0.7925322311331141,4.292863793459107
507 | 1.108795714283639,-1.580711999904499,2.0138608001262384
508 | 0.4277065402423189,-1.3547077118190682,3.396678882035314
509 | 2.300109353153811,-2.045225395090009,1.3280937892495956
510 | 0.7973525920631698,4.100276970772704,2.4519601232265966
511 | -2.811979512419647,9.236506805051091,11.996942964424235
512 | 1.0261684927840928,3.3682568719780357,2.342655173300499
513 | 0.9432330656813956,5.5050584304434,1.9716630930878603
514 | 0.7671414611818693,4.908359604278473,0.3122092905098959
515 | 0.6212033720059764,-1.1826578341777616,2.7657881091849554
516 | 0.13922619910275225,-1.1036255955555143,2.8313984406638655
517 | 0.5046657449986688,6.116141978979852,-0.2388699573665396
518 | -0.11284724122054213,-1.7358787735737804,3.8154117043239877
519 | 2.1893576845938973,5.448506129830944,3.7336719701396195
520 | 1.5488087876952146,-0.9907180475464981,2.7633923511650167
521 | -1.6999922852416314,8.162886693233904,9.378438193850057
522 | -1.0796573693955294,7.814708547377598,10.758273104580077
523 | 1.0664846138037665,-2.083233562022431,2.1004662018848452
524 | 0.8837535739176285,-1.4861857522901083,3.8427148746949173
525 | 0.6689052681644874,3.937263386495284,3.174979483621838
526 | -0.9532562600961552,-2.0207514902416537,2.420567194876811
527 | 1.667435119765154,2.397950119522506,2.337311848339526
528 | 2.063145774259301,-1.2911277281321905,3.3017852100309355
529 | -0.14973614519952338,-1.6419563706985378,3.1668770253017255
530 | 1.1382595937303126,4.83882564489764,2.885856131298483
531 | 1.3135224783239878,-2.5372741470834406,2.6858546024899725
532 | -3.1185829461454477,8.427496311162473,7.9727549186944096
533 | 0.8576539611087804,3.4956712722074528,1.336356575736954
534 | 2.8851720213931245,4.989766763493887,0.4355144040725476
535 | 0.1061308275342644,5.858359316769786,2.469760381167658
536 | -1.9901199441827662,8.285819274032116,10.484509193226621
537 | -2.055778532523183,7.364670813214483,10.48201611599791
538 | -0.21048332540679615,5.6760446141948755,9.422320790699672
539 | -2.2862927150998082,7.100432504846617,10.373754217647399
540 | -0.6595343135957674,8.150818531870504,9.623641713371201
541 | -0.13521521942154524,0.07739868915610804,0.8486189062834231
542 | 2.125710701681147,2.8954605342029875,2.15157831110405
543 | 2.019899667347663,3.5428400320970725,1.9698362038437824
544 | 2.1635409535859935,3.362565224915507,1.9270378244380402
545 | 0.7186063191597186,4.354158043637864,0.6750566463829624
546 | -0.3467257455033965,7.838330927986313,8.33955879363921
547 | -0.8578594395641838,7.767002959834428,7.852125635582714
548 | -0.6295790889423156,-0.16156553363814763,2.7969880790694504
549 | 0.4067528146557523,4.479173860117602,1.5927619819968053
550 | 0.3697832585590233,6.194237941204506,8.743266854317914
551 | 0.5619425149721822,-0.7354085603229779,2.4522087220350324
552 | 0.6849440812030911,-1.5626083014911898,3.7275032763346703
553 | 0.7808528749645809,3.0391918892473733,2.9122006969518184
554 | -0.4217731202703916,3.286740248726015,0.9658966850603938
555 | -0.16134863646479758,-2.750411800205364,2.8981613396238437
556 | 0.48960748024266043,8.400330326908755,9.127035178339991
557 | 1.4390597817268527,4.160778756864344,2.317522387350375
558 | -0.9668105390382566,9.103128289951972,8.792943989321314
559 | 0.3569539862847456,-1.9290879793377393,1.6098713313429682
560 | -0.13457881897348378,-0.41274322766754,3.162663557040456
561 | 2.2801723058983656,-1.0120063553877925,4.558606738999457
562 | 0.05995401614812246,-2.967179245897978,2.692662894472028
563 | 0.7856140993338536,4.752424854938928,1.062837749774293
564 | -1.2830659113965925,8.123670803281758,10.590648227620692
565 | 1.1947904618151899,5.618551446081602,2.3374650961913006
566 | 1.5367123732570689,-1.7548652573229933,3.030475097904951
567 | 1.0231745400659198,3.2715442907174825,2.458453202987834
568 | 2.484145994114601,3.3804456312015825,2.714045077905986
569 | 1.0418058883520447,4.714257617885761,0.886337165768204
570 | 0.970501174145663,3.321087647130744,1.2511078054910256
571 | -0.7129291829735048,6.366724915339418,7.9128261068413694
572 | -0.1928434418653453,6.727748901098874,11.659239286937016
573 | -1.0384417294753465,0.07129952331689182,3.4114128776853985
574 | 1.0747567547756471,-0.4706640322011497,5.187241819385233
575 | 1.4031660988837262,4.290937935721655,1.7030192155101882
576 | 1.3628217510266825,3.904434486935393,2.7306488844109307
577 | -1.7857068395101816,8.518240336246539,8.0723282003634
578 | -0.2544707648694482,-2.5771878222329287,3.770693092178228
579 | -1.7705568013173507,6.646484983656757,11.432009020637961
580 | 0.5985762535691701,8.411030958158813,8.167827994904405
581 | -2.695800357793542,8.011534228239054,9.616544691303973
582 | 0.1486847409094716,3.7289582846467475,2.0345159368851338
583 | 0.0916679187861138,-0.5595542412175413,2.6060883646725834
584 | 1.8899758859633984,3.6310025430097568,2.18859201893066
585 | -0.052083003714452625,8.574222283070265,7.821872758912269
586 | 0.08201134810450084,5.98908306265041,10.352727832043119
587 | -0.014633203611088552,5.321667377165674,2.396854917377015
588 | 0.6296168091063763,-0.9889801687390538,2.066719765336683
589 | 0.8275696463933863,-1.8253483203448966,2.903437959052351
590 | 0.8525199625288947,-1.0994148197398659,2.1736940366574022
591 | 0.3735714183249814,3.9242619602486988,0.9076333684198128
592 | 0.10574614947176897,-1.746813869570445,3.206019164420746
593 | -1.6060640256177297,7.2182192278774195,10.011748794974887
594 | -1.304562181161212,6.866674904770015,9.545077934197344
595 | 2.0570819916019403,4.788099481569055,2.634408000139606
596 | 2.7463344862536054,-2.263066436049133,3.1984085542905776
597 | 1.637487825449477,4.92829480642771,3.2451841891512645
598 | 0.9445467833715866,-0.641508546704861,1.2771501442446629
599 | -0.7848326000297885,-2.4141347410604306,2.7186662827425976
600 | 1.5034453517241886,-4.099613173348745,4.312272158059774
601 | 1.0663828695303028,3.3062197886103473,1.255229307038118
602 | 0.3684277499049844,-0.01608397261680028,2.540662018717211
603 | -0.7734426960698446,4.931992581850652,3.1008934669212502
604 | -0.7620366044073754,7.605568790585528,9.298547423454274
605 | -2.135764845328672,6.855265631305137,11.970608494462613
606 | 0.3012482469840928,4.171003071328351,2.675068584755692
607 | 1.640805203465454,-1.6641540548128637,2.3098612495366053
608 | 1.1790858345877042,-0.969495142088921,3.3480599315652486
609 | 1.2514683941228153,3.343032715714602,2.4321944964281608
610 | -0.6334725723728429,7.9211057902595385,8.60476771685663
611 | 2.8910922505701437,-2.9488161919709936,1.974787076781348
612 | 2.0213530828932784,2.631358693361544,2.6237337339913407
613 | -0.24083672189703598,4.463273622791651,0.34058005508980127
614 | 0.7277741162396414,3.824304401751133,1.2138108501321847
615 | 0.9872608443577781,5.0874918507580595,2.717386717518842
616 | -0.10659348232102239,-1.0883191778175885,3.0447732382545603
617 | -1.4295766933914413,7.036581355997751,8.730990469198726
618 | 2.7674385397564105,4.474787765614185,0.32959616984551365
619 | -1.577284923846329,-1.5903626084032914,3.2486603010428055
620 | -2.670577929461043,8.110285562106135,7.516432732780748
621 | -1.6996281024530326,6.94840322015545,9.176203856139175
622 | -0.10977075542351544,8.813145499099003,9.298467201513981
623 | 1.1321045921064579,-3.6326272958916235,3.534816498657801
624 | -0.28720201400094736,7.347625791958831,8.323381274264113
625 | -1.6659750645593876,7.069945950779829,8.05246495140688
626 | 0.593783865132024,4.995449245818215,2.4091525329080943
627 | 1.4990211250721273,4.557843652748372,-0.1217485588820697
628 | 1.4658188367460292,-1.1384059395434827,2.9534811442192614
629 | 3.0607117693947106,5.817263418257229,-0.04555721160323234
630 | 2.029692077212885,-1.8356625693401403,4.539106190266299
631 | -1.5360276455025497,7.72998584684837,10.595941188714425
632 | 0.16683891136947304,7.062095403115821,8.417542552365047
633 | -1.9289664050739999,7.008512059073179,8.928699418040296
634 | 1.6122478466204007,0.15838060093212025,4.575629173255992
635 | 0.3511234624099149,7.287111012675194,8.35946443663995
636 | -0.2847208568336196,7.306473433160672,10.451502261630758
637 | 0.07547329489795906,-2.153504637506459,2.0263873711299243
638 | 0.045966331115981585,5.192767439452957,3.7507293542674303
639 | -0.6906316687755312,8.812933217441683,7.804270904220022
640 | 1.092994409702558,-2.7639780098134383,1.8005417020021977
641 | -1.3762595878217176,7.211181962299589,10.951869904677238
642 | 1.3735302857281662,-1.8114635076263754,4.061159133780752
643 | 0.8335149582324675,-1.805643217875114,2.0170937930184105
644 | 0.8392500736790481,5.29121182257561,1.3367178396065795
645 | 0.6453482595630509,-2.4402561838313277,3.996112491080833
646 | 2.811571337941335,3.463847469867084,1.2748434706629375
647 | -1.8634671597750758,7.189202560540761,8.218155590057718
648 | -0.8864413193410869,-0.5097698404931901,3.2813409423093867
649 | 0.06685438147477585,4.894692630023692,2.2617289388617374
650 | -1.9567561792098966,8.657193954462342,10.627968882242966
651 | 2.083894756621426,4.480026079764516,1.1149139792175045
652 | 1.8213371315171045,3.7195968563594755,1.525265152897135
653 | 2.403524939538193,-1.0132384461227344,3.3655163740645277
654 | -0.9381375473639362,4.377022896606345,2.8049556544254894
655 | 0.14793626790793635,-0.3255776570982791,4.1576634901963505
656 | 2.040519761486677,5.455117162056356,1.282809814407722
657 | 2.797973386316036,-1.805736083949675,1.9206878310264757
658 | 0.4905939057445674,4.252090090353827,2.62232389346708
659 | 0.8586952855630847,4.676907488187665,1.6692387504040502
660 | -2.118864286267044,8.292852478561263,9.408695079518434
661 | -2.3225432027215396,8.778843778050451,9.616674164326641
662 | 0.6063540047281535,5.253407544897859,2.0359691466335366
663 | -0.8340368917286587,5.834614125202642,2.022016428222348
664 | -0.5385095168952558,-1.3755910681570973,3.036259018149949
665 | -2.360506142776102,6.252008760782194,8.523378533643584
666 | -1.4972683301194365,9.223976687953723,8.595357040894655
667 | 1.0673297443557959,5.128173666073435,1.755659098537127
668 | -1.564203485067328,8.428544252310717,10.246195234299734
669 | 0.27838633684311986,4.191085678927014,1.047002676225289
670 | 0.7309093836560603,-1.4344493049524003,0.7466453932360726
671 | -0.013890063963833632,6.176181405974314,1.8141939309729669
672 | -0.3346321361510003,-2.308991276884087,1.5826934131052632
673 | 0.6432126771051705,4.351152144738689,3.5180079688812826
674 | 1.4473839664851833,-1.3846016274650428,2.8793734578469574
675 | 0.1985828189380796,8.94703784792159,10.913003347821855
676 | -2.234776052985125,7.14604427085656,9.544939446483225
677 | -0.26566085637192915,7.002692223091861,9.445412133959508
678 | 0.8277431980397748,2.729205180627485,1.5595793239460458
679 | 0.7932896264398221,-2.120380005081315,2.047440793803448
680 | 1.4006825373748097,5.3930963725530034,1.6710818404347552
681 | 1.6274794243888482,3.1732908779461613,1.27792086567076
682 | 0.9218052347652407,2.4925085365303437,1.424092303685038
683 | -0.9906785562250445,9.554545094193957,9.8095379285901
684 | 1.928310156972107,3.6728399523719744,0.6349902584948908
685 | -0.3469863729310225,7.722342845627871,9.186798015549693
686 | 2.2686050412533616,3.3650254203304075,0.8427346182580988
687 | -2.201864698693005,7.0911961795617255,8.089716062319862
688 | 1.0117128506857287,3.8258862317734588,2.678960691773574
689 | 1.7374834773534733,-1.0414327432124717,0.6934674567373396
690 | -0.8051653726725051,7.0385757455533415,8.997135884515405
691 | 3.757718224340811,-1.8824194434746864,4.28464112206662
692 | 1.0688610517254211,3.0276595101577177,2.689885997085667
693 | 1.8289827021485872,-3.353024793887296,1.626896480093094
694 | 2.9250290931904397,-1.1925504839392511,3.48927874494074
695 | -0.08462077812442192,4.3582611770954856,1.9509888892095586
696 | 1.8065563494358554,0.28515880104673474,2.6614018442044625
697 | -0.7196466186197789,8.061292847214975,10.495277159531378
698 | -1.5020729010560268,9.034774698193278,9.80629987583674
699 | -0.11318016479130133,8.358359532065695,9.229515768213437
700 | -0.09181797211620613,-2.6610213390813264,2.7961156054665075
701 | -0.6608129904712611,9.411224509664635,9.722375108941396
702 | -0.505173585718556,7.394575127706767,9.83561997601711
703 | 1.026392753774279,-3.5024190060014706,2.742928791566501
704 | -0.9095953712546941,9.16306153276462,9.159204710339573
705 | 0.5690849760060511,-1.4870881466416501,3.4605298996150298
706 | -1.3578193070186086,5.838469315922798,8.299097718095515
707 | 0.7177934597906703,8.822175168345696,9.554472100752822
708 | -0.17663917861923295,5.244818138433079,1.0267405902901015
709 | 0.6735372464174432,-1.9051754752111945,2.4840580199593036
710 | -0.9814587851521124,8.850267998974495,8.79987355910617
711 | 2.983638155493366,-1.2941357219899992,3.791669314275426
712 | -1.7944353801699067,8.538636586847174,8.118741434062846
713 | 1.6097466267333496,2.2845316105609768,2.5480316230961204
714 | 0.6701702394571896,5.205728144679834,2.887646287852787
715 | -1.3490469263333427,8.832612874763738,8.564120544514456
716 | 0.7946875058152991,5.713991958579604,1.6807958304526718
717 | 1.3945389980173115,0.1171001138403378,3.461515397728713
718 | 1.2891232550014147,-2.0056690636585386,1.3297152033648556
719 | -2.6580202677866245,7.8595248726211535,9.238729547785537
720 | 0.08819844369029783,3.7587026548366413,2.6637965627622515
721 | 1.7082255610963397,3.7523381472485635,1.3031338088991462
722 | -2.0120880080034835,6.699649202260483,9.402731482842668
723 | 2.5112992076656777,4.870227365477708,2.2045326131452123
724 | 0.8866896766033916,-0.4510194503013656,3.521425985652715
725 | -0.27556451533722126,-2.5003848310189265,3.666186330101572
726 | -0.20532853392647255,7.666372011221007,10.826882300772361
727 | 1.2034688484778464,-2.5530058392286614,2.8224397217331956
728 | 1.0296149855656977,5.334603275117922,0.7782785344070642
729 | -0.498093983762097,7.225745953854006,11.11045945686854
730 | 1.341921524255858,4.229863861800936,1.5617499501823178
731 | 0.8155743056631346,-1.0788999513036803,2.5183373713029615
732 | 1.8282020557472136,5.67476949234798,2.3293420534182694
733 | 0.7018217179980284,0.2363638887387527,2.3958915156398954
734 | 1.0110910885772935,4.304227091841517,2.2164721345908323
735 | -0.8863306928976991,-3.0157910721516537,2.342437295865568
736 | -1.0893520588641599,9.429622524108753,9.108129968308834
737 | 0.5061228372121156,5.063611043018868,1.7722731724170828
738 | 1.3800791074915995,3.2637586738723465,3.3086523442803464
739 | 0.9942085337359636,2.018307415524265,0.5764223938313147
740 | -1.1584293268566355,6.830445357115336,9.773053496948275
741 | 1.587373788412204,3.426424005656452,0.43418002496167074
742 | -0.24543103463548954,6.815956449560344,9.598060302345457
743 | -2.11638595752052,5.891114962713251,8.198924046868083
744 | -0.9016014977542988,8.811818076825354,9.189434334090704
745 | 1.65965411374929,4.068862672572571,2.9756702283571834
746 | -1.2807080244135352,8.268915069982114,10.446194571391544
747 | 1.003759349421613,-1.9333538518106934,1.628797726543194
748 | -0.6291238237489922,3.5962717399316095,-0.09383693494214329
749 | -0.3751130983266624,7.332049690043185,8.110757561636314
750 | -1.0544674747964304,8.526768655251058,9.923619056055234
751 | -1.91207499158653,6.6276047068733,9.717002974643377
752 | 0.6876468593763466,5.35176955214176,2.3052250622519157
753 | 1.913649976818292,4.925528180932929,0.37439815063747806
754 | 2.152524058810157,-0.1156091442540077,3.049430144938886
755 | -1.2124960516053236,9.756575990951294,8.457217856564464
756 | -1.5122303099087804,5.887325987220725,9.055799109144697
757 | 1.7957366869193985,4.825775057053788,3.2525273862908493
758 | -1.1657704259723674,5.4753035933900875,2.128737395077197
759 | -1.1302523476321742,6.0061553489327135,9.060093165258461
760 | 0.8507841047004436,-2.27012300277251,1.1126135824564525
761 | -0.91155978305718,8.473422031897567,9.461249368125042
762 | -0.5632688371692998,8.835569296060175,8.710638819322227
763 | -0.7271456857268241,-3.3690734403185933,2.287853135049017
764 | -0.003174125061963351,-1.588114797427941,1.0251009040183012
765 | 0.927991640219218,-1.225575113912882,1.8526638628276433
766 | -0.3104336614112866,6.561819844445375,8.887512265389445
767 | 1.4468414530814027,-1.4430152200603488,4.594645260840562
768 | 1.4408445414842346,-1.956811359909862,4.650108764220487
769 | -1.6948785266467832,5.582353894179091,8.294030535551078
770 | -0.828467119176068,-1.8558848387577491,2.598764190735349
771 | -1.224351454072633,7.817535734714233,10.363469661929251
772 | -2.283772960913022,8.330209878099534,9.19634200911012
773 | 1.1812831662654844,5.515150834708585,-0.11415567140964322
774 | 0.8126931114255727,3.676807419342252,3.7017733211057133
775 | 0.5320857911873358,-1.8991333727565751,1.9259466502228775
776 | 0.8632041730715487,3.9941945633075266,1.998082821240724
777 | -0.18111304112442728,3.694870317818514,1.0530843007281834
778 | -1.1991621229080192,7.740284590774232,9.992901607761842
779 | 1.3901700551890528,5.50110930809115,3.938621379348188
780 | -2.063986669089021,0.583395824625653,3.4985523008774293
781 | 1.8267347817166257,5.093998593793733,2.1659943861575797
782 | -1.0418967214638941,-1.1305823290979162,2.414441693404779
783 | -0.5270886493948995,5.505246895023509,8.031836834857236
784 | 0.8120156376612738,4.960424004319936,1.254066478446555
785 | 0.2801586037733914,-1.28043007052708,3.148138577800119
786 | 0.8840183137551477,-2.164481951686322,4.154988345445973
787 | 1.4249889606542507,2.0222236544477306,1.2664580132985064
788 | 1.4689591217370914,-2.2365739196408065,4.941273248000774
789 | -0.16853648818509925,4.251328622325788,2.6099147809154344
790 | 2.897617033907669,3.8440068037526607,0.9662330861957611
791 | 0.20050772517241822,5.299498676095447,0.12206274202576206
792 | 0.12352604587367799,-2.903311783514491,3.5844608228430013
793 | 1.4258826908237516,2.924736883954861,0.5571452319921333
794 | -0.47595278085896575,8.408362381194182,7.570521943908187
795 | 0.20854313924421275,-2.060972485265432,3.430106464321071
796 | -0.34069989865886297,8.056231377842353,10.16684481825354
797 | -2.5429106678276887,-0.6981074507984767,3.734935027852453
798 | 1.4153010824228947,-1.3565239696418419,4.815377080888816
799 | -0.13777886461429345,7.643735238139401,8.659838289275157
800 | 0.595511837671462,-0.8531521771047795,4.586146684033446
801 | -0.9109247482445639,6.354801811296477,10.44301321374158
802 | -0.4723534714626769,8.237972261312471,8.961068753007972
803 | -0.15986545873125735,2.2216575784559596,0.40247556656863637
804 | -1.3646812067548606,6.6677943136577085,9.10404805784928
805 | 1.2657310896759815,-1.4878394350542625,2.374027283543395
806 | -0.030201714972656002,-0.8902274991015646,1.9383876029080769
807 | -0.10200792403659542,5.6992595977544545,3.8427515669958803
808 | 0.9714773372975792,-0.6476846497982657,2.825760676735563
809 | -1.8683278094795561,7.537985439642576,9.78621550223654
810 | -0.9390111444958474,7.469821225670275,9.15745852375843
811 | 1.173757179606279,-1.2677417354985687,2.6718113842746636
812 | 0.9285663094175491,0.03000138878526326,1.332391227098736
813 | -2.4348059104864195,9.117309460284895,8.232642607045772
814 | 0.0002904127848184501,8.23634109880347,8.827985469193699
815 | 2.114096944176946,4.1346300763064745,1.2913538492053762
816 | -1.4827783198049054,7.057617415798421,8.765792305343787
817 | 2.9143050592231194,4.524178638379071,1.5801726310655324
818 | -1.9941198151069635,8.454000940793279,10.457559022140032
819 | -1.250469034737563,8.280429060512622,8.310470664018112
820 | 0.6246603949709215,4.893586466232009,0.5762993931344886
821 | 0.822615840624033,-2.0666128943303557,3.1309533290310285
822 | 1.8364320612399623,4.2610440046714135,1.9800903746193796
823 | 0.004958280239937052,9.83394591291512,7.545721590654498
824 | 1.9924652791332567,4.1061359363193315,2.397256345225435
825 | -0.698571716555238,7.609854501447379,9.424499189397121
826 | -0.10953051692913296,4.9435233223838635,1.6694041849897852
827 | -0.9184561460918941,7.111729062668292,9.804144187723569
828 | -1.7722764174353682,8.213844445496715,10.69058222684269
829 | 1.7719762347239572,3.961202798121459,2.4237344288367995
830 | -0.4078648963829996,8.10366643726418,9.322252970830732
831 | 0.039470913828625,-0.7140213660566048,3.813491706204056
832 | 1.7632037670668215,-1.4739738437049401,3.6041321977920493
833 | -3.0396145809929624,7.638557890746987,10.589841450403942
834 | -2.570357200853608,8.865499969770633,9.95285924907416
835 | 0.8469532586773268,3.405247914656231,3.98591524076924
836 | 0.8607733493250692,-0.7448132796446332,2.1459935624952955
837 | -1.5126596351573318,7.05956011775404,9.113415714346141
838 | 1.852782456447971,-1.9059764912470896,2.3620482168094856
839 | -0.5667863551652665,5.9632476622778485,1.0851752991484602
840 | 0.655490209315536,3.711122511840907,1.663238095121252
841 | -2.476823643987911,9.819090230697514,9.443307201062076
842 | 0.8419238292826985,3.546537655924727,2.218657322779793
843 | 0.6971682982740474,-2.1771628449691147,1.6766126218102355
844 | -1.5764264982915752,7.779880251978534,10.058913762411542
845 | -2.0055387452938485,9.159916094004686,8.80160646546145
846 | 1.836015392328198,4.670067862593104,2.7816906820424987
847 | 0.7380152328173579,4.635295477912116,1.192692627039111
848 | 2.0353126603736236,-0.964844679453339,2.747952267056246
849 | 1.7270314804907594,4.465905615081932,2.679167965337665
850 | 1.1025738317826288,4.2601582268922265,3.0679825401211467
851 | 0.4652615568493419,2.3321755626260896,3.048012289881547
852 | 1.0768264997621573,5.804444090488523,2.007837107735035
853 | 1.183345652601103,4.8272503546376715,1.3558727001002884
854 | -2.388937985175161,7.03298494644083,7.691982005860479
855 | 1.295057270017177,-0.937730745219682,5.3013754298941285
856 | -1.264183232646029,8.753386632765663,8.82324115786026
857 | 2.2769663500489443,5.221990153834312,1.8964670498581704
858 | 1.330782161440374,-2.069411382671081,3.563633585388957
859 | -1.4883132192975195,8.039008368665021,8.266155727015388
860 | 1.5967092621158219,-1.0654999278418547,3.0423183275303227
861 | 1.0788892577923477,-0.7001220648947267,2.754614285717128
862 | 0.3993829550594703,5.4365285481253,2.5544337259044303
863 | 2.286137659525187,-0.75257891060584,3.8571810237040145
864 | 0.012206719704912827,2.3130085074481475,2.1449982483341863
865 | 1.08020599082485,3.4742161408117282,2.548026912848675
866 | 1.9359738881347208,-2.5284889215834094,1.550741277822358
867 | -1.3586246506833755,6.618311549526137,7.372898368526292
868 | -0.4091600406792597,4.748418970134418,1.2085057839513724
869 | -0.5569850505629088,-0.012262153696345868,2.0561387292735724
870 | 0.11091025120584119,-1.0869582294309852,3.047243778448296
871 | 1.055595640687859,-3.044481638695497,3.0052280003238057
872 | -1.5267768688908447,8.517990588717636,8.813289293327486
873 | -0.0770579475151918,-2.261855564879665,3.81394052860004
874 | -0.9014473529706564,8.150841614671961,8.882867606393845
875 | -0.5936121205172942,6.950239371297882,9.746592403273251
876 | -1.7844480785251178,8.036831080026394,8.572320613527642
877 | 1.5325445859062672,-1.1167048386287892,3.1928357973369557
878 | -0.26993300064750503,6.500027250824759,8.31067971988406
879 | 1.673642902680943,2.5663580897830465,2.171123219325952
880 | 0.7056797708478888,-1.1035364049328553,4.095564390943471
881 | -1.4932530056685018,3.1546635722015792,1.5542967353708967
882 | -1.2868277086247562,7.763484341459655,7.896298130186474
883 | 0.17803277968082076,-2.6999162819228824,4.539375706718122
884 | -1.8821674201941225,8.537598575779269,8.706308473332797
885 | 0.7958248161249022,-1.4475166652839848,3.654216696367418
886 | 1.0268559554966445,0.23576457355923353,2.5021656615816084
887 | 1.2219352983509404,-0.2300610229795581,4.221789715140197
888 | -2.435674500272181,7.649084669270109,7.5651185882032435
889 | 0.0012891127328533702,6.234288678617261,3.5491218009110312
890 | 1.8418568152921715,-2.5827301213292957,3.045547360799401
891 | 0.2747399283524139,6.907474649168059,8.917709548701568
892 | -1.3959486848821738,6.550384941526115,7.986520134413488
893 | 2.078194827905329,0.7926048799691254,2.476395660509841
894 | 1.918104416720949,4.021652185844471,1.079612855760506
895 | 2.684308467814808,-1.5798395724556609,3.246316315044342
896 | 1.9498687908276424,4.511070099883154,3.1549094941023714
897 | 0.7318674910635502,4.485770411425078,0.7168589640729615
898 | 2.619881364152967,-1.0658545450257526,3.7350312056926978
899 | 1.0624083787431529,2.5665524002572977,2.2102012988737605
900 | -0.7631559567417372,6.6479350476646175,10.20303778955965
901 | 2.890624457724499,4.784476622752317,2.0675768163272674
902 | 1.3433056176459814,4.636654767546166,1.5593994923340342
903 | 0.006249091828487319,-1.4456689186109826,2.3468885715233583
904 | 0.28057918560059847,-2.781577876449761,2.011007676121713
905 | -0.7706197747207717,0.4196125439190639,2.7824845016936846
906 | -3.424762736472672,8.649490253641488,7.983941771295228
907 | 1.6144583466646847,-1.4647572769426234,2.823722336948524
908 | -0.04137793794456579,10.01377487494677,9.804904327338539
909 | 2.5004968913122516,6.167362645236398,3.346645441988535
910 | 1.2149240677016995,4.709429763566921,2.3549262511248794
911 | -2.536916824703287,7.972375224524267,8.529419739581597
912 | 3.279673658824334,-1.4573641808488258,3.1551420852498007
913 | 2.452259911028767,4.950567424587176,1.6909332094985658
914 | 1.0744567693817448,5.209277280637901,3.0740089583330588
915 | 0.046130083700252955,2.8097138088902565,2.5240067897624687
916 | -1.9115698358841975,7.863573944704653,8.12912043963226
917 | 0.5415628424712968,-2.0867033270727804,2.6515573763864166
918 | 1.2667395626441946,-1.71393529321674,2.9949961993456613
919 | 1.3426127052267915,-1.4459384223612706,3.0243097893551067
920 | -1.716933196726254,-1.0467982272415832,2.1690958759106547
921 | 1.203195803237794,-0.7019517296766964,3.874680123848658
922 | 0.9832737921737267,-1.9693618999208087,1.8279747599450265
923 | -2.039231608724165,7.960023080077676,9.801310926108638
924 | -1.5311766191387495,6.957555248805834,7.843963321796138
925 | -2.468804298709996,8.192077540713033,10.99757745051988
926 | 0.3705993219165258,7.189412713247708,10.036748274272464
927 | 1.6831124673128324,5.096395112176477,1.8218444395372237
928 | -0.015307866611385723,-1.1001641752237785,3.354426818603293
929 | 1.9855146094610514,5.017176897967928,1.3272098026044703
930 | 0.296007761635376,9.130520897496694,10.089725634491261
931 | -0.7889918169642478,-2.0169719388746468,3.525334990486183
932 | 1.4546749583789118,4.39552497920373,2.097920998298672
933 | -0.8125714496717991,5.3056016440155,10.034327070263906
934 | -1.9289132013388361,9.147632144275118,9.782326431243607
935 | -1.5174466540135731,9.449236901595855,9.144797445881114
936 | 1.4045958168075443,-1.579567126025129,4.757587684223678
937 | 1.8169998795086804,-1.1025296863638019,3.686042358738552
938 | -1.3558992783114945,6.779189688501344,10.03010154364713
939 | -0.821415253808407,7.256604253781066,8.226306500026627
940 | 1.8695464362604728,4.690548492144033,2.050133249573679
941 | -0.41492303676007647,4.34004706914198,1.2408619600747115
942 | 0.2698262195221425,-1.899158718231087,3.762779862156557
943 | 2.519276708212101,-1.962964859608087,3.9247520691468747
944 | -3.115840270900345,7.928687521370281,9.671091845746718
945 | -1.6757443414357986,8.045085948062507,10.001284586254922
946 | -0.8035100191508147,7.496342214629416,8.64022254603333
947 | 2.8915969341455376,-1.6912010275495393,2.5849381813329533
948 | 1.8002033440507552,-2.812593451593551,3.2281848846993317
949 | 1.3831862133034667,-1.9707123915561842,2.5946714623674847
950 | -1.6939535272360342,7.939838815177863,8.86277644876249
951 | -1.59206059308127,8.619203270379979,11.057000430153943
952 | 1.9750434203403415,-2.712800399216209,2.384105759973349
953 | -0.17519556693028493,4.020601451686841,1.9854077662844714
954 | 2.6601925367117096,5.586159746045876,1.71157729768843
955 | 0.694743727989845,4.864156659649771,2.8104765027483896
956 | 0.5449502617092813,-0.990142380338694,2.695747285140985
957 | 0.4906237234642068,8.271240080835877,9.928118981501928
958 | 2.262242639648106,3.1487202969345702,2.1741439755844496
959 | -0.026638202575014036,-1.483120962264854,1.158640474792675
960 | -1.0709694018377358,-0.5869988819632916,3.381111437305695
961 | 0.12374425884791296,4.690517232281894,2.966006946680185
962 | 1.1836190495334793,-3.0096439719045005,4.561808529225727
963 | 0.5162155487932396,0.849708326137089,4.176496888418931
964 | -1.847672921568942,8.560272444173922,9.082781785962462
965 | 1.390032299360482,-3.031225648671349,2.732362499447468
966 | -1.4788483810482487,4.8011005985249975,1.5502545127552474
967 | 0.8489856287437733,3.462803316578767,1.5599613206259269
968 | 1.693225270687357,-1.376392534697569,3.275521956366704
969 | -1.424443080752048,7.95619766799728,8.013585808957849
970 | 0.5361587836444708,3.398674434497289,1.730701039082371
971 | -2.5183118864599483,6.641592374794139,8.544197689525603
972 | -0.06840443540899332,-0.4699161214036345,3.9364313854554958
973 | -0.7736779351523653,9.814777057287532,8.627059524660721
974 | 1.2595582570143957,3.505862703353556,3.6219964635460133
975 | -0.44668588861886604,3.47732620677496,2.8394761476670443
976 | -1.4964120435122135,7.780593884520513,8.793235273303734
977 | -1.0389045185270867,8.19926005472849,8.98913711954563
978 | 0.9054938382271919,0.7630325461064449,0.5527855885716946
979 | 0.04212505226977026,7.262368064645625,6.068984148467471
980 | 0.218796329899959,-2.182536950625483,3.9578745942959164
981 | -0.9725776556044927,9.227262534925472,10.193246847166845
982 | 1.3818210274534222,6.984956891544929,9.64726972494305
983 | 2.5337274409208415,-1.1655612441842624,2.668030497738718
984 | 0.46783738724730384,8.196975659932535,8.642789295993383
985 | -1.1339340055699745,7.7853433467196815,10.825768336621294
986 | -1.5393708533218633,7.351350607098357,8.513724841301608
987 | -2.326241030915212,7.421232527135594,10.877942154699175
988 | -0.3769298627028812,4.274841799163397,0.337835049976815
989 | 0.626845220194512,-2.298066852170238,2.5797562932341456
990 | -1.1598274434328888,7.331088312898528,8.523672506248023
991 | 0.5183476581425921,4.72918072591804,2.0272963379630977
992 | -2.026007889821278,7.937452210475632,9.6962477722933
993 | -0.2937369793850533,-1.6194902829828899,3.1179800941171196
994 | -1.5089682078589552,4.884370708346513,10.07635204953735
995 | 0.9668854086764306,0.4465477629631287,4.154783303714957
996 | 0.5967055690807888,4.160564093370887,0.8291267310621453
997 | -1.403240267764577,7.440178148673143,8.472791217035006
998 | 1.3384216382618366,3.8902912554592195,3.5956564334153245
999 | -0.25432303813402624,2.345515717943158,1.53730483530035
1000 | 0.7288550305114597,5.895845668088949,2.6181875205838585
1001 |
--------------------------------------------------------------------------------
/vendor/nanoflann/nanoflann.hpp:
--------------------------------------------------------------------------------
1 | /***********************************************************************
2 | * Software License Agreement (BSD License)
3 | *
4 | * Copyright 2008-2009 Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
5 | * Copyright 2008-2009 David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
6 | * Copyright 2011-2016 Jose Luis Blanco (joseluisblancoc@gmail.com).
7 | * All rights reserved.
8 | *
9 | * THE BSD LICENSE
10 | *
11 | * Redistribution and use in source and binary forms, with or without
12 | * modification, are permitted provided that the following conditions
13 | * are met:
14 | *
15 | * 1. Redistributions of source code must retain the above copyright
16 | * notice, this list of conditions and the following disclaimer.
17 | * 2. Redistributions in binary form must reproduce the above copyright
18 | * notice, this list of conditions and the following disclaimer in the
19 | * documentation and/or other materials provided with the distribution.
20 | *
21 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 | *************************************************************************/
32 |
33 | /** \mainpage nanoflann C++ API documentation
34 | * nanoflann is a C++ header-only library for building KD-Trees, mostly
35 | * optimized for 2D or 3D point clouds.
36 | *
37 | * nanoflann does not require compiling or installing, just an
38 | * #include in your code.
39 | *
40 | * See:
41 | * - C++ API organized by modules
42 | * - Online README
43 | * - Doxygen
44 | * documentation
45 | */
46 |
47 | #ifndef NANOFLANN_HPP_
48 | #define NANOFLANN_HPP_
49 |
50 | #include
51 | #include
52 | #include
53 | #include // for abs()
54 | #include // for fwrite()
55 | #include // for abs()
56 | #include
57 | #include // std::reference_wrapper
58 | #include
59 | #include
60 |
61 | /** Library version: 0xMmP (M=Major,m=minor,P=patch) */
62 | #define NANOFLANN_VERSION 0x132
63 |
64 | // Avoid conflicting declaration of min/max macros in windows headers
65 | #if !defined(NOMINMAX) && \
66 | (defined(_WIN32) || defined(_WIN32_) || defined(WIN32) || defined(_WIN64))
67 | #define NOMINMAX
68 | #ifdef max
69 | #undef max
70 | #undef min
71 | #endif
72 | #endif
73 |
74 | namespace nanoflann {
75 | /** @addtogroup nanoflann_grp nanoflann C++ library for ANN
76 | * @{ */
77 |
78 | /** the PI constant (required to avoid MSVC missing symbols) */
79 | template T pi_const() {
80 | return static_cast(3.14159265358979323846);
81 | }
82 |
83 | /**
84 | * Traits if object is resizable and assignable (typically has a resize | assign
85 | * method)
86 | */
87 | template struct has_resize : std::false_type {};
88 |
89 | template
90 | struct has_resize().resize(1), 0)>
91 | : std::true_type {};
92 |
93 | template struct has_assign : std::false_type {};
94 |
95 | template
96 | struct has_assign().assign(1, 0), 0)>
97 | : std::true_type {};
98 |
99 | /**
100 | * Free function to resize a resizable object
101 | */
102 | template
103 | inline typename std::enable_if::value, void>::type
104 | resize(Container &c, const size_t nElements) {
105 | c.resize(nElements);
106 | }
107 |
108 | /**
109 | * Free function that has no effects on non resizable containers (e.g.
110 | * std::array) It raises an exception if the expected size does not match
111 | */
112 | template
113 | inline typename std::enable_if::value, void>::type
114 | resize(Container &c, const size_t nElements) {
115 | if (nElements != c.size())
116 | throw std::logic_error("Try to change the size of a std::array.");
117 | }
118 |
119 | /**
120 | * Free function to assign to a container
121 | */
122 | template
123 | inline typename std::enable_if::value, void>::type
124 | assign(Container &c, const size_t nElements, const T &value) {
125 | c.assign(nElements, value);
126 | }
127 |
128 | /**
129 | * Free function to assign to a std::array
130 | */
131 | template
132 | inline typename std::enable_if::value, void>::type
133 | assign(Container &c, const size_t nElements, const T &value) {
134 | for (size_t i = 0; i < nElements; i++)
135 | c[i] = value;
136 | }
137 |
138 | /** @addtogroup result_sets_grp Result set classes
139 | * @{ */
140 | template
142 | class KNNResultSet {
143 | public:
144 | typedef _DistanceType DistanceType;
145 | typedef _IndexType IndexType;
146 | typedef _CountType CountType;
147 |
148 | private:
149 | IndexType *indices;
150 | DistanceType *dists;
151 | CountType capacity;
152 | CountType count;
153 |
154 | public:
155 | inline KNNResultSet(CountType capacity_)
156 | : indices(0), dists(0), capacity(capacity_), count(0) {}
157 |
158 | inline void init(IndexType *indices_, DistanceType *dists_) {
159 | indices = indices_;
160 | dists = dists_;
161 | count = 0;
162 | if (capacity)
163 | dists[capacity - 1] = (std::numeric_limits::max)();
164 | }
165 |
166 | inline CountType size() const { return count; }
167 |
168 | inline bool full() const { return count == capacity; }
169 |
170 | /**
171 | * Called during search to add an element matching the criteria.
172 | * @return true if the search should be continued, false if the results are
173 | * sufficient
174 | */
175 | inline bool addPoint(DistanceType dist, IndexType index) {
176 | CountType i;
177 | for (i = count; i > 0; --i) {
178 | #ifdef NANOFLANN_FIRST_MATCH // If defined and two points have the same
179 | // distance, the one with the lowest-index will be
180 | // returned first.
181 | if ((dists[i - 1] > dist) ||
182 | ((dist == dists[i - 1]) && (indices[i - 1] > index))) {
183 | #else
184 | if (dists[i - 1] > dist) {
185 | #endif
186 | if (i < capacity) {
187 | dists[i] = dists[i - 1];
188 | indices[i] = indices[i - 1];
189 | }
190 | } else
191 | break;
192 | }
193 | if (i < capacity) {
194 | dists[i] = dist;
195 | indices[i] = index;
196 | }
197 | if (count < capacity)
198 | count++;
199 |
200 | // tell caller that the search shall continue
201 | return true;
202 | }
203 |
204 | inline DistanceType worstDist() const { return dists[capacity - 1]; }
205 | };
206 |
207 | /** operator "<" for std::sort() */
208 | struct IndexDist_Sorter {
209 | /** PairType will be typically: std::pair */
210 | template
211 | inline bool operator()(const PairType &p1, const PairType &p2) const {
212 | return p1.second < p2.second;
213 | }
214 | };
215 |
216 | /**
217 | * A result-set class used when performing a radius based search.
218 | */
219 | template
220 | class RadiusResultSet {
221 | public:
222 | typedef _DistanceType DistanceType;
223 | typedef _IndexType IndexType;
224 |
225 | public:
226 | const DistanceType radius;
227 |
228 | std::vector> &m_indices_dists;
229 |
230 | inline RadiusResultSet(
231 | DistanceType radius_,
232 | std::vector> &indices_dists)
233 | : radius(radius_), m_indices_dists(indices_dists) {
234 | init();
235 | }
236 |
237 | inline void init() { clear(); }
238 | inline void clear() { m_indices_dists.clear(); }
239 |
240 | inline size_t size() const { return m_indices_dists.size(); }
241 |
242 | inline bool full() const { return true; }
243 |
244 | /**
245 | * Called during search to add an element matching the criteria.
246 | * @return true if the search should be continued, false if the results are
247 | * sufficient
248 | */
249 | inline bool addPoint(DistanceType dist, IndexType index) {
250 | if (dist < radius)
251 | m_indices_dists.push_back(std::make_pair(index, dist));
252 | return true;
253 | }
254 |
255 | inline DistanceType worstDist() const { return radius; }
256 |
257 | /**
258 | * Find the worst result (furtherest neighbor) without copying or sorting
259 | * Pre-conditions: size() > 0
260 | */
261 | std::pair worst_item() const {
262 | if (m_indices_dists.empty())
263 | throw std::runtime_error("Cannot invoke RadiusResultSet::worst_item() on "
264 | "an empty list of results.");
265 | typedef
266 | typename std::vector>::const_iterator
267 | DistIt;
268 | DistIt it = std::max_element(m_indices_dists.begin(), m_indices_dists.end(),
269 | IndexDist_Sorter());
270 | return *it;
271 | }
272 | };
273 |
274 | /** @} */
275 |
276 | /** @addtogroup loadsave_grp Load/save auxiliary functions
277 | * @{ */
278 | template
279 | void save_value(FILE *stream, const T &value, size_t count = 1) {
280 | fwrite(&value, sizeof(value), count, stream);
281 | }
282 |
283 | template
284 | void save_value(FILE *stream, const std::vector &value) {
285 | size_t size = value.size();
286 | fwrite(&size, sizeof(size_t), 1, stream);
287 | fwrite(&value[0], sizeof(T), size, stream);
288 | }
289 |
290 | template
291 | void load_value(FILE *stream, T &value, size_t count = 1) {
292 | size_t read_cnt = fread(&value, sizeof(value), count, stream);
293 | if (read_cnt != count) {
294 | throw std::runtime_error("Cannot read from file");
295 | }
296 | }
297 |
298 | template void load_value(FILE *stream, std::vector &value) {
299 | size_t size;
300 | size_t read_cnt = fread(&size, sizeof(size_t), 1, stream);
301 | if (read_cnt != 1) {
302 | throw std::runtime_error("Cannot read from file");
303 | }
304 | value.resize(size);
305 | read_cnt = fread(&value[0], sizeof(T), size, stream);
306 | if (read_cnt != size) {
307 | throw std::runtime_error("Cannot read from file");
308 | }
309 | }
310 | /** @} */
311 |
312 | /** @addtogroup metric_grp Metric (distance) classes
313 | * @{ */
314 |
315 | struct Metric {};
316 |
317 | /** Manhattan distance functor (generic version, optimized for
318 | * high-dimensionality data sets). Corresponding distance traits:
319 | * nanoflann::metric_L1 \tparam T Type of the elements (e.g. double, float,
320 | * uint8_t) \tparam _DistanceType Type of distance variables (must be signed)
321 | * (e.g. float, double, int64_t)
322 | */
323 | template
324 | struct L1_Adaptor {
325 | typedef T ElementType;
326 | typedef _DistanceType DistanceType;
327 |
328 | const DataSource &data_source;
329 |
330 | L1_Adaptor(const DataSource &_data_source) : data_source(_data_source) {}
331 |
332 | inline DistanceType evalMetric(const T *a, const size_t b_idx, size_t size,
333 | DistanceType worst_dist = -1) const {
334 | DistanceType result = DistanceType();
335 | const T *last = a + size;
336 | const T *lastgroup = last - 3;
337 | size_t d = 0;
338 |
339 | /* Process 4 items with each loop for efficiency. */
340 | while (a < lastgroup) {
341 | const DistanceType diff0 =
342 | std::abs(a[0] - data_source.kdtree_get_pt(b_idx, d++));
343 | const DistanceType diff1 =
344 | std::abs(a[1] - data_source.kdtree_get_pt(b_idx, d++));
345 | const DistanceType diff2 =
346 | std::abs(a[2] - data_source.kdtree_get_pt(b_idx, d++));
347 | const DistanceType diff3 =
348 | std::abs(a[3] - data_source.kdtree_get_pt(b_idx, d++));
349 | result += diff0 + diff1 + diff2 + diff3;
350 | a += 4;
351 | if ((worst_dist > 0) && (result > worst_dist)) {
352 | return result;
353 | }
354 | }
355 | /* Process last 0-3 components. Not needed for standard vector lengths. */
356 | while (a < last) {
357 | result += std::abs(*a++ - data_source.kdtree_get_pt(b_idx, d++));
358 | }
359 | return result;
360 | }
361 |
362 | template
363 | inline DistanceType accum_dist(const U a, const V b, const size_t) const {
364 | return std::abs(a - b);
365 | }
366 | };
367 |
368 | /** Squared Euclidean distance functor (generic version, optimized for
369 | * high-dimensionality data sets). Corresponding distance traits:
370 | * nanoflann::metric_L2 \tparam T Type of the elements (e.g. double, float,
371 | * uint8_t) \tparam _DistanceType Type of distance variables (must be signed)
372 | * (e.g. float, double, int64_t)
373 | */
374 | template
375 | struct L2_Adaptor {
376 | typedef T ElementType;
377 | typedef _DistanceType DistanceType;
378 |
379 | const DataSource &data_source;
380 |
381 | L2_Adaptor(const DataSource &_data_source) : data_source(_data_source) {}
382 |
383 | inline DistanceType evalMetric(const T *a, const size_t b_idx, size_t size,
384 | DistanceType worst_dist = -1) const {
385 | DistanceType result = DistanceType();
386 | const T *last = a + size;
387 | const T *lastgroup = last - 3;
388 | size_t d = 0;
389 |
390 | /* Process 4 items with each loop for efficiency. */
391 | while (a < lastgroup) {
392 | const DistanceType diff0 = a[0] - data_source.kdtree_get_pt(b_idx, d++);
393 | const DistanceType diff1 = a[1] - data_source.kdtree_get_pt(b_idx, d++);
394 | const DistanceType diff2 = a[2] - data_source.kdtree_get_pt(b_idx, d++);
395 | const DistanceType diff3 = a[3] - data_source.kdtree_get_pt(b_idx, d++);
396 | result += diff0 * diff0 + diff1 * diff1 + diff2 * diff2 + diff3 * diff3;
397 | a += 4;
398 | if ((worst_dist > 0) && (result > worst_dist)) {
399 | return result;
400 | }
401 | }
402 | /* Process last 0-3 components. Not needed for standard vector lengths. */
403 | while (a < last) {
404 | const DistanceType diff0 = *a++ - data_source.kdtree_get_pt(b_idx, d++);
405 | result += diff0 * diff0;
406 | }
407 | return result;
408 | }
409 |
410 | template
411 | inline DistanceType accum_dist(const U a, const V b, const size_t) const {
412 | return (a - b) * (a - b);
413 | }
414 | };
415 |
416 | /** Squared Euclidean (L2) distance functor (suitable for low-dimensionality
417 | * datasets, like 2D or 3D point clouds) Corresponding distance traits:
418 | * nanoflann::metric_L2_Simple \tparam T Type of the elements (e.g. double,
419 | * float, uint8_t) \tparam _DistanceType Type of distance variables (must be
420 | * signed) (e.g. float, double, int64_t)
421 | */
422 | template
423 | struct L2_Simple_Adaptor {
424 | typedef T ElementType;
425 | typedef _DistanceType DistanceType;
426 |
427 | const DataSource &data_source;
428 |
429 | L2_Simple_Adaptor(const DataSource &_data_source)
430 | : data_source(_data_source) {}
431 |
432 | inline DistanceType evalMetric(const T *a, const size_t b_idx,
433 | size_t size) const {
434 | DistanceType result = DistanceType();
435 | for (size_t i = 0; i < size; ++i) {
436 | const DistanceType diff = a[i] - data_source.kdtree_get_pt(b_idx, i);
437 | result += diff * diff;
438 | }
439 | return result;
440 | }
441 |
442 | template
443 | inline DistanceType accum_dist(const U a, const V b, const size_t) const {
444 | return (a - b) * (a - b);
445 | }
446 | };
447 |
448 | /** SO2 distance functor
449 | * Corresponding distance traits: nanoflann::metric_SO2
450 | * \tparam T Type of the elements (e.g. double, float)
451 | * \tparam _DistanceType Type of distance variables (must be signed) (e.g.
452 | * float, double) orientation is constrained to be in [-pi, pi]
453 | */
454 | template
455 | struct SO2_Adaptor {
456 | typedef T ElementType;
457 | typedef _DistanceType DistanceType;
458 |
459 | const DataSource &data_source;
460 |
461 | SO2_Adaptor(const DataSource &_data_source) : data_source(_data_source) {}
462 |
463 | inline DistanceType evalMetric(const T *a, const size_t b_idx,
464 | size_t size) const {
465 | return accum_dist(a[size - 1], data_source.kdtree_get_pt(b_idx, size - 1),
466 | size - 1);
467 | }
468 |
469 | /** Note: this assumes that input angles are already in the range [-pi,pi] */
470 | template
471 | inline DistanceType accum_dist(const U a, const V b, const size_t) const {
472 | DistanceType result = DistanceType();
473 | DistanceType PI = pi_const();
474 | result = b - a;
475 | if (result > PI)
476 | result -= 2 * PI;
477 | else if (result < -PI)
478 | result += 2 * PI;
479 | return result;
480 | }
481 | };
482 |
483 | /** SO3 distance functor (Uses L2_Simple)
484 | * Corresponding distance traits: nanoflann::metric_SO3
485 | * \tparam T Type of the elements (e.g. double, float)
486 | * \tparam _DistanceType Type of distance variables (must be signed) (e.g.
487 | * float, double)
488 | */
489 | template
490 | struct SO3_Adaptor {
491 | typedef T ElementType;
492 | typedef _DistanceType DistanceType;
493 |
494 | L2_Simple_Adaptor distance_L2_Simple;
495 |
496 | SO3_Adaptor(const DataSource &_data_source)
497 | : distance_L2_Simple(_data_source) {}
498 |
499 | inline DistanceType evalMetric(const T *a, const size_t b_idx,
500 | size_t size) const {
501 | return distance_L2_Simple.evalMetric(a, b_idx, size);
502 | }
503 |
504 | template
505 | inline DistanceType accum_dist(const U a, const V b, const size_t idx) const {
506 | return distance_L2_Simple.accum_dist(a, b, idx);
507 | }
508 | };
509 |
510 | /** Metaprogramming helper traits class for the L1 (Manhattan) metric */
511 | struct metric_L1 : public Metric {
512 | template struct traits {
513 | typedef L1_Adaptor distance_t;
514 | };
515 | };
516 | /** Metaprogramming helper traits class for the L2 (Euclidean) metric */
517 | struct metric_L2 : public Metric {
518 | template struct traits {
519 | typedef L2_Adaptor distance_t;
520 | };
521 | };
522 | /** Metaprogramming helper traits class for the L2_simple (Euclidean) metric */
523 | struct metric_L2_Simple : public Metric {
524 | template struct traits {
525 | typedef L2_Simple_Adaptor distance_t;
526 | };
527 | };
528 | /** Metaprogramming helper traits class for the SO3_InnerProdQuat metric */
529 | struct metric_SO2 : public Metric {
530 | template struct traits {
531 | typedef SO2_Adaptor distance_t;
532 | };
533 | };
534 | /** Metaprogramming helper traits class for the SO3_InnerProdQuat metric */
535 | struct metric_SO3 : public Metric {
536 | template struct traits {
537 | typedef SO3_Adaptor distance_t;
538 | };
539 | };
540 |
541 | /** @} */
542 |
543 | /** @addtogroup param_grp Parameter structs
544 | * @{ */
545 |
546 | /** Parameters (see README.md) */
547 | struct KDTreeSingleIndexAdaptorParams {
548 | KDTreeSingleIndexAdaptorParams(size_t _leaf_max_size = 10)
549 | : leaf_max_size(_leaf_max_size) {}
550 |
551 | size_t leaf_max_size;
552 | };
553 |
554 | /** Search options for KDTreeSingleIndexAdaptor::findNeighbors() */
555 | struct SearchParams {
556 | /** Note: The first argument (checks_IGNORED_) is ignored, but kept for
557 | * compatibility with the FLANN interface */
558 | SearchParams(int checks_IGNORED_ = 32, float eps_ = 0, bool sorted_ = true)
559 | : checks(checks_IGNORED_), eps(eps_), sorted(sorted_) {}
560 |
561 | int checks; //!< Ignored parameter (Kept for compatibility with the FLANN
562 | //!< interface).
563 | float eps; //!< search for eps-approximate neighbours (default: 0)
564 | bool sorted; //!< only for radius search, require neighbours sorted by
565 | //!< distance (default: true)
566 | };
567 | /** @} */
568 |
569 | /** @addtogroup memalloc_grp Memory allocation
570 | * @{ */
571 |
572 | /**
573 | * Allocates (using C's malloc) a generic type T.
574 | *
575 | * Params:
576 | * count = number of instances to allocate.
577 | * Returns: pointer (of type T*) to memory buffer
578 | */
579 | template inline T *allocate(size_t count = 1) {
580 | T *mem = static_cast(::malloc(sizeof(T) * count));
581 | return mem;
582 | }
583 |
584 | /**
585 | * Pooled storage allocator
586 | *
587 | * The following routines allow for the efficient allocation of storage in
588 | * small chunks from a specified pool. Rather than allowing each structure
589 | * to be freed individually, an entire pool of storage is freed at once.
590 | * This method has two advantages over just using malloc() and free(). First,
591 | * it is far more efficient for allocating small objects, as there is
592 | * no overhead for remembering all the information needed to free each
593 | * object or consolidating fragmented memory. Second, the decision about
594 | * how long to keep an object is made at the time of allocation, and there
595 | * is no need to track down all the objects to free them.
596 | *
597 | */
598 |
599 | const size_t WORDSIZE = 16;
600 | const size_t BLOCKSIZE = 8192;
601 |
602 | class PooledAllocator {
603 | /* We maintain memory alignment to word boundaries by requiring that all
604 | allocations be in multiples of the machine wordsize. */
605 | /* Size of machine word in bytes. Must be power of 2. */
606 | /* Minimum number of bytes requested at a time from the system. Must be
607 | * multiple of WORDSIZE. */
608 |
609 | size_t remaining; /* Number of bytes left in current block of storage. */
610 | void *base; /* Pointer to base of current block of storage. */
611 | void *loc; /* Current location in block to next allocate memory. */
612 |
613 | void internal_init() {
614 | remaining = 0;
615 | base = NULL;
616 | usedMemory = 0;
617 | wastedMemory = 0;
618 | }
619 |
620 | public:
621 | size_t usedMemory;
622 | size_t wastedMemory;
623 |
624 | /**
625 | Default constructor. Initializes a new pool.
626 | */
627 | PooledAllocator() { internal_init(); }
628 |
629 | /**
630 | * Destructor. Frees all the memory allocated in this pool.
631 | */
632 | ~PooledAllocator() { free_all(); }
633 |
634 | /** Frees all allocated memory chunks */
635 | void free_all() {
636 | while (base != NULL) {
637 | void *prev =
638 | *(static_cast(base)); /* Get pointer to prev block. */
639 | ::free(base);
640 | base = prev;
641 | }
642 | internal_init();
643 | }
644 |
645 | /**
646 | * Returns a pointer to a piece of new memory of the given size in bytes
647 | * allocated from the pool.
648 | */
649 | void *malloc(const size_t req_size) {
650 | /* Round size up to a multiple of wordsize. The following expression
651 | only works for WORDSIZE that is a power of 2, by masking last bits of
652 | incremented size to zero.
653 | */
654 | const size_t size = (req_size + (WORDSIZE - 1)) & ~(WORDSIZE - 1);
655 |
656 | /* Check whether a new block must be allocated. Note that the first word
657 | of a block is reserved for a pointer to the previous block.
658 | */
659 | if (size > remaining) {
660 |
661 | wastedMemory += remaining;
662 |
663 | /* Allocate new storage. */
664 | const size_t blocksize =
665 | (size + sizeof(void *) + (WORDSIZE - 1) > BLOCKSIZE)
666 | ? size + sizeof(void *) + (WORDSIZE - 1)
667 | : BLOCKSIZE;
668 |
669 | // use the standard C malloc to allocate memory
670 | void *m = ::malloc(blocksize);
671 | if (!m) {
672 | fprintf(stderr, "Failed to allocate memory.\n");
673 | throw std::bad_alloc();
674 | }
675 |
676 | /* Fill first word of new block with pointer to previous block. */
677 | static_cast(m)[0] = base;
678 | base = m;
679 |
680 | size_t shift = 0;
681 | // int size_t = (WORDSIZE - ( (((size_t)m) + sizeof(void*)) &
682 | // (WORDSIZE-1))) & (WORDSIZE-1);
683 |
684 | remaining = blocksize - sizeof(void *) - shift;
685 | loc = (static_cast(m) + sizeof(void *) + shift);
686 | }
687 | void *rloc = loc;
688 | loc = static_cast(loc) + size;
689 | remaining -= size;
690 |
691 | usedMemory += size;
692 |
693 | return rloc;
694 | }
695 |
696 | /**
697 | * Allocates (using this pool) a generic type T.
698 | *
699 | * Params:
700 | * count = number of instances to allocate.
701 | * Returns: pointer (of type T*) to memory buffer
702 | */
703 | template T *allocate(const size_t count = 1) {
704 | T *mem = static_cast(this->malloc(sizeof(T) * count));
705 | return mem;
706 | }
707 | };
708 | /** @} */
709 |
710 | /** @addtogroup nanoflann_metaprog_grp Auxiliary metaprogramming stuff
711 | * @{ */
712 |
713 | /** Used to declare fixed-size arrays when DIM>0, dynamically-allocated vectors
714 | * when DIM=-1. Fixed size version for a generic DIM:
715 | */
716 | template struct array_or_vector_selector {
717 | typedef std::array container_t;
718 | };
719 | /** Dynamic size version */
720 | template struct array_or_vector_selector<-1, T> {
721 | typedef std::vector container_t;
722 | };
723 |
724 | /** @} */
725 |
726 | /** kd-tree base-class
727 | *
728 | * Contains the member functions common to the classes KDTreeSingleIndexAdaptor
729 | * and KDTreeSingleIndexDynamicAdaptor_.
730 | *
731 | * \tparam Derived The name of the class which inherits this class.
732 | * \tparam DatasetAdaptor The user-provided adaptor (see comments above).
733 | * \tparam Distance The distance metric to use, these are all classes derived
734 | * from nanoflann::Metric \tparam DIM Dimensionality of data points (e.g. 3 for
735 | * 3D points) \tparam IndexType Will be typically size_t or int
736 | */
737 |
738 | template
740 | class KDTreeBaseClass {
741 |
742 | public:
743 | /** Frees the previously-built index. Automatically called within
744 | * buildIndex(). */
745 | void freeIndex(Derived &obj) {
746 | obj.pool.free_all();
747 | obj.root_node = NULL;
748 | obj.m_size_at_index_build = 0;
749 | }
750 |
751 | typedef typename Distance::ElementType ElementType;
752 | typedef typename Distance::DistanceType DistanceType;
753 |
754 | /*--------------------- Internal Data Structures --------------------------*/
755 | struct Node {
756 | /** Union used because a node can be either a LEAF node or a non-leaf node,
757 | * so both data fields are never used simultaneously */
758 | union {
759 | struct leaf {
760 | IndexType left, right; //!< Indices of points in leaf node
761 | } lr;
762 | struct nonleaf {
763 | int divfeat; //!< Dimension used for subdivision.
764 | DistanceType divlow, divhigh; //!< The values used for subdivision.
765 | } sub;
766 | } node_type;
767 | Node *child1, *child2; //!< Child nodes (both=NULL mean its a leaf node)
768 | };
769 |
770 | typedef Node *NodePtr;
771 |
772 | struct Interval {
773 | ElementType low, high;
774 | };
775 |
776 | /**
777 | * Array of indices to vectors in the dataset.
778 | */
779 | std::vector vind;
780 |
781 | NodePtr root_node;
782 |
783 | size_t m_leaf_max_size;
784 |
785 | size_t m_size; //!< Number of current points in the dataset
786 | size_t m_size_at_index_build; //!< Number of points in the dataset when the
787 | //!< index was built
788 | int dim; //!< Dimensionality of each data point
789 |
790 | /** Define "BoundingBox" as a fixed-size or variable-size container depending
791 | * on "DIM" */
792 | typedef
793 | typename array_or_vector_selector::container_t BoundingBox;
794 |
795 | /** Define "distance_vector_t" as a fixed-size or variable-size container
796 | * depending on "DIM" */
797 | typedef typename array_or_vector_selector::container_t
798 | distance_vector_t;
799 |
800 | /** The KD-tree used to find neighbours */
801 |
802 | BoundingBox root_bbox;
803 |
804 | /**
805 | * Pooled memory allocator.
806 | *
807 | * Using a pooled memory allocator is more efficient
808 | * than allocating memory directly when there is a large
809 | * number small of memory allocations.
810 | */
811 | PooledAllocator pool;
812 |
813 | /** Returns number of points in dataset */
814 | size_t size(const Derived &obj) const { return obj.m_size; }
815 |
816 | /** Returns the length of each point in the dataset */
817 | size_t veclen(const Derived &obj) {
818 | return static_cast(DIM > 0 ? DIM : obj.dim);
819 | }
820 |
821 | /// Helper accessor to the dataset points:
822 | inline ElementType dataset_get(const Derived &obj, size_t idx,
823 | int component) const {
824 | return obj.dataset.kdtree_get_pt(idx, component);
825 | }
826 |
827 | /**
828 | * Computes the inde memory usage
829 | * Returns: memory used by the index
830 | */
831 | size_t usedMemory(Derived &obj) {
832 | return obj.pool.usedMemory + obj.pool.wastedMemory +
833 | obj.dataset.kdtree_get_point_count() *
834 | sizeof(IndexType); // pool memory and vind array memory
835 | }
836 |
837 | void computeMinMax(const Derived &obj, IndexType *ind, IndexType count,
838 | int element, ElementType &min_elem,
839 | ElementType &max_elem) {
840 | min_elem = dataset_get(obj, ind[0], element);
841 | max_elem = dataset_get(obj, ind[0], element);
842 | for (IndexType i = 1; i < count; ++i) {
843 | ElementType val = dataset_get(obj, ind[i], element);
844 | if (val < min_elem)
845 | min_elem = val;
846 | if (val > max_elem)
847 | max_elem = val;
848 | }
849 | }
850 |
851 | /**
852 | * Create a tree node that subdivides the list of vecs from vind[first]
853 | * to vind[last]. The routine is called recursively on each sublist.
854 | *
855 | * @param left index of the first vector
856 | * @param right index of the last vector
857 | */
858 | NodePtr divideTree(Derived &obj, const IndexType left, const IndexType right,
859 | BoundingBox &bbox) {
860 | NodePtr node = obj.pool.template allocate(); // allocate memory
861 |
862 | /* If too few exemplars remain, then make this a leaf node. */
863 | if ((right - left) <= static_cast(obj.m_leaf_max_size)) {
864 | node->child1 = node->child2 = NULL; /* Mark as leaf node. */
865 | node->node_type.lr.left = left;
866 | node->node_type.lr.right = right;
867 |
868 | // compute bounding-box of leaf points
869 | for (int i = 0; i < (DIM > 0 ? DIM : obj.dim); ++i) {
870 | bbox[i].low = dataset_get(obj, obj.vind[left], i);
871 | bbox[i].high = dataset_get(obj, obj.vind[left], i);
872 | }
873 | for (IndexType k = left + 1; k < right; ++k) {
874 | for (int i = 0; i < (DIM > 0 ? DIM : obj.dim); ++i) {
875 | if (bbox[i].low > dataset_get(obj, obj.vind[k], i))
876 | bbox[i].low = dataset_get(obj, obj.vind[k], i);
877 | if (bbox[i].high < dataset_get(obj, obj.vind[k], i))
878 | bbox[i].high = dataset_get(obj, obj.vind[k], i);
879 | }
880 | }
881 | } else {
882 | IndexType idx;
883 | int cutfeat;
884 | DistanceType cutval;
885 | middleSplit_(obj, &obj.vind[0] + left, right - left, idx, cutfeat, cutval,
886 | bbox);
887 |
888 | node->node_type.sub.divfeat = cutfeat;
889 |
890 | BoundingBox left_bbox(bbox);
891 | left_bbox[cutfeat].high = cutval;
892 | node->child1 = divideTree(obj, left, left + idx, left_bbox);
893 |
894 | BoundingBox right_bbox(bbox);
895 | right_bbox[cutfeat].low = cutval;
896 | node->child2 = divideTree(obj, left + idx, right, right_bbox);
897 |
898 | node->node_type.sub.divlow = left_bbox[cutfeat].high;
899 | node->node_type.sub.divhigh = right_bbox[cutfeat].low;
900 |
901 | for (int i = 0; i < (DIM > 0 ? DIM : obj.dim); ++i) {
902 | bbox[i].low = std::min(left_bbox[i].low, right_bbox[i].low);
903 | bbox[i].high = std::max(left_bbox[i].high, right_bbox[i].high);
904 | }
905 | }
906 |
907 | return node;
908 | }
909 |
910 | void middleSplit_(Derived &obj, IndexType *ind, IndexType count,
911 | IndexType &index, int &cutfeat, DistanceType &cutval,
912 | const BoundingBox &bbox) {
913 | const DistanceType EPS = static_cast(0.00001);
914 | ElementType max_span = bbox[0].high - bbox[0].low;
915 | for (int i = 1; i < (DIM > 0 ? DIM : obj.dim); ++i) {
916 | ElementType span = bbox[i].high - bbox[i].low;
917 | if (span > max_span) {
918 | max_span = span;
919 | }
920 | }
921 | ElementType max_spread = -1;
922 | cutfeat = 0;
923 | for (int i = 0; i < (DIM > 0 ? DIM : obj.dim); ++i) {
924 | ElementType span = bbox[i].high - bbox[i].low;
925 | if (span > (1 - EPS) * max_span) {
926 | ElementType min_elem, max_elem;
927 | computeMinMax(obj, ind, count, i, min_elem, max_elem);
928 | ElementType spread = max_elem - min_elem;
929 | ;
930 | if (spread > max_spread) {
931 | cutfeat = i;
932 | max_spread = spread;
933 | }
934 | }
935 | }
936 | // split in the middle
937 | DistanceType split_val = (bbox[cutfeat].low + bbox[cutfeat].high) / 2;
938 | ElementType min_elem, max_elem;
939 | computeMinMax(obj, ind, count, cutfeat, min_elem, max_elem);
940 |
941 | if (split_val < min_elem)
942 | cutval = min_elem;
943 | else if (split_val > max_elem)
944 | cutval = max_elem;
945 | else
946 | cutval = split_val;
947 |
948 | IndexType lim1, lim2;
949 | planeSplit(obj, ind, count, cutfeat, cutval, lim1, lim2);
950 |
951 | if (lim1 > count / 2)
952 | index = lim1;
953 | else if (lim2 < count / 2)
954 | index = lim2;
955 | else
956 | index = count / 2;
957 | }
958 |
959 | /**
960 | * Subdivide the list of points by a plane perpendicular on axe corresponding
961 | * to the 'cutfeat' dimension at 'cutval' position.
962 | *
963 | * On return:
964 | * dataset[ind[0..lim1-1]][cutfeat]cutval
967 | */
968 | void planeSplit(Derived &obj, IndexType *ind, const IndexType count,
969 | int cutfeat, DistanceType &cutval, IndexType &lim1,
970 | IndexType &lim2) {
971 | /* Move vector indices for left subtree to front of list. */
972 | IndexType left = 0;
973 | IndexType right = count - 1;
974 | for (;;) {
975 | while (left <= right && dataset_get(obj, ind[left], cutfeat) < cutval)
976 | ++left;
977 | while (right && left <= right &&
978 | dataset_get(obj, ind[right], cutfeat) >= cutval)
979 | --right;
980 | if (left > right || !right)
981 | break; // "!right" was added to support unsigned Index types
982 | std::swap(ind[left], ind[right]);
983 | ++left;
984 | --right;
985 | }
986 | /* If either list is empty, it means that all remaining features
987 | * are identical. Split in the middle to maintain a balanced tree.
988 | */
989 | lim1 = left;
990 | right = count - 1;
991 | for (;;) {
992 | while (left <= right && dataset_get(obj, ind[left], cutfeat) <= cutval)
993 | ++left;
994 | while (right && left <= right &&
995 | dataset_get(obj, ind[right], cutfeat) > cutval)
996 | --right;
997 | if (left > right || !right)
998 | break; // "!right" was added to support unsigned Index types
999 | std::swap(ind[left], ind[right]);
1000 | ++left;
1001 | --right;
1002 | }
1003 | lim2 = left;
1004 | }
1005 |
1006 | DistanceType computeInitialDistances(const Derived &obj,
1007 | const ElementType *vec,
1008 | distance_vector_t &dists) const {
1009 | assert(vec);
1010 | DistanceType distsq = DistanceType();
1011 |
1012 | for (int i = 0; i < (DIM > 0 ? DIM : obj.dim); ++i) {
1013 | if (vec[i] < obj.root_bbox[i].low) {
1014 | dists[i] = obj.distance.accum_dist(vec[i], obj.root_bbox[i].low, i);
1015 | distsq += dists[i];
1016 | }
1017 | if (vec[i] > obj.root_bbox[i].high) {
1018 | dists[i] = obj.distance.accum_dist(vec[i], obj.root_bbox[i].high, i);
1019 | distsq += dists[i];
1020 | }
1021 | }
1022 | return distsq;
1023 | }
1024 |
1025 | void save_tree(Derived &obj, FILE *stream, NodePtr tree) {
1026 | save_value(stream, *tree);
1027 | if (tree->child1 != NULL) {
1028 | save_tree(obj, stream, tree->child1);
1029 | }
1030 | if (tree->child2 != NULL) {
1031 | save_tree(obj, stream, tree->child2);
1032 | }
1033 | }
1034 |
1035 | void load_tree(Derived &obj, FILE *stream, NodePtr &tree) {
1036 | tree = obj.pool.template allocate();
1037 | load_value(stream, *tree);
1038 | if (tree->child1 != NULL) {
1039 | load_tree(obj, stream, tree->child1);
1040 | }
1041 | if (tree->child2 != NULL) {
1042 | load_tree(obj, stream, tree->child2);
1043 | }
1044 | }
1045 |
1046 | /** Stores the index in a binary file.
1047 | * IMPORTANT NOTE: The set of data points is NOT stored in the file, so when
1048 | * loading the index object it must be constructed associated to the same
1049 | * source of data points used while building it. See the example:
1050 | * examples/saveload_example.cpp \sa loadIndex */
1051 | void saveIndex_(Derived &obj, FILE *stream) {
1052 | save_value(stream, obj.m_size);
1053 | save_value(stream, obj.dim);
1054 | save_value(stream, obj.root_bbox);
1055 | save_value(stream, obj.m_leaf_max_size);
1056 | save_value(stream, obj.vind);
1057 | save_tree(obj, stream, obj.root_node);
1058 | }
1059 |
1060 | /** Loads a previous index from a binary file.
1061 | * IMPORTANT NOTE: The set of data points is NOT stored in the file, so the
1062 | * index object must be constructed associated to the same source of data
1063 | * points used while building the index. See the example:
1064 | * examples/saveload_example.cpp \sa loadIndex */
1065 | void loadIndex_(Derived &obj, FILE *stream) {
1066 | load_value(stream, obj.m_size);
1067 | load_value(stream, obj.dim);
1068 | load_value(stream, obj.root_bbox);
1069 | load_value(stream, obj.m_leaf_max_size);
1070 | load_value(stream, obj.vind);
1071 | load_tree(obj, stream, obj.root_node);
1072 | }
1073 | };
1074 |
1075 | /** @addtogroup kdtrees_grp KD-tree classes and adaptors
1076 | * @{ */
1077 |
1078 | /** kd-tree static index
1079 | *
1080 | * Contains the k-d trees and other information for indexing a set of points
1081 | * for nearest-neighbor matching.
1082 | *
1083 | * The class "DatasetAdaptor" must provide the following interface (can be
1084 | * non-virtual, inlined methods):
1085 | *
1086 | * \code
1087 | * // Must return the number of data poins
1088 | * inline size_t kdtree_get_point_count() const { ... }
1089 | *
1090 | *
1091 | * // Must return the dim'th component of the idx'th point in the class:
1092 | * inline T kdtree_get_pt(const size_t idx, const size_t dim) const { ... }
1093 | *
1094 | * // Optional bounding-box computation: return false to default to a standard
1095 | * bbox computation loop.
1096 | * // Return true if the BBOX was already computed by the class and returned
1097 | * in "bb" so it can be avoided to redo it again.
1098 | * // Look at bb.size() to find out the expected dimensionality (e.g. 2 or 3
1099 | * for point clouds) template bool kdtree_get_bbox(BBOX &bb) const
1100 | * {
1101 | * bb[0].low = ...; bb[0].high = ...; // 0th dimension limits
1102 | * bb[1].low = ...; bb[1].high = ...; // 1st dimension limits
1103 | * ...
1104 | * return true;
1105 | * }
1106 | *
1107 | * \endcode
1108 | *
1109 | * \tparam DatasetAdaptor The user-provided adaptor (see comments above).
1110 | * \tparam Distance The distance metric to use: nanoflann::metric_L1,
1111 | * nanoflann::metric_L2, nanoflann::metric_L2_Simple, etc. \tparam DIM
1112 | * Dimensionality of data points (e.g. 3 for 3D points) \tparam IndexType Will
1113 | * be typically size_t or int
1114 | */
1115 | template
1117 | class KDTreeSingleIndexAdaptor
1118 | : public KDTreeBaseClass<
1119 | KDTreeSingleIndexAdaptor,
1120 | Distance, DatasetAdaptor, DIM, IndexType> {
1121 | public:
1122 | /** Deleted copy constructor*/
1123 | KDTreeSingleIndexAdaptor(
1124 | const KDTreeSingleIndexAdaptor
1125 | &) = delete;
1126 |
1127 | /**
1128 | * The dataset used by this index
1129 | */
1130 | const DatasetAdaptor &dataset; //!< The source of our data
1131 |
1132 | const KDTreeSingleIndexAdaptorParams index_params;
1133 |
1134 | Distance distance;
1135 |
1136 | typedef typename nanoflann::KDTreeBaseClass<
1137 | nanoflann::KDTreeSingleIndexAdaptor,
1139 | Distance, DatasetAdaptor, DIM, IndexType>
1140 | BaseClassRef;
1141 |
1142 | typedef typename BaseClassRef::ElementType ElementType;
1143 | typedef typename BaseClassRef::DistanceType DistanceType;
1144 |
1145 | typedef typename BaseClassRef::Node Node;
1146 | typedef Node *NodePtr;
1147 |
1148 | typedef typename BaseClassRef::Interval Interval;
1149 | /** Define "BoundingBox" as a fixed-size or variable-size container depending
1150 | * on "DIM" */
1151 | typedef typename BaseClassRef::BoundingBox BoundingBox;
1152 |
1153 | /** Define "distance_vector_t" as a fixed-size or variable-size container
1154 | * depending on "DIM" */
1155 | typedef typename BaseClassRef::distance_vector_t distance_vector_t;
1156 |
1157 | /**
1158 | * KDTree constructor
1159 | *
1160 | * Refer to docs in README.md or online in
1161 | * https://github.com/jlblancoc/nanoflann
1162 | *
1163 | * The KD-Tree point dimension (the length of each point in the datase, e.g. 3
1164 | * for 3D points) is determined by means of:
1165 | * - The \a DIM template parameter if >0 (highest priority)
1166 | * - Otherwise, the \a dimensionality parameter of this constructor.
1167 | *
1168 | * @param inputData Dataset with the input features
1169 | * @param params Basically, the maximum leaf node size
1170 | */
1171 | KDTreeSingleIndexAdaptor(const int dimensionality,
1172 | const DatasetAdaptor &inputData,
1173 | const KDTreeSingleIndexAdaptorParams ¶ms =
1174 | KDTreeSingleIndexAdaptorParams())
1175 | : dataset(inputData), index_params(params), distance(inputData) {
1176 | BaseClassRef::root_node = NULL;
1177 | BaseClassRef::m_size = dataset.kdtree_get_point_count();
1178 | BaseClassRef::m_size_at_index_build = BaseClassRef::m_size;
1179 | BaseClassRef::dim = dimensionality;
1180 | if (DIM > 0)
1181 | BaseClassRef::dim = DIM;
1182 | BaseClassRef::m_leaf_max_size = params.leaf_max_size;
1183 |
1184 | // Create a permutable array of indices to the input vectors.
1185 | init_vind();
1186 | }
1187 |
1188 | /**
1189 | * Builds the index
1190 | */
1191 | void buildIndex() {
1192 | BaseClassRef::m_size = dataset.kdtree_get_point_count();
1193 | BaseClassRef::m_size_at_index_build = BaseClassRef::m_size;
1194 | init_vind();
1195 | this->freeIndex(*this);
1196 | BaseClassRef::m_size_at_index_build = BaseClassRef::m_size;
1197 | if (BaseClassRef::m_size == 0)
1198 | return;
1199 | computeBoundingBox(BaseClassRef::root_bbox);
1200 | BaseClassRef::root_node =
1201 | this->divideTree(*this, 0, BaseClassRef::m_size,
1202 | BaseClassRef::root_bbox); // construct the tree
1203 | }
1204 |
1205 | /** \name Query methods
1206 | * @{ */
1207 |
1208 | /**
1209 | * Find set of nearest neighbors to vec[0:dim-1]. Their indices are stored
1210 | * inside the result object.
1211 | *
1212 | * Params:
1213 | * result = the result object in which the indices of the
1214 | * nearest-neighbors are stored vec = the vector for which to search the
1215 | * nearest neighbors
1216 | *
1217 | * \tparam RESULTSET Should be any ResultSet
1218 | * \return True if the requested neighbors could be found.
1219 | * \sa knnSearch, radiusSearch
1220 | */
1221 | template
1222 | bool findNeighbors(RESULTSET &result, const ElementType *vec,
1223 | const SearchParams &searchParams) const {
1224 | assert(vec);
1225 | if (this->size(*this) == 0)
1226 | return false;
1227 | if (!BaseClassRef::root_node)
1228 | throw std::runtime_error(
1229 | "[nanoflann] findNeighbors() called before building the index.");
1230 | float epsError = 1 + searchParams.eps;
1231 |
1232 | distance_vector_t
1233 | dists; // fixed or variable-sized container (depending on DIM)
1234 | auto zero = static_cast(0);
1235 | assign(dists, (DIM > 0 ? DIM : BaseClassRef::dim),
1236 | zero); // Fill it with zeros.
1237 | DistanceType distsq = this->computeInitialDistances(*this, vec, dists);
1238 | searchLevel(result, vec, BaseClassRef::root_node, distsq, dists,
1239 | epsError); // "count_leaf" parameter removed since was neither
1240 | // used nor returned to the user.
1241 | return result.full();
1242 | }
1243 |
1244 | /**
1245 | * Find the "num_closest" nearest neighbors to the \a query_point[0:dim-1].
1246 | * Their indices are stored inside the result object. \sa radiusSearch,
1247 | * findNeighbors \note nChecks_IGNORED is ignored but kept for compatibility
1248 | * with the original FLANN interface. \return Number `N` of valid points in
1249 | * the result set. Only the first `N` entries in `out_indices` and
1250 | * `out_distances_sq` will be valid. Return may be less than `num_closest`
1251 | * only if the number of elements in the tree is less than `num_closest`.
1252 | */
1253 | size_t knnSearch(const ElementType *query_point, const size_t num_closest,
1254 | IndexType *out_indices, DistanceType *out_distances_sq,
1255 | const int /* nChecks_IGNORED */ = 10) const {
1256 | nanoflann::KNNResultSet resultSet(num_closest);
1257 | resultSet.init(out_indices, out_distances_sq);
1258 | this->findNeighbors(resultSet, query_point, nanoflann::SearchParams());
1259 | return resultSet.size();
1260 | }
1261 |
1262 | /**
1263 | * Find all the neighbors to \a query_point[0:dim-1] within a maximum radius.
1264 | * The output is given as a vector of pairs, of which the first element is a
1265 | * point index and the second the corresponding distance. Previous contents of
1266 | * \a IndicesDists are cleared.
1267 | *
1268 | * If searchParams.sorted==true, the output list is sorted by ascending
1269 | * distances.
1270 | *
1271 | * For a better performance, it is advisable to do a .reserve() on the vector
1272 | * if you have any wild guess about the number of expected matches.
1273 | *
1274 | * \sa knnSearch, findNeighbors, radiusSearchCustomCallback
1275 | * \return The number of points within the given radius (i.e. indices.size()
1276 | * or dists.size() )
1277 | */
1278 | size_t
1279 | radiusSearch(const ElementType *query_point, const DistanceType &radius,
1280 | std::vector> &IndicesDists,
1281 | const SearchParams &searchParams) const {
1282 | RadiusResultSet resultSet(radius, IndicesDists);
1283 | const size_t nFound =
1284 | radiusSearchCustomCallback(query_point, resultSet, searchParams);
1285 | if (searchParams.sorted)
1286 | std::sort(IndicesDists.begin(), IndicesDists.end(), IndexDist_Sorter());
1287 | return nFound;
1288 | }
1289 |
1290 | /**
1291 | * Just like radiusSearch() but with a custom callback class for each point
1292 | * found in the radius of the query. See the source of RadiusResultSet<> as a
1293 | * start point for your own classes. \sa radiusSearch
1294 | */
1295 | template
1296 | size_t radiusSearchCustomCallback(
1297 | const ElementType *query_point, SEARCH_CALLBACK &resultSet,
1298 | const SearchParams &searchParams = SearchParams()) const {
1299 | this->findNeighbors(resultSet, query_point, searchParams);
1300 | return resultSet.size();
1301 | }
1302 |
1303 | /** @} */
1304 |
1305 | public:
1306 | /** Make sure the auxiliary list \a vind has the same size than the current
1307 | * dataset, and re-generate if size has changed. */
1308 | void init_vind() {
1309 | // Create a permutable array of indices to the input vectors.
1310 | BaseClassRef::m_size = dataset.kdtree_get_point_count();
1311 | if (BaseClassRef::vind.size() != BaseClassRef::m_size)
1312 | BaseClassRef::vind.resize(BaseClassRef::m_size);
1313 | for (size_t i = 0; i < BaseClassRef::m_size; i++)
1314 | BaseClassRef::vind[i] = i;
1315 | }
1316 |
1317 | void computeBoundingBox(BoundingBox &bbox) {
1318 | resize(bbox, (DIM > 0 ? DIM : BaseClassRef::dim));
1319 | if (dataset.kdtree_get_bbox(bbox)) {
1320 | // Done! It was implemented in derived class
1321 | } else {
1322 | const size_t N = dataset.kdtree_get_point_count();
1323 | if (!N)
1324 | throw std::runtime_error("[nanoflann] computeBoundingBox() called but "
1325 | "no data points found.");
1326 | for (int i = 0; i < (DIM > 0 ? DIM : BaseClassRef::dim); ++i) {
1327 | bbox[i].low = bbox[i].high = this->dataset_get(*this, 0, i);
1328 | }
1329 | for (size_t k = 1; k < N; ++k) {
1330 | for (int i = 0; i < (DIM > 0 ? DIM : BaseClassRef::dim); ++i) {
1331 | if (this->dataset_get(*this, k, i) < bbox[i].low)
1332 | bbox[i].low = this->dataset_get(*this, k, i);
1333 | if (this->dataset_get(*this, k, i) > bbox[i].high)
1334 | bbox[i].high = this->dataset_get(*this, k, i);
1335 | }
1336 | }
1337 | }
1338 | }
1339 |
1340 | /**
1341 | * Performs an exact search in the tree starting from a node.
1342 | * \tparam RESULTSET Should be any ResultSet
1343 | * \return true if the search should be continued, false if the results are
1344 | * sufficient
1345 | */
1346 | template
1347 | bool searchLevel(RESULTSET &result_set, const ElementType *vec,
1348 | const NodePtr node, DistanceType mindistsq,
1349 | distance_vector_t &dists, const float epsError) const {
1350 | /* If this is a leaf node, then do check and return. */
1351 | if ((node->child1 == NULL) && (node->child2 == NULL)) {
1352 | // count_leaf += (node->lr.right-node->lr.left); // Removed since was
1353 | // neither used nor returned to the user.
1354 | DistanceType worst_dist = result_set.worstDist();
1355 | for (IndexType i = node->node_type.lr.left; i < node->node_type.lr.right;
1356 | ++i) {
1357 | const IndexType index = BaseClassRef::vind[i]; // reorder... : i;
1358 | DistanceType dist = distance.evalMetric(
1359 | vec, index, (DIM > 0 ? DIM : BaseClassRef::dim));
1360 | if (dist < worst_dist) {
1361 | if (!result_set.addPoint(dist, BaseClassRef::vind[i])) {
1362 | // the resultset doesn't want to receive any more points, we're done
1363 | // searching!
1364 | return false;
1365 | }
1366 | }
1367 | }
1368 | return true;
1369 | }
1370 |
1371 | /* Which child branch should be taken first? */
1372 | int idx = node->node_type.sub.divfeat;
1373 | ElementType val = vec[idx];
1374 | DistanceType diff1 = val - node->node_type.sub.divlow;
1375 | DistanceType diff2 = val - node->node_type.sub.divhigh;
1376 |
1377 | NodePtr bestChild;
1378 | NodePtr otherChild;
1379 | DistanceType cut_dist;
1380 | if ((diff1 + diff2) < 0) {
1381 | bestChild = node->child1;
1382 | otherChild = node->child2;
1383 | cut_dist = distance.accum_dist(val, node->node_type.sub.divhigh, idx);
1384 | } else {
1385 | bestChild = node->child2;
1386 | otherChild = node->child1;
1387 | cut_dist = distance.accum_dist(val, node->node_type.sub.divlow, idx);
1388 | }
1389 |
1390 | /* Call recursively to search next level down. */
1391 | if (!searchLevel(result_set, vec, bestChild, mindistsq, dists, epsError)) {
1392 | // the resultset doesn't want to receive any more points, we're done
1393 | // searching!
1394 | return false;
1395 | }
1396 |
1397 | DistanceType dst = dists[idx];
1398 | mindistsq = mindistsq + cut_dist - dst;
1399 | dists[idx] = cut_dist;
1400 | if (mindistsq * epsError <= result_set.worstDist()) {
1401 | if (!searchLevel(result_set, vec, otherChild, mindistsq, dists,
1402 | epsError)) {
1403 | // the resultset doesn't want to receive any more points, we're done
1404 | // searching!
1405 | return false;
1406 | }
1407 | }
1408 | dists[idx] = dst;
1409 | return true;
1410 | }
1411 |
1412 | public:
1413 | /** Stores the index in a binary file.
1414 | * IMPORTANT NOTE: The set of data points is NOT stored in the file, so when
1415 | * loading the index object it must be constructed associated to the same
1416 | * source of data points used while building it. See the example:
1417 | * examples/saveload_example.cpp \sa loadIndex */
1418 | void saveIndex(FILE *stream) { this->saveIndex_(*this, stream); }
1419 |
1420 | /** Loads a previous index from a binary file.
1421 | * IMPORTANT NOTE: The set of data points is NOT stored in the file, so the
1422 | * index object must be constructed associated to the same source of data
1423 | * points used while building the index. See the example:
1424 | * examples/saveload_example.cpp \sa loadIndex */
1425 | void loadIndex(FILE *stream) { this->loadIndex_(*this, stream); }
1426 |
1427 | }; // class KDTree
1428 |
1429 | /** kd-tree dynamic index
1430 | *
1431 | * Contains the k-d trees and other information for indexing a set of points
1432 | * for nearest-neighbor matching.
1433 | *
1434 | * The class "DatasetAdaptor" must provide the following interface (can be
1435 | * non-virtual, inlined methods):
1436 | *
1437 | * \code
1438 | * // Must return the number of data poins
1439 | * inline size_t kdtree_get_point_count() const { ... }
1440 | *
1441 | * // Must return the dim'th component of the idx'th point in the class:
1442 | * inline T kdtree_get_pt(const size_t idx, const size_t dim) const { ... }
1443 | *
1444 | * // Optional bounding-box computation: return false to default to a standard
1445 | * bbox computation loop.
1446 | * // Return true if the BBOX was already computed by the class and returned
1447 | * in "bb" so it can be avoided to redo it again.
1448 | * // Look at bb.size() to find out the expected dimensionality (e.g. 2 or 3
1449 | * for point clouds) template bool kdtree_get_bbox(BBOX &bb) const
1450 | * {
1451 | * bb[0].low = ...; bb[0].high = ...; // 0th dimension limits
1452 | * bb[1].low = ...; bb[1].high = ...; // 1st dimension limits
1453 | * ...
1454 | * return true;
1455 | * }
1456 | *
1457 | * \endcode
1458 | *
1459 | * \tparam DatasetAdaptor The user-provided adaptor (see comments above).
1460 | * \tparam Distance The distance metric to use: nanoflann::metric_L1,
1461 | * nanoflann::metric_L2, nanoflann::metric_L2_Simple, etc. \tparam DIM
1462 | * Dimensionality of data points (e.g. 3 for 3D points) \tparam IndexType Will
1463 | * be typically size_t or int
1464 | */
1465 | template
1467 | class KDTreeSingleIndexDynamicAdaptor_
1468 | : public KDTreeBaseClass,
1470 | Distance, DatasetAdaptor, DIM, IndexType> {
1471 | public:
1472 | /**
1473 | * The dataset used by this index
1474 | */
1475 | const DatasetAdaptor &dataset; //!< The source of our data
1476 |
1477 | KDTreeSingleIndexAdaptorParams index_params;
1478 |
1479 | std::vector &treeIndex;
1480 |
1481 | Distance distance;
1482 |
1483 | typedef typename nanoflann::KDTreeBaseClass<
1484 | nanoflann::KDTreeSingleIndexDynamicAdaptor_,
1486 | Distance, DatasetAdaptor, DIM, IndexType>
1487 | BaseClassRef;
1488 |
1489 | typedef typename BaseClassRef::ElementType ElementType;
1490 | typedef typename BaseClassRef::DistanceType DistanceType;
1491 |
1492 | typedef typename BaseClassRef::Node Node;
1493 | typedef Node *NodePtr;
1494 |
1495 | typedef typename BaseClassRef::Interval Interval;
1496 | /** Define "BoundingBox" as a fixed-size or variable-size container depending
1497 | * on "DIM" */
1498 | typedef typename BaseClassRef::BoundingBox BoundingBox;
1499 |
1500 | /** Define "distance_vector_t" as a fixed-size or variable-size container
1501 | * depending on "DIM" */
1502 | typedef typename BaseClassRef::distance_vector_t distance_vector_t;
1503 |
1504 | /**
1505 | * KDTree constructor
1506 | *
1507 | * Refer to docs in README.md or online in
1508 | * https://github.com/jlblancoc/nanoflann
1509 | *
1510 | * The KD-Tree point dimension (the length of each point in the datase, e.g. 3
1511 | * for 3D points) is determined by means of:
1512 | * - The \a DIM template parameter if >0 (highest priority)
1513 | * - Otherwise, the \a dimensionality parameter of this constructor.
1514 | *
1515 | * @param inputData Dataset with the input features
1516 | * @param params Basically, the maximum leaf node size
1517 | */
1518 | KDTreeSingleIndexDynamicAdaptor_(
1519 | const int dimensionality, const DatasetAdaptor &inputData,
1520 | std::vector &treeIndex_,
1521 | const KDTreeSingleIndexAdaptorParams ¶ms =
1522 | KDTreeSingleIndexAdaptorParams())
1523 | : dataset(inputData), index_params(params), treeIndex(treeIndex_),
1524 | distance(inputData) {
1525 | BaseClassRef::root_node = NULL;
1526 | BaseClassRef::m_size = 0;
1527 | BaseClassRef::m_size_at_index_build = 0;
1528 | BaseClassRef::dim = dimensionality;
1529 | if (DIM > 0)
1530 | BaseClassRef::dim = DIM;
1531 | BaseClassRef::m_leaf_max_size = params.leaf_max_size;
1532 | }
1533 |
1534 | /** Assignment operator definiton */
1535 | KDTreeSingleIndexDynamicAdaptor_
1536 | operator=(const KDTreeSingleIndexDynamicAdaptor_ &rhs) {
1537 | KDTreeSingleIndexDynamicAdaptor_ tmp(rhs);
1538 | std::swap(BaseClassRef::vind, tmp.BaseClassRef::vind);
1539 | std::swap(BaseClassRef::m_leaf_max_size, tmp.BaseClassRef::m_leaf_max_size);
1540 | std::swap(index_params, tmp.index_params);
1541 | std::swap(treeIndex, tmp.treeIndex);
1542 | std::swap(BaseClassRef::m_size, tmp.BaseClassRef::m_size);
1543 | std::swap(BaseClassRef::m_size_at_index_build,
1544 | tmp.BaseClassRef::m_size_at_index_build);
1545 | std::swap(BaseClassRef::root_node, tmp.BaseClassRef::root_node);
1546 | std::swap(BaseClassRef::root_bbox, tmp.BaseClassRef::root_bbox);
1547 | std::swap(BaseClassRef::pool, tmp.BaseClassRef::pool);
1548 | return *this;
1549 | }
1550 |
1551 | /**
1552 | * Builds the index
1553 | */
1554 | void buildIndex() {
1555 | BaseClassRef::m_size = BaseClassRef::vind.size();
1556 | this->freeIndex(*this);
1557 | BaseClassRef::m_size_at_index_build = BaseClassRef::m_size;
1558 | if (BaseClassRef::m_size == 0)
1559 | return;
1560 | computeBoundingBox(BaseClassRef::root_bbox);
1561 | BaseClassRef::root_node =
1562 | this->divideTree(*this, 0, BaseClassRef::m_size,
1563 | BaseClassRef::root_bbox); // construct the tree
1564 | }
1565 |
1566 | /** \name Query methods
1567 | * @{ */
1568 |
1569 | /**
1570 | * Find set of nearest neighbors to vec[0:dim-1]. Their indices are stored
1571 | * inside the result object.
1572 | *
1573 | * Params:
1574 | * result = the result object in which the indices of the
1575 | * nearest-neighbors are stored vec = the vector for which to search the
1576 | * nearest neighbors
1577 | *
1578 | * \tparam RESULTSET Should be any ResultSet
1579 | * \return True if the requested neighbors could be found.
1580 | * \sa knnSearch, radiusSearch
1581 | */
1582 | template
1583 | bool findNeighbors(RESULTSET &result, const ElementType *vec,
1584 | const SearchParams &searchParams) const {
1585 | assert(vec);
1586 | if (this->size(*this) == 0)
1587 | return false;
1588 | if (!BaseClassRef::root_node)
1589 | return false;
1590 | float epsError = 1 + searchParams.eps;
1591 |
1592 | // fixed or variable-sized container (depending on DIM)
1593 | distance_vector_t dists;
1594 | // Fill it with zeros.
1595 | assign(dists, (DIM > 0 ? DIM : BaseClassRef::dim),
1596 | static_cast(0));
1597 | DistanceType distsq = this->computeInitialDistances(*this, vec, dists);
1598 | searchLevel(result, vec, BaseClassRef::root_node, distsq, dists,
1599 | epsError); // "count_leaf" parameter removed since was neither
1600 | // used nor returned to the user.
1601 | return result.full();
1602 | }
1603 |
1604 | /**
1605 | * Find the "num_closest" nearest neighbors to the \a query_point[0:dim-1].
1606 | * Their indices are stored inside the result object. \sa radiusSearch,
1607 | * findNeighbors \note nChecks_IGNORED is ignored but kept for compatibility
1608 | * with the original FLANN interface. \return Number `N` of valid points in
1609 | * the result set. Only the first `N` entries in `out_indices` and
1610 | * `out_distances_sq` will be valid. Return may be less than `num_closest`
1611 | * only if the number of elements in the tree is less than `num_closest`.
1612 | */
1613 | size_t knnSearch(const ElementType *query_point, const size_t num_closest,
1614 | IndexType *out_indices, DistanceType *out_distances_sq,
1615 | const int /* nChecks_IGNORED */ = 10) const {
1616 | nanoflann::KNNResultSet resultSet(num_closest);
1617 | resultSet.init(out_indices, out_distances_sq);
1618 | this->findNeighbors(resultSet, query_point, nanoflann::SearchParams());
1619 | return resultSet.size();
1620 | }
1621 |
1622 | /**
1623 | * Find all the neighbors to \a query_point[0:dim-1] within a maximum radius.
1624 | * The output is given as a vector of pairs, of which the first element is a
1625 | * point index and the second the corresponding distance. Previous contents of
1626 | * \a IndicesDists are cleared.
1627 | *
1628 | * If searchParams.sorted==true, the output list is sorted by ascending
1629 | * distances.
1630 | *
1631 | * For a better performance, it is advisable to do a .reserve() on the vector
1632 | * if you have any wild guess about the number of expected matches.
1633 | *
1634 | * \sa knnSearch, findNeighbors, radiusSearchCustomCallback
1635 | * \return The number of points within the given radius (i.e. indices.size()
1636 | * or dists.size() )
1637 | */
1638 | size_t
1639 | radiusSearch(const ElementType *query_point, const DistanceType &radius,
1640 | std::vector> &IndicesDists,
1641 | const SearchParams &searchParams) const {
1642 | RadiusResultSet resultSet(radius, IndicesDists);
1643 | const size_t nFound =
1644 | radiusSearchCustomCallback(query_point, resultSet, searchParams);
1645 | if (searchParams.sorted)
1646 | std::sort(IndicesDists.begin(), IndicesDists.end(), IndexDist_Sorter());
1647 | return nFound;
1648 | }
1649 |
1650 | /**
1651 | * Just like radiusSearch() but with a custom callback class for each point
1652 | * found in the radius of the query. See the source of RadiusResultSet<> as a
1653 | * start point for your own classes. \sa radiusSearch
1654 | */
1655 | template
1656 | size_t radiusSearchCustomCallback(
1657 | const ElementType *query_point, SEARCH_CALLBACK &resultSet,
1658 | const SearchParams &searchParams = SearchParams()) const {
1659 | this->findNeighbors(resultSet, query_point, searchParams);
1660 | return resultSet.size();
1661 | }
1662 |
1663 | /** @} */
1664 |
1665 | public:
1666 | void computeBoundingBox(BoundingBox &bbox) {
1667 | resize(bbox, (DIM > 0 ? DIM : BaseClassRef::dim));
1668 |
1669 | if (dataset.kdtree_get_bbox(bbox)) {
1670 | // Done! It was implemented in derived class
1671 | } else {
1672 | const size_t N = BaseClassRef::m_size;
1673 | if (!N)
1674 | throw std::runtime_error("[nanoflann] computeBoundingBox() called but "
1675 | "no data points found.");
1676 | for (int i = 0; i < (DIM > 0 ? DIM : BaseClassRef::dim); ++i) {
1677 | bbox[i].low = bbox[i].high =
1678 | this->dataset_get(*this, BaseClassRef::vind[0], i);
1679 | }
1680 | for (size_t k = 1; k < N; ++k) {
1681 | for (int i = 0; i < (DIM > 0 ? DIM : BaseClassRef::dim); ++i) {
1682 | if (this->dataset_get(*this, BaseClassRef::vind[k], i) < bbox[i].low)
1683 | bbox[i].low = this->dataset_get(*this, BaseClassRef::vind[k], i);
1684 | if (this->dataset_get(*this, BaseClassRef::vind[k], i) > bbox[i].high)
1685 | bbox[i].high = this->dataset_get(*this, BaseClassRef::vind[k], i);
1686 | }
1687 | }
1688 | }
1689 | }
1690 |
1691 | /**
1692 | * Performs an exact search in the tree starting from a node.
1693 | * \tparam RESULTSET Should be any ResultSet
1694 | */
1695 | template
1696 | void searchLevel(RESULTSET &result_set, const ElementType *vec,
1697 | const NodePtr node, DistanceType mindistsq,
1698 | distance_vector_t &dists, const float epsError) const {
1699 | /* If this is a leaf node, then do check and return. */
1700 | if ((node->child1 == NULL) && (node->child2 == NULL)) {
1701 | // count_leaf += (node->lr.right-node->lr.left); // Removed since was
1702 | // neither used nor returned to the user.
1703 | DistanceType worst_dist = result_set.worstDist();
1704 | for (IndexType i = node->node_type.lr.left; i < node->node_type.lr.right;
1705 | ++i) {
1706 | const IndexType index = BaseClassRef::vind[i]; // reorder... : i;
1707 | if (treeIndex[index] == -1)
1708 | continue;
1709 | DistanceType dist = distance.evalMetric(
1710 | vec, index, (DIM > 0 ? DIM : BaseClassRef::dim));
1711 | if (dist < worst_dist) {
1712 | if (!result_set.addPoint(
1713 | static_cast(dist),
1714 | static_cast(
1715 | BaseClassRef::vind[i]))) {
1716 | // the resultset doesn't want to receive any more points, we're done
1717 | // searching!
1718 | return; // false;
1719 | }
1720 | }
1721 | }
1722 | return;
1723 | }
1724 |
1725 | /* Which child branch should be taken first? */
1726 | int idx = node->node_type.sub.divfeat;
1727 | ElementType val = vec[idx];
1728 | DistanceType diff1 = val - node->node_type.sub.divlow;
1729 | DistanceType diff2 = val - node->node_type.sub.divhigh;
1730 |
1731 | NodePtr bestChild;
1732 | NodePtr otherChild;
1733 | DistanceType cut_dist;
1734 | if ((diff1 + diff2) < 0) {
1735 | bestChild = node->child1;
1736 | otherChild = node->child2;
1737 | cut_dist = distance.accum_dist(val, node->node_type.sub.divhigh, idx);
1738 | } else {
1739 | bestChild = node->child2;
1740 | otherChild = node->child1;
1741 | cut_dist = distance.accum_dist(val, node->node_type.sub.divlow, idx);
1742 | }
1743 |
1744 | /* Call recursively to search next level down. */
1745 | searchLevel(result_set, vec, bestChild, mindistsq, dists, epsError);
1746 |
1747 | DistanceType dst = dists[idx];
1748 | mindistsq = mindistsq + cut_dist - dst;
1749 | dists[idx] = cut_dist;
1750 | if (mindistsq * epsError <= result_set.worstDist()) {
1751 | searchLevel(result_set, vec, otherChild, mindistsq, dists, epsError);
1752 | }
1753 | dists[idx] = dst;
1754 | }
1755 |
1756 | public:
1757 | /** Stores the index in a binary file.
1758 | * IMPORTANT NOTE: The set of data points is NOT stored in the file, so when
1759 | * loading the index object it must be constructed associated to the same
1760 | * source of data points used while building it. See the example:
1761 | * examples/saveload_example.cpp \sa loadIndex */
1762 | void saveIndex(FILE *stream) { this->saveIndex_(*this, stream); }
1763 |
1764 | /** Loads a previous index from a binary file.
1765 | * IMPORTANT NOTE: The set of data points is NOT stored in the file, so the
1766 | * index object must be constructed associated to the same source of data
1767 | * points used while building the index. See the example:
1768 | * examples/saveload_example.cpp \sa loadIndex */
1769 | void loadIndex(FILE *stream) { this->loadIndex_(*this, stream); }
1770 | };
1771 |
1772 | /** kd-tree dynaimic index
1773 | *
1774 | * class to create multiple static index and merge their results to behave as
1775 | * single dynamic index as proposed in Logarithmic Approach.
1776 | *
1777 | * Example of usage:
1778 | * examples/dynamic_pointcloud_example.cpp
1779 | *
1780 | * \tparam DatasetAdaptor The user-provided adaptor (see comments above).
1781 | * \tparam Distance The distance metric to use: nanoflann::metric_L1,
1782 | * nanoflann::metric_L2, nanoflann::metric_L2_Simple, etc. \tparam DIM
1783 | * Dimensionality of data points (e.g. 3 for 3D points) \tparam IndexType Will
1784 | * be typically size_t or int
1785 | */
1786 | template
1788 | class KDTreeSingleIndexDynamicAdaptor {
1789 | public:
1790 | typedef typename Distance::ElementType ElementType;
1791 | typedef typename Distance::DistanceType DistanceType;
1792 |
1793 | protected:
1794 | size_t m_leaf_max_size;
1795 | size_t treeCount;
1796 | size_t pointCount;
1797 |
1798 | /**
1799 | * The dataset used by this index
1800 | */
1801 | const DatasetAdaptor &dataset; //!< The source of our data
1802 |
1803 | std::vector treeIndex; //!< treeIndex[idx] is the index of tree in which
1804 | //!< point at idx is stored. treeIndex[idx]=-1
1805 | //!< means that point has been removed.
1806 |
1807 | KDTreeSingleIndexAdaptorParams index_params;
1808 |
1809 | int dim; //!< Dimensionality of each data point
1810 |
1811 | typedef KDTreeSingleIndexDynamicAdaptor_
1812 | index_container_t;
1813 | std::vector index;
1814 |
1815 | public:
1816 | /** Get a const ref to the internal list of indices; the number of indices is
1817 | * adapted dynamically as the dataset grows in size. */
1818 | const std::vector &getAllIndices() const { return index; }
1819 |
1820 | private:
1821 | /** finds position of least significant unset bit */
1822 | int First0Bit(IndexType num) {
1823 | int pos = 0;
1824 | while (num & 1) {
1825 | num = num >> 1;
1826 | pos++;
1827 | }
1828 | return pos;
1829 | }
1830 |
1831 | /** Creates multiple empty trees to handle dynamic support */
1832 | void init() {
1833 | typedef KDTreeSingleIndexDynamicAdaptor_
1834 | my_kd_tree_t;
1835 | std::vector index_(
1836 | treeCount, my_kd_tree_t(dim /*dim*/, dataset, treeIndex, index_params));
1837 | index = index_;
1838 | }
1839 |
1840 | public:
1841 | Distance distance;
1842 |
1843 | /**
1844 | * KDTree constructor
1845 | *
1846 | * Refer to docs in README.md or online in
1847 | * https://github.com/jlblancoc/nanoflann
1848 | *
1849 | * The KD-Tree point dimension (the length of each point in the datase, e.g. 3
1850 | * for 3D points) is determined by means of:
1851 | * - The \a DIM template parameter if >0 (highest priority)
1852 | * - Otherwise, the \a dimensionality parameter of this constructor.
1853 | *
1854 | * @param inputData Dataset with the input features
1855 | * @param params Basically, the maximum leaf node size
1856 | */
1857 | KDTreeSingleIndexDynamicAdaptor(const int dimensionality,
1858 | const DatasetAdaptor &inputData,
1859 | const KDTreeSingleIndexAdaptorParams ¶ms =
1860 | KDTreeSingleIndexAdaptorParams(),
1861 | const size_t maximumPointCount = 1000000000U)
1862 | : dataset(inputData), index_params(params), distance(inputData) {
1863 | treeCount = static_cast(std::log2(maximumPointCount));
1864 | pointCount = 0U;
1865 | dim = dimensionality;
1866 | treeIndex.clear();
1867 | if (DIM > 0)
1868 | dim = DIM;
1869 | m_leaf_max_size = params.leaf_max_size;
1870 | init();
1871 | const size_t num_initial_points = dataset.kdtree_get_point_count();
1872 | if (num_initial_points > 0) {
1873 | addPoints(0, num_initial_points - 1);
1874 | }
1875 | }
1876 |
1877 | /** Deleted copy constructor*/
1878 | KDTreeSingleIndexDynamicAdaptor(
1879 | const KDTreeSingleIndexDynamicAdaptor &) = delete;
1881 |
1882 | /** Add points to the set, Inserts all points from [start, end] */
1883 | void addPoints(IndexType start, IndexType end) {
1884 | size_t count = end - start + 1;
1885 | treeIndex.resize(treeIndex.size() + count);
1886 | for (IndexType idx = start; idx <= end; idx++) {
1887 | int pos = First0Bit(pointCount);
1888 | index[pos].vind.clear();
1889 | treeIndex[pointCount] = pos;
1890 | for (int i = 0; i < pos; i++) {
1891 | for (int j = 0; j < static_cast(index[i].vind.size()); j++) {
1892 | index[pos].vind.push_back(index[i].vind[j]);
1893 | if (treeIndex[index[i].vind[j]] != -1)
1894 | treeIndex[index[i].vind[j]] = pos;
1895 | }
1896 | index[i].vind.clear();
1897 | index[i].freeIndex(index[i]);
1898 | }
1899 | index[pos].vind.push_back(idx);
1900 | index[pos].buildIndex();
1901 | pointCount++;
1902 | }
1903 | }
1904 |
1905 | /** Remove a point from the set (Lazy Deletion) */
1906 | void removePoint(size_t idx) {
1907 | if (idx >= pointCount)
1908 | return;
1909 | treeIndex[idx] = -1;
1910 | }
1911 |
1912 | /**
1913 | * Find set of nearest neighbors to vec[0:dim-1]. Their indices are stored
1914 | * inside the result object.
1915 | *
1916 | * Params:
1917 | * result = the result object in which the indices of the
1918 | * nearest-neighbors are stored vec = the vector for which to search the
1919 | * nearest neighbors
1920 | *
1921 | * \tparam RESULTSET Should be any ResultSet
1922 | * \return True if the requested neighbors could be found.
1923 | * \sa knnSearch, radiusSearch
1924 | */
1925 | template
1926 | bool findNeighbors(RESULTSET &result, const ElementType *vec,
1927 | const SearchParams &searchParams) const {
1928 | for (size_t i = 0; i < treeCount; i++) {
1929 | index[i].findNeighbors(result, &vec[0], searchParams);
1930 | }
1931 | return result.full();
1932 | }
1933 | };
1934 |
1935 | /** An L2-metric KD-tree adaptor for working with data directly stored in an
1936 | * Eigen Matrix, without duplicating the data storage. You can select whether a
1937 | * row or column in the matrix represents a point in the state space.
1938 | *
1939 | * Example of usage:
1940 | * \code
1941 | * Eigen::Matrix mat;
1942 | * // Fill out "mat"...
1943 | *
1944 | * typedef KDTreeEigenMatrixAdaptor< Eigen::Matrix >
1945 | * my_kd_tree_t; const int max_leaf = 10; my_kd_tree_t mat_index(mat, max_leaf
1946 | * ); mat_index.index->buildIndex(); mat_index.index->... \endcode
1947 | *
1948 | * \tparam DIM If set to >0, it specifies a compile-time fixed dimensionality
1949 | * for the points in the data set, allowing more compiler optimizations. \tparam
1950 | * Distance The distance metric to use: nanoflann::metric_L1,
1951 | * nanoflann::metric_L2, nanoflann::metric_L2_Simple, etc. \tparam row_major
1952 | * If set to true the rows of the matrix are used as the points, if set to false
1953 | * the columns of the matrix are used as the points.
1954 | */
1955 | template
1957 | struct KDTreeEigenMatrixAdaptor {
1958 | typedef KDTreeEigenMatrixAdaptor self_t;
1959 | typedef typename MatrixType::Scalar num_t;
1960 | typedef typename MatrixType::Index IndexType;
1961 | typedef
1962 | typename Distance::template traits::distance_t metric_t;
1963 | typedef KDTreeSingleIndexAdaptor
1965 | index_t;
1966 |
1967 | index_t *index; //! The kd-tree index for the user to call its methods as
1968 | //! usual with any other FLANN index.
1969 |
1970 | /// Constructor: takes a const ref to the matrix object with the data points
1971 | KDTreeEigenMatrixAdaptor(const size_t dimensionality,
1972 | const std::reference_wrapper &mat,
1973 | const int leaf_max_size = 10)
1974 | : m_data_matrix(mat) {
1975 | const auto dims = row_major ? mat.get().cols() : mat.get().rows();
1976 | if (size_t(dims) != dimensionality)
1977 | throw std::runtime_error(
1978 | "Error: 'dimensionality' must match column count in data matrix");
1979 | if (DIM > 0 && int(dims) != DIM)
1980 | throw std::runtime_error(
1981 | "Data set dimensionality does not match the 'DIM' template argument");
1982 | index =
1983 | new index_t(static_cast(dims), *this /* adaptor */,
1984 | nanoflann::KDTreeSingleIndexAdaptorParams(leaf_max_size));
1985 | index->buildIndex();
1986 | }
1987 |
1988 | public:
1989 | /** Deleted copy constructor */
1990 | KDTreeEigenMatrixAdaptor(const self_t &) = delete;
1991 |
1992 | ~KDTreeEigenMatrixAdaptor() { delete index; }
1993 |
1994 | const std::reference_wrapper m_data_matrix;
1995 |
1996 | /** Query for the \a num_closest closest points to a given point (entered as
1997 | * query_point[0:dim-1]). Note that this is a short-cut method for
1998 | * index->findNeighbors(). The user can also call index->... methods as
1999 | * desired. \note nChecks_IGNORED is ignored but kept for compatibility with
2000 | * the original FLANN interface.
2001 | */
2002 | inline void query(const num_t *query_point, const size_t num_closest,
2003 | IndexType *out_indices, num_t *out_distances_sq,
2004 | const int /* nChecks_IGNORED */ = 10) const {
2005 | nanoflann::KNNResultSet resultSet(num_closest);
2006 | resultSet.init(out_indices, out_distances_sq);
2007 | index->findNeighbors(resultSet, query_point, nanoflann::SearchParams());
2008 | }
2009 |
2010 | /** @name Interface expected by KDTreeSingleIndexAdaptor
2011 | * @{ */
2012 |
2013 | const self_t &derived() const { return *this; }
2014 | self_t &derived() { return *this; }
2015 |
2016 | // Must return the number of data points
2017 | inline size_t kdtree_get_point_count() const {
2018 | if(row_major)
2019 | return m_data_matrix.get().rows();
2020 | else
2021 | return m_data_matrix.get().cols();
2022 | }
2023 |
2024 | // Returns the dim'th component of the idx'th point in the class:
2025 | inline num_t kdtree_get_pt(const IndexType idx, size_t dim) const {
2026 | if(row_major)
2027 | return m_data_matrix.get().coeff(idx, IndexType(dim));
2028 | else
2029 | return m_data_matrix.get().coeff(IndexType(dim), idx);
2030 | }
2031 |
2032 | // Optional bounding-box computation: return false to default to a standard
2033 | // bbox computation loop.
2034 | // Return true if the BBOX was already computed by the class and returned in
2035 | // "bb" so it can be avoided to redo it again. Look at bb.size() to find out
2036 | // the expected dimensionality (e.g. 2 or 3 for point clouds)
2037 | template bool kdtree_get_bbox(BBOX & /*bb*/) const {
2038 | return false;
2039 | }
2040 |
2041 | /** @} */
2042 |
2043 | }; // end of KDTreeEigenMatrixAdaptor
2044 | /** @} */
2045 |
2046 | /** @} */ // end of grouping
2047 | } // namespace nanoflann
2048 |
2049 | #endif /* NANOFLANN_HPP_ */
2050 |
--------------------------------------------------------------------------------