SFML community forums

Help => Graphics => Topic started by: Cadisol87 on January 31, 2014, 10:53:49 pm

Title: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on January 31, 2014, 10:53:49 pm
Hello everybody!

First of all: Excuse my terrible English  ;)

Im new to SFML and I made a little Program that shows some Circles Bouncing around in the window. That works fine.
But now I want that the Circles bounce away when the collide with another Circle.
How can I implement that?

Title: Re: [Beginner] Help with Bouncing Circles
Post by: Assassin0795 on January 31, 2014, 10:58:09 pm
You'd want to make it so the circles have boundaries; one of the simplest ways I've worked with collision is box collision - that is, you make a box around the entity you wish to implement collision for, and when two entities collide (for example, when the left boundary of thisCircle is at the same coordinates of the right boundary of thatCircle), you can then add code as to how they behave.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: G. on January 31, 2014, 11:00:32 pm
You don't need bounding boxes for only circles. Circle to circle collisions detection is easy: if the distance between their centers is longer than the sum of their radiuses, they collide.

Here's a good tutorial: http://gamedevelopment.tutsplus.com/tutorials/when-worlds-collide-simulating-circle-circle-collisions--gamedev-769
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Assassin0795 on February 01, 2014, 03:18:17 am
You don't need bounding boxes for only circles. Circle to circle collisions detection is easy: if the distance between their centers is longer than the sum of their radiuses, they collide.

Here's a good tutorial: http://gamedevelopment.tutsplus.com/tutorials/when-worlds-collide-simulating-circle-circle-collisions--gamedev-769

^ And it's things like this that I need to remember if I plan to get a job programming... Ignore my first post; sorry!
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Jesper Juhl on February 01, 2014, 05:19:18 am
Read this: http://www.gamasutra.com/view/feature/131424/pool_hall_lessons_fast_accurate_.php?print=1 (http://www.gamasutra.com/view/feature/131424/pool_hall_lessons_fast_accurate_.php?print=1)
It describes very nicely how to do circle/circle collision detection.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 01, 2014, 03:38:09 pm
Okay, Thanks for the fast replies, I will try to implement the methods from the tutorials later.

I found a new Problem: I use a Clock, a xSpeed and a ySpeed to Calculate the Bouncing-Direction, when a Ball Collides with a Window-Border. But sometimes, a Ball slides along the Window Border, it doesnt Bounce away.  :(

Have you any Idea what I can do to solve this Problem?
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Jesper Juhl on February 01, 2014, 03:52:09 pm
When you detect a collision you need to calculate bounce, the new direction and length of your velocity vector, depending on where on the circle the collision happens and the velocities and mass of the objects involved.
This is all described in great detail in the gamasutra article I linked you to above.

A little physics and vector math is really all that's needed and in 2d it's not too complicated.

Ohh and by the way, a sf::Vector2f is a convenient container for you vectors rather than xSpeed/ySpeed variables, but it makes no real difference, it's just convenient :)
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 01, 2014, 03:57:48 pm
Okay, I solved the Sliding-Window-Border-Problem by making some changes with the Clock.  :)

Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 01, 2014, 05:16:14 pm
Okay, my Project is nearly complete, but I've noticed that my CPU is getting hot when I run my Application.
It uses a lot of the system resources.  ???

Is there any way to stop that?

I've got Win7 Ultimate, an i5-CPU and 8GB RAM.

Thanks in advance for your Help!
Title: Re: [Beginner] Help with Bouncing Circles
Post by: G. on February 01, 2014, 05:21:11 pm
Did you enable vertical synchronization or set a frame rate limit?
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 01, 2014, 05:32:03 pm
Oops... Thanks a lot, G!
I enabled Vertical Sync and now it works perfectly without slowing down my system.  :)
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 01, 2014, 07:35:47 pm
Theres another problem now... I thought I solved it, but now its there again... Sometimes, when a Ball Collides with the Window-Border and should Bounce away, it sticks on the border, and only moves at one Axis. For example, when the Ball reaches the Top Window-Border and should bounce away, it sticks on the border and only moves from one side to the other on the x-Axis.

Has anyone a possible solution?

I appreciate any help and patience with an Beginner like me!  :)
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Azaral on February 02, 2014, 04:13:10 am
Theres another problem now... I thought I solved it, but now its there again... Sometimes, when a Ball Collides with the Window-Border and should Bounce away, it sticks on the border, and only moves at one Axis. For example, when the Ball reaches the Top Window-Border and should bounce away, it sticks on the border and only moves from one side to the other on the x-Axis.

Has anyone a possible solution?

I appreciate any help and patience with an Beginner like me!  :)

Can you show us the code?
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 02, 2014, 11:48:23 am
Of course, Azaral!

Here it is:
#include <SFML/Graphics.hpp>
#include <windows.h>
#include <iostream>
#include <vector>


using namespace std;

    int width = GetSystemMetrics(SM_CXSCREEN); // Get the Screen-Width
    int height =  GetSystemMetrics(SM_CYSCREEN); //Get the Screen-Height
        int ballradius = 50;
    vector <float> xSpeed{53.4f, 71.7f, 76.7f, 72.5f, 76.1f, 46.1f, 74.4f, 75.6f, 53.2f, 51.8f}; // Well, I dont know if thats very clever...
    vector <float> ySpeed{77.9f, 70.9f, 70.9f, 17.9f, 50.9f, 19.2f, 73.6f, 73.5f, 60.1f, 63.9f};

    bool RightBorderTouching(int TempPositionX)         // Yep, I know that you can do this shorter, but I like 'comprehensive' code.
    {
    int RightBorderPosition = TempPositionX + ballradius * 2;
    if(RightBorderPosition >= width){return true;}
    if(RightBorderPosition < width){return false;}
    }

    bool LeftBorderTouching(int TempPositionX)
    {
    int LeftBorderPosition = TempPositionX;
    if(LeftBorderPosition <= 0){return true;}
    if(LeftBorderPosition > 0){return false;}
    }

    bool TopBorderTouching(int TempPositionY)
    {
    int TopBorderPosition = TempPositionY;
    if(TopBorderPosition <= 0){return true;}
    if(TopBorderPosition > 0){return false;}
    }

    bool BottomBorderTouching(int TempPositionY)
    {
    int BottomBorderPosition = TempPositionY + ballradius * 2;
    if(BottomBorderPosition >= height){return true;}
    if(BottomBorderPosition < height){return false;}
    }

