G'MIC exercises

I was thinking more of this.

f "
begin(
    x_length=4;
    y_length=4;
    line_a_x(v)=(
        val=I(x,y,z,0,2);
        changes=0;
        for(n=1,n<v-1,n++,
            if(I(x+n,y,z,0,2)!=val,
            changes++;
            );
        );
        changes;
    );
);
line_a_x(x_length);
"

All you need to do is to add more macros, and then you have what you want.


Never mind. Thought of a way to minimize loop to find objects centers

Could someone explain how pattern works? E.g., polygon uses pattern.

polygon (+):
    N>=1,x1[%],y1[%],...,xN[%],yN[%],_opacity,_pattern,_color1,...

Pattern is an hexadecimal number with 8 digits, like 0xCCCCFFFF.
It has then 64 bits (0 or 1) that defines the pattern uses to draw the outline of the polygon.
Commonly used patterns are:

  • 0xFFFFFFFF : plain line. Use it to draw an outlined polygon.
    polygon0xFFFFFFFF

  • 0xF0F0F0F0 : dashed line with 8px plain, 8px empty:
    polygon0xF0F0F0F0

  • 0xCCCCCCCC : dashed line with 2px plain, 2px empty:
    polygon0xCCCCCCCC

  • 0xAAAAAAAA: dashed line with 1px plain, 1px empty:
    polygon0xAAAAAAAA

It’s quite flexible, as you can choose exactly what pattern you want.
For instance:

  • 0xF99FF99F gives something like this:
    polygon0xF99FF99F

Sorry, I have no idea how to decipher the hexadecimal value and how it contributes to the pattern. :blush: Could you please elaborate?

(Looks like more than 8 digits 0xccccccccc produces a solid line.)

You just write the sequence of 1 and 0 that defines your pattern (64 digits), and then use a binary to hexadecimal converter, as: https://www.rapidtables.com/convert/number/binary-to-hex.html![bin2hex|638x318](upload://iuD3o7yAr1VzYRVuG7HKvE4cZPH.png)

1 Like

To work on a neighbourhood of pixels (N), I would do

foo_k : check ${1=1}>=1
  f "begin(const boundary=1; const S=$1*2+1);
    ref(crop(x-$1,y-$1,0,c,S,S,1,1),N)"

How about a non-rectangular neighbourhood; e.g. an x shape?

xmarksthespot

In that case, you have to define your own pixel extraction macro, e.g.

xcross() = (
  ref(vector5(),res);
  res[0] = j(-1,-1);
  res[1] = j(1,-1);
  res[2] = i;
  res[3] = j(-1,1);
  res[4] = j(1,1);
  res;
);

If needed, it is possible to write some commands to auto-generate macros that do something similar according to a certain shape. I’ve done something like this for command percentile, with:

  # Generate code for masking.
  pass$1 0 !=. 0 N={is} if !$N rm. return fi 128,$N
  eval.. ">
    begin(
      p = 0;
      const w2 = int(w/2);
      const h2 = int(h/2);
    );
    i?(
      out = string('N[',p,']=j(',x - w2,',',y - h2,');');
      copy(i(#-1,0,p++),out,size(out));
    )"
  discard. 0 code={t} rm[-2,-1]
1 Like

How exactly should I format this? To expand, let’s say there’s 6 variables next to formulamode with formulamode set to 1, and 4 variables next to formulamode with formulamode set to 0. How should I format it so that cli users can understand there are 4 variables next to formulamode if it is set to 4, and 6 if it is set to 1?

#@cli rep_popcorn_fractal  : _pts_per_pixels>0,0<_density<=1,_H,_K,_zoom>0,_rotation_angle,_formulamode

If you would like to go by convention, you have two choices.

1 Easy: make 2 commands; one per mode.
2 Medium: allow 2 sets of parameters (see resize).

#@cli resize : [image],_interpolation,_boundary_conditions,_ax,_ay,_az,_ac : \
# {[image_w] | width>0[%]},_{[image_h] | height>0[%]},_{[image_d] | depth>0[%]},\
# _{[image_s] | spectrum>0[%]},_interpolation,_boundary_conditions,_ax,_ay,_az,_ac : (+)
1 Like

@afre

This doesn’t look nice.

#@cli rep_pfrac : eq. to 'rep_popcorn_fractal' : (+)
#@cli rep_popcorn_fractal: _pts_per_pixels>0,_density>0,_H,_K,_zoom,_rotation_angle,_origin_x,_origin_y,_formulamode : \
# _pts_per_pixels>0,_density>0,_H,_K,_zoom,_rotation_angle,_origin_x,_origin_y,_formulamode=0, _formulafunc_a={ 0=sin | 1=cos | 2=tan | 3=atan},, _formulafunc_b={ 0=sin | 1=cos | 2=tan | 3=atan}, _formulafunc_c={ 0=sin | 1=cos | 2=tan | 3=atan},_formulafunc_d={ 0=sin | 1=cos | 2=tan | 3=atan} : \
# _pts_per_pixels>0,_density>0,_H,_K,_zoom,_rotation_angle,_origin_x,_origin_y,_formulamode=0, _formulafunc_a={ 0=sin | 1=cos | 2=tan | 3=atan},, _formulafunc_b={ 0=sin | 1=cos | 2=tan | 3=atan}, _formulafunc_c={ 0=sin | 1=cos | 2=tan | 3=atan},_formulafunc_d={ 0=sin | 1=cos | 2=tan | 3=atan},_formulafunc_e={ 0=sin | 1=cos | 2=tan | 3=atan},_formulafunc_d={ 0=sin | 1=cos | 2=tan | 3=atan}

Output:

    rep_pfrac: Shortcut for command 'rep_popcorn_fractal'.

    rep_popcorn_fractal:
        _pts_per_pixels>0,_density>0,_H,_K,_zoom,_rotation_angle,_origin_x,_origin_y,\
         _formulamode |
        _pts_per_pixels>0,_density>0,_H,_K,_zoom,_rotation_angle,_origin_x,_origin_y,\
         _formulamode=0, _formulafunc_a={ 0=sin | 1=cos | 2=tan | 3=atan},, \
         _formulafunc_b={ 0=sin | 1=cos | 2=tan | 3=atan}, _formulafunc_c={ 0=sin | \
         1=cos | 2=tan | 3=atan},_formulafunc_d={ 0=sin | 1=cos | 2=tan | 3=atan} |
        _pts_per_pixels>0,_density>0,_H,_K,_zoom,_rotation_angle,_origin_x,_origin_y,\
         _formulamode=0, _formulafunc_a={ 0=sin | 1=cos | 2=tan | 3=atan},, \
         _formulafunc_b={ 0=sin | 1=cos | 2=tan | 3=atan}, _formulafunc_c={ 0=sin | \
         1=cos | 2=tan | 3=atan},_formulafunc_d={ 0=sin | 1=cos | 2=tan | 3=atan},\
         _formulafunc_e={ 0=sin | 1=cos | 2=tan | 3=atan},_formulafunc_d={ 0=sin | 1=cos \
         | 2=tan | 3=atan}

In fact, I think this is a good solution with clarification added.

#@cli rep_pfrac : eq. to 'rep_popcorn_fractal' : (+)
rep_pfrac: rep_popcorn_fractal $*
#@cli rep_popcorn_fractal: _pts_per_pixels>0,_density>0,_H,_K,_zoom,_rotation_angle,_origin_x,_origin_y,_formulamoda,_formulafunc_1.._formulafunc_n

Output

   rep_popcorn_fractal:
        _pts_per_pixels>0,_density>0,_H,_K,_zoom,_rotation_angle,_origin_x,_origin_y,\
         _formulamoda,_formulafunc_1.._formulafunc_n

I would do this

...parameters...,function1={ 0=sin | 1=cos | 2=tan | 3=atan },...

,... means this pattern continues
formula_mode isn’t necessary

PS Also consider function1={ sin | cos | tan | atan }, or even trig_function1 if you want to give the user all the power.

Question, what to do about Default values section? Formulamode defines whether there are 4 or 6 variables next to it. It is like a switch. The last half of those additional variables use the first half when undefined.

@afre This is what I came up with. I’m not a fan of the output, but it’s readable.

#@cli rep_pfrac : eq. to 'rep_popcorn_fractal' : (+)
#@cli rep_popcorn_fractal: _pts_per_pixels>0,_density>0,_H,_K,_zoom,_rotation_angle,_origin_x,_origin_y,_formulamode,_formulafunc_1={ 0=sin | 1=cos | 2=tan | 3=atan},...
#@cli : Generates Pickover Popcorn Fractal. Code was adapted from Paul Bourke's c code, and extended for more possibilities. Fractal is attributed to Clifford Pickover.\n
#@cli : Default values: '_pts_per_pixels=50','_density=1','_H=.05','_K=3','_zoom=1','_rotation_angle=0','_origin_x=0','_origin_y=0','_formulamode=0','_formulafunc_1=0','_formulafunc_2=2','_formulafunc_3=_formulafunc_1','_formulafunc_4=_formulafunc_2'\n
#@cli : Note: When _formulamode is equal to 1, then default values for _formulafunc1... becomes: '_formulafunc_1=0','_formulafunc_2=1','_formulafunc_3=2','_formulafunc_4=_formulafunc_1','_formulafunc_5=_formulafunc_2','_formulafunc_6=_formulafunc_2'

Output

    rep_pfrac: Shortcut for command 'rep_popcorn_fractal'.

    rep_popcorn_fractal:
        _pts_per_pixels>0,_density>0,_H,_K,_zoom,_rotation_angle,_origin_x,_origin_y,\
         _formulamode,_formulafunc_1={ 0=sin | 1=cos | 2=tan | 3=atan},...

      Generates Pickover Popcorn Fractal. Code was adapted from Paul Bourke's c code, and extended
        for more possibilities. Fractal is attributed to Clifford Pickover.

      Default values: '_pts_per_pixels=50','_density=1','_H=.05','_K=3','_zoom=1','_rotation_angle=0',
        '_origin_x=0','_origin_y=0','_formulamode=0','_formulafunc_1=0','_formulafunc_2=2',
        '_formulafunc_3=_formulafunc_1','_formulafunc_4=_formulafunc_2'

      Note: When _formulamode is equal to 1, then default values for _formulafunc1... becomes:
        '_formulafunc_1=0','_formulafunc_2=1','_formulafunc_3=2','_formulafunc_4=_formulafunc_1',
        '_formulafunc_5=_formulafunc_2','_formulafunc_6=_formulafunc_2'

Sorry, that’s really hard to follow. I actually had to rewrite this post a few times because I realized that I misunderstood something each time. :confused::dizzy_face:

I stand by my advice and would add that you haven’t explained what _formulamode does in your description. (It is implied in the note but the user has to connect a few dots.)

Ok, here’s the full cli and output

#@cli rep_pfrac : eq. to 'rep_popcorn_fractal' : (+)
#@cli rep_popcorn_fractal: _pts_per_pixels>0,_density>0,_H,_K,_zoom,_rotation_angle,_origin_x,_origin_y,_formulamode,_formulafunc_1={ 0=sin | 1=cos | 2=tan | 3=atan},...
#@cli : Generates Pickover Popcorn Fractal. Code was adapted from Paul Bourke's c code, and extended for more possibilities. Fractal is attributed to Clifford Pickover.\n
#@cli : _pts_per_pixels defines the maximum number of points to be added on image based on pixel location.
#@cli : _density defines the frequency of points to be added along row and height of image. A value of one implies n points to be added per pixel. 
#@cli : _H is the function multiplier used to subtract from the new found values from each iteration.
#@cli : _K is the inner multiplier for the inside function. See popcorn_x(a,b), and popcorn_y embedded within the code of rep_popcorn_fractal for more information.
#@cli : _zoom defines the magnification of image. A negative value will "shrink" the structure of generated fractal.
#@cli : _rotation_angle defines the function angle of fractal.
#@cli : _origin_x defines the position of fractal. Center of image row will be treated as zero, and the ranges for image row are treated as -1,1.
#@cli : _origin_y defines the position of fractal. Center of image column will be treated as zero, and the ranges for image column are treated as -1,1.
#@cli : _formulamode defines whether to use 4 trigometric functions or 6 trigometric functions.
#@cli : _formulafunc_n defines the individual trigometric function to be used. The last half use the function on first half unless the user defines the trigometric function.\n
#@cli : Default values: '_pts_per_pixels=50','_density=1','_H=.05','_K=3','_zoom=1','_rotation_angle=0','_origin_x=0','_origin_y=0','_formulamode=0','_formulafunc_1=0','_formulafunc_2=2','_formulafunc_3=_formulafunc_1','_formulafunc_4=_formulafunc_2'\n
#@cli : Note: When _formulamode is equal to 1, then default values for _formulafunc1... becomes: '_formulafunc_1=0','_formulafunc_2=1','_formulafunc_3=2','_formulafunc_4=_formulafunc_1','_formulafunc_5=_formulafunc_2','_formulafunc_6=_formulafunc_3'
    rep_pfrac: Shortcut for command 'rep_popcorn_fractal'.

    rep_popcorn_fractal:
        _pts_per_pixels>0,_density>0,_H,_K,_zoom,_rotation_angle,_origin_x,_origin_y,\
         _formulamode,_formulafunc_1={ 0=sin | 1=cos | 2=tan | 3=atan},...

      Generates Pickover Popcorn Fractal. Code was adapted from Paul Bourke's c code, and extended
        for more possibilities. Fractal is attributed to Clifford Pickover.

      _pts_per_pixels defines the maximum number of points to be added on image based on pixel location.
      _density defines the frequency of points to be added along row and height of image. A value of
        one implies n points to be added per pixel.
      _H is the function multiplier used to subtract from the new found values from each iteration.
      _K is the inner multiplier for the inside function. See popcorn_x(a,b), and popcorn_y embedded
        within the code of rep_popcorn_fractal for more information.
      _zoom defines the magnification of image. A negative value will "shrink" the structure of
        generated fractal.
      _rotation_angle defines the function angle of fractal.
      _origin_x defines the position of fractal. Center of image will be treated as zero, and x-axis+
        y-axis are both treated as -1,1 range.
      _origin_y defines the position of fractal. Center of image will be treated as zero, and x-axis+
        y-axis are both treated as -1,1 range.
      _formulamode defines whether to use 4 trigometric functions or 6 trigometric functions.
      _formulafunc_n defines the individual trigometric function to be used. The last half use the
        function on first half unless the user defines the trigometric function.

      Default values: '_pts_per_pixels=50','_density=1','_H=.05','_K=3','_zoom=1','_rotation_angle=0',
        '_origin_x=0','_origin_y=0','_formulamode=0','_formulafunc_1=0','_formulafunc_2=2',
        '_formulafunc_3=_formulafunc_1','_formulafunc_4=_formulafunc_2'

      Note: When _formulamode is equal to 1, then default values for _formulafunc1... becomes:
        '_formulafunc_1=0','_formulafunc_2=1','_formulafunc_3=2','_formulafunc_4=_formulafunc_1',
        '_formulafunc_5=_formulafunc_2','_formulafunc_6=_formulafunc_3'

Note: Each halves of formulafunc series are used in different-axis formulas. Yes, they’re part of popcorn_x(a,b), and popcorn_y(a,b) macro.

Make it more readable.

1 Only prepend _s on the line the parameters first appear, where they serve a purpose.

2 Reduce the amount of text.

3 Add spaces after ,s.

I suggest you replace “default values” and “note” with this (and put it above the parameters’ description).

Default values:

  If mode=0: 'points=50', 'density=1', 'H=.05', 'K=3', 'zoom=1', 'angle=0', 'origin_x=0',
    'origin_y=0', 'mode=0', 'fn1=fn3=0' and 'fn2=fn4=2'.

  If mode=1: 'points=50', 'density=1', 'H=.05', 'K=3', 'zoom=1', 'angle=0', 'origin_x=0',
    'origin_y=0', 'mode=1', 'fn1=fn4=0', 'fn2=fn5=1' and 'fn3=fn6=2'.
1 Like

That’s actually what I was looking for. Thank you so much! I don’t get the 3 part though.

Ok, I think I’ll settle for this. Though, I have a concern that it might be confusing. I did left a little note though pointing that fx_n comes before fy_n. I guess I shouldn’t use fx_n, or fy_n.

    rep_pfrac: Shortcut for command 'rep_popcorn_fractal'.

    rep_popcorn_fractal:
        _points>0,_density>0,_H,_K,_zoom,_rotation_angle,_origin_x,_origin_y,_mode,\
         _fx_1={ 0=sin | 1=cos | 2=tan | 3=atan},...,_fy_1={ 0=sin | 1=cos | 2=tan | \
         3=atan},...

      Generates Pickover Popcorn Fractal. Code was adapted from Paul Bourke's c code, and extended
        for more possibilities. Fractal is attributed to Clifford Pickover.

      _points defines the maximum number of points to be added on image based on pixel location.
      _density defines the frequency of points to be added along row and height of image. A value of
        one implies n points to be added per pixel.
      _H is the function multiplier used to subtract from the new found values from each iteration.
      _K is the inner multiplier for the inside function. See popcorn_x(a,b), and popcorn_y embedded
        within the code of rep_popcorn_fractal for more information.
      _zoom defines the magnification of image. A negative value will "shrink" the structure of
        generated fractal.
      _rotation_angle defines the function angle of fractal.
      _origin_x defines the position of fractal. Center of image row will be treated as zero, and the
        ranges for image row are treated as -1,1.
      _origin_y defines the position of fractal. Center of image column will be treated as zero, and
        the ranges for image column are treated as -1,1.
      _mode defines whether to use 4 trigometric functions or 6 trigometric functions. Each halves of
        functions are used on 2 functions used by different axis.
      _fx_n defines individual function used for x-axis function.
      _fy_n defines individual function used for y-axis function.

      Default values: '_points=50','density=1','H=.05','_K=3','_rotation_angle','_origin_x=0',
        '_origin_y=0','_mode=0',...

          If _mode=0: ... : '_fx_1=_fy_1=0','_fx_2=_fy_2=2'
          If _mode=1: ... : '_fx_1=_fy_1=0','_fx_2=_fy_2=1','_fx_3=_fy_3=1'

@David_Tschumperle It has been a year but I still haven’t figured out how to use search_dichotomic in math_lib form. An example would be nice. :crossed_fingers:

@Reptorian You could chime in if you wish using the example from post #131.

Did you try eval ${-math_lib}"". I think to do it, you need to make a for x, for y loop. It’s possible multiple loops would be needed though.