Author Topic: Plotting the Mandelbrot Fractal atleast once before I die.  (Read 5060 times)

0 Members and 1 Guest are viewing this topic.

Offline Pixel_Outlaw

  • Pentium
  • *****
  • Posts: 1390
  • Karma: 84
    • View Profile

I would like to plot the Mandelbrot atleast once in my life. My problem is I don't know what value to feed the formula. On a recent video I was given the formula. The formula takes one value and refeeds the value back to the start a few times. My question is how do you get a value for each pixel given their location (x,y)?

The forumula:

Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Check Wikipedia.
For every picture, center (Re,Im) and diameter are given.
Challenge Trophies Won:

Offline Pixel_Outlaw

  • Pentium
  • *****
  • Posts: 1390
  • Karma: 84
    • View Profile
Ah thanks. I did not see the pseudocode section before. The formula given on wikipedia seems MUCh more complex. Could anyone explain why it is?
Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Because "z" is a complex number with associated algebraic rules.
Challenge Trophies Won:

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17427
  • Karma: 499
  • evil/good
    • View Profile
    • My Homepage
And here is a source I made, but beware it's very old and has stupid variable names because I was drunk when I made it.

Code: [Select]
' Little Mandlebrot using tinyptc by Shockwave ^ DBF
' Fuck I must be bored tonight....
'
' For those learning fractals, the colour of the point is determined by how many
' iterations of z=z^2 +c it takes to determine if a point is a part of the set or
' if it bails out before it can be determined (try playing with the iterations variable).
' Meh! Last time I coded one of these it was in Pascal in college a long time ago.
'
'-------------------------------------------------------------------------------

 '#DEFINE PTC_WIN
 #Include Once "tinyptc.bi"
 If( ptc_open( "LITTLE MANDELBROT BY SHOCKWAVE^DBF", 320, 240 ) = 0 ) Then End
 dim shared buffer(320*240) as integer
 dim shared as double XADD,XPX,YADD,YPY,AAAA,BBBB,FLOOP,AAA,BBB
 option explicit
 dim shared MINIMUM_X,MAXIMUM_X,TWAT,BOLLOCKS,PASS,ITERATIONS,y,x as uinteger
 dim shared COLOUR_MULT,scale  as double

        MINIMUM_X = 0
        MAXIMUM_X = 319
        TWAT = 0
        BOLLOCKS = 239
PASS=10
ITERATIONS=50
COLOUR_MULT = (500/ITERATIONS)
dim gadd as uinteger
do     
    gadd=gadd+1
    scale = (4*sin(gadd/27))+7
XADD= (scale/(MAXIMUM_X - MINIMUM_X))
XPX=-scale
YADD= (scale/(BOLLOCKS - TWAT))
YPY=-scale /2
        for y = TWAT to BOLLOCKS
XPX=-scale /1.6
for x = MINIMUM_X to MAXIMUM_X
                AAA=XPX
                BBB=YPY
                FLOOP=0
do
        FLOOP=FLOOP+1
        AAAA=AAA*AAA-BBB*BBB+XPX
        BBBB=2*AAA*BBB+YPY
        AAA=AAAA
        BBB=BBBB         
loop until ((FLOOP>ITERATIONS) or ((AAA*AAA)+(BBB*BBB)>PASS))
                if FLOOP>=ITERATIONS then                 
                FLOOP=0                 
                else               
                FLOOP=FLOOP*COLOUR_MULT               
                end if
                buffer((y*320)+x)=rgb(FLOOP,0,FLOOP)         
                XPX = XPX + XADD
        next x
        YPY = YPY + YADD
        next y
 ptc_update@buffer(0)
 loop until inkey$<>""

Hope that gives a little extra help.
Shockwave ^ Codigos
Challenge Trophies Won:

Offline Motorherp

  • C= 64
  • **
  • Posts: 57
  • Karma: 8
    • View Profile
    • Shmup Dev
And if anyone wants c++ code this was my DX fractal generator which I've dug up from my archives.  Same as shockwave though, beware.  I wrote this a very long time ago when my coding standards sucked.

Code: [Select]
//////////////////////////////////////////////////////////////////
//
// enFractalGenerator.h
//
///////////////////////////////////////////////////////////////////

#ifndef ENFRACTALGENERATOR
#define ENFRACTALGENERATOR

#include <d3dx9.h>
#include <vector>
#include "D3DManager.h"

using namespace std;