int main()

{

cout << "Width: " << width << endl;
cout << "Height: " << height << endl;

vector <sf::CircleShape> Ball(10); // Should I make the Balls within a vector or separately?
    for(int i = 0; i < 10; i++  )
    {
        Ball[i].setRadius(ballradius);
        Ball[i].setPointCount(100);
        Ball[i].setFillColor(sf::Color(34 , 186 , 186 ));
        Ball[i].setOutlineThickness(5);
        Ball[i].setOutlineColor(sf::Color(88, 97, 97));
        Ball[i].setPosition( 245 , 245);
    }

     sf::Clock clock;

     sf::ContextSettings settings;
     settings.antialiasingLevel = 8;

    sf::RenderWindow window(sf::VideoMode(width, height), "Bouncing Balls", sf::Style::Fullscreen, settings);

    window.setVerticalSyncEnabled(true);



    while (window.isOpen())
    {



        sf::Event event;
        while (window.pollEvent(event))
        {

            if (event.type == sf::Event::Closed)
            {
                window.close();
            }

            if (event.type == sf::Event::KeyPressed)
{

    if (event.key.code == sf::Keyboard::Escape)
    {
        window.close();
    }
}


        }

        auto  dt = clock.restart().asSeconds();
        window.clear(sf::Color::White);
        for(int i = 0; i < 10; i++  )

    {
       Ball[i].move(xSpeed[i] * dt, ySpeed[i] * dt );

    }

        for(int i = 0; i < 10; i++  )
    {
        window.draw(Ball[i]);
    }

        window.display();

for(int i = 0; i < 10; i++  )
    {
        if(RightBorderTouching(Ball[i].getPosition().x)) {xSpeed[i] = -xSpeed[i];}
        if(LeftBorderTouching(Ball[i].getPosition().x)) {xSpeed[i] = -xSpeed[i];}
        if(TopBorderTouching(Ball[i].getPosition().y)) {ySpeed[i] = -ySpeed[i];}
        if(BottomBorderTouching(Ball[i].getPosition().y)){ySpeed[i] = -ySpeed[i];}
    }
    }

    return 0;
}
 

Title: Re: [Beginner] Help with Bouncing Circles
Post by: krzat on February 02, 2014, 02:14:00 pm
You forgot to move ball so it doesn't collide anymore. For example ball at {x:50 y:0} and radius 10 should be moved to {x: 50 y:10}.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 02, 2014, 02:58:53 pm
You forgot to move ball so it doesn't collide anymore. For example ball at {x:50 y:0} and radius 10 should be moved to {x: 50 y:10}.
Okay, but what can I do to solve this Problem? First I set every x and y Speed to over 50, but that didnt work. So I think I misunderstood you  :-\

Which Values do I need to change?
Title: Re: [Beginner] Help with Bouncing Circles
Post by: krzat on February 02, 2014, 03:54:54 pm
I meant position. If RightBorderTouching returns true, you should move the ball and then change velocity.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 02, 2014, 06:10:49 pm
Wow, thanks krzat!   :)

I modified my code and now it looks like this:
for(int i = 0; i < 10; i++  )
    {
        if(RightBorderTouching(Ball[i].getPosition().x)) {Ball[i].move( -ballradius * dt, 0 * dt); xSpeed[i] = -xSpeed[i];}
        if(LeftBorderTouching(Ball[i].getPosition().x)) {Ball[i].move(  ballradius * dt, 0 * dt); xSpeed[i] = -xSpeed[i];}
        if(TopBorderTouching(Ball[i].getPosition().y)) {Ball[i].move(  0 * dt, ballradius * dt); ySpeed[i] = -ySpeed[i];}
        if(BottomBorderTouching(Ball[i].getPosition().y)){Ball[i].move( 0 * dt, -ballradius * dt); ySpeed[i] = -ySpeed[i];}
    }

I think the Problem is gone now!

(If I did something wrong please tell me  ;) )
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 04, 2014, 09:36:38 pm
Ok, today I finally got time to continue working on my project.

I created a bool to check for collisions:
bool Collision(const float& TempPositionY1, const float& TempPositionY2, const float& TempPositionX1, const float& TempPositionX2)
    {
        int distance = ((TempPositionX1 - TempPositionX2) * (TempPositionX1 - TempPositionX2)) + ((TempPositionY1 - TempPositionY2) * (TempPositionY1 - TempPositionY2));
        if (distance < ballradius + ballradius )
        {
            return true;
        }
        else return false;

    }

Okay, I think this should work.
But now I have to create a loop to check all possible combinations of Collisions.

I created something like that first:
for (int i = 0; i < ballcount; i++)  
{  
    for (int j = i + 1; j < ballcount; j++)  
    {  
        if (Collision(Ball[i].getPosition().y, Ball[j].getPosition().y, Ball[i].getPosition().x, Ball[j].getPosition().x))
        {
            // Calculate new direction
        }
    }
}

But that doesnt detect all the collisions, for example Ball[4] and Ball[8].

So my question is:

How can I effectively cover all the possible Collisions in my loop?
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Nexus on February 04, 2014, 09:51:56 pm
You forgot to square the radiuses.

Short tip: You should abstract your code to make it much more readable.
How I would write the collision:
float SquaredLength(sf::Vector2f vector);
float Square(float value);

// 1. vectors instead of floats
// 2. pass by value instead of reference (for floats for sure, for vectors it's arguable)
// 3. shorter names (lhs, rhs are conventions for "left/right hand side")
bool Collision(sf::Vector2f lhs, sf::Vector2f rhs)
{
    // 4. reuse existing functions
    // 5. instead of      if (...) return true; else return false;
    //         write      return ...;
    return SquaredLength(lhs - rhs) < Square(2*ballRadius);
}

