c++ - Best data structure for point traversal -


looking c++ solution.

i had thoughts whether ask question on here or mathexchange etc. since it's more of programming based question posting here.

real problem:

i have xml field as:

<part name='01' x='351' y='151'/> 

where x , y, storing qpointf object. also, require name=01 value mapping qpointf object create map.

now there operations need on map :

  • first need points(qpointf) , draw on image.
  • second, modify x , y value of points getting points gui.
  • when points gui, need check x , y value in each qpointf inside map.

problem in simpler form:

i looking data structure such instead of having map of key , qpointf, makes parsing , looking x , y value of points(qpointf) easier. qpointf , key should form unique pair each other, parsing through entire list of points find (x,y) , modifying faster , when x , y value of qpointf modified key attached same.

ps: hope clear problem, if there unclear please edit/comment question can improved.

my guess here important aspect finding set of x , y points when user uses ui. there many acceleration structures possible, recommend point index grid. is, partition indices of points 2d buckets. when user chooses point in ui, can quick look-up on bucket point in, , can iterate on points present in bucket find actual point.

as data, store in array:

struct namepoint {     int name, x, y; }; std::vector<namepoint> points; 

now create point index grid refers points array. implementing 1 might worthwhile, otherwise know there exists openvdb version works.


i made small dirty implementation can see principle. have no checks inputs, if you're not careful access out of bounds of vector (e.g., calling pointindexgrid.indicesforpoint(5, 5) gives segmentation fault).

#include <iostream> #include <vector> #include <limits>  struct namepoint {     int name, x, y; };  template <typename t> // array type can work struct pointindexgrid {     using arraytype = t;     using size_type = typename arraytype::size_type;      pointindexgrid(const arraytype& points, int gridsize)         : mgridsize(gridsize)      {         // find domain. create 2d vector contain vector indices.         maxx = maxy = std::numeric_limits<int>::min();         minx = miny = std::numeric_limits<int>::max();         (const auto& p : points) {             maxx = p.x > maxx ? p.x : maxx;             maxy = p.y > maxy ? p.y : maxy;             minx = p.x < minx ? p.x : minx;             miny = p.x < miny ? p.x : miny;         }          // create buckets         int nbrxbuckets = (maxx - minx)/mgridsize + 1; // due integer arithmetics round down -- lets add 1 in case         int nbrybuckets = (maxy - miny)/mgridsize + 1;         (int n = 0; n < nbrxbuckets; ++n) {             mbuckets.emplace_back(std::vector<std::vector<size_type>>(nbrybuckets));         }          // partition points         (size_type = 0; < points.size(); ++i) {             int xbucket = (points[i].x - minx)/mgridsize; // method how calculate bucket. pure arithmetics -- goes fast             int ybucket = (points[i].y - miny)/mgridsize;             mbuckets[xbucket][ybucket].emplace_back(i);         }     }      std::vector<size_type> indicesforpoint(int x, int y)      {         int xbucket = (x - minx)/mgridsize; // same above         int ybucket = (y - miny)/mgridsize;         return mbuckets[xbucket][ybucket];     }  private:     int mgridsize;     int maxx, minx;     int maxy, miny;     std::vector<std::vector<std::vector<size_type>>> mbuckets; };  int main() {     std::vector<namepoint> points;     points.emplace_back(namepoint{1, 1, 1});     points.emplace_back(namepoint{2, 1, 2});     points.emplace_back(namepoint{3, 1, 2});     points.emplace_back(namepoint{4, 2, 2});     points.emplace_back(namepoint{5, 3, 3});      pointindexgrid<std::vector<namepoint>> pointindexgrid(points, 2);      std::cout << "indices (1, 1): " << std::endl;     (const auto& : pointindexgrid.indicesforpoint(1, 1)) {         std::cout << " " << << std::endl;     }      std::cout << "indices (3, 3): " << std::endl;     (const auto& : pointindexgrid.indicesforpoint(3, 3)) {         std::cout << " " << << std::endl;     } } 

this prints out:

indices (1, 1):   0  1  2  3 indices (3, 3):   4 

so find point @ specific (x, y):

  1. partition points using pointindexgrid.
  2. use pointindexgrid.indicesforpoint(x, y).
  3. iterate through indices there (and points in points-array).
  4. grab point want.

Comments

Popular posts from this blog

Is there a better way to structure post methods in Class Based Views -

performance - Why is XCHG reg, reg a 3 micro-op instruction on modern Intel architectures? -

jquery - Responsive Navbar with Sub Navbar -