Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Creating Multiple Shapes  (Read 12427 times)

0 Members and 1 Guest are viewing this topic.

PhysicsManUK

  • Newbie
  • *
  • Posts: 9
    • View Profile
Creating Multiple Shapes
« on: December 05, 2013, 10:35:48 pm »
Hello there, I am fairly new to SFML (and C++ as a whole really) and I was wondering if there is a way to render multiple shapes (in my case, circles) to a window without physically declaring each circle once at a time.

I want to create several hundred circles to represent particles in order to carry out a Brownian Motion animation in 2d; and of course I don't really want to declare each circle, so it would be great if someone could tell me of a way to collectively declare all these circles (same radius, fill colour, but their origin positions will be set my an RNG) in a single body of code.

Thanks.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Creating Multiple Shapes
« Reply #1 on: December 05, 2013, 11:40:31 pm »
Hello there, I am fairly new to SFML (and C++ as a whole really) and I was wondering if there is a way to render multiple shapes (in my case, circles) to a window without physically declaring each circle once at a time.
Yes, of course. You should use STL containers such as std::vector to store the shapes. Do you have a C++ book that teaches you these concepts? They're rather basic (after all, the STL is one of the most often used parts of the standard library), and every reasonable C++ book must cover them. There are a lot of bad books unfortunately...
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

PhysicsManUK

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Creating Multiple Shapes
« Reply #2 on: December 05, 2013, 11:56:23 pm »
Indeed, I have a book called "Beginning Visual C++ 2012" by Ivor Horton; I'm not sure it covers vectors but it's good anyhow. I do, however, have some experience with using vectors in C++, but not an awful lot. I shall have a play around with my code and see if I can store the shapes I need in a vector - can the same not be achieved with an array, by the way?

AlexAUT

  • Sr. Member
  • ****
  • Posts: 396
    • View Profile
Re: Creating Multiple Shapes
« Reply #3 on: December 06, 2013, 06:44:11 pm »
can the same not be achieved with an array,

Yes you could achieve it with arrays, but you have to give an array a fixed size. e.g. std::array<int, 15>, except you are using pointers. But with std::vectors you can avoid pointers and you have a dynamic container because vectors have no fixed size, you can easily push_back objects and erase(might be slow) them. And especially in your case, particle system, you won't know how many particles you will create.

They make you life easier  ;)



AlexAUT
« Last Edit: December 06, 2013, 07:48:03 pm by AlexAUT »

PhysicsManUK

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Creating Multiple Shapes
« Reply #4 on: December 06, 2013, 06:55:04 pm »
I see, that makes sense. At the moment I have the simulation working using an array of fixed size, but I shall explore the use of vectors instead given those points.

Thanks.  :)

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Creating Multiple Shapes
« Reply #5 on: December 06, 2013, 08:54:52 pm »
In C++, there's actually no reason anymore to use arrays. Fixed-size arrays can be represented by std::array and dynamic ones by std::vector. You don't lose performance in Release mode, but you'll benefit from many additional features, such as automatic memory management (RAII), automatic insertion/removal, runtime checks in debug mode or uniform STL interface. I highly recommend to have a deep look at how the STL works (not only containers, but also algorithms and iterators), it's an extremely powerful tool that assists in daily work.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

PhysicsManUK

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Creating Multiple Shapes
« Reply #6 on: December 07, 2013, 12:33:47 am »
Understood. Do you have any suggestions on some books that would be good for me to read up on the STL and a C++ in general? As I said, I have "Beginning Visual C++ 2012" by Ivor Horton which is a very good book, from my experience, but in order to go into more detail with the Standard Library (algorithms, vectors etc) then I'd need a more specific book.

I should note that at the moment I am in my 2nd year of my Physics degree and next (academic) year I shall be taking an "Intercalated Year in Computer Science" (so basically a year in computer science instead of physics), so I expect that I shall be learning about a fair amount of this material there.

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Creating Multiple Shapes
« Reply #7 on: December 07, 2013, 01:15:42 am »
Understood. Do you have any suggestions on some books that would be good for me to read up on the STL and a C++ in general? As I said, I have "Beginning Visual C++ 2012" by Ivor Horton which is a very good book, from my experience, but in order to go into more detail with the Standard Library (algorithms, vectors etc) then I'd need a more specific book.
http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list

I should note that at the moment I am in my 2nd year of my Physics degree and next (academic) year I shall be taking an "Intercalated Year in Computer Science" (so basically a year in computer science instead of physics), so I expect that I shall be learning about a fair amount of this material there.
Don't get your hopes up too much. As a computer science student, I can tell you that you learn more about programming on your own than at universities. Universities are there to teach you about theory. If you are lucky, you will get a practice-oriented lecturer and get to know a programming language at the same time. In your programming lectures, you will learn about paradigms first then about well-known concepts such as OOP and SCM if it even comes to that (a year is too little time), in any case, very abstract topics that have no connection to a specific programming language. But since you say this is about computer science, the majority of the time will be dedicated to highly theoretical topics such as complexity and computability theory. It is not uncommon for students at my university to leave with no real practical knowledge after they are done, but I guess there is a market for them as well ^^. Maybe physics students at your university are given a pass on all the "boring" stuff for physicists and you get to concentrate on more practical topics, but it still stands that the best place to learn a programming language let alone C++ for that matter is on your own.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

