Don't kill me for making another thread :ohdear:
So yeah, I jumped on the fractal :bandwagon: and came up with this:
[url]http://cloud.anyhub.net.nyud.net/0-Mandelbrot---HSV.exe[/url]
(Arrow keys, A and Z for zoom, S and X for iteration changes)
Now I'm making a second version, that allows you to zoom in based on drawing a square.
[code]#include <SFML/Graphics.hpp>
void DrawMandelbrot();
const int W = 512;
const int H = 512;
// Image to draw to
sf::Image buffer(W, H);
// And a sprite to draw it with
sf::Sprite bufferSpr(buffer);
// Zoom factor
double zoom = 2.0f;
// Real and imaginary center
double centreRe = 0.0f;
double centreIm = 0.0f;
// Bounds
double minRe = centreRe - zoom;
double maxRe = centreRe + zoom;
double minIm = centreIm - zoom;
double maxIm = centreIm + zoom;
// Relative value per pixel
double pixRe = (maxRe - minRe) / W;
double pixIm = (maxIm - minIm) / H;
// Number of iterations per point
int iterations = 50;
// Magical point C
double cRe = 0.0f;
double cIm = 0.0f;
int main()
{
sf::RenderWindow App(sf::VideoMode(W, H), "Mandelbrot Set");
// Display the window
App.Display();
// So we can have controls
const sf::Input &input = App.GetInput();
// For mouseDown and mouseUp event
int leftWasPressed = 0;
int mouseDown = 0;
int mouseUp = 0;
// Selection rectangle stuff
bool rect_draw = false;
float rect_startX = 0.0f;
float rect_startY = 0.0f;
float rect_endX = 0.0f;
float rect_endY = 0.0f;
// Draw the initial set
DrawMandelbrot();
// Main loop
while(App.IsOpened())
{
sf::Event Event;
while(App.GetEvent(Event))
{
if(Event.Type == sf::Event::Closed)
App.Close();
if(Event.Type == sf::Event::KeyPressed && Event.Key.Code == sf::Key::Escape)
App.Close();
}
if(input.IsMouseButtonDown(sf::Mouse::Left) && leftWasPressed == 0)
{
leftWasPressed = 1;
mouseDown = 1;
}
else if(input.IsMouseButtonDown(sf::Mouse::Left) && leftWasPressed == 1)
mouseDown = 0;
if(!input.IsMouseButtonDown(sf::Mouse::Left) && leftWasPressed == 1)
{
leftWasPressed = 0;
mouseUp = 1;
}
else if(!input.IsMouseButtonDown(sf::Mouse::Left) && leftWasPressed == 0)
mouseUp = 0;
// Create the selection rectangle
sf::Shape rect_select = sf::Shape::Rectangle(rect_startX, rect_startY, rect_endX, rect_endY, sf::Color(0,0,0), 1.0f, sf::Color(200, 50, 0));
rect_select.EnableFill(false);
rect_select.EnableOutline(true);
if(mouseDown)
{
// Set the selection rectangle start X and Y
rect_startX = input.GetMouseX();
rect_startY = input.GetMouseY();
// Tell it to draw
rect_draw = true;
}
if(mouseUp)
{
rect_draw = false;
int centreX = rect_endX - rect_startX;
int centreY = rect_endY - rect_startY;
int newCentreRe = minRe + (centreX*pixRe);
int newCentreIm = minIm + (centreY*pixIm);
centreRe = newCentreRe;
centreIm = newCentreIm;
DrawMandelbrot();
}
// If we should draw the selection rectangle..
if(rect_draw)
{
// Set the end points
rect_endX = input.GetMouseX();
// This is calculated based on aspect ratio, so it always fits the window
//rect_endY = rect_startY + ((rect_endX-rect_startX)*(W/H));
rect_endY = input.GetMouseY();
}
// Draw everything
// The buffer
bufferSpr.SetImage(buffer);
App.Draw(bufferSpr);
if(rect_draw)
App.Draw(rect_select);
// Show the window
App.Display();
}
return 0;
}
void DrawMandelbrot()
{
// Recalculate the bounds
minRe = centreRe - zoom;
maxRe = centreRe + zoom;
minIm = centreIm - zoom;
maxIm = centreIm + zoom;
// And the value per pixel
double pixRe = (maxRe - minRe) / W;
double pixIm = (maxIm - minIm) / H;
// Loop through all pixels
for(int re = 0; re < W; re++)
{
// Calculate the point value
cRe = minRe + (re*pixRe);
for(int im = 0; im < H; im++)
{
// Calculate point value
cIm = minIm + (im*pixIm);
// Initialise Z as C
double zRe = cRe;
double zIm = cIm;
// Colour base value for this point
int colBase = 0;
// Perform the iteration
for(int n = 0; n < iterations; n++)
{
// If we've left the bounds..
if((zRe*zRe) + (zIm*zIm) > 4)
{
colBase = n;
break;
}
// If not, apply:
// Z = Z*Z + C
// For zIm:
// Imaginary part = (2*Imaginary*Real) + C
// Real part = (zRe^2 - zIm^2) + C
// Z^2 imaginary
double zIm2 = zIm*zIm;
zIm = (2*zIm*zRe) + cIm;
zRe = ((zRe*zRe) - zIm2) + cRe;
}
// And finally colour it
// If the point escaped to infinity...
if(colBase == 0)
{
buffer.SetPixel(re, im, sf::Color(0,0,0));
}
else
{
buffer.SetPixel(re, im, sf::Color((colBase*8)%255, 0, 0));
}
}
}
}[/code]
The bit I'm trying to make work at the moment is:
[code]if(mouseUp)
{
rect_draw = false;
int centreX = rect_endX - rect_startX;
int centreY = rect_endY - rect_startY;
int newCentreRe = minRe + (centreX*pixRe);
int newCentreIm = minIm + (centreY*pixIm);
centreRe = newCentreRe;
centreIm = newCentreIm;
DrawMandelbrot();
}[/code]
No zoom at the moment, but this should move the "viewport" to the center of my rectangle... except it doesn't. Can anyone work out why?
Thank you
centreX = rect_endX - ((rect_endX - rect_startX) / 2);
Etc.
You calculate the distance of the rectangle. What mine does is takes the end location minus half of the distance to get the middle.
Damn, how did I miss that?
I've been making mandelbrots and julia sets all day O_o
I think I should take a break
Been there done that :P
Took me about a week to get my Mandelbrot to zoom on the Xbox.
All working now, and I made a copy of it that generates julia sets :D
Thanks for the help :)
Can someone please explain to me why drawing a mandlebrot when you are really far zoomed in takes a lot longer? I always thought it only had to render what was in the window.
[editline]12:07PM[/editline]
And why do they always go very pixelated when you zoom in really far?
Because it needs more iterations.
Even though you are zoomed in, it takes really a lot iterations to actually make that detail visible.
[QUOTE=nos217;20872218]Can someone please explain to me why drawing a mandlebrot when you are really far zoomed in takes a lot longer? I always thought it only had to render what was in the window.
[editline]12:07PM[/editline]
And why do they always go very pixelated when you zoom in really far?[/QUOTE]
More iterations needed.
[b]:Edit:[/b]
Not a ninja again :C
Ahh, I get it. Thanks. Surely there is a way mathematically to "skip out" the first iterations?
Skipping iterations out = less iterations = less detail I'm afraid :P
[QUOTE=nos217;20872373]Ahh, I get it. Thanks. Surely there is a way mathematically to "skip out" the first iterations?[/QUOTE]
No, because they are different for every position. You could keep a cache of positions that you have done, so that they don't need to be recalculated when zooming in, and you can do things for checking for bulbs and cardoids, but that's about it, I think.
That sucks, so basically we will never be able to zoom pseudo-infinitely.
Nope, but we will continue getting closer and closer.
Some people have rendered zooms that mean that if the last frame of the video was the size of your screen, the entire image would be larger than the known universe. That video took about 3 months to render I believe.
[IMG]http://i40.tinypic.com/29ygl4x.png[/IMG]
I made a mandelwagon for you guys.
[QUOTE=Chris220;20874624]Nope, but we will continue getting closer and closer.
Some people have rendered zooms that mean that if the last frame of the video was the size of your screen, the entire image would be larger than the known universe. That video took about 3 months to render I believe.[/QUOTE]
Imagine if we could do that real time.
[editline]03:41PM[/editline]
[QUOTE=iPope;20874989][IMG]http://i40.tinypic.com/29ygl4x.png[/IMG]
I made a mandelwagon for you guys.[/QUOTE]
Very nice, but it needs transparency.
I claim copyright on the term "Mandelwagon"
Sorry, you need to Log In to post a reply to this thread.