I'm currently working on a 2D shoot them up type of game, and I'm using a quad tree for my collision detections. I wrote a working quad tree that correctly pushes my actors into the nodes/leaves they belong to in the tree. However, I've got a few problems.
Firstly, how do I actually use my quadtree to select against which other objects an object should test collisions ? I'm unsure about how this is done.
Which brings up a second question. Say I have an object in node that is not a neighbour of another node, but that the object is large enough that it spans a few node, how can I check for an actual collision, since I'm guessing the tree might consider it's not close enough to collide with objects in a "far away" node? Should objects that don't completely fit in a node be kept in the parent node?
In my game, most of the objects are of different sizes and moving around.
I've read a good number of blogs/articles about quadtrees but most just explain how to build a tree which is not really what I'm looking for.
Any help/info is welcome.
You can establish a convention that every element is contained in the smallest quadtree node which contains it fully.
Then when you check the collisions for node A, you proceed like this:
current node = root node
check collisions of A with each element directly in current node
if A can be contained entirely in any of sub-nodes of the current node, set the current node to that sub-node and go to 2 again
finally, check collisions of A with all the elements in children nodes of the current node, recursively.
Note that the smaller the objects, the deeper they will be located in the quad tree, hence they will be compared less often.
Related
Sorry in advance, this a very specific question and I cannot provide any piece of code as this is for my job, thus confidential.
I am using the Boost R-trees, and an algorithm that I need to implement requires to access the non leaf nodes of the tree. With Boost rtree library, I only can access leaf nodes in an easy way. I noticed that there is a function to print all the nodes including the non leaf nodes (which means they exist, they are computed), with their position, their level in the tree etc, but I cannot access them the same way than the leaf nodes.
For now, the best solution that I have is to implement a visitor for the tree and overload the operator () to gather the nodes (this is what the print method does to access the nodes).
My question is, does anybody know an easier way to access the non leaf nodes ? Because this one does not seem to be efficient, and I'm loosing time each time I want to access a non leaf node. Moreover, I need to replicate the structure of the tree without the points, and I cannot do that if I cannot access the non leaf nodes.
Thank you in advance !
I don't know what would you like to do exactly so this will be a general answer.
In order to access the tree nodes for the first time you have to traverse the tree structure. In Boost.Geometry rtree visitor pattern is used for that. You could do it manually but internally Boost.Variant is used to represent the nodes so you'll end up with variant visitor instead. At this point you have a few options depending what are you going to do with the nodes. Are you going to modify the r-tree? Will the rtree be moved in memory? Will the addresses of nodes change? How many nodes are you going to access? Do you want to store some kind of reference to a node and traverse the tree structure from that point? Do you want to traverse the structure downward or upward?
One option as you noticed is to traverse the tree structure each time. This is a good approach if the tree structure can change. The obvious drawback is that you have to check all child nodes at each node using some condition (whatever you do in order to pick the node of interest).
If the tree structure does not change but the tree is copied to a different place in memory you can represent the node as a path from the root to the node of interest as list of indexes of child nodes. E.g. a list {1, 2, 3} meaning: traverse the tree using child node 1 of root node, then at the next level pick child node 2, then your node will be child node 3 at the next level. In this case you still have to traverse the tree but doesn't have to check conditions again.
If the tree does not change and nodes stays in the same place in memory you can simply use pointers or references.
I'm trying to create a quad tree for my 3D environment (all elements are on a flat terrain, so they can be represented with 2D data), but I'm a little lost on the implementation of the finer parts of it.
I will first begin by describing my current quad tree, than move on to its flaws, and than ask the questions.
What I currently have is a quad tree that takes in a very specific rectangle in which I define the x,z,width, and forward. Here is an overview of my operations.
Insert an object into the quadtree:
Check if the current node has any child. If it does, check if the object is able to completely fit into any of the four nodes. If Possible, recurse and repeat. If the object does not completely fit into the four nodes or there are no nodes at all, it will add it to a std vector, than check if it should split. If it splits, split it and split the current objects into their respective nodes.
Delete an object from the quadtree:
Check if the object is inside the current node. Than move onto children. If found, pop the object out of the vector.
Update the quadtree:
Moving and static objects are stored in different quad trees. Moving quad tree will always delete whatever has moved and reinsert. Static quad tree just chills.
Retrieving an object
First find which of the four nodes it belongs to, than move recursively, taking all of the node's current objects and adding it to a vector that is returned at the end.
So here are my flaws: Not all of my rects are located in the leaf. I have no idea what I should do with those that intersect between the nodes. This also makes collision detection checking kinda stupid in a quad tree; why do I need to put rects inside parent nodes? I am thoroughly unhappy about the Retrieve object function.
My second flaw is that I can only take a rect in. While this was useful in making the quad tree and debugging it, I would like to move on and be able to directly put my Objects in my game inside.
So here are my questions
I've read Quadtree for 2D collision detection. Everything seems good enough, until "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."
I have no idea what that means, or how to do that. The operations for collision detection also seems much better than what I currently have. I want to know what he means and how its done.
My second question is regarding the insertion of objects into the tree. All my objects in the game would be part of a base class. Should I just make them add the base class directly? Or should I cast the objects into rects and than add a pointer to the object? I am loading some models for my game as well, and they are stretched around and played with by glScalef(). Thus it seems really hard (but possible) to get the scaling of and the position of the models after scaling.
On a side note, the main reason I am scaling the models is because I am basically making walls for a maze game. So I need them to fit perfectly around, and I can't mathematics on maya.
How do you use quad tree for 3d? Maybe you mean 2d? Because usually octree is used for 3d.
About you first question. Your objects may belong to several quads in quadtree. When you retrieve objects you need to check collision with you just check if you already detected collision between two objects and if you did you dont do the detection again to bypass duplicates. For example you have 2 objects in one quad. You check collision between 1st and second and then between 2nd and 1st. You need to check that you already detected this collision before.
Try reading this link for details.
You can try a morton curve to find overlapping area I also think you need an octree:http://dmytry.com/texts/collision_detection_using_z_order_curve_aka_Morton_order.html. Here are example of overlapping objects:https://books.google.fr/books?id=1mu099DN9UwC&pg=PA29&lpg=PA22&ots=pzvPDLu5qi&focus=viewport&dq=hilbert+curve+overlapping+objects&hl=de&output=html_text
I have a doubly-linked list based Polygon2D class that needs to be searched and modified, and is to be used in a game engine for various utilities like collision detection and to define graphical shapes and possibly texture coordinates, among other things. The polygon should be able to be concave or convex, but it cannot intersect itself.
I'm having trouble coming up with a method to insert a point such that it doesn't cause an intersection with the polygon. What I've been doing is searching for the closest edge to the point to insert by having two pointers to nodes, both starting at the head and iterating in separate directions. When the "next" node for either is the other pointer, the search is complete and the point is inserted between the two. Otherwise, the node iterating forward goes until it gets to the closest point so far (stopping if the next node is the other pointer), then the node iterating "backwards" does the same.
Unfortunately, this still results in intersections in cases where the edge just before the forward iterating pointer or the edge just "after" the backwards iterating pointer intersects the new edge created when inserting a new point. After that, more and more intersections can easily slip in.
Here is the insert method's code.
Can I improve this algorithm and still keep it O(n) or is there an entirely different method which may work better?
As a side note, the "findClosest[Edge](vec2 pt)" search uses a slightly modified version of the algorithm, but I feel like there must be a more effective way to do these searches without using more memory or time.
As for the calculation of the distance from a given point to a vertex this Distance from a point to a polygon might help.
I would like to implement a custom graph data structure for my project and I had a question about proper memory management.
Essentially, the data structure will contain nodes that have two vectors: one for edges coming into the node and one for edges coming out of the node (no looped edges). The graph is connected. The graph will also contain one 'entry' node that will have no edges coming into it. An edge is simply a pointer to a node.
My question here is: What would be the best method of clearing up memory for this type of data structure? I understand how to do it if there was only one entry edge (at which point this structure degenerates to a n-ary tree), but I'm not sure what to do in the case where there are multiple nodes that have edges going into a single node. I can't just call delete from an arbitrary entry node because this will likely result in 'double free' bugs later on.
For example, suppose I had this subgraph:
C <-- B
^
|
A
If I were to call delete from node B, I would remove the memory allocated for C, but A would still have a pointer to it. So if I wanted to clear all the nodes A had connections to, I would get a double free error.
You will need to perform a search to figure out which node is still connected to the input edge, when you remove a component. If you end up with more than one connected group, you will need to figure out which one of these contains the entry node and remove all others.
No greedy (local) algorithm for this can exist, which can be shown by a simple thought experiment:
Let A, B be subgraphs connected only through the node n, which shall be removed. We are left with two unconnected subgraphs. There is no way of knowing (without a whole bunch of state per node) if we have just removed the only route to the entry node for A or B. And, it is necessary to figure that out, so that the appropriate choice of removing either A or B can be made.
Even if every node stored every single route to the entry node, it would mean you have to clean up all routes in all nodes whenever you remove a single node.
Solution Sketch
Let us talk about a graphical representation of what we need to do:
First, Color the node that is being deleted black. Then perform the following for every node we encounter:
For uncolored nodes:
If the node we came from is black, give this node a new color
If the node we came from is colored, give this node the same color
Travel through every outgoing edge
For colored nodes:
If the node we came from is black, just return
If the node we came from is the same color, just return
If the node we came from has a different color, merge the two colors (e.g. by remembering that green and blue are the same, or by painting every green node blue)
Travel through every outgoing edge
At the end we will know which connected components will exist after we delete the current node. All connected components (plus our original to be deleted node) which do not contain the entry node must be deleted (Note: This may delete every single node, if our to-be-deleted node was the entry node...)
Implementation
You will need a data structure like the following:
struct cleanup {
vector<set<node*>> colors;
node* to_be_deleted;
size_t entry_component;
};
The index into the vector of lists will be your "color". The "color black" will be represented by usage of to_be_deleted. Finally, the entry_component will contain the index of the color that has the entry node.
Now, the previous algorithm can be implemented. There are quite a few things to consider, and the implementation may end up being different, depending on what kind of support structures you already keep for other operations.
The answer depends on the complexity of the graph:
If the graph is a tree, each parent can own its children and delete them in its destructor.
If the graph is a directed acyclic graph, an easy and performant way to handle it is to do reference counting on the nodes.
If the graph can be cyclic, you are out of luck. You will need to keep track of each and every node in your graph, and then do garbage collection. Depending on your use case, you can either do the collection by
cleaning up everything when you are done with the complete graph, or by
repeatedly marking all connected nodes and cleaning up all the unreachable ones.
If there is any possibility to get away with option 1 or 2 (possibly tweaking the problem to ensure that the graph fulfills the constraint), you should do so; option 3 implies significant overheads in terms of code complexity and runtime.
There are a couple of ways. One way is to make your nodes know what other nodes have edges to it. So, if you delete C from B, C will need to remove the edge to it from A. So later when you remove/delete A, it won't try to delete C.
std::shared_ptr or some other type of reference counting may also work for you.
Here's a simple way to avoiding memory problems when implementing a graph: Don't use pointers to represent edges.
Instead, give each node a unique ID number (an incrementing integer counter will suffice). Keep a global unordered_map<int, shared_ptr<Node> > so that you can quickly look up any Node by its ID number. Then each Node can represent its edges as a set of integer Node IDs.
After you delete a Node (i.e. remove it from the global map of Nodes), it's possible that some other Nodes will now have "dangling edges", but that will be easy to detect and handle because when you go to look up the now-removed Node's ID in your global map, the lookup will fail. You can then gracefully respond by ignoring that edge, or by removing that edge its the source Node, or etc.
The advantages of doing it this way: The code remains very simple, and there is no need to worry about reference-cycles, memory leaks, or double-frees.
The disadvantages: It's a little bit less efficient to traverse the graph (since doing a map lookup takes more cycles than a simple pointer dereference) and (depending on what you are doing) the 'dangling edges' might require occasional cleanup sweeps (but those are easy enough to do... just iterate over the global map, and for each node, check each edge in its edge-set and remove the ones with IDs that aren't present in the global map)
Update: If you don't like doing a lot of unordered_map lookups, you could alternatively get very similar functionality by representing your edges using weak_ptr instead. A weak_ptr will automagically become NULL/invalid when the object it is pointing at goes away.
I need some working snippets on C++ code regarding breadth/depth first searches. Also, in the links below, when using the term tree, is it in reference to a binary tree or more specefically a red and black tree? Or is this a more abstract tree of sorts? Does anyone have a link to working code for these searches...along with constructing the tree?
Tree seems to refer to some sort of constuct with in the "graph"? I believe this is some sort of math I have not taken yet.
breadth or depth first search 1
breadth or depth first search 2
The tree in question is the thing they're searching. It's kinda hard to understand search algorithms without knowing what it is they are searching through.
A tree is a type of graph. A graph is a series of nodes (which presumably represent some data) with connections between certain nodes. A tree is a graph where the connections between nodes form a hierarchy. For any given node in the graph, it has exactly one "parent" that points to it, and it points to zero or more child nodes. And the nodes cannot form circles; a parent cannot point to a child who points to that parent.
Basically, like branches on a tree.
The term "tree" refers to any data structure that can be abstractly looked at as a tree.
A "tree" is a data structure in which there are parent nodes and child nodes, and each child has a single parent, with a single "root" node not having a parent.
If a node in your tree has multiple parents, it is called a "graph".
A tree is a special case of a directed acyclic graph (basically a bunch of 'nodes' with arrows ('edges') pointing at each other, such that there cannot be a loop of arrows) in which the following two conditions hold:
No node has more than one incoming edge
There exists a single distinguished node (the 'root') from which all other nodes are reachable.
The nodes reachable via an outgoing edge from some node N are often called N's children.
Breadth-first and depth-first search apply to generic trees (indeed, they apply to all DAGs). However there are some more specific types:
Binary trees are trees in which no node has more than two outgoing edges; outgoing edges are labelled, usually as 'left' and 'right'
Search trees are binary trees in which each node has a key; further, the key in some node N is greater than the child on its left edge (if any) and less than the child on its right edge (if any). This allows for very fast searching for a specific key.
Red-black trees are a specific kind of search tree in which a moderately complex algorithm is used to make sure all keys are approximately the same distance from the root.