G'MIC fun with Reptorian

In the Generative discord, @weightt_an posted this code - p5.js Web Editor

Fun Code (Too slow for actual usage)
rep_quick_test:
{w},{h},1,1,"begin(
 const scaleP=2;
 const wx=.043333;
 const wy=.053333;
 const a=.7;
 const TWO_PI=pi*2;
);
xx=scaleP*x/w;
yy=scaleP*y/h;
for(n=0,n<10,n++,
 newx=xx+wx-a/(TWO_PI*sin(TWO_PI*yy));
 newy=yy+wy-a/(TWO_PI*sin(TWO_PI*xx));
 xx=newx%w;
 yy=newy%h;
 i(#0,xx,yy)++;
);
"
rm..

Coded it in gmic for fun.

3 Likes

Add several eyes and you will have a freakier image.

like this? Ü

3 Likes

cool! can you make a bigger version? like 3000 x 3000 or something like that

It reminds me of the nebulous filter I had made (code isn’t entirely my creation, I translated c# into gmic and extended it as well as optimized it) though I didn’t use that much distortion for this one (can be set to use more), but the idea should be similar as I think they both use trigonometric functions. But, to answer your question, yes.

This is the filter I refer to:

Code is super simple, here's the code
#@cli rep_nebulous: _main_surf_xy_factor>0,_main_surf_x_factor>0,_main_surf_y_factor>0,-100<=_x_center[%]<=100,-100<=_y_center[%]<=100,0<=_fxyangle<=360,_wave,0<=_lighting_angle<=360,_disturbance>=0,_distx,_disty,0<=_distangle<=360,_disturbance_mode={ 0= do_not_scale | 1=scale_by_axisfact },_color={ 0=gray | 1=color },_alpha_base={ 0=None | 1=hard_light | 2=hard_shade | 3=soft_light | 4=soft_light },_subpixelevel>=0,subpixelprocessingmethod={ 0=Average | 1=Linear | 2=Grid | 3=Bicubic | 4=Lanczos }
#@cli : Creates a Nebulous texture inspired by its Paint.NET plugin equivalent made by MadJik.\n
#@cli : '_main_surf_xy_factor' - Amount of waves by xy-axis.
#@cli : '_main_surf_x_factor' - Amount of waves by x-axis.
#@cli : '_main_surf_y_factor' - Amount of waves by y-axis.
#@cli : '_x_center' - Placement of Nebulous texture relative to the center by x-axis.
#@cli : '_y_center' - Placement of Nebulous texture relative to the center by y-axis.
#@cli : '_fxyangle' - Function angle of Nebulous texture.
#@cli : '_wave' - Amount of waves within waves.
#@cli : '_lighting_angle' - Shifts color output within waves
#@cli : '_disturbance' - Multiplier for distortion.
#@cli : '_distx' - Distorts function by x-axis.
#@cli : '_disty' - Distorts function by y-axis.
#@cli : '_distangle' - Distortion function Angle
#@cli : '_disturbance_mode' - Influences how the distortion result is calculated.
#@cli : '_color' - Color Output
#@cli : '_alpha_base' - determines the alpha based on waves angle.
#@cli : '_subpixelevel' - Subpixel processing level
#@cli : '_subpixelprocessingmethod' - Subpixel processing method. Only applicable when '_subpixelevel' is greater than 0.\n
#@cli : Default value: '_main_surf_x_factor=10','_main_surf_y_factor=10','_x_center[%]=0','_y_center[%]=0','_fxangle=0','_wave=1','_lighting_angle=0','_disturbance=0','_distx=100','_disty=100','_distangle=0','_disturbance_mode=0','_color=1','_alpha_base=0','_subpixellevel=1','_subpixelprocessingmethod=1'\n
#@cli : Author: Reptorian.
#@cli : $ 640,480,1,1 rep_nebulous 10,,,,,45,,,750,100,100,15,0,1,3 n 0,255 drgba
rep_nebulous:
skip ${2=10},${3=10},${4=0},${5=0},${6=0},${7=1},${8=0},${9=0},${10=100},${11=100},${12=0},${13=0},${14=1},${15=0},${16=0},${17=1}
if $1==0||$2==0||$3==0 v + error "Variable 1 to 3 cannot be zero!" v - fi
if $9<0 v + error "Disturbance factor cannot be less than 0!" v - fi
use_sub={abs($16)}
sublevel={$use_sub+1}
spec_count={!14?0+($15?1:0):3+($15?1:0)}
repeat $! l[$>]
 iw={w}
 ih={h}
 {$use_sub?w*$sublevel:w},{$use_sub?h*$sublevel:h},1,$spec_count,"begin(
   const sd=w/h;
   const shx=($4*w)/2;
   const shy=($5*h)/2;
   const sx=w>h?1:1/sd;
   const sy=w>h?sd:1;
   const sx2=2/sx;
   const sy2=2/sy;
   const ang=-pi*$6/180;
   const cos_ang=cos(ang);
   const sin_ang=sin(ang);
   const distlvl=$9*$1;
   const dist=pi/(distlvl/100);
   const disth=$10;
   const distv=$11;
   const dang=-pi*$12/180;
   const cos_dang=cos(dang);
   const sin_dang=sin(dang);
   const k=pi+((-pi+(pi*$7))*10)/10;
   const ld=-($8-$6)*pi/180;
   const IX_mul=$2*4;
   const IY_mul=$3*4;
   const cx_mul=$13?$2:1;
   const cy_mul=$13?$3:1;
   const iml=1.5*($1*10);
   const angld=ang+ld;
   const hpi=pi/2;
  );
  ix=(((x+shx)/w-.5)*iml)/sx;
  iy=(((y+shy)/h-.5)*iml)/sy;
  IX=ix*cos_ang-iy*sin_ang;
  IY=ix*sin_ang+iy*cos_ang;
  IX*=IX_mul;
  IY*=IY_mul;
  if(distlvl,
   dix=(x/w-.5)*sx2;
   diy=(y/h-.5)*sy2;
   DIX=dix*cos_dang-diy*sin_dang;
   DIY=dix*sin_dang+diy*cos_dang;
   cx=DIX*cx_mul;
   cy=DIY*cy_mul;
   fsd=sin(((cx+cy)/2)/dist);
   fcd=cos(((cy-cx)/2)/dist);
   IX+=disth*(fsd-fcd);
   IY-=distv*(fsd+fcd);
  );
  t=atan2(IY,IX);
  r=sqrt(IX*IX+IY*IY)/100;
  ti=sin(t)*cos(r)*k+r+angld;
  $15?(
   cg=[sin(pi+ti),sin(hpi+ti),sin(ti)];
   g=sum(cg);
   alp=$15>2?($15==3?g:g*-1):($15==2?(g*-1<0?-1:1):(g<0?-1:1));
   $14?[cg,alp]:[g,alp];
  ):(
   $14?[sin(pi+ti),sin(hpi+ti),sin(ti)]:sin(ti)+sin(hpi+ti)+sin(pi+ti);
  );"
 rm..
 if $use_sub r $iw,$ih,1,{s},{$17+2} fi
endl done

On the 3000x3000, ask and you shall receive:

3 Likes

awesome!

A new concept idea (Not sure what to name it)

gmic shape_circle 500 r. 200%,200%,100%,100%,0,0,.5,.5 rep_frblur 5,200 *. 255 +store. test_image +colormap. 2 r. {w-1},100%,100%,100%,0,0,1 r.. 100%,100%,{w#-1},100%,0,1 f.. i">"i(#-1,z,0,0); rm. s z distance 0,2 n 0,1 blend average * 2 f i"^"2 $test_image +f. i">"0?1 distance. 0,2 mv[1] 0 rv[-2,-1]

Middle is distance. Right is looped distance (I’ll name it looped distance).

1 Like

Looks practical. :+1:

Not sure what name would describe this. Make more samples to brainstorm.

Here you go. Before is on left, after is on right.

What you can see here is that it’s supposed to be a float-based form of distance.

@David_Tschumperle might be able to implement a better version of this idea.

1 Like

Looks like fun. Could consider throwing in a cost image. (a.k.a. " Custom Metric Maps")

Yeah, only problem is that very accurate result requires intensive memory. I wish there was a float-based version of distance.

distance already returns a float-valued image, so what do you mean by this?

Taking into account of weigh of shading which is why I did a loop utilizing threshold and combine them together.

This would be actually equivalent to the computation of a geodesic distance, and this cannot be achieved in linear time (which is current implementation of distance is able to do).

So, basically gmic doesn’t have geodesic distance? It’s a little convoluted to wrap my head around though. Maybe later, I’ll try that.

Computing a geodesic distance basicaly involve the resolution of the eikonal equation where f(x) corresponds to the local weights of your distance function.
This can be done iteratively, with the Fast Marching method. I’m 100% sure this can be implemented with G’MIC.

As mentionned in the wikipedia page, another way of computing such a geodesic distance is to use the Dijkstra algorithm (in G’MIC, with command djikstra), but this basically requires to define a huge matrix, so this would not be optimal.

<https://pixls-discuss.s3.dualstack.us-east-1.amazonaws.com/original/3X/9/b/9b946cee771a062b3bf0d533fd9bf5b3cdd28687.jpeg

Can you make generator for only one of the square which is faster?

The number of square is irrelevant to the speed. The code is why it is so slow. There’s no way to optimize it. If I did, then it’d be a new filter. Hence, why I posted it here.

Nevertheless, could you make generator for only one square pattern ?

Yes, I can do that. I’ll get to that today.

Edit: I forgotten, I was doing other projects.