Sorry it took so long to get back to this, Timeroot. The multiplication and division I had in mind was based on squaring the radius and doubling the angle in standard spherical coordinates, then converting to cartesian. Once I realized how problematic this definition could be, I stopped working on it for a while. Eventually, I decided to finish it even though it wouldn't be similar to triplex algebra.
It looks like the continued fraction definition just results in a sphere, unless I did something stupid. I'll put the code here just in case there are glaring errors somewhere. I used ChaosPro:
Ztanzbulb(QUATERNION) {
parameter real bailout;
parameter int steps;
real pixelr,pixeli,pixelj;
real x1,x2,y1,y2,z1,z2,rho1,rho2,A,B,C;
quaternion res, res1,c;
int m;
quaternion inv(quaternion q)
{
q = q-quaternion(0,2*part_i(q),0,0);
q = q/|q|;
return(q);
}
quaternion mult(quaternion q, quaternion p)
{
x1 = part_r(q);
y1 = part_i(q);
z1 = part_j(q);
rho1 = sqrt(x1*x1+y1*y1);
x2 = part_r(p);
y2 = part_i(p);
z2 = part_j(p);
rho2 = sqrt(x2*x2+y2*y2);
if (rho1 == 0){
p =(z1*p);
} else if (rho2 == 0){
p = z2*p;
} else{
A = (x1*x2-y1*y2)*(z1/rho1+z2/rho2);
B = (x1*y2+x2*y1)*(z1/rho1+z2/rho2);
C = (rho1*rho2-z1*z2);
p = (quaternion(A,B,C,0));
}
return(p);
}
quaternion div(quaternion q, quaternion p)
{
x1 = part_r(q);
y1 = part_i(q);
z1 = part_j(q);
rho1 = sqrt(x1*x1+y1*y1);
x2 = part_r(p);
y2 = part_i(p);
z2 = part_j(p);
rho2 = sqrt(x2*x2+y2*y2);
if (rho1 == 0){
p =inv(p)*z1;
} else if (rho2 == 0){
p = p/z2;
} else{
A = (x1*x2+y1*y2)*(z1/rho1-z2/rho2)/|p|;
B = (x1*y2-x2*y1)*(z1/rho1-z2/rho2)/|p|;
C = (rho1*rho2+z1*z2)/|p|;
p = (quaternion(A,B,C,0));
}
return(p);
}
quaternion tangent(quaternion q)
{
res = 0.0;
for (m = steps+1; m>1; m=m-1){
res1 = mult(z,z)*(-1.0/(2*m-3)/(2*m-1));
res = div(res1,res+quaternion(0,0,1,0));
}
return(div(z,res+quaternion(0,0,1,0)));
}
void init(void)
{
pixelr=part_r(pixel);
pixeli=part_i(pixel);
pixelj=part_j(pixel);
c=quaternion(pixelr,pixeli,pixelj,0);
z=c;
}
void loop(void)
{
z=mult(z,tangent(z))+c;
}
bool bailout(void)
{
return(|z|<bailout);
}
void description(void)
{
this.title = "ztanzbulb";
bailout.caption = "Bailout Value";
bailout.default = 4.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.";
steps.caption = "Steps";
steps.default = 2;
steps.min = 1;
steps.hint = "Controls how deep into the continued fraction the tangent function goes.";
}
}