Question

First of all, sorry if the code it's huge there. I'll try to modularize to make it simple. Second, it's a strange error, so I've used a intuitive main with the example, if anyone want to test it. I want it to insert dots on a Quadtree that represent recursive quadrants. If the dots inserted hits the cap, then it's divided by four and the limits are divided in 4 different quadrants. I've tried to insert the dot (16.0,16.0) (double) and doesn't works. All other dots I've tried works perfectly (it's a double variable so, obviously, I can't test all the values). When it hits the cap, works perfectly the division and the new dots. Only the 16,16 that don't (I've tried a lot of numbers.... some dozens). EDIT: When I make the quadtree huge, it starts to don't insert some points (even some that were inserted before, when it's smaller). ok: here's the funcion in highest level:

//This will insert on a tree (that have a root)
    void insert_dot(Tree * A, Dot b){
        if (b.x<0 || b.y<0.0){
            printf("Invalid coordinates");
            return;
        }
        Quad_node * Aux;
        if (A->start_->key->used_capacity > A->start_->key->max_capacity){
            printf("invalid result\n");
        }
        else if (A->start_->key->used_capacity < A->start_->key->max_capacity){
            A->start_->key->dots_[(A->start_->key->used_capacity)].x=b.x;
            A->start_->key->dots_[(A->start_->key->used_capacity)].y=b.y;
            A->start_->key->used_capacity++;
        }
        else{
            Aux=return_leaf_tree(A,b);
            insert_dot_quadrant(Aux,b);
        }

    }
//This is the auxiliar function
void insert_dot_quadrant(Quad_node * A,Dot b ){
    Quad_node * Aux,* Aux2;
    Dot * aux=(Dot*)malloc(A->key->max_capacity*sizeof(Dot));
    int i;
    if (A->key->used_capacity > A->key->max_capacity){
        printf("invalid result\n");
        return;
    }
    else if (A->key->used_capacity < A->key->max_capacity){
        A->key->dots_[(A->key->used_capacity)].x=b.x;
        A->key->dots_[(A->key->used_capacity)].y=b.y;
        A->key->used_capacity++;
    }
    else{
        for(i=0;i<A->key->max_capacity;i++){
            aux[i].x=A->key->dots_[i].x;
            aux[i].y=A->key->dots_[i].y;
            A->key->dots_[i].x=-1.0;
            A->key->dots_[i].y=-1.0;
        }
        Aux=divide_quadrant(A);
        for (i=0;i<A->key->max_capacity;i++){
            Aux2=return_leaf_node(Aux,aux[i]);
            insert_dot_quadrant(Aux2,aux[i]);
        }
    }
    free(aux);
}

Auxiliary functions (relevant):

Quad_node * return_leaf_tree(Tree * A,Dot b){
    Quad_node * Aux=(Quad_node_Pointer)malloc(sizeof(Quad_node));
    Aux=return_leaf_node(START_(A),b);
    return (Aux);
}

Quad_node * return_leaf_node(Quad_node * A,Dot b){
    if (A==NULL){
        printf("invalid node\n");
        return (NULL);
    }
    Quad_node * Aux,*Aux2;
    Aux=(Quad_node_Pointer) malloc (sizeof(Quad_node));
    Aux2=(Quad_node_Pointer) malloc (sizeof(Quad_node));
    Aux=A;
    Aux2=A;
    while (Aux!=NULL && Aux->key->used_capacity == Aux->key->max_capacity){
        if (b.x==16)
            printf("16 entered\n");
        if ((Aux->key->max.x)/2 <= b.x && b.x <= Aux->key->max.x  &&  (Aux->key->max.y)/2 <= b.y && b.y <= Aux->key->max.y){
            Aux->father=Aux;
            Aux=Aux->child[0];
            if (b.x==16)
                printf("16 here on child[0]\n");
        }
        else if (0 <= b.x && b.x < (Aux->key->max.x)/2  &&  (Aux->key->max.y)/2 <= b.y && b.y <= (Aux->key->max.y)){
            Aux->father=Aux;
            Aux=Aux->child[1];
            if (b.x==16)
                printf("16 here on child[1]\n");
        }
        else if (0 <= b.x && b.x < (Aux->key->max.x)/2  &&  0 <= b.y && b.y < (Aux->key->max.y)/2){
            Aux->father=Aux;
            Aux=Aux->child[2];
            if (b.x==16)
                printf("16 here on child[2]\n");
        }
        else if ((Aux->key->max.x)/2 <= b.x && b.x <= Aux->key->max.x &&  0 <= b.y && b.y < (Aux->key->max.y)/2){
            Aux->father=Aux;
            Aux=Aux->child[3];
            if (b.x==16)
                printf("16 here on child[3]\n");
        }
        else{
            printf("x=%f , y=%f\n",b.x,b.y);
            printf("max x= %f , max y=%f\nmin x=%f , min y=%f\n",Aux->key->max.x,Aux->key->max.y,Aux->key->min.x,Aux->key->min.y);
            printf("erro\n");
            if (b.x==16)
                printf("16 here on invalid position\n");
            return (EXIT_SUCCESS);
        }
        if (Aux!=NULL){
            Aux2=Aux;
        }

    }
    return (Aux2);
}

