G'MIC Adventures: Samila Mappings

Given that @David_Tschumperle has been making his own G’MIC adventures series, I thought I could join in the fun. Right now, I looked back at Paul Bourke’s website, and saw samila mappings.

Here is a example of samila mapping:


And the explanation goes like this:

Now, I have no idea what this means yet, but I do strongly suspect it is related to one of my code. But, my guess is that it is related to Henon Phase, which I do have code for.

So far, this is my code based on my guess, and it doesn’t look good:

#@cli rep_samila:
#@cli : Test code to test samila mapping
rep_samila:
channels. 0
200%,200%,1,2,"begin(
		const shift_x=w#-1/2;
		const shift_y=h#-1/2;
		const mx=w-1;
		const my=h-1;
		const cx=mx/2;
		const cy=my/2;
		const sd=max(w,h)/min(w,h);
		const sx=w>h?cx/sd:cx;
		const sy=w>h?cy:cy/sd;
		const scale_factor=min(cx,cy)*.12;
		f1(X,Y)=sqr(X)-sin(sqr(Y))+abs(Y-X);
		f2(X,Y)=sqr(Y)-cos(sqr(X))+2*X;
	);
	X=(x-cx)/sx;
	Y=(y-cy)/sy;
	result=[f1(X,Y),f2(X,Y)]*scale_factor+[shift_x,shift_y];
	++I(#-1,result);
	result;
	"

I’m a bit rusty with math parser code as all I been doing is refactoring and improving other G’MIC codes, but should be able to pick up regardless.

The above code gives me this:

Source: samila mappings

My version:

samilla :
  15000,15000,1,2,":
    const r = 0.05;
    f1(x,y) = (r*x^2 - sin(y^2) + abs(y - x));
    f2(x,y) = (r*y^3 - cos(x^2) + 2*x);

    x = lerp(-pi,pi,x/w);
    y = lerp(-pi,pi,y/h);

    f1xy = f1(x,y);
    f2xy = f2(x,y);

    nx = f1xy*cos(f2xy);
    ny = f1xy*sin(f2xy);

    [ nx,ny ]"
  s. c n[-2,-1] 50,750 a[-2,-1] c round.

  800,800
  eval.. ";++i(#-1,i0,i1); I" rm..

  n. 0,1 pow. 0.3 n. 0,255
  map cube

1 Like

And a variant, using an image as a source for colors :

foo :
  1024,1024,1,4 # Output image

  15000,15000,1,2,":
    const r = 0.025;
    f1(x,y) = (r*x^2 - sin(y^2) + abs(y - x));
    f2(x,y) = (r*y^3 - cos(x^2) + 2*x);

    x = lerp(-pi,pi,x/w);
    y = lerp(-pi,pi,y/h);

    f1xy = f1(x,y);
    f2xy = f2(x,y);

     nx = f1xy*cos(f2xy);
     ny = f1xy*sin(f2xy);

    [ nx,ny ]"
  s. c n[-2,-1] {0,[50,w-50]} a[-2,-1] c round.

  sp colorful
  eval.. "
    const interpolation = 1;
    X = lerp(0,w#-1,x/w);
    Y = lerp(0,h#-1,y/h);
    I(#0,i0,i1)+=[ I(#-1,X,Y),1 ];
    I
  "
  k[0] s c,-3 max. 1 /

1 Like

@David_Tschumperle Thank you so much, I been able to progress my own version:

I added notes to this version for future release version:

#@cli rep_samila:
#@cli : Test code to test samila mapping
rep_samila:
channels. 0

1000%,1000%,1,2,:" # The dimensions doesn't have to be a rectangle in case of rectangle input. So, force squre dimensions is to be user-defined.
	begin(
		const mx=w-1;
		const my=h-1;
		const cx=mx/2;
		const cy=my/2;
		const sd=max(w,h)/min(w,h);
		const sx=(w>h?cx/sd:cx)/pi;
		const sy=(w>h?cy:cy/sd)/pi;

		f1(X,Y)=r*X^3-sin(sqr(Y))+abs(Y-X);
		f2(X,Y)=r*Y^3-cos(sqr(X))+2*X;

		# Planned to be used with user-defined setting
		const use_polar=1;
		const ang=45;
		const r=.05;
		const use_rotation=ang%360;

		if(use_rotation,
			const cos_ang=cos(ang);
			const sin_ang=sin(ang);
			rot_x(a,b)=a*cos_ang-b*sin_ang;
			rot_y(a,b)=a*sin_ang+b*cos_ang;
		);
	);

	X=(x-cx)/sx;
	Y=(y-cy)/sy;

	nx=f1(X,Y);
	ny=f2(X,Y);

	if(use_polar,
		tx=nx;
		nx*=cos(ny);
		ny=tx*sin(ny);
	);

	if(use_rotation,
		tx=nx;
		nx=rot_x(nx,ny);
		ny=rot_y(tx,ny);
	);

	[nx,ny];
	"

s. c
n[-2,-1] 50,750 # Needs to be user defined. Also, this is dependent on values, so I will find a way to make sure user-defined setting don't automatically rescale to refit.
a[-2,-1] c
round.

eval. ":++i(#-2,i0,i1);I" rm.

n. 0,1 pow. 0.4

Result test: