Yeah I can try to use arrays but it's hard to do, I am not as expert by Jesse
Anyway I will not transpose this formula tomorrow, so let me take my time. If you want to add something you are welcome!
For example, I need to know exactly
what parameters should be user defined before beginning
Ok..
The formula has very few params, so later I will unwind the loops and rewrite it in a more clearly way..
Here is also another formula..this uses the vertices of a Icosahedron, but I think that you can hardly use it, since it uses 13 transformations and it requires a double type (if you use floats, some strange box shapes appers).. anyways, here is it:
Initializations:
const float Icosahedron[]={
0.000f, 0.000f, 1.000f,
0.894f, 0.000f, 0.447f,
0.276f, 0.851f, 0.447f,
-0.724f, 0.526f, 0.447f,
-0.724f, -0.526f, 0.447f,
0.276f, -0.851f, 0.447f,
0.724f, 0.526f, -0.447f,
-0.276f, 0.851f, -0.447f,
-0.894f, 0.000f, -0.447f,
-0.276f, -0.851f, -0.447f,
0.724f, -0.526f, -0.447f,
0.000f, 0.000f, -1.000
};
float Ta[15],Tb[15],Tc[15],Td[15];
const float disx=Icosahedron[0]-Icosahedron[3];
const float disy=Icosahedron[1]-Icosahedron[4];
const float disz=Icosahedron[2]-Icosahedron[5];
const float tdistance=sqrt(disx*disx+disy*disy+disz*disz)/2;//calc the size of the transformation
const float variation=1.05;//make the transformation a little bigger, so they intersect.
for (int tr=0; tr<13;tr++){
if (tr<12){
//Icosahedron corners
Ta[tr]=Icosahedron[tr*3];
Tb[tr]=Icosahedron[tr*3+1];
Tc[tr]=Icosahedron[tr*3+2];
Td[tr]=tdistance*variation;
} else {
//central transformation
Ta[tr]=0;
Tb[tr]=0;
Tc[tr]=0;
Td[tr]=(1-tdistance)*variation;
}
Td[tr]=Td[tr]*Td[tr];
}
And the formula:
bool Icosa(double x, double y, double z, int iter)
{
if(sqrt(x*x+y*y+z*z)>1.1)return false; //filter unneresary areas, must be removed for other sets
bool escape;//if the orbit escapes, it returns false, else it return true..
int ic;
double X1[13],Y1[13],Z1[13],DST[13];//temporal storage of the iteration values and distances
for (ic=0;ic<iter;ic++){
for (int tr=0;tr<13;tr++){
const double ax=x - Ta[tr];
const double ay=y - Tb[tr];
const double az=z - Tc[tr];
const double radius=Td[tr]/(ax*ax+ay*ay+az*az);
X1[tr] = Ta[tr] + (x - Ta[tr])*radius;
Y1[tr] = Tb[tr] + (y - Tb[tr])*radius;
Z1[tr]= Tc[tr] + (z - Tc[tr])*radius;
//Method 1 Centered at Origin
//DST[tr]=X1[tr]*X1[tr]+Y1[tr]*Y1[tr]+Z1[tr]*Z1[tr];
//Method 2 General, using transformation centers
DST[tr]=(Ta[tr]-X1[tr])*(Ta[tr]-X1[tr])+(Tb[tr]-Y1[tr])*(Tb[tr]-Y1[tr])+(Tc[tr]-Z1[tr])*(Tc[tr]-Z1[tr]);
}
int tr1=0;
double rdst=0;
//select the transformation..the most distant one wins
for (int tr=0;tr<13;tr++){
if (rdst<DST[tr]){
rdst=DST[tr];
tr1=tr;
}
}
x=X1[tr1];
y=Y1[tr1];
z=Z1[tr1];
if(1.5<DST[tr1])break;
}
if(ic<iter && ic>1)escape=true;else escape=false;
return escape;
}
call it by:
bool Icosa(x, y,z, 16); //16 iterations
This formula is very interesting and beautiful, saddly my renders are not very good, but the internal structure is very fine..
I have included the renders of the two methods.