• Mandelwagon
    15 replies, posted
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.