{"id":429,"date":"2012-05-07T14:38:30","date_gmt":"2012-05-07T21:38:30","guid":{"rendered":"http:\/\/www.lothlorien.com\/kf6gpe\/?p=429"},"modified":"2012-05-07T14:38:30","modified_gmt":"2012-05-07T21:38:30","slug":"a-forest-of-trees","status":"publish","type":"post","link":"https:\/\/www.lothlorien.com\/kf6gpe\/a-forest-of-trees\/","title":{"rendered":"A forest of trees!"},"content":{"rendered":"<p>I recently needed a spatial index for some data I was working with at work, and decided to rough out both a quad tree and a k-d tree implementation for Qt. <\/p>\n<p>Indexing data spatially is important if you have a lot of objects organized spatially, and need to do queries by an object&#8217;s location, rather than a single-dimensional key such as an ID. Qt has a framework for doing this in the context of the QGraphicsFramework, but doesn&#8217;t have generalized container classes that index along multiple dimensions &#8212; think, for example, of a multi-dimensional QMap.<\/p>\n<p>I implemented the quad tree largely from scratch, looking at <a href=\"http:\/\/en.wikipedia.org\/wiki\/Quadtree\" title=\"wikipedia\">wikipedia<\/a> and a couple implementations such as the one <a href=\" http:\/\/veeableful.wordpress.com\/2012\/02\/07\/algorithm-space-partitioning-using-quadtree\/\" title=\"here\">here<\/a>. My quad tree uses C++ templates to abstract the data type, so you can stick anything in it (as long as it can be put in a QList; the underlying store uses QList for object management). Quad trees come up a lot in collision detection in computer graphics and gaming, where you want to know if an object is close enough to another object to collide, but don&#8217;t want to search through lots of objects and do collision detection on each object. It works by recursively subdividing the plane containing the objects, performing additional subdivisions each time a region contains more than a specific number of objects.<\/p>\n<p>I cheated when it came to the <a href=\"http:\/\/en.wikipedia.org\/wiki\/K-d_tree\" title=\"WIkipedia\">k-d tree<\/a>, because there&#8217;s a great C implementation on <a href=\"http:\/\/code.google.com\/p\/kdtree\/\" title=\"code.google.com\">code.google.com<\/a> that did precisely what I needed. Because I needed to store QVariants in the k-d tree, I just wrapped the entire C library in a Qt class, making the C code static to my implementation. It&#8217;s not quite as sexy as a templated version, because it&#8217;ll only store objects you can wrap in a QVariant, but for my application it was enough, and in the future if I have a different kind of object I want to store, it&#8217;s easy enough to make it storable as a QVariant, too. k-d trees are more general than quad trees, operating in more dimensions than two as they subdivide the search space. <\/p>\n<p>Neither of these implementations are truly &#8220;high performance&#8221; &#8212; for clarity and ease of debugging, they use Qt&#8217;s data structures under the hood, which are fairly performant but not as high performance as managing all the data out of the application&#8217;s heap using pointers alone. This is especially true for the <code>find<\/code> methods, which return copies of the data stored in the trees rather than pointers to the actual data. This is, I believe, correct in my case, where I don&#8217;t want to expose the internal structure of my data, and where I&#8217;m using Qt classes that use references and copy-on-write semantics anyway. However, if you&#8217;re looking to squeeze every last bit of performance from your spatial index, you probably don&#8217;t want to start with the code you&#8217;ll find here. Nonetheless, for general computational tasks, these should serve you quite well.<\/p>\n<p>You can find both of the implementations and a little standard I\/O app for using them <a href=\"http:\/\/www.lothlorien.com\/kf6gpe\/wp-content\/uploads\/2012\/05\/trees.zip\" title=\"code\">here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I recently needed a spatial index for some data I was working with at work, and decided to rough out both a quad tree and a k-d tree implementation for Qt. Indexing data spatially is important if you have a lot of objects organized spatially, and need to do queries by an object&#8217;s location, rather &hellip; <a href=\"https:\/\/www.lothlorien.com\/kf6gpe\/a-forest-of-trees\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">A forest of trees!<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[20],"class_list":["post-429","post","type-post","status-publish","format-standard","hentry","category-programming","tag-qt"],"_links":{"self":[{"href":"https:\/\/www.lothlorien.com\/kf6gpe\/wp-json\/wp\/v2\/posts\/429","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lothlorien.com\/kf6gpe\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lothlorien.com\/kf6gpe\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lothlorien.com\/kf6gpe\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lothlorien.com\/kf6gpe\/wp-json\/wp\/v2\/comments?post=429"}],"version-history":[{"count":4,"href":"https:\/\/www.lothlorien.com\/kf6gpe\/wp-json\/wp\/v2\/posts\/429\/revisions"}],"predecessor-version":[{"id":433,"href":"https:\/\/www.lothlorien.com\/kf6gpe\/wp-json\/wp\/v2\/posts\/429\/revisions\/433"}],"wp:attachment":[{"href":"https:\/\/www.lothlorien.com\/kf6gpe\/wp-json\/wp\/v2\/media?parent=429"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lothlorien.com\/kf6gpe\/wp-json\/wp\/v2\/categories?post=429"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lothlorien.com\/kf6gpe\/wp-json\/wp\/v2\/tags?post=429"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}