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
*/