If you deal a lot with vector operations, you could reuse the functions I wrote inThor.Vectors (http://www.bromeon.ch/libraries/thor/v2.0/doc/_vector_algebra2_d_8hpp.html). You don't need to build Thor for that, the Vectors module is header-only and can be used directly.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 05, 2014, 03:26:41 pm
Thanks, Nexus!

But when I try to compile my code, it gives me these two errors: undefined reference to `SquaredLength(sf::Vector2<float>)', and
 undefined reference to `Square(float)'.

Heres my if-statement:
    sf::Vector2f lhs(Ball[1].getPosition().y, Ball[1].getPosition().x);
    sf::Vector2f rhs(Ball[2].getPosition().y, Ball[2].getPosition().x);
    if (Collision(lhs,  rhs))
        {

        }

What did I do wrong?
Title: Re: [Beginner] Help with Bouncing Circles
Post by: eXpl0it3r on February 05, 2014, 05:20:56 pm
You need to implement SquaredLength and Square of course. Nexus just gave the deceleration of the function. ;)
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Jesper Juhl on February 05, 2014, 05:22:35 pm
You did not implement the functions.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 05, 2014, 06:44:49 pm
Im not getting it...
I declared Squared Length and Square at the Beginning:
    float SquaredLength(sf::Vector2f vector);
    float Square(float value);

Heres my Collision Bool:
  bool Collision(sf::Vector2f lhs, sf::Vector2f rhs)
{
    return SquaredLength(lhs - rhs) < Square(2*ballradius);
}
 

And heres my if-statement:
    sf::Vector2f lhs(Ball[1].getPosition().y, Ball[1].getPosition().x);
    sf::Vector2f rhs(Ball[2].getPosition().y, Ball[2].getPosition().x);
    if (Collision(lhs,  rhs))
        {
        }

Okay, and what has to be implemented now?
For me, this seems very plausible.

Oh god, im feeling stupid right now...


Title: Re: [Beginner] Help with Bouncing Circles
Post by: Jesper Juhl on February 05, 2014, 06:57:26 pm
You have declared the signatures of the functions but you have not implemented them.
They are not pre-existing functions. You have to write their actual implementation yourself.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 05, 2014, 08:00:13 pm
Ahh, thanks Jesper, now I understand...  :)

(http://i.imgur.com/aKPkoZZ.jpg)

For me!  :D
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 05, 2014, 10:21:07 pm
Okay, I've got a function for calculating the Square:
float Square(float value)
{
    return value * value;
}
 
It think this should work.

But what is the Squared lenght?
Which lenght do you mean?
How do I have to calculate that?
Title: Re: [Beginner] Help with Bouncing Circles
Post by: wintertime on February 06, 2014, 12:32:15 am
The squared length is what you get from the dot product of a vector with itself. Its an optimization to not take the squareroot of it when you just need it for comparing it with another length and just square that length instead.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Nexus on February 06, 2014, 09:52:30 am
As stated earlier:
Quote
If you deal a lot with vector operations, you could reuse the functions I wrote in Thor.Vectors (http://www.bromeon.ch/libraries/thor/v2.0/doc/_vector_algebra2_d_8hpp.html). You don't need to build Thor for that, the Vectors module is header-only and can be used directly.

You can also have a look at the documentation and/or implementation in order to understand what these functions do. But they require some basic knowledge about vector algebra.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 06, 2014, 06:09:25 pm
Okay, but where can I find the Header for SFML 2.1?


Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 06, 2014, 08:49:14 pm
Success!

Okay, I downloaded the Thor library and searched for the SquareLenght function. I found it and Implemented it.
So heres my complete Collision detection:
float dotProduct(sf::Vector2f lhs, sf::Vector2f rhs)
{
        return lhs.x * rhs.x + lhs.y * rhs.y;
}
float Square(float value)
{
    return value * value;
}

float SquaredLength(sf::Vector2f vector)
{
   return dotProduct(vector, vector);
}
bool Collision(sf::Vector2f lhs, sf::Vector2f rhs)
{

    return SquaredLength(lhs - rhs) < Square(2*ballradius);
}
 

Thank you Nexus, for making such an awesome library!
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 07, 2014, 01:22:38 pm
Now I got a question about calculating the new velocities and directions.

I read the tutsplus article (http://gamedevelopment.tutsplus.com/tutorials/when-worlds-collide-simulating-circle-circle-collisions--gamedev-769 (http://gamedevelopment.tutsplus.com/tutorials/when-worlds-collide-simulating-circle-circle-collisions--gamedev-769)) , but the comments say that the method to calculate new directions and velocities is wrong.

So how should I calculate the collisions now?
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 08, 2014, 09:57:25 am
Has anyone an Idea?
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Azaral on February 08, 2014, 01:23:54 pm
http://en.wikipedia.org/wiki/Elastic_collision
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Jesper Juhl on February 08, 2014, 02:44:20 pm
Have you tried the techniques in the gamasutra article I linked you to in my first reply in this thread?
I've used what's described in that article myself to calculate collisions between circles and circles and circles and straight surfaces, calculate the bounce and speed after collision etc. and it works very nicely.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 08, 2014, 04:35:52 pm
Okay, I tried to Implement the Collision-Resolving.
But there's a problem: When the balls collide, they stick at each other and don't bounce away.

Here's some Code:
int ballradius = 50;
int mass = ballradius;

float newVelY1(float yVel1, float yVel2)
{
     float NEWyVel1 = (yVel1 * (mass - mass) + (2 * mass * yVel2)) / (mass + mass);
     return NEWyVel1;
}

float newVelY2(float yVel1, float yVel2)
{
    float NEWyVel2 = (yVel2 * (mass - mass) + (2 * mass * yVel1)) / (mass + mass);
    return NEWyVel2;
}

float newVelX1(float xVel1, float xVel2)
{
    float NEWxVel1 = (xVel1 * (mass - mass) + (2 * mass * xVel2)) / (mass + mass);
    return NEWxVel1;
}

float newVelX2(float xVel1, float xVel2)
{
    float NEWxVel2 = (xVel2 * (mass - mass) + (2 * mass * xVel1)) / (mass + mass);
    return NEWxVel2;
}

 // In the main-loop:
for (int i = 0; i < ballcount; i++)
{
    for (int j = i + 1; j < ballcount; j++)
    {
        if (Collision(sf::Vector2f(Ball[i].getPosition().y, Ball[i].getPosition().x), sf::Vector2f(Ball[j].getPosition().y, Ball[j].getPosition().x)))
        {


            Ball[i].move(newVelX1(xSpeed[i], xSpeed[j]) * dt,  newVelY1(ySpeed[i], ySpeed[j]) * dt);
            Ball[j].move(newVelX2(xSpeed[i], xSpeed[j]) * dt,  newVelY2(ySpeed[i], ySpeed[j])* dt);


            xSpeed[i] = newVelX1(xSpeed[i], xSpeed[j]);
            xSpeed[j] = newVelX2(xSpeed[i], xSpeed[j]);
            ySpeed[i] = newVelY1(ySpeed[i], ySpeed[j]);
            ySpeed[j] = newVelY2(ySpeed[i], ySpeed[j]);

        }
    }
}
 

Has anybody an idea what I did wrong?

Title: Re: [Beginner] Help with Bouncing Circles
Post by: Nexus on February 09, 2014, 11:00:46 am
(mass - mass)

Why are you now again using separate coordinates instead of vectors? I think we agreed that vectors would make the code simpler and more readable ;)

And don't duplicate code, you can merge the four functions to one.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 09, 2014, 11:46:29 am
(mass - mass)

Why are you now again using separate coordinates instead of vectors? I think we agreed that vectors would make the code simpler and more readable ;)

And don't duplicate code, you can merge the four functions to one.

Yeah, you're right, but I don't think I have to use vectors, because every ball has the same mass.  :)

But are the calculations right?
I don't understand why the balls stick together...
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Nexus on February 09, 2014, 12:01:36 pm
The very first line in my post! ::)

Of course you don't have to use vectors, but they simplify everything a lot. If you prefer verbose and badly abstracted code, that's your decision.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 09, 2014, 04:29:04 pm
Ok, Nexus, now I defined the mass as a vector.  :)

But how can I solve the sticky-balls problem?

Title: Re: [Beginner] Help with Bouncing Circles
Post by: Hapax on February 09, 2014, 04:56:52 pm
I think that mass might be the only value that shouldn't be a vector since it's a single value. :p Vectors (in this case) are for positions, velocities etc.

As for your calculations, Nexus pointed out a tiny bit of your code that you should really study:
(mass - mass)
What does it do?
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 09, 2014, 06:15:08 pm
I think that mass might be the only value that shouldn't be a vector since it's a single value. :p Vectors (in this case) are for positions, velocities etc.

As for your calculations, Nexus pointed out a tiny bit of your code that you should really study:
(mass - mass)
What does it do?

Yeah, I thought Nexus meant that I should define mass as a vector... I don't know why is should do this, maybe I misunderstood him  :-\

And the mass - mass thing is from the tutsplus article mentioned earlier. http://gamedevelopment.tutsplus.com/tutorials/when-worlds-collide-simulating-circle-circle-collisions--gamedev-769 (http://gamedevelopment.tutsplus.com/tutorials/when-worlds-collide-simulating-circle-circle-collisions--gamedev-769)

Its important when each ball has a different mass.
And yeah, then Vectors would be helpful  ;)
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Azaral on February 09, 2014, 07:35:11 pm
(mass - mass)

Why are you now again using separate coordinates instead of vectors? I think we agreed that vectors would make the code simpler and more readable ;)

And don't duplicate code, you can merge the four functions to one.

If you are suggesting that mass should be a vector, it can't be as it is a scalar.

However, all of these functions can be combined into a single function and if the vector arithmetic is set up correctly, you do not have to calculate the values of the vectors separately.

Also, beware of changing the velocity of one before you calculate the new velocity of the other. If you do not, then you will not have a correct collision.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Hapax on February 09, 2014, 07:39:18 pm
It's mass1 - mass2. It's the difference between the two masses. At the moment (and I didn't think I'd have to point this out explicitly) you are subtracting something from itself and it will always be zero. If the circles were to have different masses, you would use them there, but since they're all the same, you can remove (mass-mass) since it is 0.

The vectors (i.e. sf::Vector2f) are for the positions and velocities so that x and y can be conveniently in one variable. In some cases, calculation can be applied to the vector rather than directly to its components.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 09, 2014, 09:01:56 pm
Also, beware of changing the velocity of one before you calculate the new velocity of the other. If you do not, then you will not have a correct collision.

I did that, didn't I?  ???
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 09, 2014, 09:07:19 pm
It's mass1 - mass2. It's the difference between the two masses. At the moment (and I didn't think I'd have to point this out explicitly) you are subtracting something from itself and it will always be zero. If the circles were to have different masses, you would use them there, but since they're all the same, you can remove (mass-mass) since it is 0.

Are you sure that I can just remove it? It would give me a different result...

The vectors (i.e. sf::Vector2f) are for the positions and velocities so that x and y can be conveniently in one variable. In some cases, calculation can be applied to the vector rather than directly to its components.

Well, I know that's more convenient to use vectors, but I think that Im going to that after I solved the problem with the sticky balls
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Hapax on February 09, 2014, 09:22:42 pm
Are you sure that I can just remove it? It would give me a different result...
It wouldn't. You're subtracting zero. Removing that subtraction would change nothing. The (mass + mass) must stay, however, and leaving in the (mass - mass) won't harm anything so it's possibly safer to leave it there.

... the problem with the sticky balls
You have the vector values the wrong way around for the collision. X comes before Y.