class enFractalGenerator
{
private:
float mPosX, mPosY; // centre position of the current render set
float mZoomFactor; // zoom factor of the current render set
float mRealConst, mImgConst; // the real and imaginary constants
float mThresholdSquare; // bail out threshold squared
int mMaxIterations; // the number of iterations to take to determine the set
vector<D3DXCOLOR> mvColourTable; // table of colours for redering the set

public:
inline enFractalGenerator();
inline ~enFractalGenerator();

inline void SetRenderSetPos(const float x, const float y);
inline void TranslateRenderSetPos(const float dx, const float dy);
inline void GetRenderSetPos(float* pX, float* pY) const;

inline void SetZoomFactor(float const zoomFactor);
inline float GetZoomFactor() const;
inline void Zoom(const float zoomFactor);

inline void SetConstants(const float realConst, const float imgConst);
inline void SetRealConstant(const float realConst);
inline void SetImgConstant(const float imgConst);
inline float GetRealConstant() const;
inline float GetImgConstant() const;

inline void SetThreshold(const float threshold);
inline float GetThreshold() const;

inline void SetMaxIterations(const int maxIterations);
inline int GetMaxIterations() const;

inline int GetLengthOfColourTable() const;
inline const D3DXCOLOR& GetColourTableEntry(const int index) const;
inline D3DXCOLOR& AccessColourTableEntry(const int index);
inline void SetColourTableEntry(const int index, const D3DXCOLOR& colour);
inline void SetColourBlend(const int startIndex, const D3DXCOLOR& startColour, const int endIndex, const D3DXCOLOR& endColour);

inline bool RenderToSurface(IDirect3DSurface9* pSurface) const;

};

inline enFractalGenerator::enFractalGenerator()
{
// set the variables
mPosX = mPosY = 0.0f;
mZoomFactor = 0.25f;
mRealConst = mImgConst = 0.0f;
mThresholdSquare = 4.0f;
mMaxIterations = 0;
}

inline enFractalGenerator::~enFractalGenerator()
{
mvColourTable.empty();
}

inline void enFractalGenerator::SetRenderSetPos(const float x, const float y)
{
mPosX = x;
mPosY = y;
}

inline void enFractalGenerator::TranslateRenderSetPos(const float dx, const float dy)
{
mPosX += dx;
mPosY += dy;
}

inline void enFractalGenerator::GetRenderSetPos(float* pX, float* pY) const
{
*pX = mPosX;
*pY = mPosY;
}

inline void enFractalGenerator::SetZoomFactor(const float zoomFactor)
{
assert(zoomFactor != 0.0f);
mZoomFactor = zoomFactor;
}

inline float enFractalGenerator::GetZoomFactor() const
{
return mZoomFactor;
}

inline void enFractalGenerator::Zoom(const float zoomFactor)
{
mZoomFactor *= zoomFactor;
}

inline void enFractalGenerator::SetConstants(const float realConst, const float imgConst)
{
mRealConst = realConst;
mImgConst = imgConst;
}

inline void enFractalGenerator::SetRealConstant(const float realConst)
{
mRealConst = realConst;
}

inline void enFractalGenerator::SetImgConstant(const float imgConst)
{
mImgConst = imgConst;
}

inline float enFractalGenerator::GetRealConstant() const
{
return mRealConst;
}

inline float enFractalGenerator::GetImgConstant() const
{
return mImgConst;
}

inline void enFractalGenerator::SetThreshold(const float threshold)
{
mThresholdSquare = threshold*threshold;
}

inline float enFractalGenerator::GetThreshold() const
{
return sqrt(mThresholdSquare);
}

inline void enFractalGenerator::SetMaxIterations(const int maxIterations)
{
// resize table to accomodate new colours or delete unused colours
mvColourTable.resize(maxIterations);

// initialise any new colours added to table (white)
for(int index = mMaxIterations; index < maxIterations; index++)
{
mvColourTable[index] = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
}

mMaxIterations = maxIterations;
}

inline int enFractalGenerator::GetMaxIterations() const
{
return mMaxIterations;
}

inline int enFractalGenerator::GetLengthOfColourTable() const
{
return mMaxIterations;
}

inline const D3DXCOLOR& enFractalGenerator::GetColourTableEntry(const int index) const
{
assert((index < mMaxIterations)&&(index >= 0));
return mvColourTable[index];
}

inline D3DXCOLOR& enFractalGenerator::AccessColourTableEntry(const int index)
{
assert((index < mMaxIterations)&&(index >= 0));
return mvColourTable[index];
}

inline void enFractalGenerator::SetColourTableEntry(const int index, const D3DXCOLOR& colour)
{
assert((index < mMaxIterations)&&(index >= 0));
mvColourTable[index] = colour;
}

