2

I have been studying about quadtrees and their usage in collision detection in videogame code.

However, all the implementations so far rely on object-oriented features of C++,C#, javascript and Lua to do every node, and I have absolutely no idea of how to translate that to raw C.

The objective is to test multiple objects (shots) against actors (constantly moving) and terrain (static). Then actors with terrain. Since I cannot find an example I can read in "pure" C terms (that is, not using methods or self-referencing objects), I cannot even grasp the basic idea of how to code it, while I do understand the idea behind the algorithm. I don't know how to set it up, how to reference it, what datatypes should I use, or anything at all. I know absolutely nothing of C++, which makes translating it to C impossible.

As well, I will be using tilemaps for terrain, and I want to do things like maps that are tall or wide, not perfect squares. A quadtree still works with such a map?

Also, there will be a number of moving elements, being the terrain the only static part in play (elements like moving blocks or doors are separate entities). Is it worth it using a quadtree if updates will be required often? Do I even need to make it global data? (could as well be forged inside some function and then passed around when collisions are enabled). Do I need to allocate memory for it in such a case?

roger_rales
  • 191
  • 1
  • 2
  • 7
  • Have a look at [this][1]. [1]: http://stackoverflow.com/questions/4544928/quadtree-explanation-and-c-implementation – phimuemue Aug 02 '11 at 21:03
  • I have been there first. The links provided are a PDF that only contains diagrams, and a lot of undocumented source code with no explanation of what is what. As well, google searches only return complete code where the basics are hidden by proper functions in that code. I haven't seen any question here which properly addresses the point. (Also broken links) – roger_rales Aug 02 '11 at 21:09
  • Just so I understand: Is it the basic code for a quadtree that's troubling you? Or do you already have that and is it something else? – Bart Aug 02 '11 at 21:29
  • The basic code. I don't know how to translate that logic into usable C code without using OO code. – roger_rales Aug 02 '11 at 21:30
  • @ phimuemue I just saw I gave the same link in my answer(deleted ... tried to) ... @in_disarray First link in the list provided by the selected answer looks actually pretty good to me http://hyantes.gforge.inria.fr/doc/quadtree_8c-source.html. What's wrong with it? – celavek Aug 02 '11 at 21:33
  • @celavek It's...fairly unreadable. The commenting there is stating the obvious but doesn't explain anything, and most stuff is in some header file who knows where. It's clearly not something oriented to teaching. – roger_rales Aug 02 '11 at 21:37
  • I don't know how good your C is, but a quadtree would be nothing more than a Node struct which contains 4 pointers to sub-Node-s. Of course the Nodes would hold some other data as well, but this is the very basic. – Bart Aug 02 '11 at 21:39
  • By way of understanding your level of preparation: Do you understand how one would maintain a linked list in c? How about a sorted binary tree? If you understand those can you say more precisely what is stopping you from generalizing from the binary tree? – dmckee --- ex-moderator kitten Aug 02 '11 at 21:49
  • My C is fairly basic. The jargon certainly doesn't help in most online references. I really don't know how should I handle the pointers, the growing, and if I need to allocate memory or not. Also, if quadtrees won't work in rectangular maps, I am not going to bother with it anymore. – roger_rales Aug 02 '11 at 21:49
  • A link that may help a bit: [What is the best way to plan and organize development of an application in C?](http://stackoverflow.com/q/436446/2509). – dmckee --- ex-moderator kitten Aug 02 '11 at 21:52
  • 2
    Having a working understanding of pointers is *mandatory* for trying to manage a structure like a quad-tree in c. So your first step might be to work through some linked-list and binary-tree implementation exercises. From there things should be pretty clear. And quad-trees will work fine on a rectangular map. There are actual quite a few questions by/for programers from high level languages struggling with low level concepts like pointer, so have a look around. – dmckee --- ex-moderator kitten Aug 02 '11 at 21:55
  • Learn C. Pick up a good book and learn the language. Learn about basic data structures as dmckee suggests. You'll naturally figure out how the language concepts map to this problem. – Bart Aug 02 '11 at 22:00
  • I just want to see if it's really better. For being something that is recommended so often, it's not really that documented for beginners. The diagrams are nice and all, but they still don't explain how it is done. I know what it does, but not how it's implemented. It's a lot of study just to check if it makes a difference. – roger_rales Aug 02 '11 at 22:04

2 Answers2

2

Because you are asking for help with absolutely nothing to start with, I'll show you some example data structures that might work, as well as an API.

In C, one would implement nodes with structures. Something like this:

struct quadtree {
    int size;
    struct node *root;
};

struct node {
    struct node *children[4];
};

And then to stick objects in the quadtree, you can add some extra fields.

struct object {
    int x, y;
    // plus extra info not related to quadtree
};

struct node {
    struct node *children[4];
    int nobjects;
    struct object *objects;
};

The quadtree interface would give you some basic operations:

void quadtree_insert(struct quadtree *q, struct object *obj);
void quadtree_remove(struct quadtree *q, struct object *obj);
// Equivalent to remove + insert, but more efficient
void quadtree_move(struct quadtree *q, struct object *obj, int x, int y);
int quadtree_query(struct quadtree *q, struct object **obj, int max,
                   int x0, int y0, int x1, int y1);

That's it, basically. But the implementation will not be trivial. Note that the maximum depth of this quadtree is about 32, which can simplify the implementation somewhat.

If you're having problems here, I suggest taking a step back and tackling a similar but simpler data structure first. For example, try implementing a Red-Black or AVL tree without using source code as a reference. If you're not somewhat well-versed in C programming, then a quad tree may be a poor choice for a first project due to its moderate complexity.

Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
  • I have done other project using basic "2D" (note the quotes) arrays to store position data, and I can get a consistent FPS with over 2000 shots, more than enough. But everyone insists on quadtrees being the "right way", but I was baffled at finding it was explained so for...computer science students. However, this is an example I understand, enough to get started with. – roger_rales Aug 02 '11 at 22:13
  • Yes, this is definitely what I needed. Thank you very much for the answer. My only remaining concern is if I should make the shot tree a global that is updated constantly, or a local generated after parsing the objects, generated every frame. I keep hearing updating is a slow operation. – roger_rales Aug 02 '11 at 22:19
  • @in_disarray: Updating an object is about as fast as removing it and then inserting it again. When you're using C, this will be quite fast. It may be faster to regenerate the quadtree after each frame, and it would be easy to find out with profiling. But it probably won't be *much* faster, and you might want to spend your time on something else instead. – Dietrich Epp Aug 02 '11 at 22:24
  • I will experiment with it. But since I fear memory allocation, I will try linked lists and such as suggested...I really didn't want to dwell into the arcane depths of C, really. – roger_rales Aug 02 '11 at 22:34
  • Actually, in order to code something like a red-black or AVL. What's their actual *purpose*? Aside from learning the intricacies of C, what's the purpose of those algorithms? Will they serve any purpose in a game? – roger_rales Aug 02 '11 at 22:40
  • I mean, just this random example. http://www.cs.auckland.ac.nz/software/AlgAnim/red_black.html It shows me plenty of code I could just copy and paste. But it doesn't tell me what it's supposed to do *for me*. (or my program, rather). No use cases at all. – roger_rales Aug 02 '11 at 23:01
  • @in_disarray: A Red-Black tree is just one possible species of balanced binary tree. The site appears to be a book; CS and math books are notoriously incomprehensible if you skip ahead. Go back to chapter 4 for more information about trees. Wikipedia is also an excellent reference. – Dietrich Epp Aug 02 '11 at 23:15
  • But why should I use one? What's their use? I only see algorithms everywhere and a lot of math jargon, but not a simple reason to use them. What kind of data do I need, and what do I need to do with it, to use either a AVL or a red-black? – roger_rales Aug 02 '11 at 23:20
  • @in_disarray: Please, just go to the Red-Black tree page on Wikipedia, and read the first sentence. – Dietrich Epp Aug 03 '11 at 00:17
  • I have been there several times. "Put very simply, a red–black tree is a binary search tree that inserts and deletes in such a way that the tree is always reasonably balanced.". I get that. But what data is it useful for? What results should I expect? I don't have a chance to write something like that without reference code, without having an use for it on the first place. So to put it simply "*when do I use a red-black tree*"? Even better. Can you put it in task form? "with data X Y Z do A", or something like that. – roger_rales Aug 03 '11 at 00:23
  • @in_disarray: "typically to implement associative arrays" there you go. – Dietrich Epp Aug 03 '11 at 00:25
1

If all your examples use for "object orientation" is method calls it is very easy to translate things to C. It only gets a bit harder if you need to implement things like polymorphism (two different subclasses witha method with the same name) or inheritance.

To create a class in C:

//Define your struct, containing all instance attributes
typedef struct Tree{
    int something;
    struct Tree * child; //must use the long "struct Tree*" here, long story...
} Tree;

//to create a method, just make a normal function that receives a pointer to the
// object as the first parameter

void init_tree(Tree* this, /*arguments*/)
{
    //constructor logic would come here

    //Note that "this" is NOT a magic/reserved word in C.
    //I'm only using it to make the correspondence with the OO
    // stuff more obvious.
}

void insert(Tree* this, /*whatever the arguments are*/)
{
    //You can acess the properties of a struct pointer with "->"
    this->child = /*...*/;
}

//Using the class:
int main(){
    Tree * my_tree = malloc(sizeof Tree);
    init_tree(my_tree);
    ...
    free(my_tree);
}

As was already mentioned in the comments, you should probably try to make a simpler datastructure like a Linked List first, to learn how to deal with the pointers, etc. The basic ideas of emulating "OO" remain the same though.

hugomg
  • 68,213
  • 24
  • 160
  • 246
  • But I don't want to emulate OO. I just say that all the examples are oriented and explained in regards to OO, which I don't understand enough to translate into C. – roger_rales Aug 02 '11 at 22:09
  • Do you not understand the OO, the C or the quadtrees? All I was trying to say here is that the "OO" you see is probably way simpler than you were imagining. – hugomg Aug 02 '11 at 22:43
  • I only understand I have a struct with 4 pointers to other identical structs and that I need to make new ones every time one of the structs is "full" of elements to store. I don't know how to make an array full of shot objects (x,y,height,width) fit into that scheme. My only guess is putting a reference to the index for that array as the "elements to store" in the struct. I have no idea of how to do the partitioning, or how to make the pointer maze required here. (and most importantly, how to not make it explode) – roger_rales Aug 02 '11 at 22:51
  • You can create an array at runtime with malloc() – hugomg Aug 03 '11 at 00:59
  • 1
    *"don't know how to make an array full of shot objects (x,y,height,width) fit into that scheme"* Remember when I said understanding pointer is mandatory? This is why. To do any serious work in c you will need to understand pointers, and you will need to understand the ins and outs of at least a few basic graph-like data structures. It is pointless to ask for help if you are unwilling to do the groundwork. – dmckee --- ex-moderator kitten Aug 03 '11 at 01:14
  • More than being unwilling is the amount of terms increases exponentially, and a game requires more work than just code to work. I happened to put my mastery in other things like binary logic and arithmetic, and making everything work on the surface, which only needed basic usage of pointers. Optimizing is the problem though. You can see above I am recommended to try things like red-black trees and such, but I am not giving any reason to do them other than "to learn". Give me a simple game example for a binary search tree and I will understand and get to practice immediately. – roger_rales Aug 03 '11 at 01:33
  • Two principles: never dereference an invalid pointer and never lose a block you allocated. C makes all that is your responsibility. Use `malloc` or `calloc` to allocate blocks, `realloc` to change their size and `free` to release them. Pointers to released blocks are invalid as are pointers to automatic variables after their block ends. Uninitialized pointers should be assumed to be invalid. In principle you now know everything about you need to implement the quadtree. If you are a genius that will do it; mere mortals work simpler problems to get the kinks out in easy situations. Good luck. – dmckee --- ex-moderator kitten Aug 03 '11 at 02:48
  • I have been asking for a test case to do those simpler problems you speak about. You can't expect me to implement a linked list without knowing what to do with them. Just give me one example where you use a binary tree. I don't mean example code, I mean a example situation. "With this list of items X do Y". You can see I asked several times for such example and I am not getting one, which feels like I am being made fun of, or that people doesn't know any application for those algorithms. – roger_rales Aug 03 '11 at 12:14