Hypercomplex Math in Fractal Programming |
This is a tutorial on using hypercomplex math in fractal coding. The code examples I show will be C code from my own programs, just to illustrate the technique. Hypercomplex numbers are four-dimensional in the form of h(4) = hr+hi+hj+hk. To begin with, we set up a basic structure for the variables we'll be using in hypercomplex math: typedef struct hcomplex{ double x; double y; double z; double w; }hcomplex; This contains the first two dimensions of a complex variable, x and y, which refer to real and imaginary z, plus a couple more for the hypercomplex "extensions." The way hypercomplex math is done (using Fractal Creation's method), a sort of matrix math is used to combine the first two fields with the last two extension fields. A complex function is called twice with different combinations of the hypercomplex fields, and the separate complex return values are recombined into a single hypercomplex variable. The first call to a function uses the arguments (h.x-h.w,h.y+h.z). The second call uses (h.x+h.w,h.y-h.z). For a hypercomplex cubing function, this looks like: hcomplex cubeh(hcomplex *h) { cmplex c,d; hcomplex r; c=cubez(h->x-h->w,h->y+h->z); d=cubez(h->x+h->w,h->y-h->z); r.x=(c.x+d.x)/2.0; r.y=(c.y+d.y)/2.0; r.z=(c.y-d.y)/2.0; r.w=(d.x-c.x)/2.0; return(r); }
int snowflake(double x, double y) { if(y<0.0){ r1=0.0; r2=-1.0; return(TRUE); } if(x<(-y/1.7320508+1.0)){ r1=3.0*x; r2=3.0*y; return(TRUE); } if(x>=(-y/1.7320508+1.0) && x<1.5){ r1=(9.0-3.0*x-5.1961524*y)/2.0; r2=(5.1961524-5.1961524*x+3.0)/2.0; return(TRUE); } if(x>=1.5 && x<(x/1.7320508+2.0)){ r1=(3.0*x-5.1961524*y)/4.0; r2=(5.1961524*x+3.0*y-10.3923048)/4.0; return(TRUE); } r1=9.0-3.0*x; r2=3.0*y; return(TRUE); } int hype25() /* hypercomplex snowflake */ { double cx,cy,dx,dy; snowflake(a0-a3,a1+a2); cx=r1; cy=r2; snowflake(a0+a3,a1-a2); dx=r1; dy=r2; a0=(cx+dx)/2.0; a1=(cy+dy)/2.0; a2=(cy-dy)/2.0; a3=(dx-cx)/2.0; magh(); return(TRUE); } This example uses only complex z, but you could have a formula which used both z and c, and pass both sets of arguments to it, such as: someformula (h.x-h.k, h.y+h.j, c.x-c.k, c.y+c.j); Note the magh() function at the end of hype25(). This converts the hypercomplex variable into a complex modulus of z, for loop-bailout purposes. Magh() looks like: void magh() { double temp; zr=a0; temp=a1*a1+a2*a2+a3*a3; if(temp <= DBL_MIN) zi = 0.0; else zi=sqrt(temp); } What I haven't shown is an example that uses the discrete form of hypercomplex math in an actual formula. A simple example is: hype0() /* h^2+c */ { hcomplex h; h.x=a0; h.y=a1; h.z=a2; h.w=a3; sqrh(&h); a0=r1+conr; a1=r2+coni; a2=r3+conj; a3=r4+conk; magh(); return(TRUE); } |
Copyright © 1989-2005 Mystic Fractal. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of Mystic Fractal is prohibited. The name 'Mystic Fractal' and the Mystic Fractal logo are trademarks.