inline void enFractalGenerator::SetColourBlend(const int startIndex, const D3DXCOLOR& startColour, const int endIndex, const D3DXCOLOR& endColour)
{
assert((startIndex < mMaxIterations)&&(startIndex >= 0));
assert((endIndex < mMaxIterations)&&(endIndex >= 0));
assert(startIndex < endIndex);

// blend between the two colours across the range specified and put colours into table
mvColourTable[startIndex] = startColour;
mvColourTable[endIndex] = endColour;

int numEntries = endIndex - startIndex;
float numEntriesRec = 1.0f / (float)numEntries;

for(int index = 1; index < numEntries; index++)
{
D3DXColorLerp(&mvColourTable[startIndex + index], &startColour, &endColour, (float)index*numEntriesRec);
}
}

inline bool enFractalGenerator::RenderToSurface(IDirect3DSurface9* pSurface) const
{
// get surface description
HRESULT hr;
D3DSURFACE_DESC surfaceDesc;

hr = pSurface->GetDesc(&surfaceDesc);
if(FAILED(hr))
{
assert(false);
return false;
}

// calculate the width, height, and the top left start coord of the complex plane from the set pos and zoom
float width = 1.0f / mZoomFactor;
float height = width*((float)surfaceDesc.Height / (float)surfaceDesc.Width);

float startX = mPosX - width*0.5f;
float startY = mPosY + height*0.5f;

float surfaceHeightRec = 1.0f / (float)surfaceDesc.Height;
float surfaceWidthRec = 1.0f / (float)surfaceDesc.Width;

float xNew, xOld, yNew, yOld, cx, cy;
int numIterations;

// lock the surface and get a pointer to its data buffer
D3DLOCKED_RECT surfaceRect;
hr = pSurface->LockRect(&surfaceRect, 0, D3DLOCK_DISCARD);
if(FAILED(hr))
{
assert(false);
return false;
}

int pitch = surfaceRect.Pitch / 4;
DWORD* pTexels = (DWORD*)surfaceRect.pBits;

// calculate the colour at each texel by evaluating the complex equation using the texel coord as input and using the
// number of iterations before exceeding the threshold as an index into the colour table.
for(int v = 0; v < surfaceDesc.Height; v++)
{
cy = startY - height*(float)v*surfaceHeightRec;

for(int u = 0; u < surfaceDesc.Width; u++)
{
cx = startX + width*(float)u*surfaceWidthRec;
xOld = mRealConst;
yOld = mImgConst;

numIterations = -1;
for(int i = 0; i < mMaxIterations; i++)
{
numIterations++;

xNew = xOld*xOld - yOld*yOld + cx;
yNew = 2.0f*xOld*yOld + cy;

if(xNew*xNew + yNew*yNew > mThresholdSquare)
{
break;
}

xOld = xNew;
yOld = yNew;
}

pTexels[v*pitch + u] = (DWORD)mvColourTable[numIterations];
}
}

hr = pSurface->UnlockRect();
if(FAILED(hr))
{
assert(false);
return false;
}

return true;
}



#endif

A picture of it in action:



The cool thing about the code is that it allows morphing, repositioning, and zooming which is pretty cool to see in real time.
« Last Edit: June 07, 2008 by Motorherp »

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17427
  • Karma: 499
  • evil/good
    • View Profile
    • My Homepage
Nice colours and K+ for putting the source up which is much cleaner than mine :)
Shockwave ^ Codigos
Challenge Trophies Won:

Offline p01

  • Atari ST
  • ***
  • Posts: 158
  • Karma: 51
    • View Profile
    • www.p01.org
You could also look at Mandelbrot Rotozoom, a 256b intro I wrote in JavaScript, which does what it says on the tin.

The code is small, but not too small to be completely unreadable, and all the JavaScript you need to know is that setInterval(foo,delay) is a loop, bar.innerHTML=baz simply dumps the "image" in the element bar in the page, and the < br > is like a \n\r in text mode.

Code: [Select]

<pre id=B><script>setInterval("for(d='p01‡*×:,~.    ',C=Math.cos(n-=88),S=Math.sin(n),Y=m=1+C,z=2048;z;Y-=m/16)for(d+='<br>',X=m;--z&63;X-=m/32,d+=d.charAt(k))for(r=i=k=0;++k+r*r+i*i<13;i=t)t=2*r*i-X*C+Y*S,r=r*r-i*i-X*S-Y*C+C-1;B.innerHTML=d",n=9)</script>


HTH

Offline rain_storm

  • Here comes the Rain
  • DBF Aficionado
  • ******
  • Posts: 3088
  • Karma: 182
  • Rain never hurt nobody
    • View Profile
    • org_100h
That is awesome p01, really nice ascii graphics

Challenge Trophies Won: