```
#include <iostream>
#include <cmath>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <ctime>
using namespace std;
typedef long double LD;
class IFS
{
public:
IFS();
IFS(const LD&, const LD&, const LD&,
const LD&, const LD&, const LD&,
const LD&, const LD&, const LD&);
bool is_valid() const; //valid object?
LD set_A (int, const LD&);
LD get_A (LD)const;
void eval(vector<LD>&, vector<LD>&);
private:
vector <LD> matrix;
bool valid;
};
ostream& operator<<(ostream&, const IFS&);
IFS operator*(const IFS&, vector<int>);
IFS operator*(const IFS&, const IFS&);
IFS operator+(const IFS&, const IFS&);
IFS operator-(const IFS&, const IFS&);
/****************************************************************************
The various member functions
****************************************************************************/
int main ()
{
/* //tests
IFS f(0.0, 1.0, 2.0, 0.0, 3.0, 2.0, 0.0, 0.0, 1.0);
cout << f << endl;
if(f.is_valid())
cout << "f(x) is a valid object." << endl;
else
cout << "f(x) is not valid" << endl; */
std::vector<LD> a(1);
a[0] = 0.0;
std::vector<LD> b(1);
b[0] = 0.0;
/*sierpinski triangle/*
/*IFS f_1(0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 1.0);
IFS f_2(0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 1.0);
IFS f_3(0.5, 0.0, 0.25, 0.0, 0.5, 0.4, 0.0, 0.0, 1.0);
srand((unsigned)time(0));
int number ;
int k;
cout << "Please enter the number of transformations desired: ";
cin >> k;
for (int j=1; j<=k; j++)
{
number = rand()%3+1;
if (number == 1)
{
f_1.eval(a, b);}
else if (number == 2)
{
f_2.eval(a, b);}
else
{
f_3.eval(a, b);}
cout << a[j] << '\t' << b[j] << endl;
} */
/*fern*/
/*
IFS f_1(0.14, 0.01, -0.08, 0.0, 0.51, -1.31, 0.0, 0.0, 1.0);
IFS f_2(0.43, 0.52, 1.49, -0.45, 0.5, -0.75, 0.0, 0.0, 1.0);
IFS f_3(0.45, -0.49, -1.62, 0.47, 0.47, -0.75, 0.0, 0.0, 1.0);
IFS f_4(0.49, 0.0, 0.02, 0.0, 0.51, 1.62, 0.0, 0.0, 1.0);
srand((unsigned)time(0));
int number ;
int k;
cout << "Please enter the number of transformations required: ";
cin >> k;
for (int j=1; j<=k; j++)
{
number = rand()%100+1;
if (number<= 10)
{
f_1.eval(a, b);}
else if ((number >10) && (number<=45))
{
f_2.eval(a, b);}
else if ((number>45) && (number<=70))
{
f_3.eval(a, b);}
else
{
f_4.eval(a, b);
}
cout << a[j] << '\t' << b[j] << endl;
}
*/
/*spleenwortfern*/
IFS f_1(0.0, 0.00, 0.00, 0.0, 0.16, 0.0, 0.0, 0.0, 1.0);
IFS f_2(0.85, 0.04, 0.0, -0.04, 0.85, 1.6, 0.0, 0.0, 1.0);
IFS f_3(0.2, -0.26, 0, 0.23, 0.22, 1.6, 0.0, 0.0, 1.0);
IFS f_4(-0.15, 0.28, 0.0, 0.26, 0.24, 0.44, 0.0, 0.0, 1.0);
srand((unsigned)time(0));
int number ;
int k;
cout << "Please enter the number of transformations desired:";
cin >> k;
for (int j=1; j<=k; j++)
{
number = rand()%100+1;
if (number<= 10)
{
f_1.eval(a, b);}
else if ((number >10) && (number<=85))
{
f_2.eval(a, b);}
else if ((number>85) && (number<=92))
{
f_3.eval(a, b);}
else
{
f_4.eval(a, b);
}
cout << a[j] << '\t' << b[j] << endl;
}
return 0;
}
// Constructors
IFS::IFS()
{
// No argument constructor
matrix.push_back(1.0);
matrix.push_back(0.0);
matrix.push_back(0.0);
matrix.push_back(0.0);
matrix.push_back(1.0);
matrix.push_back(0.0);
matrix.push_back(0.0);
matrix.push_back(0.0);
matrix.push_back(1.0);
}
IFS::IFS(const LD& xx, const LD& xy, const LD& xz, const LD& yx, const LD& yy, const LD& yz,
const LD& zx, const LD& zy, const LD& zz)
{
// Nine argument constructor
matrix.push_back(xx);
matrix.push_back(xy);
matrix.push_back(xz);
matrix.push_back(yx);
matrix.push_back(yy);
matrix.push_back(yz);
matrix.push_back(zx);
matrix.push_back(zy);
matrix.push_back(zz);
if (zx!=0 || zy!=0 || zz!=1)
valid = false;
}
bool IFS::is_valid()const
{
return valid;
}
LD IFS::set_A(int A, const LD& m)
{
if (A<0 || A>8) //ensure A is valid
A=A%9;
matrix[A]=m;
if (matrix[6]!=0 || matrix[7]!=0 || matrix[8]!=1)
valid = false;
else
valid = true;
}
LD IFS::get_A(LD A)const
{
return matrix[A];
}
ostream& operator<<(ostream& os, const IFS& f)
{
os << f.get_A(0) << " " << f.get_A(1)<< " " << f.get_A(2) << '\n' << f.get_A(3) << " " << f.get_A(4) << " "
<< f.get_A(5) << '\n' << f.get_A(6) << " " << f.get_A(7) << " "<< f.get_A(8)<< " X";
return os;
}
void IFS::eval(vector<LD>&a, vector<LD>&b) // to find product of 3x3 matrix and (x,y,1)
{
int m = a.size() - 1;
a.push_back(matrix[0]*a[m] + matrix[1]*b[m] + matrix[2]);
b.push_back(matrix[3]*a[m] + matrix[4]*b[m] + matrix[5]);
}
// The next three constructors are not necessary for the transformations performed here.
// However, there is potential to generate new interesting fractals by using products of affine transformations etc.
IFS operator*(const IFS& f, const IFS& g)
{
int xx = f.get_A(0)*g.get_A(0) + f.get_A(1)*g.get_A(3) + f.get_A(2)*g.get_A(6);
int xy = f.get_A(0)*g.get_A(1) + f.get_A(1)*g.get_A(4) + f.get_A(2)*g.get_A(7);
int xz = f.get_A(0)*g.get_A(2) + f.get_A(1)*g.get_A(5) + f.get_A(2)*g.get_A(8);
int yx = f.get_A(3)*g.get_A(0) + f.get_A(4)*g.get_A(3) + f.get_A(5)*g.get_A(6);
int yy = f.get_A(3)*g.get_A(1) + f.get_A(4)*g.get_A(4) + f.get_A(5)*g.get_A(7);
int yz = f.get_A(3)*g.get_A(2) + f.get_A(4)*g.get_A(5) + f.get_A(5)*g.get_A(8);
int zx = f.get_A(6)*g.get_A(0) + f.get_A(7)*g.get_A(3) + f.get_A(8)*g.get_A(6);
int zy = f.get_A(6)*g.get_A(1) + f.get_A(7)*g.get_A(4) + f.get_A(8)*g.get_A(7);
int zz = f.get_A(6)*g.get_A(2) + f.get_A(7)*g.get_A(5) + f.get_A(8)*g.get_A(8);
return IFS(xx,xy,xz,yx,yy,yz,zx,zy,zz);
}
IFS operator+(const IFS& f, const IFS& g)
{
int xx = f.get_A(0)+g.get_A(0);
int xy = f.get_A(1)+g.get_A(1);
int xz = f.get_A(2)+g.get_A(2);
int yx = f.get_A(3)+g.get_A(3);
int yy = f.get_A(4)+g.get_A(4);
int yz = f.get_A(5)+g.get_A(5);
int zx = f.get_A(6)+g.get_A(6);
int zy = f.get_A(7)+g.get_A(7);
int zz = f.get_A(8)+g.get_A(8);
return IFS(xx,xy,xz,yx,yy,yz,zx,zy,zz);
}
IFS operator-(const IFS& f, const IFS& g)
{
int xx = f.get_A(0)-g.get_A(0);
int xy = f.get_A(1)-g.get_A(1);
int xz = f.get_A(2)-g.get_A(2);
int yx = f.get_A(3)-g.get_A(3);
int yy = f.get_A(4)-g.get_A(4);
int yz = f.get_A(5)-g.get_A(5);
int zx = f.get_A(6)-g.get_A(6);
int zy = f.get_A(7)-g.get_A(7);
int zz = f.get_A(8)-g.get_A(8);
return IFS(xx,xy,xz,yx,yy,yz,zx,zy,zz);
}
```