Created
January 23, 2018 03:20
-
-
Save Sam-Belliveau/42da13ec5c3cc639fe5d2345db11fe46 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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