“Pure” C quadtree to use for collision detection purposes

与世无争的帅哥 提交于 2019-12-24 00:35:13

问题


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?


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/6918427/pure-c-quadtree-to-use-for-collision-detection-purposes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!