├── 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 | --------------------------------------------------------------------------------