Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "base.h"
- /*#include <fstream>
- #include <SFML\Graphics.hpp>
- #include <string>
- #include <vector>
- #include <math.h>
- const double e=2.71828183;*/
- const int w=64,h=48; //width and height of the simulation in cells
- const int px_per_cell_w=4,px_per_cell_h=4; //width and height of a single cell in pixels
- const float change_weight=2.0; //rate of change towards average value of neighbours per step, 1=100% change 0=no change
- float grid[w][h]={0};
- float grid_new[w][h]={0};
- float power=0.005;
- sf::Vector2i mouse;
- float positive(float x)
- {
- if(x<0) return -x;
- return x;
- }
- float sign(float x) //for use in "to_channel" function
- {
- if(x>0) return 1;
- if(x<0) return -1;
- return 0;
- }
- float cast_0to1sharp(float x)
- {
- return 1.0-1.0/(1.0+sqrt(abs(x))); //useful for mapping a logarithmically large but positive (including 0) range of values to a value from 0 to 1
- }
- float cast_0to1soft(float x) //useful for mapping a logarithmically large but positive (including 0) range of values to a value from 0 to 1
- {
- return 1.0-1.0/(1.0+abs(x));
- }
- float to_channel(float channel) //for use of pixel display
- {
- return 128.0*sign(channel)*cast_0to1soft(channel)+128.0; //useful for mapping a logarithmically large (but not necessarily positive) range of values from 0 to 1
- }
- float get(int x,int y)
- {
- int cx=x,cy=y;
- if(x<0) cx=w-1;
- if(y<0) cy=h-1;
- if(x>=w) cx=0;
- if(y>=h) cy=0;
- return grid[cx][cy];
- }
- int main()
- {
- sf::Clock clock;
- sf::ContextSettings set;
- set.antialiasingLevel=8;
- sf::RenderWindow window(sf::VideoMode(w*px_per_cell_w,h*px_per_cell_h),"fluid sim");
- while(window.isOpen())
- {
- clock.restart();
- sf::Event event;
- while (window.pollEvent(event)) {if (event.type == sf::Event::Closed) window.close();}
- window.clear(sf::Color::Black);
- //[do physics step and render]
- //user interaction
- mouse.x=sf::Mouse::getPosition(window).x-1000;//I only add 1000 so that I can evade this weird strangely x-axis-specific glitch
- mouse.y=sf::Mouse::getPosition(window).y;
- float temp=grid[(mouse.x/px_per_cell_w)%w][(mouse.y/px_per_cell_h)%h];
- if(mouse.x>=0 && mouse.x<w*px_per_cell_w && mouse.y>=0 && mouse.y<h*px_per_cell_h)
- {
- if(sf::Mouse::isButtonPressed(sf::Mouse::Button::Left))
- {
- grid[(mouse.x/px_per_cell_w)%w][(mouse.y/px_per_cell_h)%h]+=32.0;//+abs(temp)*power;
- }
- if(sf::Mouse::isButtonPressed(sf::Mouse::Button::Right))
- {
- grid[(mouse.x/px_per_cell_w)%w][(mouse.y/px_per_cell_h)%h]-=32.0;//+abs(temp)*power;
- }
- }
- //simulation and rendering
- for(int cy=0;cy<h;cy++)
- {
- for(int cx=0;cx<w;cx++)
- {
- //for convenience of reference
- float curcell=grid[cx][cy];
- float newcell=grid_new[cx][cy];
- //what is our neighbourhood? (I've organised it so that it is visually obvious what neighbour each term corresponds to)
- float neighbour[8]=
- {get(cx-1,cy-1),get(cx,cy-1),get(cx+1,cy-1),
- get(cx-1,cy), get(cx+1,cy),
- get(cx-1,cy+1),get(cx,cy+1),get(cx+1,cy+1)};
- //calculate the average
- float average=0;
- for(int i=0;i<8;i++)
- {
- average+=neighbour[i]/8.0;
- }
- newcell+=(average-curcell)/change_weight; //find the difference between the average and the current value, and divide by change_weight, then change by that
- float difference=curcell-newcell;
- grid_new[cx][cy]=newcell;
- sf::RectangleShape square(sf::Vector2f(px_per_cell_w,px_per_cell_h));
- float b=to_channel(difference*10.0); //float b=255*(1.0-1.0/(1+curcell));
- float g=255.0/(1.0+pow(e,-curcell)); //float g=255*(1.0-1.0/(1+sqrt(curcell*2.0)));
- float r=255.0/(1.0+pow(e,curcell)); //float r=255*(1.0-1.0/(1+sqrt(sqrt(curcell*4.0))));
- square.setFillColor(sf::Color(r,g,b));
- square.setPosition(sf::Vector2f(cx*px_per_cell_w,cy*px_per_cell_h));
- window.draw(square);
- }
- }
- //copy new array of grid cells to old one
- for(int cy=0;cy<h;cy++)
- {
- for(int cx=0;cx<w;cx++)
- {
- grid[cx][cy]=grid_new[cx][cy];
- }
- }
- //window.draw(pwrdisp);
- window.display();
- //end step
- //attempting to sleep a negative amount of time will probably either crash it, cause the universe to stop existing or make a time travel machine...
- sf::Time sleep_time=sf::seconds(1.0/60.0)-clock.getElapsedTime(),no_time=sf::seconds(0.0);
- if(sleep_time>no_time) sf::sleep(sleep_time);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement