| | |
 |
| Release 4.0 |
|
|
ChaosPro Formula Database |
| | | | Name | Malinovsky3D.cfm | | Path | /Compiler/MalinovskyFract/ | | Type | Formula | | Size | 57 KB | | Owner | Edgar Malinovsky | | Last Modified: | 18 Jul 2017 | | | |
|
GilgameshHead (quaternion) {
//18.12.2011. by Edgars Malinovskis.
//Based on mandelbar.
//The fractal is interferance pattern of 4 mandelbrot sets,
//who in 3D are (revolution) wave surfaces.
//You may redistribute this algorithm, modify, derivate or use comercialy as you wish as long as you give proper credits.
// 09.03.2012. a bitt simplification of code + full power UV instead of just more rough surfaces.
// 16.06.2012. + cuttings along Axis.
// 11.10.2012. iterate altz instead of z, so that fractal would work in 2D.
// in 2D z is complex, but it uses quaternion math. Not very usefull, but still nice to have.
parameter real bailout, coef1, coef2, coef3, coef4;
parameter int settype, powers;
parameter bool testInverted, testNumbers, depthincreaser;
parameter quaternion julia, perturb;
quaternion C, altz;
parameter real coefVector;
// block for cutout.
parameter int iscuted;
parameter quaternion Ctaxis;
real autobailout, coordX, coordY, coordZ;
void init(void)
{
if (testInverted==true && settype=="Julia Set")
{
altz = recip(pixel);
C = julia;
}
else if (settype=="Julia Set")
{
altz = pixel;
C = julia;
}
else if (testInverted==true && settype=="Mandelbrot Set")
{
altz = perturb;
C= recip(pixel);
}
else
{
altz=perturb;
C=pixel;
}
//block for cutout. An unelegant code.
autobailout=0;
coordX= real(Ctaxis);
coordY= imag(Ctaxis);
coordZ= part_j(Ctaxis);
if (iscuted == "Larger than")
{
if (coordX!=0 && real(pixel) > coordX )
{
autobailout= bailout +1;
}
if (coordY!=0 && imag(pixel) > coordY )
{
autobailout= bailout +1;
}
if (coordZ!=0 && part_j(pixel) > coordZ )
{
autobailout= bailout +1;
}
}
else if (iscuted == "Smaller than")
{
if (coordX!=0 && real(pixel) < coordX )
{
autobailout= bailout +1;
}
if (coordY!=0 && imag(pixel) < coordY )
{
autobailout= bailout +1;
}
if (coordZ!=0 && part_j(pixel) < coordZ )
{
autobailout= bailout +1;
}
}
}
void loop(void)
{
if (testNumbers==true)
{
//manipulate numbers so that x^2 >< y^2 >< z^2 generating flat mandelbrot
altz= quaternion ( real(altz) , imag(altz), part_j(altz) + part_k(altz), 0.5*part_k(altz) - part_j(altz) );
}
//Matrix of -> z^pow and numbers: real, imag, j, k. All parts are in each column and row.
if (powers=="3,3,3,3")
{
altz= altz*altz*altz+C+altz*coef1;
altz= quaternion ( imag(altz) , real(altz), part_k(altz), part_j(altz) );
altz= altz*altz*altz+altz*coef2;
altz= quaternion ( part_k(altz) , part_j(altz), imag(altz), real(altz) ) ;
altz= altz*altz*altz+altz*coef3;
altz= quaternion ( part_j(altz) , imag(altz), real(altz), part_k(altz) ) ;
altz= altz*altz*altz+altz*coef4;
altz= quaternion ( real(altz) , part_k(altz), part_j(altz), imag(altz) );
}
else if (powers=="4,4,4,4")
{
altz= sqr(sqr(altz))+C+altz*coef1;
altz= quaternion ( imag(altz) , real(altz), part_k(altz), part_j(altz) );
altz= sqr(sqr(altz))+altz*coef2;
altz= quaternion ( part_k(altz) , part_j(altz), imag(altz), real(altz) ) ;
altz= sqr(sqr(altz))+altz*coef3;
altz= quaternion ( part_j(altz) , imag(altz), real(altz), part_k(altz) ) ;
altz= sqr(sqr(altz))+altz*coef4;
altz= quaternion ( real(altz) , part_k(altz), part_j(altz), imag(altz) );
}
else if (powers=="5,4,2,3")
{
altz= sqr(sqr(altz))*altz+C+altz*coef1;
altz= quaternion ( imag(altz) , real(altz), part_k(altz), part_j(altz) );
altz= sqr(sqr(altz))+altz*coef2;
altz= quaternion ( part_k(altz) , part_j(altz), imag(altz), real(altz) ) ;
altz= sqr(altz)+altz*coef3;
altz= quaternion ( part_j(altz) , imag(altz), real(altz), part_k(altz) ) ;
altz= altz*altz*altz+altz*coef4;
altz= quaternion ( real(altz) , part_k(altz), part_j(altz), imag(altz) );
}
else if (powers=="5,5,5,5")
{
altz= sqr(sqr(altz))*altz+C+altz*coef1;
altz= quaternion ( imag(altz) , real(altz), part_k(altz), part_j(altz) );
altz= sqr(sqr(altz))*altz+altz*coef2;
altz= quaternion ( part_k(altz) , part_j(altz), imag(altz), real(altz) ) ;
altz= sqr(sqr(altz))*altz+altz*coef3;
altz= quaternion ( part_j(altz) , imag(altz), real(altz), part_k(altz) ) ;
altz= sqr(sqr(altz))*altz+altz*coef4;
altz= quaternion ( real(altz) , part_k(altz), part_j(altz), imag(altz) );
}
else if (powers=="2,2,2,2")
{
altz= sqr(altz)+C+altz*coef1;
altz= quaternion ( imag(altz) , real(altz), part_k(altz), part_j(altz) );
altz= sqr(altz)+altz*coef2;
altz= quaternion ( part_k(altz) , part_j(altz), imag(altz), real(altz) ) ;
altz= sqr(altz)+altz*coef3;
altz= quaternion ( part_j(altz) , imag(altz), real(altz), part_k(altz) ) ;
altz= sqr(altz)+altz*coef4;
altz= quaternion ( real(altz) , part_k(altz), part_j(altz), imag(altz) );
}
//Unit vector addition formula. First were implemented here.
if(depthincreaser==true)
{
if (cabs(altz)!=0)
{
altz=altz/cabs(altz)*coefVector +altz;
}
else
{
altz=altz + 1.0E-15;
}
}
z=altz;
}
bool bailout(void)
{
return( |altz| + autobailout < bailout);
}
void description(void)
{
this.title = "Gilgamesh Head (Quaternion)";
this.helpfile="http://www.fractalforums.com/3d-fractal-generation/gilgamesh-head-the-3d-mandelbulb-like-fractal/";
bailout.caption = "Bailout Value";
bailout.default = 12.0;
bailout.min = 0.5;
bailout.hint = "Defines the bailout radius: If pixel falls out of it, the iteration stops. Larger number increases details";
settype.caption = "Set type";
settype.enum = "Mandelbrot Set\nJulia Set";
settype.default = 0;
testInverted.caption="Inverted 'Cave' Set";
testInverted.default=false;
testNumbers.caption="-Surface by x^2 >< y^2 >< z^2";
testNumbers.default=false;
julia.caption = "Julia Parameter";
julia.default = (-0.73,0.3,-0.5,0.3);
julia.hint = "Different values create different Julia Sets.";
julia.visible = (settype=="Julia Set");
separator.label1.caption = "Distorts basic shape by modifying 1 of 4 m-brots.";
coef1.caption = "K of z=z^n+K*z+c";
coef1.default = 0;
coef1.hint = "Implements linear z to the matrix of equations.";
coef1.min = -2.1;
coef1.max = 2.1;
coef2.caption = "K2 of z=z^n+K2*z";
coef2.default = 0;
coef2.min = -2.1;
coef2.max = 2.1;
coef3.caption = "K3 of z=z^n+K3*z";
coef3.default = 0;
coef3.min = -2.1;
coef3.max = 2.1;
coef4.caption = "K4 of z=z^n+K4*z";
coef4.default = 0;
coef4.min = -2.1;
coef4.max = 2.1;
separator.label2.caption = "Used Formulas.";
powers.caption = "Equation Powers n";
powers.enum = "3,3,3,3\n4,4,4,4\n5,4,2,3\n5,5,5,5\n2,2,2,2";
powers.default = 0;
perturb.caption = "Start/perturbation";
perturb.default = (0,0,0,0);
perturb.hint = "Starts calculation with this number.";
perturb.min = -0.9;
perturb.max = 0.9;
perturb.visible = (settype=="Mandelbrot Set");
separator.label3.caption = "For more rough surfaces.";
depthincreaser.caption="+ Unit Vector Addition";
depthincreaser.default=false;
coefVector.caption="Vector factor";
coefVector.default = 0.1;
coefVector.visible = (depthincreaser==true);
//block for cutout.
separator.label4.caption = "CUTS along NONZERO coordinates, 4th dim is unused.";
iscuted.caption="CUTTING";
iscuted.enum="None\nLarger than\nSmaller than";
iscuted.default= 0;
Ctaxis.caption ="Coordinates of cut";
Ctaxis.default= (0,0,0,0);
Ctaxis.visible = (iscuted=="Larger than" || iscuted=="Smaller than");
separator.label5.caption = "http://edo555.deviantart.com/";
}
}
qMandelbrot3D (quaternion) {
//Mandelbrot set is generated couse x^2 (=real^2) >< y^2 (=i^2).
//In quaternion numbers x^2 >< y^2. But z^2 (= j^2) = y^2 (= i^2).
//So equal values in z and y axis generate rotation surface.
//Unless numbers are being manipulated so that x^2 >< y^2 >< z^2
//This formula introduces that quaternion number manipulation.
//by Edgars Malinovskis 18.12.2012.
//You may redistribute this algorithm, modify, derivate or use comercialy as you wish as long as you give proper credits.
parameter real bailout;
parameter int settype;
parameter bool testInverted;
parameter quaternion julia, perturb;
quaternion C;
real zx, zy, zz, zw, zzx, zzy, zzz, zzw, Cx, Cy, Cz, Cw;
parameter real coefInv, coefInv2, coefInv3;
parameter bool addinverse;
// block for cutout.
parameter int iscuted;
parameter quaternion Ctaxis;
real autobailout, coordX, coordY, coordZ;
void init(void)
{
if (testInverted==true && settype=="Julia Set")
{
z = recip(pixel);
C = julia;
}
else if (settype=="Julia Set")
{
z = pixel;
C = julia;
}
else if (testInverted==true && settype=="Mandelbrot Set")
{
z= perturb;
C= recip(pixel);
}
else
{
z= perturb;
C= pixel;
}
//block for cutout. An unelegant code.
autobailout=0;
coordX= real(Ctaxis);
coordY= imag(Ctaxis);
coordZ= part_j(Ctaxis);
if (iscuted == "Larger than")
{
if (coordX!=0 && real(pixel) > coordX )
{
autobailout= bailout +1;
}
if (coordY!=0 && imag(pixel) > coordY )
{
autobailout= bailout +1;
}
if (coordZ!=0 && part_j(pixel) > coordZ )
{
autobailout= bailout +1;
}
}
else if (iscuted == "Smaller than")
{
if (coordX!=0 && real(pixel) < coordX )
{
autobailout= bailout +1;
}
if (coordY!=0 && imag(pixel) < coordY )
{
autobailout= bailout +1;
}
if (coordZ!=0 && part_j(pixel) < coordZ )
{
autobailout= bailout +1;
}
}
}
void loop(void)
{
//manipulate numbers so that x^2 >< y^2 >< z^2
//z= quaternion ( real(z) , imag(z), part_j(z) + part_k(z), 0.5*part_k(z) - part_j(z) );
//z= z*z+C;
//The same formula in slower vector format.
//Uncomment and it will work the same.
Cx=real(C); Cy=imag(C); Cz=part_j(C); Cw=part_k(C);
zx=real(z); zy=imag(z); zz=part_j(z); zw=part_k(z);
zzx = zx*zx - zy*zy -2*zz*zz -zz*zw -1.25*zw*zw +Cx;
zzy = 2*zx*zy +Cy;
zzz = 2*zx*(zz+zw) +Cz;
zzw = zx*(zw - 2*zz) +Cw;
z= quaternion(zzx, zzy, zzz, zzw);
zx=zzx;
zy=zzy;
zz=zzz;
zw=zzw;
//additional modifications.
if (addinverse==true && z!=0)
{
z=coefInv/z + coefInv2/(z*z*z)+coefInv3/round(z) +z;
}
}
bool bailout(void)
{
return( |z|+ autobailout < bailout);
}
void description(void)
{
this.title = "Quaternion Mandelbrot 3D";
this.maxiter=25;
this.helpfile="http://www.fractalforums.com/new-theories-and-research/few-steps-behind-perfect-3d-mandelbrot/";
bailout.caption = "Bailout Value";
bailout.default = 777.0;
bailout.min = 0.5;
bailout.hint = "Larger number increases detalisation";
settype.caption = "Set type";
settype.enum = "Mandelbrot Set\nJulia Set";
settype.default = 0;
testInverted.caption="Inverted set";
testInverted.default=false;
julia.caption = "Julia Parameter";
julia.default = (-0.45,0.5,0.0,-0.1);
julia.hint = "Different values create different Julia Sets.";
julia.visible = (settype=="Julia Set");
perturb.caption = "Perturbation";
perturb.default = (0,0,0,0);
perturb.hint = "Starts calculation with this number.";
perturb.visible = (settype=="Mandelbrot Set");
perturb.min = -0.9;
perturb.max = 0.9;
addinverse.caption="add functions Z=Z+ k/Z+l/Z^3+l/round(Z)";
addinverse.default=false;
coefInv.caption="Inversion factor k";
coefInv.default=0.125;
coefInv.visible= (addinverse==true);
coefInv2.caption="Cube Inversion l";
coefInv2.default=0;
coefInv2.visible= (addinverse==true);
coefInv3.caption="Round Inversion m";
coefInv3.default=0;
coefInv3.visible= (addinverse==true);
//block for a cutout.
separator.label2.caption = "CUTS along NONZERO coordinates.";
iscuted.caption="CUTTING";
iscuted.enum="None\nLarger than\nSmaller than";
iscuted.default= 0;
Ctaxis.caption ="Coordinates of cut";
Ctaxis.default= (0,0,0,0);
Ctaxis.visible = (iscuted=="Larger than" || iscuted=="Smaller than");
}
}
MandelbulbVariations(QUATERNION) {
// Added few variations to bult in Mandelbulb DE.
// Inverted bulb (as sphere inverse would work),
// Weared surfaces depending on small bailout values
// and geometry changing unit vector.
// Added ideas found Tobby Marshall implementation "Unit Vector Explorer"
// And in Kerry Mitchell "Unit Vector Tweaked Mandelbrot".
// by Edgars Malinovskis 01.02.2012.
// 07.02.2012 useless in 3D thing changed to Z x unit vector.
// 25.02.2012 - starfix, + boxed bulb using power 8 modulus.
// 04.03.2012 + quaternionic unit vector factor instead of complex.
// J generates interesting distortions, but at the expense of speed.
// To increase speed rewritten unit vector adition formula backwards.
// Throught in some formulas this produces different results.
// 16.06.2012. + cuttings along Axis.
// 23.09.2012 + inversion addition.
parameter bool useDE, addinverse;
parameter bool boxedBulb;
parameter int n;
parameter real bailout, coefInv, coefInv2, coefInv3;
parameter complex ep;
real sx,sy,sz;
real dzx,dzy,dzz,Rdz,thdz,phdz;
real nx,ny,nz;
complex sincos_phdz_7_phi,sincos_thdz_7_theta,sincos_n_phi,sincos_n_theta;
real sin_phdz_7_phi,cos_phdz_7_phi,sin_thdz_7_theta,cos_thdz_7_theta;
real sin_n_phi,cos_n_phi,sin_n_theta,cos_n_theta;
real r,theta,phi,r2,r3,a,b;
real rp2,rp4;
real cr,ci,cj;
parameter real threshold;
parameter real accuracy;
parameter vector perturb,c;
parameter bool juliaMode;
parameter bool depthincreaser, inverted;
quaternion INV;
parameter int vectored;
parameter quaternion coefVector;
// block for cutout.
parameter int iscuted;
parameter quaternion Ctaxis;
real autobailout, coordX, coordY, coordZ;
void init(void)
{
if (juliaMode && inverted==true)
{
z=recip(pixel);
cr=partx(c);
ci=party(c);
cj=partz(c);
}
else if (juliaMode)
{
z=pixel;
cr=partx(c);
ci=party(c);
cj=partz(c);
}
else if (inverted == true)
{
z=quaternion(partx(perturb),party(perturb),partz(perturb),0);
INV=recip(pixel);
cr=part_r(INV);
ci=part_i(INV);
cj=part_j(INV);
}
else
{
z=quaternion(partx(perturb),party(perturb),partz(perturb),0);
cr=part_r(pixel);
ci=part_i(pixel);
cj=part_j(pixel);
}
// we basically iterate sx/sy/sz instead of z...
sx=part_r(z);
sy=part_i(z);
sz=part_j(z);
dzx=1;
dzy=0;
dzz=0;
//block for cutout. An unelegant code.
autobailout=0;
coordX= real(Ctaxis);
coordY= imag(Ctaxis);
coordZ= part_j(Ctaxis);
if (iscuted == "Larger than")
{
if (coordX!=0 && real(pixel) > coordX )
{
autobailout= bailout +1;
}
if (coordY!=0 && imag(pixel) > coordY )
{
autobailout= bailout +1;
}
if (coordZ!=0 && part_j(pixel) > coordZ )
{
autobailout= bailout +1;
}
}
else if (iscuted == "Smaller than")
{
if (coordX!=0 && real(pixel) < coordX )
{
autobailout= bailout +1;
}
if (coordY!=0 && imag(pixel) < coordY )
{
autobailout= bailout +1;
}
if (coordZ!=0 && part_j(pixel) < coordZ )
{
autobailout= bailout +1;
}
}
}
void loop(void)
{
if (boxedBulb)
{
// higher dimension modulus
r2=(sx^8+sy^8+sz^8)^0.125;
}
else
{
r2=sqrt(sx^2+sy^2+sz^2);
}
theta=atan2(sx+flip(sy));
a=sqrt(sx*sx+sy*sy);
phi=atan2(a+flip(sz));
if (useDE) {
Rdz=sqrt(dzx^2+dzy^2+dzz^2);
thdz=atan2(dzx+flip(dzy));
//phdz=asin(dzz/Rdz);
phdz=atan2(sqrt(dzx*dzx+dzy*dzy)+flip(dzz));
// Let's iterate dzx/dzy/dzz: First calculate the coords of it
r=n*Rdz*r2^(n-1);
// Let's iterate dzx/dzy/dzz: And finally assign the new values to dzx/dzy/dzz
sincos_phdz_7_phi=sincos(phdz+(n-1)*phi);
sin_phdz_7_phi=real(sincos_phdz_7_phi);
cos_phdz_7_phi=imag(sincos_phdz_7_phi);
sincos_thdz_7_theta=sincos(thdz+(n-1)*theta);
sin_thdz_7_theta=real(sincos_thdz_7_theta);
cos_thdz_7_theta=imag(sincos_thdz_7_theta);
if (juliaMode) {
dzx= r*cos_phdz_7_phi*cos_thdz_7_theta;
} else {
dzx= r*cos_phdz_7_phi*cos_thdz_7_theta+1;
}
dzy= r*cos_phdz_7_phi*sin_thdz_7_theta;
dzz= r*sin_phdz_7_phi;
}
// Iterate sx/sy/sz (i.e. z itself): Calculate intermediate values
sincos_n_phi=sincos(n*phi);
sincos_n_theta=sincos(n*theta);
sin_n_phi=real(sincos_n_phi);
cos_n_phi=imag(sincos_n_phi);
sin_n_theta=real(sincos_n_theta);
cos_n_theta=imag(sincos_n_theta);
r2=r2^n; //-sinh(r2)+r2^n;
// Iterate sx/sy/sz (i.e. z itself): Assign them!
sx= r2*cos_n_phi*cos_n_theta+cr;
sy= r2*cos_n_phi*sin_n_theta+ci;
sz= r2*sin_n_phi+cj;
// Now distance estimation: In case the pixel bailed out, calculate distance
if (sx*sx+sy*sy+sz*sz>bailout && useDE) {
Rdz=sqrt(dzx*dzx+dzy*dzy+dzz*dzz);
r2=sqrt(sx^2+sy^2+sz^2);
if (juliaMode) {
a = r2*log(r2)/Rdz;
} else {
a = 0.5*r2*log(r2)/Rdz;
}
// Done distance estimation...now just compare with the threshold...setting it to 0 tells ChaosPro
// that object has been hit (same as if maxiter has been reached)
if (a<threshold) {
a=0;
} else {
a=a*0.6;
}
// assign it to the final variable...
estimatedDistance=a/accuracy;
}
// now modifaying z insted of triplex
z=quaternion(sx,sy,sz,0);
if (addinverse==true && z!=0)
{
z=coefInv/z + coefInv2/(z*z*z)+coefInv3/round (z) +z;
}
if (vectored=="None")
{
//do nothing
}
else if (vectored=="+Z/Cabs(Z)" && |z|!=0)
{
z=z/cabs(z)*coefVector + z;
}
else if (vectored=="xZ/Cabs(Z)" && |z|!=0)
{
z=z/cabs(z)*z;
}
else if (vectored=="+Z/conj(Z)" && (z)!=0)
{
z=z/quaternion ( real(z) , -imag(z), -part_j(z), -part_k(z) )*coefVector + z;
}
else if (vectored=="+Z/sqr(Z)" && sqr(z)!=0)
{
z=z/sqr(z)*coefVector +z;
}
else if (vectored=="+Z/recip(Z)" && z!=0)
{
z=z/recip(z)*coefVector + z;
//switching multiplicators changes result
}
else if (vectored=="+Z/round(Z)" && round(z)!=0)
{
z=z/round(z)*coefVector + z;
//switching multiplicators changes result
}
else if (vectored=="+Z/ln(Z)" && ln(z)!=0)
{
z=z/ln(z)*coefVector + z;
}
else if (vectored=="+Z/8th|Z|" && |z|!=0)
{
z=z/( (real(z)^8+imag(z)^8 + part_j(z)^8 + part_k(z)^8)^0.125 )*coefVector +z;
}
else
{
z=z+1.0E-10;
}
sx=part_r(z);
sy=part_i(z);
sz=part_j(z);
if(depthincreaser==true)
{
// Affects just last Z (solutions) creating naturally imperfect surfaces.
// Depends on bailout value more than on multiplier or even equation. z=z*z+pixel would had just stronger result.
z=z*1.618033988749894848204586834365;
}
}
bool bailout(void)
{
return( |z| + autobailout < bailout);
}
void description(void)
{
this.title = "Mandelbulb DE variations";
juliaMode.caption="Julia Mode";
juliaMode.default=false;
juliaMode.hint="Check if you want to generate a Julia type fractal";
inverted.caption="Inverted 'cave' set";
inverted.default=false;
bailout.caption = "Bailout Value";
bailout.default = 100.0;
bailout.min = 1.0;
bailout.hint = "Defines the bailout radius: As soon as a pixel falls outside a circle with this radius, the iteration stops.";
n.caption="Power";
n.default=8;
n.min=2;
separator.label1.caption = "Modifies the fractal. Real + factor shrunks, - bloats and imaginary rotates.";
vectored.caption="Unit Vector Addition";
vectored.default=0;
vectored.enum="None\n+Z/Cabs(Z)\nxZ/Cabs(Z)\n+Z/conj(Z)\n+Z/sqr(Z)\n+Z/recip(Z)\n+Z/round(Z)\n+Z/ln(Z)\n+Z/8th|Z|";
coefVector.caption="Unit Vector factor";
coefVector.default=(-0.2, 0, 1, 0);
coefVector.visible= (vectored!="None" && vectored!="xZ/Cabs(Z)");
useDE.caption="Use DE";
useDE.default=true;
useDE.hint="Use Distance Estimation";
boxedBulb.caption="Boxed Bulb (use 8th dimension modulus)";
boxedBulb.default=false;
threshold.caption="Threshold";
threshold.default=0.001;
threshold.min=0;
threshold.max=10000;
accuracy.caption="Accuracy";
accuracy.default=1;
accuracy.min=0;
accuracy.hint="Accuracy, avoids overstepping. The higher, the more accurate, the slower the rendering";
c.caption="Julia Seed";
c.default=(0.3,0.7,-0.55);
c.hint="Starting value for iteration";
c.visible=(juliaMode);
separator.label2.caption = "Rougher surfaces with small bailout value.";
depthincreaser.caption="+Surface lastZ=Z*GoldenRatio";
depthincreaser.default=false;
perturb.caption="Perturbation";
perturb.default=(0,0,0);
perturb.hint="Starting value for iteration";
perturb.visible=(!juliaMode);
addinverse.caption="add functions Z=Z+ k/Z+l/Z^3+l/round(Z)";
addinverse.default=false;
coefInv.caption="Inversion factor k";
coefInv.default=0;
coefInv.visible= (addinverse==true);
coefInv2.caption="Cube Inversion l";
coefInv2.default=0;
coefInv2.visible= (addinverse==true);
coefInv3.caption="Round Inversion m";
coefInv3.default=-0.25;
coefInv3.visible= (addinverse==true);
//block for cutout.
separator.label3.caption = "CUTS along NONZERO coordinates, 4th dim is unused.";
iscuted.caption="CUTTING";
iscuted.enum="None\nLarger than\nSmaller than";
iscuted.default= 0;
Ctaxis.caption ="Coordinates of cut";
Ctaxis.default= (0,0,0,0);
Ctaxis.visible = (iscuted=="Larger than" || iscuted=="Smaller than");
}
}
zAlterMandelbrot3D (quaternion) {
// Formulas z^2+C and z^3+C
// in alternative 3 part numbers, (something between tricomplex quaternions)
// defined that i^2=-1, j^2=-i, i*j=1
// so that j is sort of superimaginary unit.
// No more a rotated quaternion, but still not a Mandelbulb;)
// Interesting curved insides.
// by Edgars Malinovskis 01.02.2012.
// You may redistribute this algorithm, modify, derivate or use comercialy as you wish as long as you give proper credits.
// 07.02.2012 optimised power 4 formula and rewriten formulas with a faster sqr.
// 16.06.2012. + cuttings along Axis.
parameter real bailout;
parameter int settype, power;
parameter bool testInverted;
parameter quaternion julia, perturb;
quaternion C;
real zx, zy, zz, zzx, zzy, zzz, Cx, Cy, Cz;
parameter real coefInv, coefInv2, coefInv3;
parameter bool addinverse;
// block for cutout.
parameter int iscuted;
parameter quaternion Ctaxis;
real autobailout, coordX, coordY, coordZ;
void init(void)
{
if (testInverted==true && settype=="Julia Set")
{
z = recip(pixel);
C = julia;
}
else if (settype=="Julia Set")
{
z = pixel;
C = julia;
}
else if (testInverted==true && settype=="Mandelbrot Set")
{
z= perturb;
C= recip(pixel);
}
else
{
z= perturb;
C= pixel;
}
Cx=real(C);
Cy=imag(C);
Cz=part_j(C);
//block for cutout. An unelegant code.
autobailout=0;
coordX= real(Ctaxis);
coordY= imag(Ctaxis);
coordZ= part_j(Ctaxis);
if (iscuted == "Larger than")
{
if (coordX!=0 && real(pixel) > coordX )
{
autobailout= bailout +1;
}
if (coordY!=0 && imag(pixel) > coordY )
{
autobailout= bailout +1;
}
if (coordZ!=0 && part_j(pixel) > coordZ )
{
autobailout= bailout +1;
}
}
else if (iscuted == "Smaller than")
{
if (coordX!=0 && real(pixel) < coordX )
{
autobailout= bailout +1;
}
if (coordY!=0 && imag(pixel) < coordY )
{
autobailout= bailout +1;
}
if (coordZ!=0 && part_j(pixel) < coordZ )
{
autobailout= bailout +1;
}
}
}
void loop(void)
{
zx=real(z);
zy=imag(z);
zz=part_j(z);
if (power=="Square")
{
// optimised
zzx = sqr(zx) - sqr(zy) + 2*zy*zz + Cx;
zzy = 2* zx * zy - sqr(zz) + Cy;
zzz = 2*zx*zz + Cz;
}
else if (power=="Cube")
{
// optimised
zzx =zx*zx*zx-3*zx*sqr(zy)+6*zx*zy*zz+sqr(zz)*zy-zz*zz*zz + Cx;
zzy =3*sqr(zx)*zy-3*zx*sqr(zz)-zy*zy*zy+2*sqr(zy)*zz + Cy;
zzz =3*sqr(zx)*zz-sqr(zy)*zz+2*zy*sqr(zz) + Cz;
}
if (power=="Tesseract")
{
/// Optimised formula. Should be 2x faster.
zzx= sqr(sqr(zx)) -6*sqr(zx)*sqr(zy) +12*sqr(zx)*zy*zz +4*zx*zy*sqr(zz) -4*zx*zz*zz*zz -4*zy*zy*zy*zz + sqr(sqr(zy)) +4*sqr(zy)*sqr(zz) +Cx;
zzy= 4*zx*zx*zx*zy -6*sqr(zx)*sqr(zz) +8*zx*sqr(zy)*zz -4*zx*zy*zy*zy +2*sqr(zy)*sqr(zz) -3*zy*zz*zz*zz +Cy;
zzz= 6*zx*zx*zx*zz -2*zx*sqr(zy)*zz +4*zx*zy*sqr(zz) +zy*zz*zz*zz - sqr(sqr(zz)) +Cz;
}
/// All three number parts must be iterated seperetely, hence zzx and zx.
z= quaternion(zzx, zzy, zzz, 0);
//additional modifications.
if (addinverse==true && z!=0)
{
z=coefInv/z + coefInv2/(z*z*z)+coefInv3/round(z) +z;
}
}
bool bailout(void)
{
return( abs(zzx)+ abs(zzy) + abs(zzz) + autobailout < bailout );
}
void description(void)
{
this.title = "zAlter 3D Mandelbrot";
this.maxiter=17;
this.helpfile="http://www.fractalforums.com/index.php?topic=10079";
bailout.caption = "Bailout Value";
bailout.default = 777.0;
bailout.min = 0.5;
bailout.hint = "Larger number increases detalisation";
settype.caption = "Set type";
settype.enum = "Mandelbrot Set\nJulia Set";
settype.default = 0;
testInverted.caption="Inverted set";
testInverted.default=false;
power.caption = "Alter complex Power";
power.enum = "Square\nCube\nTesseract";
power.default = 0;
separator.label1.caption = "4th dimension is unused.";
julia.caption = "Julia Parameter";
julia.default = (0.2,-0.5,-0.31,0);
julia.hint = "4th value is not used";
julia.visible = (settype=="Julia Set");
perturb.caption = "Calculation Start";
perturb.default = (0,0,0,0);
perturb.hint = "Starts calculation with this number. 4th value is unused";
perturb.visible = (settype=="Mandelbrot Set");
perturb.min = -1.5;
perturb.max = 1.5;
addinverse.caption="add functions Z=Z+ k/Z+l/Z^3+l/round(Z)";
addinverse.default=false;
coefInv.caption="Inversion factor k";
coefInv.default=0.125;
coefInv.visible= (addinverse==true);
coefInv2.caption="Cube Inversion l";
coefInv2.default=0;
coefInv2.visible= (addinverse==true);
coefInv3.caption="Round Inversion m";
coefInv3.default=0;
coefInv3.visible= (addinverse==true);
//block for cutout.
separator.label2.caption = "CUTS along NONZERO coordinates.";
iscuted.caption="CUTTING";
iscuted.enum="None\nLarger than\nSmaller than";
iscuted.default= 0;
Ctaxis.caption ="Coordinates of cut";
Ctaxis.default= (0,0,0,0);
Ctaxis.visible = (iscuted=="Larger than" || iscuted=="Smaller than");
separator.label3.caption = "curved insides.";
}
}
zAmazingbox (quaternion) {
// Mandelbox aka Amazingbox aka Tglads formula by Tom Lowe.
// + modifications and changable boxfold lenght.
// z= scale*spherefold( boxfold(z)) + c. Round ball in square gates.
// In 2D as kalisets, but not connected.
// In coding made an error, who works in realy nice way.
// So kept it as feature (double Y no z fold).
// Unit vector addition works as with mandelbrot, positive factor
// shrinks it, negative bloats it and imaginary value rotates the fractal.
// +z/round(z) requires one number to be 1.
// by Edgar Malinovsky 25.03.2012.
// 23.09.2012 + changeable factor for inversion addition.
parameter real bailout;
parameter int settype;
parameter bool addinverse, addw1, complexscale;
parameter quaternion julia;
quaternion C;
real zx, zy, zz, temp, radius;
parameter real Fold, Min_R, Scale, check, coefInv, coefInv2, coefInv3;
parameter int vectored, spherefold, truesphfold;
parameter complex coefVector;
void init(void)
{
if (settype=="Julia Set")
{
z = pixel;
C = julia;
}
else
{
z= 0;
C= pixel;
}
}
void loop(void)
{
zx=real(z);
zy=imag(z);
zz=part_j(z);
//boxfold
if (spherefold == "Normal")
{
if (zx > check)
{
zx=Fold - zx;
}
else if (zx < -check)
{
zx=-Fold-zx;
}
if (zy > check)
{
zy=Fold - zy;
}
else if (zy <-check)
{
zy=-Fold-zy;
}
if (zz > check)
{
zz=Fold - zz;
}
else if (zz <-check)
{
zz=-Fold-zz;
}
}
else if (spherefold == "Double Y no Z fold")
{ //this was mistake of 1st implementation.
if (zx > check)
{
zx=Fold - zx;
}
else if (zx < -check)
{
zx=-Fold-zx;
}
if (zy > check)
{
zy=Fold - zy;
}
else if (zy <-check)
{
zy=-Fold-zy;
}
if (zy > check)
{
zy=Fold - zy;
}
else if (zy <-check)
{
zy=-Fold-zy;
}
}
//spherefold
if (truesphfold == "Normal")
{
radius =sqr(zx) + sqr(zy) + sqr(zz);
if (radius < sqr(Min_R) )
{
temp = Scale/sqr(Min_R);
}
else if (radius < 1 && radius !=0)
{
temp = Scale/(radius);
}
else
{
temp = Scale;
}
}
// modulus defined in power 8 squares the unit circle.
else if (truesphfold == "Power 8 modulus")
{
radius =((zx)^8 + (zy)^8+ (zz)^8)^(0.125);
if (radius < (Min_R) )
{
temp = Scale/(Min_R);
}
else if (radius < 1 && radius !=0)
{
temp = Scale/(radius);
}
else
{
temp = Scale;
}
}
//scaling. changed to 10% faster code!
if (complexscale==true)
{
if (addw1==true)
{
z = quaternion(zx, zy, zz, 1)*(1,1)* temp + C;
}
else
{
z = quaternion(zx, zy, zz, 0)*(1,1)* temp + C;
}
}
else
{
if (addw1==true)
{
z = quaternion(zx, zy, zz, 1)* temp + C;
}
else
{
z = quaternion(zx, zy, zz, 0)* temp + C;
}
}
//here goes modifications
if (addinverse==true && z!=0)
{
z=coefInv/z + coefInv2/(z*z*z)+coefInv3/round(z) +z;
}
if (vectored=="None")
{
//do nothing.
}
else if (vectored=="+Z/Cabs(Z)" && |z|!=0)
{
z=z/cabs(z)*coefVector + z;
}
else if (vectored=="+Z/8th|Z|" && |z|!=0)
{
z=z/( (real(z)^8+imag(z)^8 + part_j(z)^8 + part_k(z)^8)^0.125 )*coefVector +z;
}
else if (vectored=="+Z/round(Z)" && round(z)!=0)
{
z=z/round(z)*coefVector + z;
}
else if (vectored=="+Z/|Z|" && |z|!=0)
{
z=z/|z|*coefVector + z;
}
else
{
z=z+1.0E-10;
}
}
bool bailout(void)
{
return( |z| < bailout );
}
void description(void)
{
this.title = "Amazingbox Mandelbox";
bailout.caption = "Bailout Value";
bailout.default = 16.0;
bailout.min = 0.5;
bailout.hint = "Larger number increases detalisation";
settype.caption = "Set type";
settype.enum = "Mandelbrot Set\nJulia Set";
settype.default = 0;
separator.label1.caption = "Shape depends on fold, scale and radius, density on maxiter and bailout. Alsou negative scale.";
Fold.caption = "Fold";
Fold.default = 1.3;
Min_R.caption = "min Radius";
Min_R.default = 0.5;
Scale.caption = "Scale";
Scale.default = 1.3;
check.caption = "Boxfold Lenght";
check.default = 1.2;
spherefold.caption = "Boxfold Type";
spherefold.default=0;
spherefold.enum="Normal\nDouble Y no Z fold";
truesphfold.caption = "Spherefold Type";
truesphfold.default=0;
truesphfold.enum="Normal\nPower 8 modulus";
julia.caption = "Julia Parameter";
julia.default = (0.3,-0.2,2.3,0);
julia.hint = "4th value is not used";
julia.visible = (settype=="Julia Set");
addw1.caption="add Part w=1";
addw1.default=false;
addinverse.caption="add functions Z=Z+ k/Z+l/Z^3+l/round(Z)";
addinverse.default=false;
coefInv.caption="Inversion factor k";
coefInv.default=0;
coefInv.visible= (addinverse==true);
coefInv2.caption="Cube Inversion l";
coefInv2.default=0.125;
coefInv2.visible= (addinverse==true);
coefInv3.caption="Round Inversion m";
coefInv3.default=0;
coefInv3.visible= (addinverse==true);
complexscale.caption="use complex scale (n,n)";
complexscale.default=false;
separator.label2.caption = "Modifies the fractal. Real + factor shrunks, - bloats and imaginary rotates.";
vectored.caption="Unit Vector Addition";
vectored.default=0;
vectored.enum="None\n+Z/Cabs(Z)\n+Z/8th|Z|\n+Z/round(Z)\n+Z/|Z|";
coefVector.caption="Unit Vector factor";
coefVector.default=(0.125, 0.5);
coefVector.visible= (vectored!="None");
}
}
Slonofractal (quaternion) {
// Cross of Mandelbrot set in XY plane and mandelbrot with positive x in ZY plane.
// x beeing real numbers,
// y beeing imaginary numbers, and
// z beeing double positive numbers.
// Multiplication rules are: r=1 (r is plain real number), i*i=-r-j, j=|j|, i*r=i, i*j=i, r*r=r, j*r=r, j*j=j.
// Nice insides.
// https://sites.google.com/site/3dfractals/discussion
// http://www.fractalforums.com/new-theories-and-research/imho-reason-behind-no-3d-mandelbrot/
// by Edgars Malinovskis / Edgar Malinovsky 17.06.2012.
// 01.07.2012. + more powers, till 7th.
// You may redistribute this algorithm, modify, derivate or use comercialy as you wish as long as you give proper credits.
// (Mention my autorship.)
parameter real bailout;
quaternion C;
real zx, zy, zz, zzx, zzy, zzz, Cx, Cy, Cz, root2;
parameter bool testInverted;
parameter quaternion julia, perturb;
parameter int settype, power;
// block for cutout.
parameter int iscuted;
parameter quaternion Ctaxis;
real autobailout, coordX, coordY, coordZ;
void init(void)
{
if (testInverted==true && settype=="Julia Set")
{
z = recip(pixel);
C = julia;
}
else if (settype=="Julia Set")
{
z = pixel;
C = julia;
}
else if (testInverted==true && settype=="Mandelbrot Set")
{
z= perturb;
C= recip(pixel);
}
else
{
z= perturb;
C= pixel;
}
Cx=real(C);
Cy=imag(C);
Cz=part_j(C);
//block for cutout. An unelegant code.
autobailout=0;
coordX= real(Ctaxis);
coordY= imag(Ctaxis);
coordZ= part_j(Ctaxis);
if (iscuted == "Larger than")
{
if (coordX!=0 && real(pixel) > coordX )
{
autobailout= bailout +1;
}
if (coordY!=0 && imag(pixel) > coordY )
{
autobailout= bailout +1;
}
if (coordZ!=0 && part_j(pixel) > coordZ )
{
autobailout= bailout +1;
}
}
else if (iscuted == "Smaller than")
{
if (coordX!=0 && real(pixel) < coordX )
{
autobailout= bailout +1;
}
if (coordY!=0 && imag(pixel) < coordY )
{
autobailout= bailout +1;
}
if (coordZ!=0 && part_j(pixel) < coordZ )
{
autobailout= bailout +1;
}
}
zx=real(z);
zy=imag(z);
zz=abs(part_j(z)); //allways positive.
}
void loop(void)
{
if (power=="Square")
{
//formula optimised for speed sqr(x) is faster that x*x
zzx= sqr(zx) - sqr(zy) + 2*zz*zx + Cx;
zzy= 2*zx * zy + 2* zz * zy + Cy;
zzz= sqr(zz) - sqr(zy) + abs(Cz);
}
else if (power=="Cube")
{ // 3th power
zzx= zx*zx*zx - 4*sqr(zy)*zx + 3*sqr(zx)*zz + 3*zx*sqr(zy) - 3*sqr(zy)*zz + Cx;
zzy= 3*sqr(zx)*zy + 6*zx*zy*zz - 2*zy*zy*zy + 3*zy*sqr(zz) + Cy;
zzz= zz*zz*zz - 2*zx*sqr(zy)-3*sqr(zy)*zz + abs(Cz);
}
else if (power=="Tesseract")
{ //4th power
zzx= sqr(sqr(zx)) -9*sqr(zx)*sqr(zy) +4*zx*zx*zx*zz +6*sqr(zx)*sqr(zz) -16*zx*sqr(zy)*zz +4*zx*zy*zy*zy +2* sqr(sqr(zy)) -6*sqr(zy)*sqr(zz) +Cx;
zzy= 4*zx*zx*zx*zy +12*sqr(zx)*zy*zz -8*zx*zy*zy*zy +12*zx*zy*sqr(zz) -8*zy*zy*zy*zz +4*zy*zz*zz*zz +Cy;
zzz= sqr(sqr(zz)) -3*sqr(zx)*sqr(zy) -8*zx*sqr(zy)*zz +2*sqr(sqr(zy)) +6*sqr(zy)*sqr(zz) +abs(Cz);
}
else if (power=="Penteract")
{ // 5th power
zzx= sqr(sqr(zx))*zx +12*zx*sqr(sqr(zy)) -16*zx*zx*zx*sqr(zy) +5*sqr(sqr(zx))*zz +10*zx*zx*zx*sqr(zz) -45*sqr(zx)*sqr(zy)*zz +10*sqr(zx)*zz*zz*zz -28*zx*sqr(zy)*sqr(zz) +5*zx*sqr(sqr(zz)) +10*sqr(sqr(zy))*zz -10*sqr(zy)*zz*zz*zz + Cx;
zzy= 4*sqr(sqr(zy))*zy +5*sqr(sqr(zx))*zy +20*zx*zx*zx*zy*zz -20*sqr(zx)*zy*zy*zy +30*sqr(zx)*zy*sqr(zz) -40*zx*zy*zy*zy*zz +20*zx*zy*zz*zz*zz -8*zy*zy*zy*sqr(zz) +5*zy*sqr(sqr(zz)) +Cy;
zzz= sqr(sqr(zz))*zz -4*zx*zx*zx*sqr(zy) -15*sqr(zx)*sqr(zy)*zz +8*zx*sqr(sqr(zy)) -20*zx*sqr(zy)*sqr(zz) +10*sqr(sqr(zy))*zz +2*sqr(zy)*zz*zz*zz +abs(Cz);
}
else if (power=="Hexeract")
{ // 6th power
zzx= sqr(sqr(zx))*sqr(zx) -4*zy^6 +40*sqr(zx)*sqr(sqr(zy)) -25*sqr(sqr(zx))*sqr(zy) +6*sqr(sqr(zx))*zx*zz +15*sqr(sqr(zx))*sqr(zy) -96*zx*zx*zx*sqr(zy)*zz +20*zx*zx*zx*zy*zy*zy -123*sqr(zx)*sqr(zy)*sqr(zz) +15*sqr(zx)*sqr(sqr(zz)) +72*zx*sqr(sqr(zy))*zz -56*zx*sqr(zy)*zz*zz*zz +6*zx*sqr(sqr(zz))*zz +18*sqr(sqr(zy))*sqr(zz) -15*sqr(zy)*sqr(sqr(zz)) +Cx;
zzy= 24*zx*sqr(sqr(zy))*zy +6*sqr(sqr(zx))*zx*zy +30*sqr(sqr(zx))*zy*zz -40*zx*zx*zx*zy*zy*zy +60*zx*zx*zx*zy*sqr(zz) -120*sqr(zx)*zy*zy*zy*zz +60*sqr(zx)*zy*zz*zz*zz -96*zx*zy*zy*zy*sqr(zz) +30*zx*zy*sqr(sqr(zz)) +24*sqr(sqr(zy))*zy*zz -16*zy*zy*zy*zz*zz*zz +6*zy*sqr(sqr(zz))*zz +Cy;
zzz= sqr(sqr(zz))*sqr(zz) -4*sqr(sqr(zy))*sqr(zy) -5*sqr(sqr(zx))*sqr(zy) -24*sqr(zx)*zx*sqr(zy)*zz +20*sqr(zx)*sqr(sqr(zy)) -45*sqr(zx)*sqr(zy)*sqr(zz) +48*zx*sqr(sqr(zy))*zz -40*zx*sqr(zy)*zz*zz*zz +18*sqr(sqr(zy))*sqr(zz) -3*sqr(zy)*sqr(sqr(zz)) +abs(Cz);
}
else if (power=="Hepteract")
{
zzx= zx^7 +100*sqr(zx)*zx*sqr(sqr(zy)) -36*sqr(sqr(zx))*zx*sqr(zy) +7*sqr(sqr(zx))*sqr(zx)*zz +21*sqr(sqr(zx))*zx*sqr(zy) -175*sqr(sqr(zx))*sqr(zy)*zz +35*sqr(sqr(zx))*sqr(zy)*zy -324*sqr(zx)*zx*sqr(zy)*sqr(zz) +35*sqr(zx)*zx*sqr(sqr(zz)) +280*sqr(zx)*sqr(sqr(zy))*zz -279*sqr(zx)*sqr(zy)*sqr(zz)*zz +21*sqr(zx)*sqr(sqr(zz))*zz -32*zx*sqr(sqr(zy))*sqr(zy) +204*zx*sqr(sqr(zy))*sqr(zz) -104*zx*sqr(zy)*sqr(sqr(zz)) +7*zx*sqr(sqr(zz))*sqr(zz) -28*sqr(sqr(zy))*sqr(zy)*zz +34*sqr(sqr(zy))*sqr(zz)*zz -21*sqr(zy)*sqr(sqr(zz))*zz +Cx;
zzy= 84*sqr(zx)*zy^5 -8*zy^7 +7*sqr(sqr(zx))*sqr(zx)*zy +42*sqr(sqr(zx))*zx*zy*zz -70*sqr(sqr(zx))*sqr(zy)*zy +105*sqr(sqr(zx))*zy*sqr(zz) -280*sqr(zx)*zx*sqr(zy)*zy*zz +140*sqr(zx)*zx*zy*sqr(zz)*zz -376*sqr(zx)*sqr(zy)*zy*sqr(zz) +105*sqr(zx)*zy*sqr(sqr(zz)) +168*zx*sqr(sqr(zy))*zy*zz -208*zx*sqr(zy)*zy*sqr(zz)*zz +42*zx*zy*sqr(sqr(zz))*zz +60*sqr(sqr(zy))*zy*sqr(zz) -34*sqr(zy)*zy*sqr(sqr(zz)) +7*zy*sqr(sqr(zz))*sqr(zz) +Cy;
zzz= zy^7 -24*zx*sqr(sqr(zy))*sqr(zy) -6*sqr(sqr(zx))*zx*sqr(zy) -35*sqr(sqr(zx))*sqr(zy)*zz +40*sqr(zx)*zx*sqr(sqr(zy)) -84*sqr(zx)*zx*sqr(zy)*sqr(zz) +140*sqr(zx)*sqr(sqr(zy))*zz -105*sqr(zx)*sqr(zy)*sqr(zz)*zz +144*zx*sqr(sqr(zy))*sqr(zz) +70*zx*sqr(zy)*sqr(sqr(zz)) -28*sqr(sqr(zy))*sqr(zy)*zz +34*sqr(sqr(zy))*sqr(zz)*zz -11*sqr(zy)*sqr(sqr(zz))*zz + abs(Cz);
}
if (power=="Octeract")
{
zzx= sqr(sqr(sqr(zx))) +8*sqr(sqr(sqr(zy))) +210*sqr(sqr(zx))*sqr(sqr(zy)) -49*zx^6*sqr(zy) +8*zx^7*zz +28*zx^6*sqr(zz) -288*zx^5*sqr(zy)*zz +56*zx^5*zz^3 -688*sqr(sqr(zx))*sqr(zy)*sqr(zz) +35*sqr(sqr(zx))*sqr(sqr(zz)) +800*zx^3*sqr(sqr(zy))*zz -848*zx^3*sqr(zy)*zz^3 +56*zx^3*zz^5 -140*sqr(zx)*zy^6 +1004*sqr(zx)*sqr(sqr(zy))*sqr(zz) -418*sqr(zx)*sqr(zy)*sqr(sqr(zz)) +28*sqr(zx)*zz^6 -256*zx*zy^6*zz +480*zx*sqr(sqr(zy))*zz^3 -178*zx*sqr(zy)*zz^5 +8*zx*zz^7 -88*zy^6*sqr(zz) +68*sqr(sqr(zy))*sqr(sqr(zz)) -28*sqr(zy)*zz^6 +Cx;
zzy= 224*zx^3*zy^5 -64*zx*zy^7 +8*zx^7*zy +56*zx^6*zy*zz -112*zx^5*zy^3 +168*zx^5*zy*sqr(zz) -560*sqr(sqr(zx))*zy^3*zz +280*sqr(sqr(zx))*zy*zz^3 -1064*zx^3*zy^3*sqr(zz) +280*zx^3*zy*sqr(sqr(zz)) +672*sqr(zx)*zy^5*zz -968*sqr(zx)*zy^3*zz^3 +168*sqr(zx)*zy*zz^5 +576*zx*zy^5*sqr(zz) -276*zx*zy^3*sqr(sqr(zz)) +56*zx*zy*zz^6 -64*zy^7*zz +128*zy^5*zz^3 -66*zy^3*zz^5 +8*zy*zz^7 +Cy;
zzz= sqr(sqr(sqr(zz))) +8*sqr(sqr(sqr(zy))) -84*sqr(zx)*zy^6 -7*zx^6*sqr(zy) -48*zx^5*sqr(zy)*zz +70*sqr(sqr(zx))*sqr(sqr(zy)) -140*sqr(sqr(zx))*sqr(zy)*sqr(zz) +320*zx^3*sqr(sqr(zy))*zz -224*zx^3*sqr(zy)*zz^3 +516*sqr(zx)*sqr(sqr(zy))*sqr(zz) -210*sqr(zx)*sqr(zy)*sqr(sqr(zz)) -192*zx*zy^6*zz +352*zx*sqr(sqr(zy))*zz^3 +28*zx*sqr(zy)*zz^5 -88*zy^6*sqr(zz) +68*sqr(sqr(zy))*sqr(sqr(zz)) -18*sqr(zy)*zz^6 +abs(Cz);
}
zx=zzx;
zy=zzy;
zz=abs(zzz); //allways positive.
/// All three number parts are iterated seperetely, hence zzx and zx.
z= quaternion(zzx, zzy, zzz, 0);
}
bool bailout(void)
{
return( abs(zzx)+ abs(zzy) + abs(zzz)+ autobailout < bailout );
}
void description(void)
{
this.title = "Slonofractal";
this.maxiter=20;
this.helpfile="https://sites.google.com/site/3dfractals/discussion";
bailout.caption = "Bailout Value";
bailout.default = 777.0;
bailout.hint = "Larger number increases detalisation";
settype.caption = "Set type";
settype.enum = "Mandelbrot Set\nJulia Set";
settype.default = 0;
testInverted.caption="Inverted set";
testInverted.default=false;
power.caption = "Slono Power";
power.enum = "Square\nCube\nTesseract\nPenteract\nHexeract\nHepteract\nOcteract";
power.default = 0;
separator.label1.caption = "4th dimension is unused.";
julia.caption = "Julia Parameter";
julia.default = (0.2,-0.3,0.27,0);
julia.visible = (settype=="Julia Set");
perturb.caption = "Calculation Start";
perturb.default = (0,0,0,0);
perturb.hint = "Starts calculation with this number. 4th value is unused";
perturb.visible = (settype=="Mandelbrot Set");
perturb.min = -1.5;
perturb.max = 1.5;
//block for a cutout.
separator.label2.caption = "CUTS along NONZERO coordinates.";
iscuted.caption="CUTTING";
iscuted.enum="None\nLarger than\nSmaller than";
iscuted.default= 0;
Ctaxis.caption ="Coordinates of cut";
Ctaxis.default= (0,0,0,0);
Ctaxis.visible = (iscuted=="Larger than" || iscuted=="Smaller than");
separator.label3.caption = "Zoom inside of the fractal.";
}
}
ZwiplexMbrot (quaternion) {
// by Edgar Malinovsky.
// Based on ideas of David Makin.
// Two complex number multi power mandelbrots (multibrots)
// are calculated as projections in XY and XZ planes.
// It leaves two possible X values.
// Very similar to 3D bicomplex mandelbrot.
// http://www.fractalforums.com/index.php?topic=12831.msg49771#msg49771
// 18.07.2012.
parameter real bailout;
parameter int settype;
parameter real power1, power2, factor1, factor2;
parameter quaternion julia;
quaternion C;
real zx, zy, zz;
complex compXY, compXZ;
// block for cutout.
parameter int iscuted;
parameter quaternion Ctaxis;
real autobailout, coordX, coordY, coordZ;
void init(void)
{
if (settype=="Julia Set")
{
z = pixel;
C = julia;
}
else
{
z= 0;
C= pixel;
}
//block for cutout. An unelegant code.
autobailout=0;
coordX= real(Ctaxis);
coordY= imag(Ctaxis);
coordZ= part_j(Ctaxis);
if (iscuted == "Larger than")
{
if (coordX!=0 && real(pixel) > coordX )
{
autobailout= bailout +1;
}
if (coordY!=0 && imag(pixel) > coordY )
{
autobailout= bailout +1;
}
if (coordZ!=0 && part_j(pixel) > coordZ )
{
autobailout= bailout +1;
}
}
else if (iscuted == "Smaller than")
{
if (coordX!=0 && real(pixel) < coordX )
{
autobailout= bailout +1;
}
if (coordY!=0 && imag(pixel) < coordY )
{
autobailout= bailout +1;
}
if (coordZ!=0 && part_j(pixel) < coordZ )
{
autobailout= bailout +1;
}
}
}
void loop(void)
{
//dividing quaternion in 2 complex numbers and then calculating.
compXY = complex (real(z), imag(z));
compXZ = complex (real(z), part_j(z));
compXY = compXY^power1;
compXZ = compXZ^power2;
zy=imag(compXY);
zz=imag(compXZ);
zx=real(compXY)*factor1 +real(compXZ)*factor2;
z= quaternion(zx, zy, zz, 0)+C;
}
bool bailout(void)
{
return( |z| + autobailout < bailout );
}
void description(void)
{
this.title = "Zwiplex M-brot";
this.maxiter=50;
this.helpfile="https://sites.google.com/site/3dfractals/";
bailout.caption = "Bailout Value";
bailout.default = 7;
bailout.min = 0.5;
bailout.hint = "Larger number increases size.";
settype.caption = "Set type";
settype.enum = "Mandelbrot Set\nJulia Set";
settype.default = 0;
separator.label1.caption = "Two Z^n sets calculated simultaneously.";
power1.caption = "Power n in XY plane";
power1.default = 2;
power2.caption = "Power n in XZ plane";
power2.default = 5;
factor1.caption = "X use from XY";
factor1.default = 1;
factor2.caption = "X use from XZ";
factor2.default = 0;
julia.caption = "Julia Parameter";
julia.default = (0.3,0.5,-0.1,0);
julia.hint = "4th value is not used";
julia.visible = (settype=="Julia Set");
//block for cutout.
separator.label2.caption = "CUTS along NONZERO coordinates.";
iscuted.caption="CUTTING";
iscuted.enum="None\nLarger than\nSmaller than";
iscuted.default= 0;
Ctaxis.caption ="Coordinates of cut";
Ctaxis.default= (0,0,0,0);
Ctaxis.visible = (iscuted=="Larger than" || iscuted=="Smaller than");
}
}
Baguabox (quaternion) {
// Mandelbox alternative.
// Based on work of TGlad, Traffasel, Kali, M Benesi and LucaGen.
// By Edgar Malinovsky 25.07.2012.
// You may redistribute this algorithm, modify, derivate or use comercialy as you wish as long as you atribute proper credits.
// 10.08.2012 + smoother spherefold.
// 23.09.2012 + changeable factor for inversion addition.
// 04.10.2012 + fold using positive (non inverted) unit vector.
// 04.10.2012 + and fold using normal power 2 modulus.
parameter real bailout;
parameter quaternion julia;
quaternion C;
real zx, zy, zz, temp, modulus, radius;
parameter real add, Min_R, Scale, lenght;
parameter int settype;
parameter bool addw1;
parameter int vectored;
parameter complex coefVector;
parameter int baguafold, modulustype;
parameter real coefInv, coefInv2, coefInv3;
parameter bool addinverse;
void init(void)
{
if (settype=="Julia Set")
{
z = pixel;
C = julia;
}
else
{
z= 0;
C= pixel;
}
}
void loop(void)
{
zx=real(z);
zy=imag(z);
zz=part_j(z);
if (modulustype == 0)
{ //Folding by pow 8 modulus having unit circle shaped as octagon pillow.
modulus =((zx)^8 + (zy)^8+ (zz)^8)^0.125 ;
}
else if (modulustype == 1)
{//normal, are faster but less interesting shapes.
modulus =sqrt(sqr(zx) + sqr(zy)+ sqr(zz));
}
if (baguafold == 0)
{
//original more chaotic pattern.
if (modulus != 0)
//here formula can work without this conditional.
{
if (zx > lenght)
{
zx=-zx/modulus -add;
}
else if (zx < -lenght)
{
zx=-zx/modulus +add;
}
if (zy > lenght)
{
zy=-zy/modulus -add;
}
else if (zy < -lenght)
{
zy=-zy/modulus +add;
}
if (zz > lenght)
{
zz=-zz/modulus -add;
}
else if (zz < -lenght)
{
zz=-zz/modulus +add;
}
}
}
else if (baguafold == 1)
{
//more orderly shape
if (modulus != 0)
//here formula can work without this conditional.
{
if (zx > lenght)
{
zx=zx/modulus +add;
}
else if (zx < -lenght)
{
zx=zx/modulus -add;
}
if (zy > lenght)
{
zy=zy/modulus +add;
}
else if (zy < -lenght)
{
zy=zy/modulus -add;
}
if (zz > lenght)
{
zz=zz/modulus +add;
}
else if (zz < -lenght)
{
zz=zz/modulus -add;
}
}
}
//spherefold. Similar to TGlads original, but allows to use a negative radius.
if (Min_R ==0)
{
//if Min_R=0 spherefold is turned off.
//but radius still is calculated.
//this conditional allows not to calculate radius.
radius =1;
}
else
{
radius =sqr(zx) + sqr(zy) + sqr(zz) ;
}
if (radius < abs(Min_R) )
{
temp = Scale/Min_R;
}
else
{
temp = Scale;
}
//scaling and generating z value.
if (addw1==true)
{
z = quaternion(zx, zy, zz, 1)* temp + C;
}
else
{
z = quaternion(zx, zy, zz, 0)* temp + C;
}
//addition modifications after main iterations.
//Not part of formula.
if (addinverse==true && z!=0)
{
z=coefInv/z + coefInv2/(z*z*z)+coefInv3/round(z) +z;
}
if (vectored=="None")
{
//do nothing.
}
else if (vectored=="+Z/Cabs(Z)" && |z|!=0)
{
z=z/cabs(z)*coefVector + z;
}
else if (vectored=="+Z/8th|Z|" && |z|!=0)
{
z=z/( (real(z)^8+imag(z)^8 + part_j(z)^8 + part_k(z)^8)^0.125 )*coefVector +z;
}
else if (vectored=="+Z/round(Z)" && round(z)!=0)
{
z=z/round(z)*coefVector + z;
}
else if (vectored=="+Z/|Z|" && |z|!=0)
{
z=z/|z|*coefVector + z;
}
else
{
z=z+1.0E-10;
}
}
bool bailout(void)
{
return( |z| < bailout );
}
void description(void)
{
this.title = "Baguabox";
bailout.caption = "Bailout Value";
bailout.default = 15.0;
bailout.min = 0.5;
bailout.hint = "Larger number increases fractal";
settype.caption = "Set type";
settype.enum = "Mandelbrot Set\nJulia Set";
settype.default = 0;
separator.label1.caption = "Shape depends on folding parameters and bailout.";
add.caption = "Add value";
add.default = 0.1;
lenght.caption = "Lenght";
lenght.default = 2.0;
Min_R.caption = "Radius";
Min_R.default = 0.5;
Scale.caption = "Scale";
Scale.default = 1.5;
modulustype.caption = "Modulus for Folding";
modulustype.default=0;
modulustype.enum="Power 8 (detailed)\nPower 2 (faster)";
baguafold.caption = "Bagua Fold vector";
baguafold.default=0;
baguafold.enum="Negative\nPositive";
julia.caption = "Julia Parameter";
julia.default = (0.3,-0.3,0,0);
julia.hint = "4th value is not used";
julia.visible = (settype=="Julia Set");
separator.label2.caption = "Post transformations.";
addw1.caption="use Part w=1";
addw1.default=false;
addinverse.caption="add functions Z=Z+ k/Z+l/Z^3+l/round(Z)";
addinverse.default=false;
coefInv.caption="Inversion factor k";
coefInv.default=0;
coefInv.visible= (addinverse==true);
coefInv2.caption="Cube Inversion l";
coefInv2.default=0.125;
coefInv2.visible= (addinverse==true);
coefInv3.caption="Round Inversion m";
coefInv3.default=0;
coefInv3.visible= (addinverse==true);
separator.label3.caption = "Modifies the fractal. Real + factor shrunks, - bloats and imaginary rotates.";
vectored.caption="Unit Vector Addition";
vectored.default=0;
vectored.enum="None\n+Z/Cabs(Z)\n+Z/8th|Z|\n+Z/round(Z)\n+Z/|Z|";
coefVector.caption="Unit Vector factor";
coefVector.default=(0.1, 0.4);
coefVector.visible= (vectored!="None");
}
}
SwirlBox (quaternion) {
// Swirlbox. Idea was to bring up 3D swirl transform.
// Works in both 2D and 3D.
// by Edgar Malinovsky 28.01.2012.
parameter real bailout;
quaternion C, altz;
real zx, zy, zz, angx, angy, angz, ang, Cx, Cy, Cz, radius, fisheye, fishdivisor;
parameter bool testInverted;
parameter quaternion julia;
parameter int settype, modtype;
parameter real scal, frequency, spin;
parameter real Fold, Fisheyeness;
// block for cutout.
parameter int iscuted;
parameter quaternion Ctaxis;
real autobailout, coordX, coordY, coordZ;
void init_once(void)
{
//Do this once.
fishdivisor= 1/(Fisheyeness+1);
}
void init(void)
{
if (testInverted==true && settype=="Julia Set")
{
z = recip(pixel);
C = julia;
}
else if (settype=="Julia Set")
{
z = pixel ;
C = julia;
}
else if (testInverted==true && settype=="Mandelbrot Set")
{
z= 0;
C= recip(pixel);
}
else
{
z= 0;
C= pixel;
}
Cx=real(C);
Cy=imag(C);
Cz=part_j(C);
// for 4th dim use Cw, zw and zzw. Cw=part_k(C);
zx=real(z);
zy=imag(z);
zz=part_j(z);
//zw=zheight;
//block for cutout. An unelegant code.
autobailout=0;
coordX= real(Ctaxis);
coordY= imag(Ctaxis);
coordZ= part_j(Ctaxis);
if (iscuted == "Larger than")
{
if (coordX!=0 && real(pixel) > coordX )
{
autobailout= bailout +1;
}
if (coordY!=0 && imag(pixel) > coordY )
{
autobailout= bailout +1;
}
if (coordZ!=0 && part_j(pixel) > coordZ )
{
autobailout= bailout +1;
}
}
else if (iscuted == "Smaller than")
{
if (coordX!=0 && real(pixel) < coordX )
{
autobailout= bailout +1;
}
if (coordY!=0 && imag(pixel) < coordY )
{
autobailout= bailout +1;
}
if (coordZ!=0 && part_j(pixel) < coordZ )
{
autobailout= bailout +1;
}
}
}
void loop(void)
{
//seamless fold
zx = abs(zx-Fold) - abs(zx+Fold) + zx;
zy = abs(zy-Fold) - abs(zy+Fold) + zy;
zz = abs(zz-Fold) - abs(zz+Fold) + zz;
//Fisheye is conformal transform and a scaling.
fisheye=(Fisheyeness+sqrt( sqr(zx)+ sqr(zy)+ sqr(zz) ) )*fishdivisor*scal;
zx=fisheye*zx;
zy=fisheye*zy;
zz=fisheye*zz;
//3D Swirl. Probably at least quasi conformal, but iteration strong.
radius = sqrt( sqr(zx)+sqr(zy)+sqr(zz) );
angx=atan2(radius+1i*zx);
angy=atan2(zx+1i*zy);
angz=atan2(radius+1i*zz);
zx= cos(frequency*radius+ spin*angx)*radius+Cx;
zy= sin(frequency*radius+ spin*angy)*radius+Cy;
zz= sin(frequency*radius+ spin*angz)*radius+Cz;
z=altz= quaternion ( zx , zy, zz, 0);
}
bool bailout(void)
{
// cabs(z) is included for smooth bailout in 2D, altz coz in 2D z is complex variable, autobailot is for cutout.
return( |altz|+ autobailout < bailout );
}
void description(void)
{
this.title = "SwirlBox";
this.maxiter=5;
this.helpfile="http://www.fractalforums.com/";
bailout.caption = "Bailout Value";
bailout.default = 6.0;
testInverted.caption="Inverted set";
testInverted.default=false;
frequency.caption = "frequency";
frequency.default = 6;
spin.caption = "spin";
spin.default = 6;
scal.caption = "scale";
scal.default = 1;
Fold.caption = "Fold";
Fold.default = 1;
Fisheyeness.caption = "Fisheyeness";
Fisheyeness.default = 1;
separator.label1.caption = "Julia Block.";
settype.caption = "Set type";
settype.enum = "Mandelbrot Set\nJulia Set";
settype.default = 0;
julia.caption = "Julia Parameter";
julia.default = (-0.2,0.3,0,0);
julia.visible = (settype=="Julia Set");
//block for a cutout.
separator.label2.caption = "CUTS along NONZERO coordinates.";
iscuted.caption="CUTTING";
iscuted.enum="None\nLarger than\nSmaller than";
iscuted.default= 0;
Ctaxis.caption ="Coordinates of cut";
Ctaxis.default= (0,0,0,0);
Ctaxis.visible = (iscuted=="Larger than" || iscuted=="Smaller than");
}
}
SwirlTransf (quaternion) {
// 3D Swirl transform
// WORKS IN BOTH 2D AND 3D.
// by Edgar Malinovsky 28.01.2012.
parameter real bailout;
quaternion C, altz;
real zx, zy, zz, angx, angy, angz, ang, Cx, Cy, Cz, radius, temp;
parameter bool testInverted;
parameter quaternion julia;
parameter int settype, modtype;
parameter real scal, frequency, spin;
// block for cutout.
parameter int iscuted;
parameter quaternion Ctaxis;
real autobailout, coordX, coordY, coordZ;
void init_once(void)
{
// all callculated coefficients place here.
}
void init(void)
{
if (testInverted==true && settype=="Julia Set")
{
z = recip(pixel);
C = julia;
}
else if (settype=="Julia Set")
{
z = pixel ;
C = julia;
}
else if (testInverted==true && settype=="Mandelbrot Set")
{
z= 0;
C= recip(pixel);
}
else
{
z= 0;
C= pixel;
}
Cx=real(C);
Cy=imag(C);
Cz=part_j(C);
zx=real(z);
zy=imag(z);
zz=part_j(z);
//block for cutout. An unelegant code.
autobailout=0;
coordX= real(Ctaxis);
coordY= imag(Ctaxis);
coordZ= part_j(Ctaxis);
if (iscuted == "Larger than")
{
if (coordX!=0 && real(pixel) > coordX )
{
autobailout= bailout +1;
}
if (coordY!=0 && imag(pixel) > coordY )
{
autobailout= bailout +1;
}
if (coordZ!=0 && part_j(pixel) > coordZ )
{
autobailout= bailout +1;
}
}
else if (iscuted == "Smaller than")
{
if (coordX!=0 && real(pixel) < coordX )
{
autobailout= bailout +1;
}
if (coordY!=0 && imag(pixel) < coordY )
{
autobailout= bailout +1;
}
if (coordZ!=0 && part_j(pixel) < coordZ )
{
autobailout= bailout +1;
}
}
}
void loop(void)
{
if (modtype==0)
{
radius = sqrt( sqr(zx)+sqr(zy)+sqr(zz) );
}
else if (modtype==1)
{
radius = ( zx^8+ zy^8+ zz^8 )^0.125;
}
angx=atan2(radius+1i*zx);
angy=atan2(zx+1i*zy);
angz=atan2(radius+1i*zz);
zx= cos(frequency*radius+ spin*angx) *radius*scal+Cx;
zy= sin(frequency*radius+ spin*angy)*radius*scal+Cy;
zz= sin(frequency*radius+ spin*angz)*radius*scal+Cz;
z=altz= quaternion ( zx , zy, zz, 0);
}
bool bailout(void)
{
// cabs(z) is included for smooth bailout in 2D, altz coz in 2D z is complex variable, autobailot is for cutout.
return( cabs(altz)+ autobailout < bailout );
}
void description(void)
{
this.title = "SwirlTransform";
this.maxiter=4;
this.helpfile="http://www.fractalforums.com/";
separator.label1.caption = "To see swirls use cutting.";
bailout.caption = "Bailout Value";
bailout.default = 5.0;
settype.caption = "Set type";
settype.enum = "Mandelbrot Set\nJulia Set";
settype.default = 0;
testInverted.caption="Inverted set";
testInverted.default=false;
frequency.caption = "frequency";
frequency.default = 1;
spin.caption = "spin";
spin.default = 1;
scal.caption = "scale";
scal.default = 1.5;
modtype.caption = "Modulus type";
modtype.enum = "Normal\npower8";
modtype.default = 0;
separator.label2.caption = "4th value is unused.";
julia.caption = "Julia Parameter";
julia.default = (-0.2,0.3,0.45,0);
julia.visible = (settype=="Julia Set");
//block for a cutout.
separator.label3.caption = "CUTS along NONZERO coordinates.";
iscuted.caption="CUTTING";
iscuted.enum="None\nLarger than\nSmaller than";
iscuted.default= 0;
Ctaxis.caption ="Coordinates of cut";
Ctaxis.default= (0,0,0,0);
Ctaxis.visible = (iscuted=="Larger than" || iscuted=="Smaller than");
}
}