Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Hi, I would like to get some help with advanced c++ programming with graphic interface: SDL I need to calculate the grid and draw the

Hi, I would like to get some help with advanced c++ programming with graphic interface: SDL

I need to calculate the grid and draw the lines on the grid using a vector pointer, but I have no idea how to do them. Please help me, thank you.

ParticleManager.cpp:

#include #include #include #include #include

#include "Constants.h" #include "ParticleManager.h"

using namespace std;

Particle::Particle(double _x, double _y) : x(_x), y(_y), vx(0.f), vy(0.f), fx(0.f), fy(0.f), rho(0.f), p(0.f) { }

ParticleManager::ParticleManager() { ax = 0; ay = GRAVITY;

renderMode = "particles"; }

void ParticleManager::init(unsigned long n) { cout << "Init with " << n << " particles" << endl;

particles.clear(); particles.reserve(n);

while (particles.size() < n) {

double x = rand() / (double)(RAND_MAX)*SCREEN_WIDTH; double y = rand() / (double)(RAND_MAX)*SCREEN_HEIGHT;

double centerDist = sqrt( pow(x - SCREEN_WIDTH / 2.0, 2) + pow(y - SCREEN_HEIGHT / 2.0, 2));

if (centerDist < fmin(SCREEN_WIDTH, SCREEN_HEIGHT) * 0.25) particles.push_back(Particle(x, y)); } }

void ParticleManager::addBlock(double center_x, double center_y) { for (int i = 0; i <= 4; i++) { for (int j = 0; j <= 4; j++) { double x = center_x + (j - 2) * SCREEN_WIDTH * 0.04f + (rand() / (double)(RAND_MAX)) * H; double y = center_y + (i - 2) * SCREEN_HEIGHT * 0.04f + (rand() / (double)(RAND_MAX)) * H;

if (x >= 0 && x < SCREEN_WIDTH && y >= 0 && y < SCREEN_HEIGHT) particles.push_back(Particle(x, y)); } }

cout << particles.size() << " particles" << endl; }

void ParticleManager::addOne(double x, double y) { particles.push_back(Particle(x, y)); cout << particles.size() << " particles" << endl; }

void ParticleManager::setGravity(int direction) { switch (direction) { case DOWN: ax = 0; ay = +GRAVITY; break; case UP: ax = 0; ay = -GRAVITY; break; case RIGHT: ax = +GRAVITY; ay = 0; break; default: ax = -GRAVITY; ay = 0; } }

void ParticleManager::explode() { for (auto& p : particles) { p.vx = rand() / (double)RAND_MAX * 10000 - 5000; p.vy = rand() / (double)RAND_MAX * 10000 - 5000; } }

void ParticleManager::integrate(double dt) { for (auto& p : particles) { // forward Euler integration if (p.rho != 0 && p.fx == p.fx && p.fy == p.fy) { p.vx += dt * p.fx / p.rho; p.vy += dt * p.fy / p.rho; }

p.x += dt * p.vx; p.y += dt * p.vy;

// enforce boundary conditions if (p.x - PARTICLE_RADIUS < 0.0f) { p.vx *= BOUND_DAMPING; p.x = PARTICLE_RADIUS; } if (p.x + PARTICLE_RADIUS > SCREEN_WIDTH) { p.vx *= BOUND_DAMPING; p.x = SCREEN_WIDTH - PARTICLE_RADIUS; } if (p.y - PARTICLE_RADIUS < 0.0f) { p.vy *= BOUND_DAMPING; p.y = PARTICLE_RADIUS; } if (p.y + PARTICLE_RADIUS > SCREEN_HEIGHT) { p.vy *= BOUND_DAMPING; p.y = SCREEN_HEIGHT - PARTICLE_RADIUS; } } }

void ParticleManager::computeDensityPressure() { // for each particles for (auto& pi : particles) { pi.rho = 0.f;

// Find all the particles that contribute to the // pressure / density for (auto& pj : particles) { double distance = sqrt( pow(pj.x - pi.x, 2) + pow(pj.y - pi.y, 2));

if (distance < H) { // this computation is symmetric pi.rho += MASS * POLY6 * pow(pow(H, 2) - pow(distance, 2), 3.f); } } pi.p = GAS_CONST * (pi.rho - REST_DENS); } }

void ParticleManager::computeForces() { // For each particle for (auto& pi : particles) { double pressure_x = 0.f; double pressure_y = 0.f;

double viscosity_x = 0.f; double viscosity_y = 0.f;

// Calculate the sum of the viscosity and pressure forces // applied by the other particles for (auto& pj : particles) { if (&pi == &pj) continue;

double r = sqrt( pow(pj.x - pi.x, 2) + pow(pj.y - pi.y, 2));

if (r < H) { // compute pressure force contribution double fpress = MASS * (pi.p + pj.p) / (2.0 * pj.rho) * SPIKY_GRAD * pow(H - r, 2.0); pressure_x += (pi.x - pj.x) / r * fpress; pressure_y += (pi.y - pj.y) / r * fpress;

// compute viscosity force contribution viscosity_x += VISC * MASS * (pj.vx - pi.vx) / pj.rho * VISC_LAP * (H - r); viscosity_y += VISC * MASS * (pj.vy - pi.vy) / pj.rho * VISC_LAP * (H - r); } }

pi.fx = pressure_x + viscosity_x + ax * pi.rho; pi.fy = pressure_y + viscosity_y + ay * pi.rho; } }

void ParticleManager::update(unsigned long dt) {

// TODO: calculate the grid here

computeDensityPressure(); computeForces(); integrate(dt / 10000.0f); }

void ParticleManager::renderParticles(SDL_Renderer* renderer) { SDL_SetRenderDrawColor(renderer, 230, 120, 0, 100); SDL_Rect r;

// Draw particles for (long unsigned int i = 0; i < particles.size(); i++) { r.x = (int)(particles[i].x - PARTICLE_RADIUS); r.y = (int)(particles[i].y - PARTICLE_RADIUS); r.w = (int)(PARTICLE_RADIUS * 2); r.h = (int)(PARTICLE_RADIUS * 2); SDL_RenderFillRect(renderer, &r); } }

void ParticleManager::renderGrid(SDL_Renderer* renderer) {

// TODO: Draw the lines that form the grid cout << "Affichage de la grile (TODO)" << endl;

}

void ParticleManager::renderCells(SDL_Renderer* renderer) {

// TODO: Draw the boxes in different colors to // represent the number of particles in each cell // // Use the calculation: // int alpha = nb_particles * 255/5; // if (alpha> 255) alpha = 255; // SDL_SetRenderDrawColor (renderer, 0, 0, 255, alpha); // // To assign the color to the cell cout << "Affichage des cellules (TODO)" << endl;

}

void ParticleManager::render(SDL_Renderer* renderer) { if (renderMode.find("particle") != string::npos) renderParticles(renderer);

if (renderMode.find("grid") != string::npos) { renderCells(renderer); renderGrid(renderer); } }

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started