Use:
if (Collision(
  sf::Vector2f(Ball[i].getPosition().x, Ball[i].getPosition().y),
  sf::Vector2f(Ball[j].getPosition().x, Ball[j].getPosition().y))
rather than:
if (Collision(
  sf::Vector2f(Ball[i].getPosition().y, Ball[i].getPosition().x),
  sf::Vector2f(Ball[j].getPosition().y, Ball[j].getPosition().x))
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Nexus on February 09, 2014, 09:33:18 pm
The idea of vectors is not to unpack them to single coordinates at every opportunity :(

Why don't you simply write it like this?
if (Collision(Ball[i].getPosition(), Ball[j].getPosition()))
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Azaral on February 10, 2014, 12:34:31 am
Also, beware of changing the velocity of one before you calculate the new velocity of the other. If you do not, then you will not have a correct collision.

I did that, didn't I?  ???

I don't know, I was just throwing that out there.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Hapax on February 10, 2014, 03:53:32 am
Why don't you simply write it like this?
if (Collision(Ball[i].getPosition(), Ball[j].getPosition()))
Or just do that :p Much simpler ;)
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 10, 2014, 05:34:38 pm
The idea of vectors is not to unpack them to single coordinates at every opportunity :(

Why don't you simply write it like this?
if (Collision(Ball[i].getPosition(), Ball[j].getPosition()))

Thanks, Nexus, I did that, but the problem is still not solved...

Here's the code so far:
for (int i = 0; i < ballcount; i++)
{
    for (int j = i + 1; j < ballcount; j++)
    {
        if (Collision(Ball[i].getPosition(), Ball[j].getPosition()))
        {


            Ball[i].move(newVelX1(xSpeed[i], xSpeed[j]) * dt,  newVelY1(ySpeed[i], ySpeed[j]) * dt);
            Ball[j].move(newVelX2(xSpeed[i], xSpeed[j]) * dt,  newVelY2(ySpeed[i], ySpeed[j])* dt);


            xSpeed[i] = newVelX1(xSpeed[i], xSpeed[j]);
            xSpeed[j] = newVelX2(xSpeed[i], xSpeed[j]);
            ySpeed[i] = newVelY1(ySpeed[i], ySpeed[j]);
            ySpeed[j] = newVelY2(ySpeed[i], ySpeed[j]);

        }
    }
}
 

Or did I something wrong with the order of calculating the new Velocities?
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Hapax on February 10, 2014, 06:10:02 pm
I'm not sure I fully understand the code here, but why are you moving the balls in the direction they were travelling before the collision, after finding that they've collided? Could it be possible that the new speeds should be calculated before the balls get moved?
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 10, 2014, 08:29:25 pm
I'm not sure I fully understand the code here, but why are you moving the balls in the direction they were travelling before the collision, after finding that they've collided?

The balls are moved to the new direction, not to the old. To make sure that they dont collide anymore.


Could it be possible that the new speeds should be calculated before the balls get moved?

If I understand you right, you mean something like this:

            xSpeed[i] = newVelX1(xSpeed[i], xSpeed[j]);
            xSpeed[j] = newVelX2(xSpeed[i], xSpeed[j]);
            ySpeed[i] = newVelY1(ySpeed[i], ySpeed[j]);
            ySpeed[j] = newVelY2(ySpeed[i], ySpeed[j]);
           
            Ball[i].move(newVelX1(xSpeed[i], xSpeed[j]) * dt,  newVelY1(ySpeed[i], ySpeed[j]) * dt);
            Ball[j].move(newVelX2(xSpeed[i], xSpeed[j]) * dt,  newVelY2(ySpeed[i], ySpeed[j])* dt);
 

or


            xSpeed[i] = newVelX1(xSpeed[i], xSpeed[j]);
            xSpeed[j] = newVelX2(xSpeed[i], xSpeed[j]);
            ySpeed[i] = newVelY1(ySpeed[i], ySpeed[j]);
            ySpeed[j] = newVelY2(ySpeed[i], ySpeed[j]);

            Ball[i].move(xSpeed[i] * dt, ySpeed[i] * dt );
            Ball[j].move(xSpeed[j] * dt, ySpeed[j] * dt );
 

Good Idea, but this doesn't solve the problem.

It's weird: sometimes, when two balls which stick together, collide with one single ball, the collusion seems to be correct.

If you have time, you can compile the code by yourself and watch it. :)
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Hapax on February 10, 2014, 09:10:16 pm
The balls are moved to the new direction, not to the old. To make sure that they dont collide anymore.
Ah, I must've missed the whole "newVel" stuff in the move method. Probably because you used it the same again straight afterwards  :P

As for running the code, I might do soon, if I can work out which parts you're still using  ???
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 10, 2014, 09:35:09 pm
Here's the Code.  :)
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Hapax on February 10, 2014, 11:03:16 pm
It seems that the problem you were having is that you were assigning the new speeds as soon as you'd calculated them. This means that you calculate a new xSpeed and use the new one in the calculation for xSpeed[j]. It needs to be the same value for both calculations. You have to calculate all of the new velocities before assigning them - at the same time! It does show this in that tutorial :p
if (Collision(Ball[i].getPosition(), Ball[j].getPosition()))
{
        const float tempXSpeedI = newVelX1(xSpeed[i], xSpeed[j]);
        const float tempYSpeedI = newVelX2(xSpeed[i], xSpeed[j]);
        const float tempXSpeedJ = newVelY1(ySpeed[i], ySpeed[j]);
        const float tempYSpeedJ = newVelY2(ySpeed[i], ySpeed[j]);
        xSpeed[i] = tempXSpeedI;
        xSpeed[j] = tempYSpeedI;
        ySpeed[i] = tempXSpeedJ;
        ySpeed[j] = tempYSpeedJ;

        Ball[i].move(xSpeed[i] * dt, ySpeed[i] * dt);
        Ball[j].move(xSpeed[j] * dt, ySpeed[j] * dt);
}

It's still not perfect but they bounce now  ;)
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Nexus on February 11, 2014, 01:03:49 am
You still haven't fully understood the vector abstraction. You should also use it as return type of your function.

In fact, you should always use vectors to represent 2D coordinates, and fall back to float only in exceptional cases -- not the other way around.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Hapax on February 11, 2014, 01:45:42 am
His code is line for line from a tutorial so I thought it'd be better for him to actually see how the tutorial code works first so I fixed that. He should definitely start using vectors; not doing so is much more error-prone. However, if he'd have converted everything to use vectors and it didn't work, it would be harder to compare with the original tutorial to see what is wrong.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Nexus on February 11, 2014, 11:31:11 am
That's true, but maybe the tutorial isn't the best one if it fiddles around with separate floats. I don't see a reason not to introduce vectors from the beginning... They don't add complexity, they reduce it.

Sometimes it's really amazing how simple the code becomes if you use the right abstractions... Same for trigonometry, for example. Since I've written Thor.Vectors, I'm hardly ever using std::sin() and std::cos() :)
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Hapax on February 11, 2014, 03:06:09 pm
Your Thor library does look awesome. I'd almost certainly use it if I didn't want to work as low-level as possible to learn what's going on (I like maths etc.).
"Low as possible" means avoiding the lowest form - Windows programming. Thanks, SFML ;)
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 11, 2014, 04:38:45 pm
Thanks Golden Eagle, for solving the problem :)

I could have noticed that aswell, I should be more concentrated during programming...  ::)

I made some changes with the ball position:
Ball[i].setPosition( i * 70 ,i * 70);

Now the Balls don't stick together when you start the program.

But I noticed something like a glitch:

When a ball, collides with a wall, and at the same moment another ball collides with him, the ball is being pushed into the wall, and the two balls stick together.

It's hard to explain, if you like, you can just see it by yourself.

I think this problem can't be solved, can it?

It's still not perfect

