Skip to content

Instantly share code, notes, and snippets.

@Sam-Belliveau
Created January 23, 2018 03:20
Show Gist options
  • Save Sam-Belliveau/42da13ec5c3cc639fe5d2345db11fe46 to your computer and use it in GitHub Desktop.
Save Sam-Belliveau/42da13ec5c3cc639fe5d2345db11fe46 to your computer and use it in GitHub Desktop.
#include <SFML/Graphics.hpp>
int main()
{
#define moveSet { movement = true; scale = startScale; }
#define reset { posx = -0.75; posy = 0; zoom = 1.13; startScale = 8; endScale = 1; scale = startScale; ITER = 16; BAIL = 4; movement = true; }
typedef long double decimal; // Change The Data Type If You Want
typedef unsigned int integer; // Change The Data Type If You Want
/// CONTANTS ///
// Window Size
const decimal w = 360;
const decimal h = 180;
decimal maxScale = 1;
{
decimal tw = w/2; decimal th = h/2;
while(tw == (decimal)((int)tw) && th == (decimal)((int)th))
{
maxScale *= 2;
tw /= 2;
th /= 2;
}
}
// RGB Values For Iteration Levels
const integer colors = 48;
const sf::Uint8 r[colors] = {255, 255, 255, 255, 255, 255, 255, 255, 255, 224, 192, 160, 128, 96, 64, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 64, 96, 128, 160, 192, 224, 255, 255, 255, 255, 255, 255, 255, 255};
const sf::Uint8 g[colors] = { 0, 32, 64, 96, 128, 160, 192, 224, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 224, 192, 160, 128, 96, 64, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const sf::Uint8 b[colors] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 64, 96, 128, 160, 192, 224, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 224, 192, 160, 128, 96, 64, 32};
// Zoom Multiplyer
const decimal zoomSpeed = 1.f + (1.f / 16.f);
/// NON CONSTANTS ///
sf::RenderWindow app(sf::VideoMode((int)w, (int)h), "Fractal");
app.setFramerateLimit(100);
// realW and realH change on resize, this is for the mouse movement
decimal realW = w;
decimal realH = h;
decimal xScale = w/h; // prevents distortion
// Variables used later
decimal posx, posy, zoom, startScale, endScale, scale, BAIL;
integer ITER;
bool movement = true; // Only Update If Needed
bool mouseDown = false;
reset; // Give Variables Valuse
sf::Vector2i mouse = sf::Mouse::getPosition(); // A 1 frame delay with the mouse gives movement
while (app.isOpen())
{
sf::Event event;
while (app.pollEvent(event))
{
if (event.type == sf::Event::Closed) { app.close(); }
if (event.type == sf::Event::Resized)
{
realW = app.getSize().x;
realH = app.getSize().y;
xScale = realW/realH;
moveSet;
}
}
if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
// Use The One Frame Delay To Move Position
if(mouse.x != sf::Mouse::getPosition().x || mouse.y != sf::Mouse::getPosition().y)
{
if(mouseDown) // touch screen support
{
posx += ((decimal)(mouse.x - sf::Mouse::getPosition().x) / (realW / 2)) * zoom * xScale;
posy += ((decimal)(mouse.y - sf::Mouse::getPosition().y) / (realH / 2)) * zoom;
moveSet;
}
}
}
mouse = sf::Mouse::getPosition(); // Update frame behind
mouseDown = sf::Mouse::isButtonPressed(sf::Mouse::Left);
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
{ reset }
/// Settings
if(sf::Keyboard::isKeyPressed(sf::Keyboard::B))
{
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{ BAIL++; while(sf::Keyboard::isKeyPressed(sf::Keyboard::Up)); moveSet; }
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down) && BAIL > 1)
{ BAIL--; while(sf::Keyboard::isKeyPressed(sf::Keyboard::Down)); moveSet; }
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::I))
{
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{ ITER*=2; while(sf::Keyboard::isKeyPressed(sf::Keyboard::Up)); moveSet; }
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down) && ITER > 1)
{ ITER/=2; while(sf::Keyboard::isKeyPressed(sf::Keyboard::Down)); moveSet; }
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::S))
{
if(sf::Keyboard::isKeyPressed(sf::Keyboard::LShift))
{
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up) && endScale < startScale/2)
{ endScale *= 2; while(sf::Keyboard::isKeyPressed(sf::Keyboard::Up)); moveSet; }
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down) && endScale > 0.5)
{ endScale /= 2; while(sf::Keyboard::isKeyPressed(sf::Keyboard::Down)); moveSet; }
scale = endScale;
} else
{
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up) && startScale < maxScale)
{ startScale *= 2; while(sf::Keyboard::isKeyPressed(sf::Keyboard::Up)); moveSet; }
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down) && startScale > endScale*2)
{ startScale /= 2; while(sf::Keyboard::isKeyPressed(sf::Keyboard::Down)); moveSet; }
scale = startScale;
} movement = true;
}
else
{
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
{ zoom /= zoomSpeed; moveSet; }
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down) && zoom < 2)
{ zoom *= zoomSpeed; moveSet; }
}
/// Render
if(movement)
{
// Scaled Resolution
const integer tempW = w / scale;
const integer tempH = h / scale;
integer countMax = tempW * tempH * 4;
sf::Uint8* pixels = new sf::Uint8[countMax];
// Limit Position
if(posx > 0.5) posx = 0.5;
if(posx < -2) posx = -2;
if(posy > 1.125) posy = 1.125;
if(posy < -1.125) posy = -1.125;
const decimal xStart = posx - zoom * xScale;
const decimal xIter = 2 * xScale * zoom / tempW;
const decimal yIter = 2 * zoom / tempH;
integer counter = 0;
decimal y = posy - zoom;
for(integer iy = 0; iy < tempH; iy++)
{
decimal x = xStart;
for(integer ix = 0; ix < tempW; ix++)
{
pixels[counter + 0] = 0;
pixels[counter + 1] = 0;
pixels[counter + 2] = 0;
pixels[counter + 3] = 255;
decimal zr = x;
decimal zi = y;
for(integer iterations = 0; iterations < ITER; iterations++)
{
const decimal sqzr = zr * zr;
const decimal sqzi = zi * zi;
const decimal mult = zr * zi;
zi = mult + mult + y;
zr = sqzr - sqzi + x;
if(sqzr + sqzi > BAIL)
{
iterations %= colors;
pixels[counter + 0] = r[iterations];
pixels[counter + 1] = g[iterations];
pixels[counter + 2] = b[iterations];
break;
}
}
x += xIter;
counter += 4;
}
y += yIter;
}
sf::Texture texture;
texture.create(tempW,tempH);
texture.update(pixels);
texture.setSmooth(true);
sf::Sprite sprite;
sprite.setTexture(texture);
sprite.setScale(scale,scale);
app.draw(sprite);
app.display();
movement = false;
if(scale > endScale)
{
scale *= 0.5;
movement = true;
}
delete pixels;
}
}
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment