. HOME
 
. Features
. Gallery
. Download
. Documentation
 
. Resources
. Mailing Lists
. Programs
. Feature Voting
. Wishlist
 
. Theory
. Tutorials
 
. Formula DB
 
. Contact
CHAOSPRO 3.2
Release 4.0
.

ChaosPro Formula Database

  
NameMalinovsky3D.cfm
Path/Compiler/MalinovskyFract/
TypeFormula
Size57 KB
OwnerEdgar Malinovsky
Last Modified:25 Apr 2013
  


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");

	}
}


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");
	}
}