Why is it still not perfect? Now it's the same code as in the tutorial, isn't it?

Title: Re: [Beginner] Help with Bouncing Circles
Post by: Hapax on February 11, 2014, 05:32:19 pm
Thanks Golden Eagle, for solving the problem :)
You're welcome.

But I noticed something like a glitch:
Why is it still not perfect? Now it's the same code as in the tutorial, isn't it?
I think you answered your own question  ;)
It's not perfect because the tutorial isn't perfect. The tutorial shows how to deal with collisions with discs and which angle and velocity they should be after a collision. One of the things it doesn't cover (if I remember correctly) is when the velocity is so large that they simple pass over one another. Obviously, that's covered by testing in the tiniest of increments at a time, which can mean needing to slow down your discs. Try it with small discs that move quickly and they'll just skip over each other  ;)
Also, when the discs go into the window edge, they are just slid back into the window at a tangent of the window's edge rather than calculating where the disc should be after bouncing.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 11, 2014, 07:00:28 pm
Hmmm, and what should I do now?
I didn't know that the tutorial wasn't completely right, I'll have another look at the Gamasutra atricle, although it seems a little bit more compilcated to me.

If anyone has an idea how to solve this, please tell me! :)
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Hapax on February 11, 2014, 07:05:28 pm
It's not about "solving" it; it's about the level of accuracy you desire. It can't be 100% physically perfect, ever. It's just how close to that you want to go. The closer to perfect you go, the complicated it can become.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 11, 2014, 08:01:02 pm
But there has to be a way that the balls don't glitch, using the current  way to calculate the collision...

Title: Re: [Beginner] Help with Bouncing Circles
Post by: Hapax on February 11, 2014, 08:19:13 pm
But there has to be a way that the balls don't glitch, using the current  way to calculate the collision...
Using the same calculations, they will "glitch" the same way.
I think, instead of "glitch", you mean "noticably glitch". Generally, the more "glitchless", the more involved the process.
Have a look through that Gamasutra article that was linked earlier; it has some techniques that should "solve" your current problems  :)
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 11, 2014, 08:37:42 pm
But there has to be a way that the balls don't glitch, using the current  way to calculate the collision...
Using the same calculations, they will "glitch" the same way.
I think, instead of "glitch", you mean "noticably glitch". Generally, the more "glitchless", the more involved the process.
Have a look through that Gamasutra article that was linked earlier; it has some techniques that should "solve" your current problems  :)

Thanks for pointing that out, I will try to understand the Article ;)
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 12, 2014, 04:58:33 pm
Now I've read the Gamasutra  Article again, but I find it hard to understand the equations in the 'Calculating Bounce' Section.

So I thought it maybe would be easier to have a look at the Java Code:
// First, find the normalized vector n from the center of
// circle1 to the center of circle2
Vector n = circle1.center - circle2.center;
n.normalize();
// Find the length of the component of each of the movement
// vectors along n.
// a1 = v1 . n
// a2 = v2 . n
float a1 = v1.dot(n);
float a2 = v2.dot(n);

// Using the optimized version,
// optimizedP =  2(a1 - a2)
//              -----------
//                m1 + m2
float optimizedP = (2.0 * (a1 - a2)) / (circle1.mass + circle2.mass);

// Calculate v1', the new movement vector of circle1
// v1' = v1 - optimizedP * m2 * n
Vector v1' = v1 - optimizedP * circle2.mass * n;

// Calculate v1'
, the new movement vector of circle1
// v2' = v2 + optimizedP * m1 * n
Vector v2' = v2 + optimizedP * circle1.mass * n;

circle1.setMovementVector(v1'
);
circle2.setMovementVector(v2');

But I've got a few questions.  :P

I assume that
circle1.center
are just the coordinates of the first circle in a vector, aren't they?
What does
.normalize()
  and
.dot()
do and how can I do that in C++?
And my last question:
I assume that the 'movement vector' is just the X- and Y-Velocity saved in one Vector, am I right?

Any help is appreciated! :)










Title: Re: [Beginner] Help with Bouncing Circles
Post by: Hapax on February 12, 2014, 05:54:29 pm
I don't want to be mean but it really does tell you those things in the article. If you read it from start to finish, it tells you what normalising is, how to use the dot product etc.. It looks like you skipped to the last "version" of the code to try to understand it but it's not supposed to be alone; the earlier parts of the code are supposed to be involved or, at least, understood.
FYI, I went to the gamasutra article, and searched for normalize and it took me straight to the part that says what normalising a vector is  :P
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 12, 2014, 07:42:01 pm
... it tells you what normalising is

Yeah, it tells me what it is, but not how to calculate it :P

Anyways, I added a function to normalize a vector.

I forgot that I already implemented a function to calculate the dot product....  ::)

But there remain two questions:

I assume that
circle1.center
are just the coordinates of the first circle in a vector, aren't they?

And my last question:
I assume that the 'movement vector' is just the X- and Y-Velocity saved in one Vector, am I right?

Title: Re: [Beginner] Help with Bouncing Circles
Post by: Nexus on February 12, 2014, 07:51:49 pm
You know that Thor already provides all those vector functions (normalize/unit vector, dot product, length, ...), and that I've mentioned it at least three times in this thread? :P

Just in case you don't want to reinvent the wheel in productive code. For learning purposes, it's probably not bad if you implement those functions once on your own.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 12, 2014, 08:11:39 pm
You know that Thor already provides all those vector functions (normalize/unit vector, dot product, length, ...), and that I've mentioned it at least three times in this thread? :P

Just in case you don't want to reinvent the wheel in productive code. For learning purposes, it's probably not bad if you implement those functions once on your own.
I definetely will use thor in future projects, but since I'm still a beginner, I think I'ts better that I just write the functions by myself to learn how It works :)
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Hapax on February 12, 2014, 09:13:16 pm
I assume that
circle1.center
are just the coordinates of the first circle in a vector, aren't they?
That will be the center of the circle  :P But yeah, it'll be the position of the centre of the circle which will include all of the coordinates for that. In the case of two dimensions, it will have x and y.

And my last question:
I assume that the 'movement vector' is just the X- and Y-Velocity saved in one Vector, am I right?
Yes, movement is the amount that it has moved. As I said above, it'll be all the dimensions necessary but in 2D, it'll be x and y.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 12, 2014, 10:42:26 pm
I assume that
circle1.center
are just the coordinates of the first circle in a vector, aren't they?
That will be the center of the circle  :P But yeah, it'll be the position of the centre of the circle which will include all of the coordinates for that. In the case of two dimensions, it will have x and y.

