0

General problem statement:

Design on-canvas shape selection engine

Given:

Arbitrary convex shapes on the 2D plane. ( say represted by std::vector < IShape* >, IShape has getBBox() member )

given

Question:

Find and return collection/subset of shapes that are within given rectangular region. question

(in this particular example should return shapes A and B )

I know this typical range range-seach/range-query problem, however the "classical" examples are referring to searching of points in the given region to illustrate how kdtree can be used to solve the problem.

I can't figure out how to "extend" algorithm to work on shapes instead. I am more looking for idea rather than exact implementation.

( I am not considering trivial looping over each shape to see whether is in or out of given region )

libxelar.so
  • 473
  • 4
  • 16

2 Answers2

1

Using the bounding box you can very easily test if a shape is inside the selection (that's if all four corners are inside).

To reduce this problem to the "classical" one, just replace each shape by a random point inside the bounding box of this shape (upper left corner for instance). By doing this you may get more shapes than you want (with your example you would get the lower right rectangle) however that's not a problem as you can very easily check that the candidate shapes are indeed inside the selection.

Thomash
  • 6,339
  • 1
  • 30
  • 50
  • for 4-5 shapes iterating through all of them is ok. but how about 2M shapes if selection includes 0.1% of them ( very narrow selection ) ? – libxelar.so Apr 03 '19 at 12:37
  • You're not iterating through all of them, only the ones that have the upper left corner inside the selection. – Thomash Apr 03 '19 at 13:26
1

A KD-Tree isn't ideal for this type of search. As @Thomash suggested, it is useful to create the AABBs (axis aligned bounding boxes) for each shape. Then you can put them in something like a quadtree or R-Tree. These allow you to store AABBs and then easily query for all AABBs that intersect with a query rectangle.

For each AABB you get back from a query you then need to check whether the shape actually instersects with the query rectangle (intersecting with the AABB does obviously not guarantee intersection with the shape inside the AABB).

If you are using Java, have a look at my implementations of various spatial indexes.

TilmannZ
  • 1,784
  • 11
  • 18
  • ok, I think I've got first idea, that is "treat" all the shapes by their aligned BBoxes, which is doable. Now for the second, do we store this bboxes as a data in a tree? – libxelar.so Apr 04 '19 at 13:45
  • Yes. The tree can be like a Map where AABB is the 'key' and your data is the actual shape. – TilmannZ Apr 04 '19 at 13:47
  • Of course the 'Map' has additional functions for searching for everything intersecting with a given rectangle. – TilmannZ Apr 04 '19 at 13:48