Reptorian G'MIC Filters

Perfect for sound wave animation.

1 Like

Yes, the code can utilize animation indeed.

Another test picture:

image

Next part is to create catmull-clark interpolation along pixel.

3 Likes

EDIT: Never mind. Forget that I asked. I found this in k3dsurf which can be used to create steerable guassian.

4*x*exp(-x^2-y^2)

I ended up making a fork of Poisson Noise by @David_Tschumperle as I didn’t want to use extract for speed purposes. Also, it does utilize mask as a option. For now, I’ll just share the code of the fork. I wanted to do this in a while, but done with it.

I might make another fork of it where density is localized.

Fork of Poisson Noise
#@cli rep_noise_poissondisk_to_coordinates : _radius[%]>0,_max_sample_attempts>0,_use_mask={ 0=ignore_mask | 1=utilize_mask }
#@cli : Generates coordinates utilizing a fast poisson disk generation. Forked from David Tschumperlé original code just for this purpose. Requires a image to have a mask.
#@cli : Implements the algorithm from the article "Fast Poisson Disk Sampling in Arbitrary Dimensions",
#@cli : by Robert Bridson (SIGGRAPH'2007).
#@cli : Default values: 'radius=8' and 'max_sample_attempts=30'.
#@cli : $ 300,300 rep_noise_poissondisk_to_coordinates 8
rep_noise_poissondisk_to_coordinates : 
skip "${3=0}"
check "${1=8}>0 && ${2=30}>0"
e[^-1] "Extract poisson disk sampling points coordinates with radius $1 and max sample attempts $2."
repeat $! l[$>]

 R={${"is_percent $1"}?max(w,h,d)*$1:$1}
 
 dim={d>1?3:h>1?2:1} 
 cw={0.999*$R/sqrt($dim)}
 
 ({[w,h,d,1]}) y. c
 
 {[ceil(I/$cw)]}
 
 r[1] 1,1,1,$dim,-1
 
 1,1,1,$dim 1,1,1,1
 
 {vector$dim(2*ceil(sqrt($dim))+1)} r. 100%,100%,100%,2
 
 f. "P=[x,y,z]-int([w/2,h/2,d/2]);[sum(sqr(P)),dot(P,[1,w#2,w#2*h#2])]"
 
 r. {[whd,s,1,1,-1]} sort. +,x z. 0,1,100%,100% y. c
 
 eval ${-math_lib}"
 
  begin(
   dotoff = resize([ 1,w#2,w#2*h#2 ],d#2>1?3:h#2>1?2:1,0););
   const N = "$dim";
   const radius = "$R";
   const grid_cw = "$cw";
   const max_sample_attempts = $2;
   const value = iM#0 + (im#0==iM#0);
   const use_mask = $3;
  
   mag2(vec) = sum(sqr(vec));
   prox = I#5;
   lim = I#1;
   dar_insert(#3,I#1,0);               # dummy sample to simplify bounds checks
   dar_insert(#3,u(I#1),1);            # add initial sample to list
   dar_insert(#4,1,0);                 # add its index to active list
   I(#2,int(I[#3,1]/grid_cw)) = 1;     # add its index to grid cell
   I(#0,I[#3,1]) = value;              # draw the point
  
   while (dar_size(#4)>0,
  
    R = int(u(dar_size(#4)-1e-4));    # choose a random active list index
    P = i[#4,R];                      # get the index of that sample
    T = I[#3,P];                      # position vector of that sample

    repeat (max_sample_attempts,attempts,

     do (S = 4*(u(vectorN(1)) - 0.5); M = mag2(S), M <= 1 || M > 4);
     X = T + radius * S;
     if (min(X)<0 || min(lim-X)<0, continue());
     G = int(X/grid_cw);
     GI = dot(G,dotoff);
     
     for (K = 0; rejected = 0, K<size(prox), ++K,
      V = i[#2,GI+prox[K]];         # sample index from grid to check
      if (V>0 && mag2(I[#3,V]-X)<sqr(radius), rejected = 1; break())
     );
    
     if (!rejected,
      if(use_mask,!sum(I(#0,X))?break(););
      Q = dar_size(#3);               # sample found, get new index
      dar_insert(#3,X);               # insert into samples list
      dar_insert(#4,Q);               # insert its index into active
      I(#2,G) = Q;                    # insert its index into grid
      break();
     );
    );  
    if (attempts==max_sample_attempts, dar_remove(#4,R));     
   );
   end(resize(#3,1,dar_size(#3),1,s(#3),0););
   "
   td={(w#0>1)+(h#0>1)+(d#0>1)}
   td-=1
   channels[3] 0,$td
   k[3]
endl done

Let me give credit where credit is due, the poissondisk noise has been implemented by @garagecoder, not me.

For reference, starts here: G'MIC exercises - #177 by garagecoder.

@David_Tschumperle @afre Noted. I changed name in my user.gmic.

Ok, I am getting somewhere with the Lyapunov Fractal. Not so interesting IMO in terms of coloring.

image

image

Examples here look like you could have at least two opponent colours. Again, I want to point out that many of your filters could have an animated version (or at least allow frame exports).

Yes, I do realize that they could use animation. That would take a while to do. A long project.

That being said, I’m closer, but not quite there.

image

EDIT: New duotone output:

image

1 Like

Not really much news, but I added dx,dy into Thorn Fractal, and added useful and accessible variables to information of GUI Thorn Fractal. They were already accessible before.

One note:

altern is accessible, but not sure if anyone tested that, and I find it redundant when alternating formula allows you to use formulas based on altern.


EDIT: I managed to get double random gradients mode. I will add singular gradient mode next.


EDIT:

I had fixed some bugs on Random Gradient Bars.

More EDIT on Random Gradient Bars:

  1. The CLI command accepts percentage to define bar and width size. In addition, it also accepts hexadecimal representation of RGB color to define its color.

  2. The GUI command offers more control over bar and space size.

  3. Output is generally better now.

In addition:

I added two useful generic commands.

rep_hex2int8 and rep_int82hex enables to directly convert a command argument into a variable formatted as 8i representation or hex representation. An alternative to img2hex and hex2img. rep_hex2int8 will automatically convert capital letter into lower case, and that’s another way it makes things easier.

I added those two as these 2 would allow to make commands utilizing hexadecimal as color argument easier to make.

Here is a example:

> $ rep_hex2int8 20ecdf echo ${}
> 32,236,223

Guess what it is I’m making?

256,256,256,3,[x,y,z] #The RGB index# 
256,256,256,1,1 #Evaluates whether rgb color is available, 1 is yes, 0 is no#
4096,4096,1,3,-1 #The Target Image#

m "create_coordinate_reference: $_cpus,1,1,1,>\"begin(
 v_pixel_id=vectorw(-1);
);
new_id=round(u(0,16777215));
while(isin(new_id,v_pixel_id),
 new_id=round(u(0,16777215));
);
new_id;
\""

create_coordinate_reference #Generate a reference image to create a set of initial rgb#
create_coordinate_reference #Generate a second reference image to create a set of placement point#

int2rgb..

eval. :"
coordinate_index=i;
color_pixel=I(#-2);
ix=coordinate_index%4096;
iy=int(coordinate_index/4096);
I(#-3,ix,iy)=color_pixel;
i(#-4,color_pixel)=0;
"

Still no guess. Well, the answer is Rainbow Smoke algorithm.

I decided to put that on hold.

I added another coloring mode to the Lyapunov Fractal. Behold, the results:

image

Next up is allow the user to insert images as an argument for coloring.

1 Like

New Filter! - Weighted RGB To Grayscale

Output with efforts using the filter:

Based on MJW Black and White + PDN plugin, I have decided to make my own twist based on some of the principles found in that plugin. This is my own take on the ideas founded on that plugin.

I believe @iarga would like to use this now coming to think of it.

1 Like

Any reason why am I not getting what I want in here - https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.258.6666&rep=rep1&type=pdf

The most faithful code translation I did:

rep_popcorn_fractal_imaginary:
skip ${1=21},${2=5},${3=.05}

#$1 == iteration#
#$2 == density#
#$3 == h#

iw={w-1}
ih={h-1}

channels. 0 f. 0

{int(w*abs($2))},{int(h*abs($2))},1,3 

f. ":begin_t(
  const ww="$iw";
  const hh="$ih";
  const icx=ww/2;
  const icy=hh/2;
  const pts=$1;
  const H=$3;
  const cx=(w-1)/2;
  const cy=(h-1)/2;
  const ms=1124;
  real(a)=a[0];
  imag(a)=[a[1],0];
  g1(n)=sin(n);
  g2(n)=tan(n);
  flip(v)=[v[1],v[0]];
  a=[3,0];
  const ang=deg2rad(45);
 );
 ix=(x-cx)/cx;
 iy=(y-cy)/cy;
 zz=[ix,iy];
 repeat(pts,
  nx=[zz[0],0];
  ny=[zz[1],0];
  tx=nx;
  nx=nx-H*(g1(ny+g2(a*ny)))[0]-H*(g1(nx+g2(a*nx)))[1];
  ny=ny-H*(g1(tx+g2(a*tx)))[0]-H*(g1(ny+g2(a*ny)))[1];
  zz=nx+[0,ny[0]];
  nx=nx/norm(zz);
  ny=ny/norm(zz);
  zz=nx+[0,ny[0]];
  i(#-2,zz[0]*icx/2+icx,zz[1]*icy/2+icy)++;
  if(norm(zz)>=ms,break());
 );
 zz;
 "

And here’s the C++ code from the website

void main()
{
 double xmax=1.7,xmin=-1.7,ymax=1.7,ymin=-1.7,deltap,deltaq;
 int max_iterations=21;
 int max_size= 1124.0;
 fractal(xmax,xmin,ymax,ymin,max_iterations,max_size);
 getch();
 closegraph();
}

complex g1(complex x){return (sin(x));}

complex g2(complex x){return (tan(x));}

doublecabs(complex z){return sqrt (norm(z));}

complex flip(complex c){return complex(imag(c),real(c)); }

voidfractal(doublexmax,doublexmin,doubleymax,doubleymin,intmax_iterations,intmax_size)
{
 complex c,z;    
 complex x,y,px,a=complex(3,0);
 int color;
 float col=0,row;
 float dist;
 double deltap,deltaq;
 float h=.05;
 deltap=(xmax-xmin)/480;
 deltaq=(ymax-ymin)/480;
 while(!kbhit()&&col<480){ 
  col+=1;
  for(row=0;row<480;row+=1){
   z=c=complex(xmin+col*deltap,ymax-row*deltaq);
   color=0;
   while((color<max_iterations)&&(norm(z)<max_size)){
    x=real(z),y=imag(z);
    px=x;
    x=x-h*real(g1(y+g2(a*y)))-h*imag(g1(x+g2(a*x)));
    y=y-h*real(g1(px+g2(a*px)))-h*imag(g1(y+g2(a*y)));
    z=(x)+flip((y));
    x=x/complex(norm((z)),0.0),
    y=y/complex(norm((z)),0.0);
    z=(x)+flip((y));
    color++;
    floatangle=45.*3.14/180.;
    int x0=(real(z)*cos(angle)-imag(z)*sin(angle)-xmin)/deltap,y0=(ymax-real(z)*sin(angle)-imag(z)*cos(angle))/ deltaq;if(getpixel(x0+50,y0)<224)putpixel(x0+50,y0,getpixel(x0+50,y0)+1);
   }
  }
 }
}

EDIT:

I do not think I’ll be able to do the complex version of the Popcorn Fractal. All attempts have failed.

(irrelevant part of post deleted)

New Filter! Markus-Lyapunov Fractal!

2 Likes

The background looks like pavement slick with rain.

Now that you mentioned it, I see it too. Here’s another take I did with the new filter.

The foreground shapes remind me of

Now, I figured out how a youtuber extended Lyapunov Fractal to be allowed with c. It’s just another dimension per say.

Have a look:

Absolutely terrible. :confused: Ah well, I don’t want to do much more resolution or otherwise it will take long to render.


I had pushed adding one more dimension to Lyapunov Fractal. Now, the letter ‘C’ is an accepted character. For 3D image, every first three letters are mandatory. For 2D image, every first two letters are mandatory, but c is optional.

1 Like

I will be adding more predefined formulas to Thorn Fractal.

Any name for this one?

image

I was thinking of going with Chaotic Antique Attic .

To me, chaotic isn’t very descriptive and I don’t get any antique attic vibes. The pattern evokes a viscous liquid manipulated to make a pattern; e.g., what we do with chocolatey desserts or resins.

PS Your new display picture isn’t as eye catching as your previous two.