And my last question:
I assume that the 'movement vector' is just the X- and Y-Velocity saved in one Vector, am I right?
Yes, movement is the amount that it has moved. As I said above, it'll be all the dimensions necessary but in 2D, it'll be x and y.
Thank you!

Now It seems to work! :)
But there's one problem: The 'glitches' are still there! :(

What do I have to do to remove them? Look for an 'perfect' tutorial?
(I attached the source code, so I don't have to spam the whole thread)
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Hapax on February 12, 2014, 11:57:04 pm
The 'glitches' are still there
Which glitches? It looks fine to me.
The only thing that I can see that you may be noticing is that they still penetrate each other slightly. That is because you're calculating the radius of the filled circle, not including its outline. I believe that outlines expand outwards so you'd have to increase the radius that is tested by half of the outline width. (Not the actual radius otherwise the outline would make it even bigger!)

EDIT: I just removed the outlines and it looks awesome :p

EDIT 2: In slower situations, it glitches. It's because you are moving the discs scaled by the amount of time that has passed. There is not way of knowing how much time is going to pass. It could be five seconds! How far would they move then? You need to break time down into smaller chunks. Try reading up on timesteps. Here's an interesting read (warning: get ready to pay attention to the nitty-gritty!): Fix Your Timestep (http://gafferongames.com/game-physics/fix-your-timestep/)
You may find reading the previous article on integration (http://gafferongames.com/game-physics/integration-basics/) useful before the timestep one.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 13, 2014, 05:13:50 pm
The only thing that I can see that you may be noticing is that they still penetrate each other slightly. That is because you're calculating the radius of the filled circle, not including its outline. I believe that outlines expand outwards so you'd have to increase the radius that is tested by half of the outline width. (Not the actual radius otherwise the outline would make it even bigger!)

EDIT: I just removed the outlines and it looks awesome :p

I know, I'll  implement a feature that allows you to add and remove the outlines of the circles by pressing a button soon. :)

EDIT 2: In slower situations, it glitches. It's because you are moving the discs scaled by the amount of time that has passed. There is not way of knowing how much time is going to pass. It could be five seconds! How far would they move then? You need to break time down into smaller chunks. Try reading up on timesteps. Here's an interesting read (warning: get ready to pay attention to the nitty-gritty!): Fix Your Timestep (http://gafferongames.com/game-physics/fix-your-timestep/)
You may find reading the previous article on integration (http://gafferongames.com/game-physics/integration-basics/) useful before the timestep one.

And I thought It couldn't get more complicated anymore... ;)


Title: Re: [Beginner] Help with Bouncing Circles
Post by: Giblit on February 13, 2014, 08:51:25 pm
You could also use negative outlines where it goes into the fill.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Hapax on February 13, 2014, 08:56:33 pm
And I thought It couldn't get more complicated anymore... ;)
I did say that the more accurate you want it, the more involved it becomes  ;)
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 13, 2014, 10:44:51 pm
You could also use negative outlines where it goes into the fill.

Good Idea! Didn't know that this is possible :)
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Hapax on February 13, 2014, 11:30:45 pm
You could also use negative outlines where it goes into the fill.
Good Idea! Didn't know that this is possible :)
It's all here (http://sfml-dev.org/documentation/2.1/classsf_1_1Shape.php#a5ad336ad74fc1f567fce3b7e44cf87dc).  :P
I'd forgotten about this, actually. I got mixed up with line drawing which expands from the centre  ;D

EDIT: fixed the link. Thanks to Giblit for pointing out the error  :)
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Giblit on February 14, 2014, 01:20:17 am
Your link is a bit messed up.

http://sfml-dev.org/documentation/2.1/classsf_1_1Shape.php#a5ad336ad74fc1f567fce3b7e44cf87dc

Quote
void sf::Shape::setOutlineThickness   (   float    thickness   )   
Set the thickness of the shape's outline.

Note that negative values are allowed (so that the outline expands towards the center of the shape), and using zero disables the outline. By default, the outline thickness is 0.

Parameters
thickness   New outline thickness
Title: Re: [Beginner] Help with Bouncing Circles
Post by: zsbzsb on February 14, 2014, 01:25:37 am
Wow, 6 pages for this thread  :o

OP, can you please state clearly if you problem is solved, or if there is anything else left to solve?  ;)
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 14, 2014, 08:57:12 am
OP, can you please state clearly if you problem is solved, or if there is anything else left to solve?  ;)

When everything is solved, I'll post that, no worries :)


Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 14, 2014, 09:02:56 am
Hmmm, I got an Interesting solution from Geheim via PM.
The solution is a bit 'dirty' but seems to work.

I added this to my if-collusion-statement:
Ball[i].move(-xSpeed[i] * 0.001f, -ySpeed[i] * 0.001f);
Ball[j].move(-xSpeed[j] * 0.001f, -ySpeed[j] * 0.001f);
 

Full Source-Code as attachment :)
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Geheim on February 14, 2014, 10:31:55 am
Thats like I said just a "dirty" approach to avoid the visual jumping you experience. For me your code seems to work like it should, however you should test a bit more yourself before posting again. Of course we could give you fully working source code, but thats not what we want. You should manage it with all the help you got now yourself...
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 14, 2014, 05:32:42 pm
Just noticed that it doesn't work, glitches are still occurring.
Seems like I have to go through the 'Fix your timestep' Article...  :-\
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 14, 2014, 10:31:44 pm
Ok, still trying to fix my timestep, but meanwhile I added two features:

1. Outline can be (de-)activated by pressing the 'r' key
2. Circles change color when colliding with a window-border

But there's one thing I don't understand: It seems like the colors are always nearly the same. What did I do wrong?  :-\



Title: Re: [Beginner] Help with Bouncing Circles
Post by: Azaral on February 14, 2014, 10:43:19 pm
Ok, still trying to fix my timestep, but meanwhile I added two features:

1. Outline can be (de-)activated by pressing the 'r' key
2. Circles change color when colliding with a window-border

But there's one thing I don't understand: It seems like the colors are always nearly the same. What did I do wrong?  :-\

It looks like you keep resetting the seed for the random function. Take a look at the <random> part of the stl. IT has a lot better functionality than the old random.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 14, 2014, 11:30:06 pm
It looks like you keep resetting the seed for the random function. Take a look at the <random> part of the stl. IT has a lot better functionality than the old random.
Okay, I now I use the new random:
default_random_engine engine;
uniform_int_distribution<int> distribution(1,255);
auto random = bind ( distribution, engine );
 
I use this no matter which border is touched:
Ball[i].setFillColor(sf::Color(random(), random(), random()));
 

Now it definetely looks better, but do I need to set an extra seed for the generator?
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Giblit on February 15, 2014, 01:34:13 am
You only need to seed the generator once.

PRNG use the seed as S0. Since a PRNG is just a sequence. I don't know the exact forumas but they are something like: Sn+1 = ( A * Sn + B ) % M; Where A , B , M are given before hand. So for example a generator that looks like:
Sn+1 = ( 10 * Sn + 11 ) % 12 with a seed of 0 it would look like this: ( repeats really fast since I used really small values )

11 , 1 , 9 , 5 , 1 , ...now it is repeating

Most of the PRNG won't repeat for a very long time
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Azaral on February 15, 2014, 05:16:47 am
It looks like you keep resetting the seed for the random function. Take a look at the <random> part of the stl. IT has a lot better functionality than the old random.
Okay, I now I use the new random:
default_random_engine engine;
uniform_int_distribution<int> distribution(1,255);
auto random = bind ( distribution, engine );
 
I use this no matter which border is touched:
Ball[i].setFillColor(sf::Color(random(), random(), random()));
 

Now it definetely looks better, but do I need to set an extra seed for the generator?

The seed is to make the random generator behave differently on each run. If you did not set a seed, then the results would be the same each time you start the program. The balls would change colors in the same sequence every time the program is ran. That is the purpose of the seed, to prevent that.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 15, 2014, 09:43:17 am
The seed is to make the random generator behave differently on each run. If you did not set a seed, then the results would be the same each time you start the program. The balls would change colors in the same sequence every time the program is ran. That is the purpose of the seed, to prevent that.
Yeah, I know what a seed does, but I didn't know if the new random needs a seed too, or if, for example, the system time is automatically used as seed.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Jesper Juhl on February 15, 2014, 10:11:33 am
You should seed it.
And the system time is a terrible seed. Use std::random_device to get a good seed value.
See: http://en.cppreference.com/w/cpp/numeric/random
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 15, 2014, 11:06:26 am
Okay, I made two different engines with two different seeds. But when I try to use an number created from random_device, it compiles fine, but when I start the program, it closes immediately.

Here's some code:

        random_device seedDevice;
        uniform_int_distribution<int> seedDist(0, 1000000);
       
        default_random_engine engine(seedDist(seedDevice));
        uniform_int_distribution<int> distribution(1,255);
        auto random = bind ( distribution, engine );

        default_random_engine engine2(seedDist(seedDevice));
        auto random2 = bind (distribution, engine2);
 
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Nexus on February 15, 2014, 02:55:07 pm
And the system time is a terrible seed.
Why?

Use std::random_device to get a good seed value.
std::random_device is not guaranteed to use a hardware random source. It may fall back to a deterministic pseudo-number generator, and then you're doing even worse than with the system time.

You should really not make your life too complicated if you're just using random numbers for games. Mostly, you won't even notice the problems of LCGs (using C++11 random engines is still a good idea).

But when I try to use an number created from random_device, it compiles fine, but when I start the program, it closes immediately.
What does that mean? Find out with the debugger where the program closes. More useful than "some code" would also be a minimal complete example (http://en.sfml-dev.org/forums/index.php?topic=5559.msg36368#msg36368).

And something important: Please open new threads for new problems. This one is already far too long, and the current discussion has nothing to do with the original problem.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Jesper Juhl on February 15, 2014, 03:03:26 pm
An example:

#include <random>
#include <functional>
#include <iostream>
#include <cstdlib>

int main()
{
    std::random_device seedDevice;
    std::default_random_engine engine(seedDevice());
    std::uniform_int_distribution<int> distribution(1, 255);
    auto random = std::bind(distribution, std::ref(engine));
    std::cout << "Generating 10 random numbers" << std::endl;
    for (int i = 0; i < 10; ++i)
        std::cout << "\tRandom number " << i << ": " << random() << std::endl;
    return EXIT_SUCCESS;
}
 

Sample output:

$ g++ -std=c++11 test.cc
$ ./a.out
Generating 10 random numbers
        Random number 0: 53
        Random number 1: 136
        Random number 2: 85
        Random number 3: 210
        Random number 4: 109
        Random number 5: 50
        Random number 6: 201
        Random number 7: 195
        Random number 8: 62
        Random number 9: 124
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Jesper Juhl on February 15, 2014, 03:09:29 pm
And the system time is a terrible seed.
Why?

For a game it is probably fine.
In general it's a way too guessable value. An attacker with knowledge of the fact that you are using the system time as a seed (regardless of resolution) has just narrowed the scope, of the numbers he has to guess in order to guess your seed, greatly.

Use std::random_device to get a good seed value.
std::random_device is not guaranteed to use a hardware random source. It may fall back to a deterministic pseudo-number generator, and then you're doing even worse than with the system time.

True, so for something other than a game I guess you'd want to mix up a few sources; including random_device, system time and more.

You should really not make your life too complicated if you're just using random numbers for games. Mostly, you won't even notice the problems of LCGs (using C++11 random engines is still a good idea).

True.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 15, 2014, 04:51:37 pm
After all I just use the system time as seed :)
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Azaral on February 15, 2014, 05:52:23 pm
The seed is to make the random generator behave differently on each run. If you did not set a seed, then the results would be the same each time you start the program. The balls would change colors in the same sequence every time the program is ran. That is the purpose of the seed, to prevent that.
Yeah, I know what a seed does, but I didn't know if the new random needs a seed too, or if, for example, the system time is automatically used as seed.

The seed is just the starting point. Random number generators work off of the previous value it generated to make a number.
Title: Re: [Beginner] Help with Bouncing Circles
Post by: Cadisol87 on February 21, 2014, 12:38:38 am
And something important: Please open new threads for new problems. This one is already far too long, and the current discussion has nothing to do with the original problem.

Okay, I understand that this thread is too long... Currently I have two problems with my project, I'll open new threads for them.

This thread can be closed.