How to fix this function who should adjusting the collision of the shapes?

by throwawayinvisible   Last Updated August 14, 2019 04:26 AM

I am working on sfml. My goal is to draw a random number of shapes on the screen using a list. Obviously the problem is to avoid that the shapes on the screen, who have also a randomic position, should not be overlapped. However I am not understanding where there might be the problem. I calculate the distance of the shapes and if it's minor to the radius, then there is a collision and I should change the position. other I keep going scrolling the list. I have tried to use also the getLocalbounds function but still is not working.

So I have tried to calculate first the distance of the shapes and see if it's minor or equal to the sum of the radius, but seems it's not working. I tried then using the function getLocalbounds but even with that it's not working.

ptr_list AvoidOverlapping (int radius)
{
    float distance;
    ptr_list p = this->head;
    ptr_list p2 = this->head;
    sf::Vector2f temporaryPosition;
    float dx, dy;
    int radius1 = radius+radius;
    while (p2!=NULL)
    {
        while(p!=NULL)
        {
            //distance = Calculate_Distance(p2->Planet.planetposition, p->Planet.planetposition);
            dx = ((p->Planet.planetposition.x)-(p2->Planet.planetposition.x));
            dy = ((p->Planet.planetposition.y)-(p2->Planet.planetposition.y));
            if ((dx*dx)+(dy*dy)<(radius1*radius1))

            //if (distance<=(radius*2))
            {
                temporaryPosition = setNewPosition(p->Planet.planetposition);
                p->Planet.planetposition = temporaryPosition;
            }
            p = p->next;
        }
        p2 = p2->next;
    }
    return this->head;
}

sf::Vector2f setNewPosition (sf::Vector2f position)
{
    sf::Vector2f newposition;
    newposition.x = rand()%1020;
    newposition.y = rand()%650;
    if ((position.x!=newposition.x) && (position.y!=newposition.y))
    return newposition;
    else
        setNewPosition(position);

}

float Calculate_Distance (sf::Vector2f position1, sf::Vector2f position2)
{
    float distance=sqrt((pow((position2.x-position1.x),2))+(pow((position2.y-position1.y),2)));
    //float distance = (((position2.x-position1.x)*(position2.x-position1.x))
                      //+((position2.y-position1.y)*(position2.y-position1.y)));
    return distance;
}

What I am expecting is that there shouldn't be any overlapped shapes on the screen, however it still happens.



Answers 1


if ((position.x!=newposition.x) && (position.y!=newposition.y))`

This condition only checks if the newly generated position is exactly the same as the old. It will almost always be false and there is no guarantee that the new position doesn't overlap with anything.

You should try to make sure the planets don't overlap as you generate them the first time.

Something like the following code. This also allows each planet to have a different radius.

bool IsOverlapping(sf::Vector2f position, float radius) {
    ptr_list p = head;
    while (p != nullptr) {
        sf::Vector2f d = p->Planet.position - position;
        float radius1 = p->Planet.radius + radius;
        if (d.x * d.x + d.y * d.y < radius1 * radius1)
            return true;
        p = p->next;
    }
    return false;
}

void GereratePlanets(int num) {
    while (num) {
        sf::Vector2f position;
        position.x = rand() % 1020;
        position.y = rand() % 650;
        float radius = rand() % 25 + 5; 

        if (!IsOverlapping(position, radius)) {
            // add to list
            --num;
        }
    }
}
krisz
krisz
August 14, 2019 04:24 AM

Related Questions


Updated February 18, 2018 00:26 AM

Updated March 25, 2017 10:26 AM

Updated November 01, 2017 01:26 AM

Updated February 09, 2019 03:26 AM

Updated July 23, 2017 12:26 PM