Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
453 views
in Technique[技术] by (71.8m points)

data structures - Quadtree for 2D collision detection

I'm trying to use a quadtree for 2D collision detection, but I'm a little stumped on how to implement it. First of all, I'd have a quadtree which contains four subtrees (one representing each quadrant), as well as a collection of objects which don't fit into a single subtree.

When checking an object for collisions in the tree, I would do something like this (thanks to QuadTree for 2D collision detection):

  1. Check the object for collisions with any objects in the current node.
  2. For any subtree whose space overlaps the object, recurse.

To find all collisions within a quadtree tree:

  1. Check each object in the current node against each other object in the current node.
  2. Check each object in the current node against each subtree.

To insert into a quadtree:

  1. If the object fits into multiple subtrees, then add it to the current node, and return.
  2. Otherwise, recurse into whichever subtree contains it.

To update a quadtree:

  1. Recurse into each subtree.
  2. If any element in the current node no longer fits completely in the current tree, move it to the parent.
  3. If any element in the current node fits into a subtree, insert it into the subtree.

Is this alright? Can it be improved?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your quadtree structure isn't optimal. You're right to store 4 subtrees per node, but actual objects should only be stored inside the leaves, not inner nodes. Therefore the collection holding the actual objects needs to be moved to the leaves.

Let's have a look at the implementation of the operations:

  1. Insert an object into the quadtree:
    Check if the object intersects the current node. If so, recurse. If you've reached the leaf level, insert the object into the collection.
  2. Delete an object from the quadtree:
    Execute the exact same steps as if inserting the object, but when you've reached the leaf level delete it from the collection.
  3. Test if an object intersects any object inside the quadtree:
    Execute the exact same steps as if inserting the object, but when you've reached the leaf level check for collision with all the objects in the collection.
  4. Test for all collisions between all objects inside the quadtree:
    For every object in the quadtree execute the single object collision test.
  5. Update the quadtree:
    Delete all objects from the quadtree whose position has been modified and insert them again.

This has several advantages:

  • By only storing objects in the leaves it is very easy to handle operations on the quadtree (fewer special cases)
  • The quadtree can have leaves with different depth, thus allowing you to adapt the density of the quadtree depending on the spatial region it covers. This adaption can happen at runtime, thus keeping the object/node ratio optimal.

Only disatvantage:

  • Objects can belong to several collections inside the quadtree. You're going to need an extra linear collection outside the quadtree to enumerate every object without duplicates.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...