Like Tree1Likes
  • 1 Post By Nancy Franklin

Running/changing a very old fractal program

This is a discussion on Running/changing a very old fractal program within the C++ Programming forums, part of the General Programming Boards category; Hi- I'm trying to run some C++ code I found here that's so old, it uses <conio.h> and <graphics.h>, which ...

  1. #1
    Registered User Nancy Franklin's Avatar
    Join Date
    Sep 2011
    Posts
    15

    Running/changing a very old fractal program

    Hi- I'm trying to run some C++ code I found here that's so old, it uses <conio.h> and <graphics.h>, which aren't available. I'm trying to upgrade its code by removing the obsolete sections so that it will run, but I can't find any useful advice on how to replace the <conio.h> and <graphics.h> bits (except that I should replace conio.h's "getch" with "std::cin.get()" ). I tried contacting the maker of this code, with no response.

    I just want to get these files to run, so that I can see how they work, and build on it to make my own fractal generator from the ground up. If these are just too old to fix up, can you please point me to a way to make my own fractal generator, maybe with openGL?

    Code:
    #include <stdio.h>
    //#include <conio.h>
    #include <iostream>
    //#include <stdlig.h>
    #include <math.h>
    #include <graphics.h>
    
    void DrawSierpinski(void);
    
    void main(void)
    {
    //source: http://mathed.uta.edu/kribs/fractal.html
        int gd=VGA;
        int gm=VGAHI;
        initgraph(&gd, &gm, "\\tc\\bgi");
    
        DrawSierpinski();
        //getch();
        std::cin.get();
    }
    
    void DrawSierpinski(void)
    {
        char Direct;
        int iterate;
        unsigned int x1, y1, x2, y2;
    
        x1 = x2 = 320;
        y1 = y2 = 0;
    
        for(iterate = 0; iterate < 10000; iterate++)
        {
            Direct = random(3);
            
            if(Direct == 0)
            {
                x1 = (x2 + 320) / 2;
                y1 = (y2 + 0) / 2;    
            }
            else if(Direct == 1)
            {
                x1 = (x2 + 0) / 2;
                y1 = (y2 + 480) / 2;
            }
            else if(Direct == 2)
            {
                x1 = (x2 + 640) / 2;    
                y1 = (y2 + 480) / 2;
            }
            putpixel(x1, y1, WHITE);
    
            x2 = x1;
            y2 = y1;
        }
    }
    Code:
    #include "fractal"
    
    #include <fstream>
    
    
    using namespace fractals;
    
    int main()
    {
        // cactus fractal
        //source: http://www.codeproject.com/KB/cpp/fractal.aspx
    
        cactus<float> c(400, 400);
        c.render(-1.5, 1.5, 3, 3);
        std::ofstream os("cactus.tga", std::ios_base::binary);
        os << c;
    }
    Code:
    #include "fractal"
    
    #include <fstream>
    
    
    using namespace fractals;
    
    int main()
    {
        // san marco fractal
    
        julia<float> j(400, 400);
        j.c = std::complex<float>(-3.0f / 4.0f, 0);
        j.render(-1.5, 1.5, 3, 3);
        std::ofstream os("sanmarco.tga", std::ios_base::binary);
        os << j;
    }
    Code:
    // fractal header
    
    #ifndef _FRACTAL_
    
    #define _FRACTAL_
    
    #include <complex>
    
    #include <ostream>
    
    
    
    namespace fractals {
    
            // TEMPLATE CLASS fractal
    
    template<class _Ty>
    
            class fractal {
    
    public:
    
            fractal(unsigned short _W, unsigned short _H) :
    
                    _Width(_W), _Height(_H), iterations(256)
    
                    {_M = new unsigned char[_W * _H * 3];
    
                    ::memset(_M, 0, sizeof(unsigned char) * _W * _H * 3); }
    
            fractal(const fractal& _X) : _M(0)
    
                    {_Assign(_X); }
    
            ~fractal()
    
                    {delete[] _M; }
    
            unsigned short width() const
    
                    {return _Width; }
    
            unsigned short height() const
    
                    {return _Height; }
    
            unsigned char *data() const
    
                    {return _M; }
    
            unsigned iterations;
    
            void render(_Ty _X0, _Ty _Y0, _Ty _W, _Ty _H)
    
                    {for (unsigned short _Y = 0; _Y < _Height; _Y++)
    
                            for (unsigned short _X = 0; _X < _Width; _X++)
    
                                    {_Ty _Cx = _X0 + (_X * _W / _Width);
    
                                    _Ty _Cy = _Y0 - (_Y * _H / _Height);
    
                                    init(_Cx, _Cy);
    
                                    unsigned _N = (iterations <= 256) ?
    
                                            iterations : 256;
    
                                    unsigned _I = 0;
    
                                    for (; _I < _N; _I++)
    
                                            {if (test())
    
                                                break;
    
                                            next(); }
    
                                    unsigned char _R = 0, _G = 0, _B = 0;
    
                                    color(_I, _R, _G, _B);
    
                                    unsigned char *_P = _M + (_Y *
    
                                            (_Width * 3) + (_X * 3));
    
                                    *_P++ = _R, *_P++ = _G, *_P = _B; }}
    
    protected:
    
            void _Assign(const fractal& _X)
    
                    {delete[] _M;
    
                    _Width = _X._Width;
    
                    _Height = _X._Height;
    
                    _M = new unsigned char[_Width * _Height * 3];
    
                    ::memset(_M, 0, sizeof(unsigned char) * _Width * _Height * 3); }
    
            _Ty distance(const std::complex<_Ty>& _C)
    
                    {return ::sqrt(_C.real() * _C.real() + 
    
                    _C.imag() * _C.imag()); }
    
            virtual void init(_Ty _X, _Ty _Y) = 0;
    
            virtual bool test() = 0;
    
            virtual void color(unsigned _N, unsigned char& _R,
    
                    unsigned char& _G, unsigned char& _B) = 0;
    
            virtual void next() = 0;
    
            unsigned short _Width, _Height;
    
            unsigned char *_M;
    
            };
    
            // TEMPLATE CLASS mandelbrot
    
    template<class _Ty>
    
            class mandelbrot : public fractal<_Ty> {
    
    public:
    
            mandelbrot(unsigned short _W, unsigned short _H) :
    
                    fractal<_Ty>(_W, _H) {}
    
            mandelbrot(const mandelbrot& _X) : fractal<_Ty>(_X)
    
                    {_Z = _X._Z, _C = _X._C; }
    
            mandelbrot& operator=(const mandelbrot& _X)
    
                    {if (this == &_X) return (*this);
    
                    _Assign(_X);
    
                    _Z = _X._Z, _C = _X._C;
    
                    return (*this); }
    
    protected:
    
            virtual void init(_Ty _X, _Ty _Y)
    
                    {_C = std::complex<_Ty>(_X, _Y);
    
                    _Z = std::complex<_Ty>(0.0, 0.0); }
    
            virtual bool test()
    
                    {return (distance(_Z) > 2.0); }
    
            virtual void color(unsigned _N, unsigned char& _R,
    
                    unsigned char& _G, unsigned char& _B)
    
                    {_R = _G = _B = _N; }
    
            virtual void next()
    
                    {std::complex<_Ty> _T = _Z * _Z;            // keep borland happy
    
                    _T += _C; _Z = _T; }
    
            std::complex<_Ty> _Z, _C;
    
            };
    
            // TEMPLATE CLASS julia
    
    template<class _Ty>
    
            class julia : public fractal<_Ty> {
    
    public:
    
            std::complex<_Ty> c;
    
            julia(unsigned short _W, unsigned short _H) :
    
                    fractal<_Ty>(_W, _H), c(0.5, 0.5) {}
    
            julia(const julia& _X) : fractal<_Ty>(_X)
    
                    {_Z = _X._Z, c = _X.c; }
    
            julia& operator=(const julia& _X)
    
                    {if (this == &_X) return (*this);
    
                    _Assign(_X);
    
                    _Z = _X._Z, c = _X.c;
    
                    return (*this); }
    
    protected:
    
            virtual void init(_Ty _X, _Ty _Y)
    
                    {_Z = std::complex<_Ty>(_X, _Y); }
    
            virtual bool test()
    
                    {return (distance(_Z) > 2.0); }
    
            virtual void color(unsigned _N, unsigned char& _R,
    
                    unsigned char& _G, unsigned char& _B)
    
                    {_R = _G = _B = _N; }
    
            virtual void next()
    
                    {std::complex<_Ty> _T = _Z * _Z;            // keep borland happy
    
                    _T += c; _Z = _T; }
    
            std::complex<_Ty> _Z;
    
            };
    
            // TEMPLATE CLASS cactus
    
    template<class _Ty>
    
            class cactus : public fractal<_Ty> {
    
    public:
    
            cactus(unsigned short _W, unsigned short _H) :
    
                    fractal<_Ty>(_W, _H) {}
    
            cactus(const cactus& _X) : fractal<_Ty>(_X)
    
                    {_Z = _X._Z, _Z0 = _X._Z0; }
    
            cactus& operator=(const cactus& _X)
    
                    {if (this == &_X) return (*this);
    
                    _Assign(_X);
    
                    _Z = _X._Z, _Z0 = _X._Z0;
    
                    return (*this); }
    
    protected:
    
            virtual void init(_Ty _X, _Ty _Y)
    
                    {_Z = _Z0 = std::complex<_Ty>(_X, _Y); }
    
            virtual bool test()
    
                    {return (distance(_Z) > 2.0); }
    
            virtual void color(unsigned _N, unsigned char& _R,
    
                    unsigned char& _G, unsigned char& _B)
    
                    {_R = _G = _B = _N; }
    
            virtual void next()
    
                    {std::complex<_Ty> _T = _Z * _Z * _Z;        // keep borland happy
    
                    _T += (_Z0 - std::complex<_Ty>(1, 0)) * _Z;
    
                    _Z = _T - _Z0; }
    
            std::complex<_Ty> _Z, _Z0;
    
            };
    
            // TEMPLATE FUNCTION operator<<
    
    template<class _Ty>
    
            std::ostream& operator<<(std::ostream& _O, const fractal<_Ty>& _F)
    
            {unsigned short _W = _F.width(), _H = _F.height();
    
            _O.write("\0\0\2\0\0\0\0\0\0\0\0\0", sizeof(char) * 12);
    
            _O.write((const char *)&_W, sizeof(unsigned short));
    
            _O.write((const char *)&_H, sizeof(unsigned short));
    
            _O.write("\x18\x20", sizeof(char) * 2);
    
            unsigned char *_P = _F.data(), _C[3];
    
            for (unsigned _I = 0; _I < _W * _H * 3U; _I += 3)
    
                    {_C[0] = _P[_I + 2], _C[1] = _P[_I + 1], _C[2] = _P[_I];
    
                    _O.write((const char *)_C, 3 * sizeof(unsigned char));
    
            }
    
            return _O; }
    
    
    
    }    // namespace
    
    
    
    #endif /* _FRACTAL_ */
    
    
    
    /*
    
     * http://home.tiscali.be/zoetrope
    
     */

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,834
    Well the second set of files (the ones with using namespace fractals; ) will almost work "out of the box".

    All I added was
    #include <cstring>
    using std::memset;

    They output an image file in Truevision TGA - Wikipedia, the free encyclopedia format.
    Any decent graphics viewer should be able to render these.

    So yes, these look like a good place to start for further development.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  3. #3
    Registered User Nancy Franklin's Avatar
    Join Date
    Sep 2011
    Posts
    15
    Hmm. Thank you, that fixed all the compiling errors on the last two, "cactus" and "sanMarco", but when using g++ sanMarco.cpp gives no errors, but saying "./a.out" does nothing, just gives me another command input line. Nothing else. Am I perhaps missing something to make the window open and display the graphics or something? Is there a way to download TARGA for Ubuntu?

    it's currently
    Code:
    #include "fractal"
    
    #include <fstream>
    #include <cstring>
    using std::memset;
    
    using namespace fractals;
    
    int main()
    {
        // cactus fractal
        //source: http://www.codeproject.com/KB/cpp/fractal.aspx
    
        cactus<float> c(400, 400);
        c.render(-1.5, 1.5, 3, 3);
        std::ofstream os("cactus.tga", std::ios_base::binary);
        os << c;
    }
    and
    Code:
    #include "fractal"
    
    #include <fstream>
    #include <cstring>
    using std::memset;
    
    using namespace fractals;
    
    int main()
    {
        // san marco fractal
    
        julia<float> j(400, 400);
        j.c = std::complex<float>(-3.0f / 4.0f, 0);
        j.render(-1.5, 1.5, 3, 3);
        std::ofstream os("sanmarco.tga", std::ios_base::binary);
        os << j;
    }
    Last edited by Nancy Franklin; 10-31-2011 at 02:31 PM.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,834
    > saying "./a.out" does nothing, just gives me another command input line.
    Check your directory listing.
    You should see some new files (some .tga files).

    And ubuntu can display these directly (at least I could).
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  5. #5
    Registered User Nancy Franklin's Avatar
    Join Date
    Sep 2011
    Posts
    15
    Thank you, Salem! Just double-clicking on those .tga files worked! Now I just need to figure out how to tweak it into displaying color... Is there a graphics program to add color to .tga files? Is there an upgrade for Targa with better quality/resolution?

    Now, can you please help me replace the obsolete parts of this:
    Code:
    #include <stdio.h>
    //#include <conio.h>
    #include <iostream>
    //#include <stdlig.h>
    #include <math.h>
    #include <graphics.h>
    #include <cstring>
    using std::memset;
    void DrawSierpinski(void);
    
    void main(void)
    {
    //source: http://mathed.uta.edu/kribs/fractal.html
        int gd=VGA;
        int gm=VGAHI;
        initgraph(&gd, &gm, "\\tc\\bgi");
    
        DrawSierpinski();
        //getch();
        std::cin.get();
    }
    
    void DrawSierpinski(void)
    {
        char Direct;
        int iterate;
        unsigned int x1, y1, x2, y2;
    
        x1 = x2 = 320;
        y1 = y2 = 0;
    
        for(iterate = 0; iterate < 10000; iterate++)
        {
            Direct = random(3);
            
            if(Direct == 0)
            {
                x1 = (x2 + 320) / 2;
                y1 = (y2 + 0) / 2;    
            }
            else if(Direct == 1)
            {
                x1 = (x2 + 0) / 2;
                y1 = (y2 + 480) / 2;
            }
            else if(Direct == 2)
            {
                x1 = (x2 + 640) / 2;    
                y1 = (y2 + 480) / 2;
            }
            putpixel(x1, y1, WHITE);
    
            x2 = x1;
            y2 = y1;
        }
    }
    I really appreciate it.
    Last edited by Nancy Franklin; 10-31-2011 at 02:50 PM.

  6. #6
    Registered User Nancy Franklin's Avatar
    Join Date
    Sep 2011
    Posts
    15
    Ok, I got the program working great. It generates the fractal (with color now!), and saves it as a Targa file named "sanMarco.tga". Now, how can I make it automatically open after it is generated? My teacher will be using an Unbuntu virtual machine on his Mac. And I don't want to make him download any libraries that he doesn't already have. (And I have tried web-searches on this, with no useful results for C++/ubuntu)

    Here is the code that he will run- it uses "fractal" and its file-writing method:

    Code:
    using std::memset;
    
    using namespace fractals;
    using namespace std;
    int main()
    {
        // san marco fractal
    
        julia<float> j(400, 400);
        j.c = std::complex<float>(-3.0f / 4.0f, 0);
        //j.c = std::complex<float>(-3.0f / 5.0f, 0);
        j.render(-1.5, 1.5, 3, 3);
        std::ofstream os("sanmarco.tga", std::ios_base::binary);
        cout << "Fractal generated. It is stored in 'sanmarco.tga' in your directory. \n";
    //";
        os << j;
        return 0;
    }
    Here is the part of "fractal" that will be used to generate the .tga file:

    Code:
    template<class _Ty>
    
            std::ostream& operator<<(std::ostream& _O, const fractal<_Ty>& _F)
    
            {unsigned short _W = _F.width(), _H = _F.height();
    
            _O.write("\0\0\2\0\0\0\0\0\0\0\0\0", sizeof(char) * 12);
    
            _O.write((const char *)&_W, sizeof(unsigned short));
    
            _O.write((const char *)&_H, sizeof(unsigned short));
    
            _O.write("\x18\x20", sizeof(char) * 2);
    
            unsigned char *_P = _F.data(), _C[3];
    
            for (unsigned _I = 0; _I < _W * _H * 3U; _I += 3)
    
                    {_C[0] = _P[_I + 2], _C[1] = _P[_I + 1], _C[2] = _P[_I];
    
                    _O.write((const char *)_C, 3 * sizeof(unsigned char));
    
            }
    
            return _O; }
    
    
    
    }    // namespace
    Last edited by Nancy Franklin; 11-30-2011 at 03:44 PM. Reason: to avoid STFW

  7. #7
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,274
    The TGA format may not have a viewer available. The PPM format is also very easy to generate and is much more likely to be viewable on stock Ubuntu. Example function which saves in PPM format:

    Code:
    template<class _Ty>
    std::ostream& operator<<(std::ostream& _O, const fractal<_Ty>& _F)
    {
        _O << "P6\n" << _F.width() << " " << _F.height() << " 255\n";
        _O.write((char *)_F.data(), 3 * _F.width() * _F.height());
        return _O;
    }
    (not tested)
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  8. #8
    Registered User Nancy Franklin's Avatar
    Join Date
    Sep 2011
    Posts
    15
    Thanks, brewbuck, but I'm a bit reluctant to use a new format. My teacher gave permission to copy/use that file-writing method, it works fine, but I don't fully understand how it works, so I wouldn't know what to change.

    Using the teacher's Ubuntu virtual machine, I can open the .tga file in the "Image Viewer" application by double-clicking on the picture. Is there a way for my C++ file to open "Image Viewer" and display the new fractal image in "Image Viewer"?

    Quote Originally Posted by brewbuck View Post
    The TGA format may not have a viewer available. The PPM format is also very easy to generate and is much more likely to be viewable on stock Ubuntu. Example function which saves in PPM format:

    Code:
    template<class _Ty>
    std::ostream& operator<<(std::ostream& _O, const fractal<_Ty>& _F)
    {
        _O << "P6\n" << _F.width() << " " << _F.height() << " 255\n";
        _O.write((char *)_F.data(), 3 * _F.width() * _F.height());
        return _O;
    }
    (not tested)

  9. #9
    Registered User Nancy Franklin's Avatar
    Join Date
    Sep 2011
    Posts
    15
    Guys, I still can't figure out a way for my C++ file to open Ubuntu's "Image Viewer" and display the newly-generated .tga fractal image in it. Can someone help me do that, please?

    (nothing from Google is helping. )
    Last edited by Nancy Franklin; 12-04-2011 at 09:08 PM.

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,834
    Assuming viewer is the name of the program, then something like

    string runit = "viewer " + filename;
    system( runit.c_str() );


    might just make something happen.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  11. #11
    Registered User Nancy Franklin's Avatar
    Join Date
    Sep 2011
    Posts
    15
    Thank you, Salem! That worked. Turned out, my "image viewer" is called 'Eye of Gnome', and its manual says to call it 'eog' in the terminal. So this works:
    string runit = "eog infinitiesRed.tga";
    system( runit.c_str() );

    With this, my freestyle semester project is done! It generates the fractal and opens it in EoG. Thanks for all the help, guys!!

    I am going to post my code here, for any future fractal-seekers.

    The fractal .cpp file (requires the fractal2 namespace):
    Code:
    #include "fractal2"
    #include <stdlib.h>
    #include <stdio.h>
    #include <iostream>
    #include <sstream>
    #include <string>
    #include <cassert>
    #include <fstream>
    #include <cstring>
    using std::memset;
    
    using namespace fractals;
    using namespace std;
    int main()
    {
        julia<float> j(800, 800); //image size: width, height. This stretches the image.
        j.c = std::complex<float>(-3.0f / 2.0f, 0); //if #2=1: eyes. 
    /*
    shapes(substitute in line above): original: (-3.0 / 4.0, 0)// cross: (-5.0, 3.0, 0) or (-3, 2.0, 0) // spikes: (-3, 2.5, 0)
    // infinities: (-3, 1.5, 0) //done: (-3.0f / 2.0f, 0)
    */
    
    
        j.render(-0.55, 0.55, 1.1, 1.1); //cross done: -0.55, 0.55, 1.1, 1.1
    //camera angle. (x,y,w,h) increasing value #3 extends image to right. If its greater than 3, the image is too far right to view
    //original: (-1.5, 1.5, 3, 3) // cross: (-1.0, 1.0, 2, 2) or (-1.5, 1.5, 3, 3)
    // spikes: (-1.0, 1, 2, 2) // infinities: (-1, 1,2,2)
    
        std::ofstream os("shuriken.tga", std::ios_base::binary);
        cout << "Fractal generated. It is stored in 'shuriken.tga' in your directory. \n";
    //";
        os << j;
    string runit = "eog shuriken.tga";
    system( runit.c_str() );
        return 0;
    }
    this is the fractal2 namespace:
    Code:
    // fractal header
    
    #ifndef _FRACTAL_
    
    #define _FRACTAL_
    
    #include <complex>
    
    #include <ostream>
    
    #include <cstring>
    
    using std::memset;
    
    
    
    namespace fractals {
    
            // TEMPLATE CLASS fractal. This defines "fractals", which each .cpp file will use
    
    template<class _Ty> //this template was written by Borland. It contains the loops that generate the fractal pattern, using the given x and y positions
    
            class fractal {
    
    public:
    
            fractal(unsigned short _W, unsigned short _H) :
    
                    _Width(_W), _Height(_H), iterations(256)
    
                    {_M = new unsigned char[_W * _H * 3]; //_M is the data, _W is new width, _H is new height
    
                    ::memset(_M, 0, sizeof(unsigned char) * _W * _H * 3); }
    
            fractal(const fractal& _X) : _M(0)
    
                    {_Assign(_X); } //uses protected: void _Assign(const fractal& _X)
    
            ~fractal()
    
                    {delete[] _M; }
    
            unsigned short width() const
    
                    {return _Width; } //getWidth
    
            unsigned short height() const
    
                    {return _Height; } //getHeight
    
            unsigned char *data() const
    
                    {return _M; } //getData
    
            unsigned iterations;
    
            void render(_Ty _X0, _Ty _Y0, _Ty _W, _Ty _H) //these loops use position variables X0 and Y0, as well as width and height
    
                    {for (unsigned short _Y = 0; _Y < _Height; _Y++)
    
                            for (unsigned short _X = 0; _X < _Width; _X++)
    
                                    {_Ty _Cx = _X0 + (_X * _W / _Width);
    
                                    _Ty _Cy = _Y0 - (_Y * _H / _Height);
    
                                    init(_Cx, _Cy);
    
                                    unsigned _N = (iterations <= 256) ?
    
                                            iterations : 256;
    
                                    unsigned _I = 0;
    
                                    for (; _I < _N; _I++)
    
                                            {if (test())
    
                                                break;
    
                                            next(); }
    
                                    unsigned char _R = 0, _G = 0, _B = 0;
    
                                    color(_I, _R, _G, _B);
    
                                    unsigned char *_P = _M + (_Y *
    
                                            (_Width * 3) + (_X * 3));
    
                                    *_P++ = _R, *_P++ = _G, *_P = _B;
    
                                    _B=_B+_I;
    
                                    }}
    
    protected:
    
            void _Assign(const fractal& _X)
    
                    {delete[] _M;
    
                    _Width = _X._Width;
    
                    _Height = _X._Height;
    
                    _M = new unsigned char[_Width * _Height * 3];
    
                    ::memset(_M, 0, sizeof(unsigned char) * _Width * _Height * 3); }
    
            _Ty distance(const std::complex<_Ty>& _C)
    
                    {return ::sqrt(_C.real() * _C.real() + 
    
                    _C.imag() * _C.imag()); }
    
            virtual void init(_Ty _X, _Ty _Y) = 0;
    
            virtual bool test() = 0;
    
            virtual void color(unsigned _N, unsigned char& _R,
    
                    unsigned char& _G, unsigned char& _B) = 0;
    
            virtual void next() = 0;
    
            unsigned short _Width, _Height;
    
            unsigned char *_M;
    
            };
    
            // TEMPLATE CLASS mandelbrot            //this Mandelbrot class generated Borland's original fractal. I am utilizing the Julia class.
    
    /*
    
    template<class _Ty>
    
            class mandelbrot : public fractal<_Ty> {
    
    public:
    
            mandelbrot(unsigned short _W, unsigned short _H) :
    
                    fractal<_Ty>(_W, _H) {}
    
            mandelbrot(const mandelbrot& _X) : fractal<_Ty>(_X)
    
                    {_Z = _X._Z, _C = _X._C; }
    
            mandelbrot& operator=(const mandelbrot& _X)
    
                    {if (this == &_X) return (*this);
    
                    _Assign(_X);
    
                    _Z = _X._Z, _C = _X._C;
    
                    return (*this); }
    
    //protected:
    
            virtual void init(_Ty _X, _Ty _Y)
    
                    {_C = std::complex<_Ty>(_X, _Y);
    
                    _Z = std::complex<_Ty>(0.0, 0.0); }
    
            virtual bool test()
    
                    {return (distance(_Z) > 2.0); }
    
            virtual void color(unsigned _N, unsigned char& _R,
    
                    unsigned char& _G, unsigned char& _B)
    
                    {_R = _G = _B = _N; 
    
                        //_B=70;
    
                        //_R=70;
    
                        //_B= (_R*2);
    
                    }
    
            virtual void next()
    
                    {std::complex<_Ty> _T = _Z * _Z;            // keep borland happy
    
                    _T += _C; _Z = _T; }
    
            std::complex<_Ty> _Z, _C;
    
            };
    
    */
    
            // TEMPLATE CLASS julia
    
    template<class _Ty>                                    //begin Julia class, based on Mandelbrot class
    
            class julia : public fractal<_Ty> {
    
    public:
    
            std::complex<_Ty> c;
    
            julia(unsigned short _W, unsigned short _H) :
    
                    fractal<_Ty>(_W, _H), c(0.5, 0.5) {}
    
            julia(const julia& _X) : fractal<_Ty>(_X)
    
                    {_Z = _X._Z, c = _X.c; }
    
            julia& operator=(const julia& _X)
    
                    {if (this == &_X) return (*this);
    
                    _Assign(_X);
    
                    _Z = _X._Z, c = _X.c;
    
                    return (*this); }
    
    //protected: [I'm making drastic changes here, specifically color]
    
            virtual void init(_Ty _X, _Ty _Y)
    
                    {_Z = std::complex<_Ty>(_X, _Y); }
    
            virtual bool test()
    
                    {return (distance(_Z) > 2.0); }
    
            virtual void color(unsigned _N, unsigned char& _R, //my biggest changes were in this method- creating the color pattern
    
                    unsigned char& _G, unsigned char& _B)
    
                    {_R = _G = _B = _N;                 //in Borland's version, only this line was in "virtual void color"
    
    //when all 3 color values = N, Borland's non-existant color scheme creates the DOOM fractal, which is almost completely black.
    
    /* begin N's value-dependent scheme:    if(_B>1 && _B<240){_G=255;} 
    
                        if(_R<185){_G=_R*2;}
    
                        if(_B>200){_R=255; _G=0;} 
    
                        if(_G>3 && _G<190){_B=_G*2;} 
    
    */                    //if(_B=120){_R=100; _G=0;}
    
                        //if(_R>0 && _R<50){_R=255; _G=0;} 
    
                        //if(_B>1 && _B<240){_G=255;} 
    
                        /*******************
    //being N's red-dependent color scheme:
    
                         _B=_B+30; _R=_R+40; 
    
                        if(_B>3 && _B<60){_R=_B*3;}
    
                        if(_R>3 && _R<190){_B=_R*2;}
    
                         if(_R>50 && _R<80){_B=255; _G=0;}
    
                         if(_R>80 && _R<120){_B=100; _G=0;}
    
                        if(_R>120){_R=255;}
    
                        //*******************/
    
                        //if(_G=0){_R=150; _B=150; _G++;} 
    
    /*
    //begin shaded red/blue scheme, finished. It uses green as a counter, not a color.
    
                        _G=_G+1; _R=255-(_G*15);
    
                        if(_R>190 && _R<210){_B=130;_R=50;}//15-17
    
                        if(_R%4==0){_B=100;}
    
                        if(_R>200){_B=180;_R=(255-_R);}
    
                        if(_G%5==0){_B=200; _R=0;}
    
                        if(_B==0 && _R==0){_B=150; _R=150;}
    
    */
    //begin shaded green/blue scheme, finished. It uses red as a counter, not a color.
    
    
                        _R=_R+1; _G=255-(_R*15); //the brightest green value occurs when red is at its lowest, near the beginning
    
                        if(_G>190 && _G<210){_B=130;_G=50;}//15-17
    
                        if(_G%4==0){_B=100;} //creates a pattern for blue to appear
    
                        if(_G>200){_B=180;_G=(255-_G);} //a brighter blue, and various shades of green
    
                        if(_R%5==0){_B=200; _G=0;} //creates a pattern for bright blue to appear
    
                        if(_B==0 && _G==0){_B=150; _G=150;} //prevents black at 0 values
    
    
    
                     }
    
    
    
            virtual void next()
    
                    {std::complex<_Ty> _T = _Z * _Z;            // keep borland happy
    
                    _T += c; _Z = _T; }
    
            std::complex<_Ty> _Z;
    
            };
    
            // TEMPLATE CLASS cactus
    
    /*
    
    template<class _Ty>                    //this is Borland's 'cactus' class. I used it as reference on how to design a fractal that uses this.
    
            class cactus : public fractal<_Ty> {    //I learned from this 'cactus' structure, but did not use it for my Shiruken fractals
    
    public:
    
            cactus(unsigned short _W, unsigned short _H) :
    
                    fractal<_Ty>(_W, _H) {}
    
            cactus(const cactus& _X) : fractal<_Ty>(_X)
    
                    {_Z = _X._Z, _Z0 = _X._Z0; }
    
            cactus& operator=(const cactus& _X)
    
                    {if (this == &_X) return (*this);
    
                    _Assign(_X);
    
                    _Z = _X._Z, _Z0 = _X._Z0;
    
                    return (*this); }
    
    protected:
    
            virtual void init(_Ty _X, _Ty _Y)
    
                    {_Z = _Z0 = std::complex<_Ty>(_X, _Y); }
    
            virtual bool test()
    
                    {return (distance(_Z) > 2.0); }
    
            virtual void color(unsigned _N, unsigned char& _R,
    
                    unsigned char& _G, unsigned char& _B)
    
                    {_R = _G = _B = _N;
    
                        _R++; _G=_G+20; _B++;
    
                        if(_B>10 && _B<190){_G=255;}
    
                        if(_R<195){_R=_R+60;}
    
                        if(_G>23 && _G<30){_B=150;}
    
    
    
                     }
    
            virtual void next()
    
                    {std::complex<_Ty> _T = _Z * _Z * _Z;        // keep borland happy
    
                    _T += (_Z0 - std::complex<_Ty>(1, 0)) * _Z;
    
                    _Z = _T - _Z0; }
    
            std::complex<_Ty> _Z, _Z0;
    
            };
    
            // TEMPLATE FUNCTION operator<<
    
    */
    
    
    
    template<class _Ty> //takes input of "filename.format", and type                //this section writes the .tga file
    
            std::ostream& operator<<(std::ostream& _O, const fractal<_Ty>& _F)
    
            {unsigned short _W = _F.width(), _H = _F.height();
    
            _O.write("\0\0\2\0\0\0\0\0\0\0\0\0", sizeof(char) * 12); //begin writing
    
            _O.write((const char *)&_W, sizeof(unsigned short)); //set width
    
            _O.write((const char *)&_H, sizeof(unsigned short)); //set height
    
            _O.write("\x18\x20", sizeof(char) * 2);
    
            unsigned char *_P = _F.data(), _C[3];
    
            for (unsigned _I = 0; _I < _W * _H * 3U; _I += 3) //begin loop to draw fractal
    
                    {_C[0] = _P[_I + 2], _C[1] = _P[_I + 1], _C[2] = _P[_I]; //fills in values for _C[]. The 3 values are RGB.
    
                    _O.write((const char *)_C, 3 * sizeof(unsigned char)); //write char to file.
    
            }
    
            return _O; } //end template class ty
    
    
    
    }    // namespace
    
    
    
    #endif /* _FRACTAL_ */
    
    
    
    /*
    
     * http://home.tiscali.be/zoetrope
    
     */
    Last edited by Nancy Franklin; 12-05-2011 at 09:16 PM. Reason: adding complete version for future viewers
    Salem likes this.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Fractal Generator
    By darren78 in forum C++ Programming
    Replies: 4
    Last Post: 10-12-2010, 10:01 AM
  2. 2D Fractal Terrain
    By TheSpook in forum C++ Programming
    Replies: 15
    Last Post: 01-14-2010, 10:28 PM
  3. fractal maker
    By arjunajay in forum C++ Programming
    Replies: 2
    Last Post: 07-04-2005, 08:08 AM
  4. Fractal Graphs, anyone? (another AI question)
    By sean in forum A Brief History of Cprogramming.com
    Replies: 2
    Last Post: 03-03-2003, 12:07 PM
  5. Fractal Operating System
    By DiskJunky in forum A Brief History of Cprogramming.com
    Replies: 8
    Last Post: 07-11-2002, 02:17 AM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21