PhysicsManUK

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Creating Multiple Shapes
« Reply #8 on: December 09, 2013, 12:37:32 am »
I see, thanks for the information - I will take a look at that book list and see if I can find some good ones to buy.

Also, instead of creating a new thread, I might as well ask here about a problem I am having with a blinking window. Here is my (far from complete) code:

// Brownian_Motion_Test.cpp
// Program to simulate Brownian motion of particles in 2d
// Rendered using SFML Graphics ®

// Preprocessor directives (include headers) for program

#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <cmath>
#include <iostream>
#include <vector>
#include <sstream>
#include <string>

// Namespaces to be used by program

using namespace std;    // standard namespace (std)
using namespace sf;             // Simple and Fast Multimedia Library namespace (sf)

// Global Declaration of Mathematical/Physical Constants

const double pi = 4*atan(1);            // Value of pi
const double k_B = 1.38E-23;            // Boltzmann Constant

// Global Declaration of Rendered Window Sizes

unsigned int width = 800;               // width of rendered 2d window (in px)
unsigned int height = 600;              // height of rendered 2d window (in px)

// Global Declaration of Particle Properties

const float r = 5.0F;           // radius of particle (in px)
const int NParticles= 3;                // number of particles to be produced in simulation

// Declare time value and utility class to measure elapsed time

Time thetime;
Clock elapsedtime;

// Function to return string from integer type

string IntToString(int d) {

   stringstream ss;
   ss << d;
   return ss.str();

}

// Function to calculate frame rate (fps)

std::string getFrameRate() {
       
        static int frameCounter = 0;    // (re-)Initialise frame counter variable
        static int fps = 0;             // (re-)Initialise frames per second variables
        frameCounter++;         // Increment frameCounter by 1 for each call to function GetFrameRate
        thetime = elapsedtime.getElapsedTime();         // Returns the elapsed time since the last call to .restart()

        // if-statement to process code if thetime reaches 1 second (or greater)

        if(thetime.asMilliseconds() > 999) {
     
                fps = frameCounter;             // assign frameCounter to fps if thetime > 999ms
        frameCounter = 0;       // reinitialise frame counter to 0
        elapsedtime.restart();          // reinitialise the clock back to zero time

        }

        return IntToString(fps);                // Returns string for fps value

}

// Function to render animation sequences for each particle

void animationSequence ( RenderWindow& window, CircleShape& circle, float x, float y ) {

        window.clear(Color(255,255,255,255));           // Fill the window with even white colour
        circle.setPosition(x, y);               // Update position of circle in window
        window.draw(circle);            // Draw circle in rendered window
        window.display();                       // Display on screeen what has been rendered to the window so far

}

void displayFrameRate ( RenderWindow& window, Text& FPS ) {

        window.clear(Color(255,255,255,255));           // Fill the window with even white colour
        FPS.setString(getFrameRate());                          // Set FPS to string returned by call to GetFrameRate function
        window.draw(FPS);                                       // Draw FPS text to screen
        window.display();                       // Display on screen what has been rendered to window so far

}

int main(void) {

        RenderWindow window(VideoMode(width, height), "Brownian Motion Animation");             // Render 2d Window for Animation; width x height px

        vector<CircleShape> particle(NParticles);                       // Create a vector of circles called particle() of size NParticles

        float RandomNumberWidth[100] = {0};                             // RNG Variables for...
        float RandomNumberHeight[100] = {0};                    //... X and Y positions

        const unsigned IM = 1664525;                                    // Integer constants
        const unsigned IC = 1013904223;                                 //... for the RNG algorithm

        const float scale = 1.0/0xFFFFFFFF;                     //Scaling factor for random double between 0 and 1
        unsigned iran = time(0);                                                //Seeds the random-number generator from the system time

        const int MAX(100);             // RNG for loop maximum limit

        for ( int i = 0 ; i < MAX ; i++ ) {

                RandomNumberWidth[i] = width * scale * float ( iran = IM * iran + IC );                 // Random Number Generator for X position
                RandomNumberHeight[i] =  height * scale * float ( iran = IM * iran + IC );              // Random Number Generator for Y position

                //cout << RandomNumberWidth[i] << endl;                                 // UNCOMMENT TO PRINT RANDOM NUMBERS FOR TESTING
                //cout << RandomNumberHeight[i] << endl << endl;

        }

        Font font;              // Load character font

        if (!font.loadFromFile("arial.ttf")) {          // If the font arial.ttf cannot be loaded, print error message to console
   
                // error...

        }

        Text FPS("0", font, 25);        // text variable to store Frame Rate, initialise to 0...
                                                                //... set Font type to font, set character size to 25
       
        FPS.setOrigin(-10,-10);         // set original position of FPS text in 2d window

        FPS.setColor(Color::Red);       // set colour of FPS text

        for ( int i = 0 ; i < NParticles ; i++ ) {
               
                particle[i].setRadius(r);               // Set radius of particle[i] to r
                particle[i].setFillColor(Color::Blue);          // Set fill colour of particle[i] to blue
                particle[i].setOrigin(-RandomNumberWidth[i],-RandomNumberHeight[i]);    // Set origin position of particle[i] to random position

        }

        float x[NParticles] = {0};                                              // horizontal displacement of particles
        float y[NParticles] = {0};                                              // vertical displacement of particles

        int k = 0;                      // animation loop iterator

        while (window.isOpen()) {

                if ( k >= NParticles )                  // reset k to 0 when it reaches NParticles value
                        k = 0;

                x[k] = float(pow(-1,k)) * (10 * scale * float ( iran = IM * iran + IC ));               //Update X position of particle[k] - THIS IS TEST EXPRESSION, NOT PHYSICALLY ACCURATE
                y[k] = float(pow(-1,k)) * (10 * scale * float ( iran = IM * iran + IC ));               //Update Y position of particle[k] - THIS IS TEST EXPRESSION, NOT PHYSICALLY ACCURATE

                Event event;            // Defines a system event and its parameters

                while (window.pollEvent(event)) {
       
                        if (event.type == Event::Closed)        // close the window and destroy all attached resources if user quits animation window
                                window.close();
       
                }
               
                animationSequence(window, particle[k], x[k], y[k]);             // call to function animationSequence() to simulate particles
                displayFrameRate (window, FPS);                         // call to function displayFrameRate() to print fps to window
               
                k++;    // increment k for each while loop iteration

        }

        return 0;

}       // end of main()

/*

YET TO UPDATE:

- **PRIORITY** SOLVE GRAPHICAL GLITCH PROBLEM OF EACH PARTICLE AND FRAME RATE TEXT FLASHING RAPIDLY **PRIORITY**
- DEVISE SIMPLE COLLISION DETECTION ALGORITHM (CDA) FOR PARTICLE COLLISIONS
- INVESTIGATE USE OF .SETPOSITION FOR USE IN CDA
- LINES 162,163: REPLACE COEFFICIENT OF SCALE WITH ENERGY DISTRIBUTIONS OF PARTICLES - i.e. E[k], where E[] is random distribution array/vector

*/


As far as I can tell, I have utilised the principle of events -> draw -> display outlined in the tutorials and I cannot find the source of the rapid blinking (of the circles and the text in the window) in my code.

I would be very much appreciate if somebody could point out the problem and also explain how and why what I have done is incorrect or bad practice.

Thanks.

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Creating Multiple Shapes
« Reply #9 on: December 09, 2013, 01:24:54 am »
To create a frame you must use Window.clear once, then use Window.draw however many times you want and then use Window.display once. What you're doing is making two frames where each odd one is a shape and each even one is FPS so it looks like it's blinking.
Also don't just dump code you wrote for others to debug, I knew what to look for (double display) so it took me few seconds in text editor find function but it's bad practice to dump all your code and ask others to look through all of it when 90% is not relevant to problem.

P.S.
This is oversimplification, only display is necessary since you can render(and clear) with OpenGL and if you set all pixels to something yourself each frame you don't need clear at all but don't worry about that for now.
« Last Edit: December 09, 2013, 01:28:44 am by FRex »
Back to C++ gamedev with SFML in May 2023

PhysicsManUK

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Creating Multiple Shapes
« Reply #10 on: December 09, 2013, 06:04:49 pm »
To create a frame you must use Window.clear once, then use Window.draw however many times you want and then use Window.display once. What you're doing is making two frames where each odd one is a shape and each even one is FPS so it looks like it's blinking.
Also don't just dump code you wrote for others to debug, I knew what to look for (double display) so it took me few seconds in text editor find function but it's bad practice to dump all your code and ask others to look through all of it when 90% is not relevant to problem.

P.S.
This is oversimplification, only display is necessary since you can render(and clear) with OpenGL and if you set all pixels to something yourself each frame you don't need clear at all but don't worry about that for now.

I see, that makes sense. Thank you, problem fixed now.

Also, I'll edit out the unnecessary code segments if I get the chance but I'm quite busy at the moment so it may be left as it is for a while.

KarmaKilledtheCat

  • Newbie
  • *
  • Posts: 23
    • View Profile
    • Email
Re: Creating Multiple Shapes
« Reply #11 on: December 10, 2013, 03:57:55 am »
You should look at the Vertex array tutorial. It seems to solve your problem perfectly.

PhysicsManUK

  • Newbie
  • *
  • Posts: 9
    • View Profile
Re: Creating Multiple Shapes
« Reply #12 on: December 11, 2013, 04:19:08 pm »
You should look at the Vertex array tutorial. It seems to solve your problem perfectly.

Thanks for the tip, that tutorial will help me out with this program a lot!