Using C ++ (and Qt), I need to handle a large number of 3D coordinates.
In particular, when I get a three-dimensional coordinate (consisting of 3 doubles), I need to check the list if this coordinate has already been processed. If not, I process it and add it to the list (or container).
The number of coordinates can become very large, so I need to save the processed coordinates in the container, which will provide a quick check of the three-dimensional coordinate in the container.
I was thinking about using a map map map, keeping the x coordinate, then the y coordinate, then the z coordinate, but that makes it pretty tedious to use, so I really hope that there is a lot better way to do this that I can't think.
Probably the easiest way to speed up this processing is to save the points that have already been processed in Octree . Verification of duplication will be close to logarithmic.
Also, make sure that you make rounding errors by checking the distance between the points, and not the equality of coordinates.
You can easily use the kit as follows:
#include <set> #include <cassert> const double epsilon(1e-8); class Coordinate { public: Coordinate(double x, double y, double z) : x_(x), y_(y), z_(z) {} private: double x_; double y_; double z_; friend bool operator<(const Coordinate& cl, const Coordinate& cr); }; bool operator<(const Coordinate& cl, const Coordinate& cr) { if (cl.x_ < cr.x_ - epsilon) return true; if (cl.x_ > cr.x_ + epsilon) return false; if (cl.y_ < cr.y_ - epsilon) return true; if (cl.y_ > cr.y_ + epsilon) return false; if (cl.z_ < cr.z_ - epsilon) return true; return false; } typedef std::set<Coordinate> Coordinates; // Not thread safe! // Return true if real processing is done bool Process(const Coordinate& coordinate) { static Coordinates usedCoordinates; // Already processed? if (usedCoordinates.find(coordinate) != usedCoordinates.end()) { return false; } usedCoordinates.insert(coordinate); // Here goes your processing code return true; } // Test it int main() { assert(Process(Coordinate(1, 2, 3))); assert(Process(Coordinate(1, 3, 3))); assert(!Process(Coordinate(1, 3, 3))); assert(!Process(Coordinate(1+epsilon/2, 2, 3))); }
. . , , , . , , .
. (, 1000 ), , 2 .
, Coordinate, - hash_set . :
struct coord_eq { bool operator()(const Coordinate &s1, const Coordinate &s2) const { return s1 == s2; // or: return s1.x() == s2.x() && s1.y() == s2.y() && s1.z() == s2.z(); } }; struct coord_hash { size_t operator()(const Coordinate &s) const { union {double d, unsigned long ul} c[3]; c[0].d = s.x(); c[1].d = s.y(); c[2].d = s.z(); return static_cast<size_t> ((3 * c[0].ul) ^ (5 * c[1].ul) ^ (7 * c[2].ul)); } }; std::hash_map<Coordinate, coord_hash, coord_eq> existing_coords;
, , ... , , ?
, .
, Octree .
, - (0, 0, 0,01) , (0, 0, 0.01000001)? , , , . , .
/ ? . , (1.0, 1.0, 1.0), (0.9999999999999, 1.0, 1.0), ? , - , .
, : , , ( , , , ). , "(1.0,1.0,1.0)" . , ( ) . , , .
boost:: ?
( divide-by-epsilon .)
.
: md5 ('X, Y, Z') , .
- , . - , .
/
std:: set. 3d- ( boost:: tuple), < . , , . ( ), .
, , , . IE, (1.0, 1.0, 1.0) , (1.0, 1.0, 1.000000001)?
... , , .
, case less code , .
", " --- , typedefs - ( ).
3D- - ( , " X P" ), -... O (n) create, O (1) (, , ), .
, , . . , , .
... octree.
, , k-d tree. k-d ( , ). , Kd- Octrees, .
, , 1 , 32- ; X, Y Z . - - ( , ).
, , , , .
, , , map<map<map<>>>. !
map<map<map<>>>
, -, . , . (, (1, 2, 3) (3, 2, 1) ..), - x, y, z, .
hash_set - , "(x, y, )". hash_set , .
, epsilon ( , ), epsilon, round .
- :
struct Coor { Coor(double x, double y, double z) : X(x), Y(y), Z(z) {} double X, Y, Z; } struct coords_thesame { bool operator()(const Coor& c1, const Coor& c2) const { return c1.X == c2.X && c1.Y == c2.Y && c1.Z == c2.Z; } }; std::hash_map<Coor, bool, hash<Coor>, coords_thesame> m_SeenCoordinates;
, :)
std::map, . . _Key template . .
std::map
:
#include <map> #include <cassert> struct Point { double x, y, z; }; struct PointResult { }; PointResult point_function( const Point& p ) { return PointResult(); } // helper: binary function for comparison of two points struct point_compare { bool operator()( const Point& p1, const Point& p2 ) const { return p1.x < p2.x || ( p1.x == p2.x && ( p1.y < p2.y || ( p1.y == p2.y && p1.z < p2.z ) ) ); } }; typedef std::map<Point, PointResult, point_compare> pointmap; int _tmain(int argc, _TCHAR* argv[]) { pointmap pm; Point p1 = { 0.0, 0.0, 0.0 }; Point p2 = { 0.1, 1.0, 1.0 }; pm[ p1 ] = point_function( p1 ); pm[ p2 ] = point_function( p2 ); assert( pm.find( p2 ) != pm.end() ); return 0; }
, , .
, , , , , , (x, y, z) - , , (, ). / O (1).
, 3 , , (, OcTree, ), , O (logN) , , (, ..), , , .
std::set std::vector. . , .
std::set
std::vector
? "" ? , , , -.
. , .
Source: https://habr.com/ru/post/1696956/More articles:Related builds on website - asp.netCapturing every 4th file - scriptingЭквивалент DataGridView.HitTestInfo в Infragistics.Win.UltraWinGrid.UltraGrid? - c#.NET Framework Version - .netHow to build unit tests in Guile that output to the TAP standard? - unit-testingMocking constructors in Ruby - ruby | fooobar.comHow to test factory pattern using Mocha in Ruby? - ruby | fooobar.comStoring content in multiple languages? For instance. English, French, German - asp.netPython logic unittest - pythonhttps://translate.googleusercontent.com/translate_c?depth=1&pto=aue&rurl=translate.google.com&sl=ru&sp=nmt4&tl=en&u=https://fooobar.com/questions/1696961/how-do-i-use-htaccess-to-redirect-to-a-url-containing-httphost&usg=ALkJrhgho38e4vNZ1EpL8v3SqrCRgaw5ogAll Articles