Quad_node * divide_quadrant(Quad_node * A){
    if(A==NULL){
        printf("invalid Quad_node");
        return (NULL);
    }
    int i;
    Dot max_aux,min_aux;
    for (i=0;i<4;i++){
        A->child[i]=(Quad_node_Pointer) malloc (sizeof(Quad_node));
    }
    max_aux.x= (A->key->max.x);
    min_aux.x=(A->key->max.x)/2;
    max_aux.y=(A->key->max.y);
    min_aux.y=(A->key->max.y)/2;
    A->child[0]->key=Create_quadrant(A->key->max_capacity,max_aux,min_aux);
    max_aux.x=(A->key->max.x)/2;
    min_aux.x=0;
    max_aux.y=A->key->max.y;
    min_aux.y=(A->key->max.y)/2;
    A->child[1]->key=Create_quadrant(A->key->max_capacity,max_aux,min_aux);

    max_aux.x=(A->key->max.x)/2;
    min_aux.x=0;
    max_aux.y=(A->key->max.y)/2;
    min_aux.y=0;
    A->child[2]->key=Create_quadrant(A->key->max_capacity,max_aux,min_aux);

    max_aux.x=A->key->max.x;
    min_aux.x=(A->key->max.x)/2;
    max_aux.y=0;
    min_aux.y=(A->key->max.y)/2;
    A->child[3]->key=Create_quadrant(A->key->max_capacity,max_aux,min_aux);
    return (A);
}

Main and other functions not so relevant (I'm almost sure that they are 100% fine. Just to run the main):

Quadrant * Create_quadrant (int capacity,  Dot max_, Dot min_){
    Quadrant * A;
    A=(Quadrant*)malloc(sizeof(Quadrant));
    if (A==NULL){
        printf("null value");
        return (NULL);
    }
    A->dots_ = (Dot*) malloc (capacity * sizeof(Dot));
    int i;
    for (i=0;i<capacity;i++){
        A->dots_[i].x=-1;
        A->dots_[i].y=-1;
    }
    A->max_capacity=capacity;
    A->used_capacity=0;
    A->max.x=max_.x;
    A->max.y=max_.y;
    A->min.y=min_.y;
    A->min.x=min_.x;
    return (A);
}

Tree * Create_tree (int capacity,Dot max){
    Tree * A;
    A=(Tree*)malloc(sizeof(Tree));
    Dot min;
    min.x=0;
    min.y=0;
    A->start_=(Quad_node_Pointer) malloc (sizeof(Quad_node));
    A->start_->key=Create_quadrant(capacity,max,min);
    return (A);
}

void tree_walk (Quad_node * a){
    int i;
    if (a!=NULL){
        for(i=0;i<a->key->used_capacity;i++){
            if (a->key->dots_[i].x >= 0)
                printf("x= %f y=%f\n", a->key->dots_[i].x,a->key->dots_[i].y);
        }
        for(i=0;i<4;i++){
            if (a->child[i]!=NULL){
                printf("child[%i] not null\n",i);
                tree_walk(a->child[i]);
            }
            else
                printf("null child[%i] node\n",i);
        }
    }
    else
    return;
}

void read_tree (Tree * A){
    tree_walk(START_(A));
}

Quad_node * START_(Tree * A){
    return A->start_;
}

main:

int main(int argc, char *argv[])
{
    printf("\n---------------\n");
    Tree * A;
    int i;
    Dot b,max,teste[12];
    b.x=5.0;
    b.y=6.0;
    max.x=30;
    max.y=30;
    A = Create_tree(8,max);
    for (i=0;i<12;i++){
        teste[i].x=(double)2.0*i;
        teste[i].y=(double)2.0*i;
        printf("dot %i:\n x=%f , y=%f\n",i,teste[i].x,teste[i].y);
        insert_dot(A,teste[i]);
    }
    insert_dot(A,b);
    printf("dot 10:\n x=%f , y=%f\n",b.x,b.y);
    printf("\n---------------\n\n");
    return_leaf_node(A->start_,teste[9]);
    read_tree(A);
    printf("success\n");
    free(A);
    return EXIT_SUCCESS;
}

OBS: only positive values can be inserted. Can anyone help me, please? Thanks for reading/answering!

Was it helpful?

Solution

Found the problem. Well, just for curiosity (And maybe will be someone problem too) here was the problem:

on void insert_dot_quadrant:

Dot * aux=(Dot*)malloc(A->key->max_capacity*sizeof(Dot));
....
else{
    for(i=0;i<A->key->max_capacity;i++){
        aux[i].x=A->key->dots_[i].x;
        aux[i].y=A->key->dots_[i].y;
        A->key->dots_[i].x=-1.0;
        A->key->dots_[i].y=-1.0;
    }
    Aux=divide_quadrant(A);

This should be:

Dot * aux=(Dot*)malloc(((A->key->max_capacity)+1)*sizeof(Dot));

 ....
     else{

for(i=0;i<A->key->used_capacity;i++){
            aux[i].x=A->key->dots_[i].x;
            aux[i].y=A->key->dots_[i].y;
            A->key->dots_[i].x=-2.0;
            A->key->dots_[i].y=-2.0;
        }
        aux[A->key->used_capacity].x=b.x;
        aux[A->key->used_capacity].y=b.y;

        Aux=divide_quadrant(A);

I wasn't inserting the new dot when quadrant is full. Just dividing the older ones into the new 4 quadrants and forgetting the new dot.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top