Here's a quick example of me attempting to design a domain from scratch to achieve a specific result. I just grabbed a raytracing routine which is used to map values in a unit square (from a pseudo or quasi random number generator) to a unit circle. This has no basis in complex numbers...it's just an ad-hoc function. Visually we'll see the opposite...we'll see circles being mapped to squares. Here's the base code:

const float M_PI = 3.141592653589793238463;

const float M_PI_2 = (M_PI * 0.5);

const float M_PI_4 = (M_PI * 0.25);

// Map 'c' within unit square ([0,1],[0,1]) to a unit disk

vec2 toUnitDisk(vec2 c)

{

c += c;

float a = c.x - 1.0;

float b = c.y - 1.0;

float t,r;

if (a*a > b*b) {

r = a;

t = M_PI_4*(b/a);

} else {

r = b;

t = M_PI_2 - M_PI_4*(a/b);

}

return r*vec2(cos(t),sin(t));

}

vec2 zortho(vec2 a) { return vec2(-a.y, a.x); }

So I replaced the contents of

`domainMap` with "

`return toUnitDisk(c);`" which ended up looking humanoid like, but turn sidewise. So to place the "head" up I needed to rotate it in the visual domain, so I changed the code to this:

vec2 domainMap(vec2 c) { return toUnitDisk(zortho(c)); }

Which results in this image:

http://roquendm.deviantart.com/art/Square1-396691344There are no squares because we don't have any circles about the origin, so let's get a square. There's a circle at (-1,0) so let's move that to the origin (from the function's perspective) and try again:

vec2 domainMap(vec2 c) { return toUnitDisk(c)-vec2(1.0,0.0); }

Which results in this image:

http://roquendm.deviantart.com/art/Square2-396691523Fun a square and a heart! Of course the image is distorted due to the nature of the transform. If I really cared I could try to come up with another transform to attempt to correct that.

Anyone that want to play around with this stuff, try looking at the domain plots I posted here:

http://s824.photobucket.com/user/RoquenDM/library/DomainPlots?sort=9&page=1.

Examine the identity transform and some other transform and then use that other transform for your domain mapping function.

Also fragmentarium has an example: Experimental/LiftedDomainColoring.

While I'm at it the domain images were created with Mathematica with some code I lifted from somewhere, here it is:

complexGrid =

Compile[{{max, _Real}, {n, _Integer}},

Module[{r}, r = Range[-max, max, 2 max/(n - 1)];

Outer[Plus, -I r, r]]];

complexHSB =

Compile[{{Z, _Complex, 2}},

Module[{h, s, b, b2}, h = 0.5 + Arg[Z]/(2 Pi);

s = Abs[Sin[2 Pi Abs[Z]]];

b = Abs[Sin[2 Pi Im[Z]] Sin[2 Pi Re[Z]]]^0.25;

b2 = 0.5 ((1 - s) + b + Sqrt[(1 - s - b)^2 + 0.01]);

Transpose[{h, Sqrt[s], b2}, {3, 1, 2}]]];

domainImage[func_, max_, n_] :=

ImageResize[

ColorConvert[

Image[complexHSB@func@complexGrid[max, 2 n], ColorSpace -> "HSB"],

"RGB"], n];

domainPlot[func_, max_: Pi, n_: 500] :=

ContourPlot[0, {x, -max, max}, {y, -max, max}, Contours -> {},

RotateLabel -> False,

FrameLabel -> {"X", "Y", ToString@StandardForm@func@"z"},

BaseStyle -> {FontFamily -> "Calibri", 14},

Epilog ->

Inset[domainImage[func, max, n], {0, 0}, {Center, Center},

2` max]];

And usage examples:

domainPlot[# &] (* identity *)

F[z_] := Abs[Re[z]] + I Im[z] (* the fold used in kaliset *)

domainPlot[F[#] &]

F[z_] = Sqrt[z*z] (* note relation to the kaliset fold *)

domainPlot[F[#] &]

domainPlot[Sin] (* zeroes along the x-axis yield one origin per zero, unless there's a constant added, in that case the constant will be the point of the base fractal mapped to the zero *)