The Big Bad G'MIC Thread of Silly Questions

You can actually compute the autocrop and check if the resulting image is not empty:

# Assuming [-1] is an image of some kind.
+autocrop. 0 
if !w # Empty image -> all image has been cropped
  rm.  # Keep the original image
else
  rm.. # Keep the cropped image
fi
1 Like

Thanks, it works fine. Actually, that was easier than i thought :flushed:

btw, how does if !w know which image to check? Is it always [-1] by default?

Yes, by default, a math expression outside a fill use the latest image as the “reference image”.
That is very convenient.

1 Like

Hi,
i’m trying to draw circles in random positions but i don’t want them to be clipped if the center is too close to the image’s edge, so i want to shift the circle’s center back into the image by at least it’s radius “amount”.
I have this so far and it seems to work, but i’m not sure if it’s the right way to do it since my brain can’t calculate all the possibilities:

# Note : $1,$2,$3,$4 = 0 for this exemple.
# Used to set L,R,T,B margins, here = none.
# Everything's in % (at least i want it to be)
ML=$1   
MR:=100-$2
MT=$3
MB:=100-$4
 repeat $7 { # 100x 
    CR:=u(5) CX:=u($ML,$MR) CY:=u($MT,$MB)
    # had to *1.5 for some reason? Else circles go out of bounds
    #Makes me think i'm doing it wrong...
    if $CX-$CR<=$CR CX:=$CR*1.5 fi  
    if $CX+$CR>=100-$CR CX:=100-$CR*1.5 fi
    if $CY-$CR<=$CR CY:=$CR*1.5 fi
    if $CY+$CR>=100-$CR CY:=100-$CR*1.5 fi
    circle $CX%,$CY%,$CR%,{u},0xFFFFFFFF,255
  }

Do anyone know a sure way to do it ? Thanks.

EDIT : This seems to work fine i guess :

 repeat $7 {
    CR:=u(5) 
    CX:=u($ML+$CR*1.5,$MR-$CR*1.5) 
    CY:=u($MT+$CR*1.5,$MB-$CR*1.5)
    circle $CX%,$CY%,$CR%,{u},0xFFFFFFFF,255
  }

PS : Is there any way to find out what can be set as outline patterns?

I think @afre asked that question before, and David gave a response.

Probably this?

Yeah, I think it was that. There’s another way of coding this, but it involves the math parser, and I don’t think I can help you much with that other than to tell you to try to experiment with it and then learn it. It’s like learning another programming language.

Yes, one day i’ll have to learn how to use it, but i’m already struggling with basic stuff so i guess it won’t be anytime soon.
I guess i’m just prototyping for now?

Anyway, i got to do what i wanted to do, that is “seamless random patterns”.
Now i have to add some colors and learn to draw different shapes and objects… That’s the hardest part i guess.
And make it less chaotic, huh.

EDIT: playing with margins gave me some fun results :

2 Likes

What would be the correct way to write this little color randomizer (randomly choosing from 8 user defined colors):

rcol:
col:=floor(u(1,8))
if $col==1 C=$1,$2,$3
  elif $col==2 C=$4,$5,$6
  elif $col==3 C=$7,$8,$9
  elif $col==4 C=$10,$11,$12
  elif $col==5 C=$13,$14,$15
  elif $col==6 C=$16,$17,$18
  elif $col==7 C=$19,$20,$21
else C=$22,$24,$24 fi
u {$C}
rectangle {20%,80%,20%,80%,{u(.5,1)},0xFFFFFFFF,${"-rcol ${11--1}"} }

I just don’t want to copy paste the whole rcol code before every rectangle, polygon or circle call…
For now all i get is an error:

replace this by u $C, the evaluation of $C is incorrect (3 values separated by commas means nothing for the math expression).

1 Like

Thanks, it works now :slight_smile:

Is there any way to write a function inside a custom command? I’m not sure i want to keep rcol as a standalone command. This thing just eats 24 values to randomly select one RGB color among 8. Not really useful outside of it’s main command.

Yes, you can define a “temporary” command inside a custom command, with command command, then uncommand it when you’re done, with command uncommand.
In your case anyway, I would use the math evaluator to have a shorten version of rcol that you can store in a string and use it wherever you want:
Something like :

foo :
  rcol="arg0(int(u(8))%8,[${1-3}],[${4-6}],[${7-9}],[${10-12}],[${13-15}],[${16-18}],[${19-21}],[${22-24}])"
  rectangle 20%,80%,60%,90%,{u(.5,1)},0xFFFFFFFF,{$rcol}
  rectangle 10%,50%,40%,70%,{u(.5,1)},0xFFFFFFFF,{$rcol}

My solution to this problem is more akin to using a image. Something like these:

foo:
(${1-24}) steps:=24/3
rectangle[-2]  20%,80%,60%,90%,{u(.5,1)},0xFFFFFFFF,{crop(#-1,int(u(0,$steps,1,0)),0,0,0,3,1,1,1,0))}

or

foo:
(${1-24}) permute cyzx
rectangle[-2] 20%,80%,60%,90%,{u(.5,1)},0xFFFFFFFF,{I[#-1,int(u(0,w#-1,1,0))]}

I do wish we had something like this syntax (which would enable a easy to read one-liner):

$(5,13,15)=$5,$13,$15 # Arbitrarily select arguments based on what is inside ()

But wouldn’t that draw 2 rectangles of the same color? I want them to have different colors ( well maybe not always since it’s random anyway so there is always a possibility of getting the same color).

No, because you re-evaluate your string for each rectangle drawn.

It would, but not always. There are approaches to always drawing two different color.

I thought of one with rep_ncr_combinations_index2list command, rep_permutation_index2list command, and using map(). Basically, I select 2 colors from a image with ncr_combinations, and change their order with permutation.

There’s other method like keeping in track of what selected and increment until a not-selected index has been found. This is the best way of doing this.

Finally, have a look at this:

foo 8,2
foo:
number_of_colors=$1
selected_colors=$2

+rep_ncr_combinations $number_of_colors,$selected_colors,x
+rep_permutations $selected_colors,x

resize[-2] {w*100}%,100%,100%,100%,1
f[-2] map(I[#-1,x%w#-1],I) rm.

foo 8,2 outputs every possibilities of 2 randomly selected colors out of 8 colors without repeat. This gives us:

(0,1,0,2,0,3,0,4,0,5,0,6,0,7,1,2,1,3,1,4,1,5,1,6,1,7,2,3,2,4,2,5,2,6,2,7,3,4,3,5,3,6,3,7,4,5,4,6,4,7,5,6,5,7,6,7^1,0,2,0,3,0,4,0,5,0,6,0,7,0,2,1,3,1,4,1,5,1,6,1,7,1,3,2,4,2,5,2,6,2,7,2,4,3,5,3,6,3,7,3,5,4,6,4,7,4,6,5,7,5,7,6)

Each pixels represent the colors selected.

Another solution, that defines a temporary command rcol in your custom function:

foo : 
  m "rcol : u {[${1-24}][3*int(u(8)%8),3]}"
  rectangle 20%,80%,60%,90%,{u(.5,1)},0xFFFFFFFF,${-rcol}
  rectangle 10%,50%,40%,70%,{u(.5,1)},0xFFFFFFFF,${-rcol}
  um rcol

I like this one, it is reasonnably short to write.

2 Likes

Yes, and it works fine (had to change the vars to ${11--1} to adapt it to my script).
It’s just a bit hard to understand; at least for me, but who knows, maybe one day it’ll just pop in my brain.

Thank you @David_Tschumperle and @Reptorian. You guys come up with stuff i wouldn’t dare to dream about… It’s really abstract to me. Just like the picture above hehe.

My bad code for the curious :

Feel the Pain

#@gui Seamless Chaotic Pattern:  pr_rndpat,pr_rndpat_gui(1)
#@gui : Margin Left (%)  = float(0,0,100)
#@gui : Margin Right (%)  = float(0,0,100)
#@gui : Margin Top (%) = float(0,0,100)
#@gui : Margin Bottom (%)  = float(0,0,100)
#@gui : Rectangles = int(1,0,10)
#@gui : Triangles = int(1,0,10)
#@gui : Circles = int(1,0,10)
#@gui : Dilate - Erode = int(0,-10,10)
#@gui : Seed = int(0,0,1000000)
#@gui : Tiles = int(0,0,3)
#@gui : Color 1 = color(255,255,255)
#@gui : Color 2 = color(255,255,255)
#@gui : Color 3 = color(255,255,255)
#@gui : Color 4 = color(255,255,255)
#@gui : Color 5 = color(255,255,255)
#@gui : Color 6 = color(255,255,255)
#@gui : Color 7 = color(255,255,255)
#@gui : Color 8 = color(255,255,255)
#@gui : sep = separator()
#@gui : note = note("<small>Author: <i><a href="http://prawnsushi.free.fr">Prawnsushi</i></a>.\
# Latest Update: <i>2024/02/15</i>.</small>")
pr_rndpat_gui :
pr_rndpat $*

# Removed #cli info placeholder here

pr_rndpat :

ML=$1
MR:=100-$2
MT=$3
MB:=100-$4
 m "rcol : u {[${11--1}][3*int(u(8)%8),3]}"

if $9 srand $9 fi
repeat 10 {
  repeat $5 { rectangle {u($ML,$MR)}%,{u($MT,$MB)}%,{u($ML,$MR)}%,{u($MT,$MB)}%,{u(.5,1)},0xFFFFFFFF,${-rcol} }
  repeat $6 { polygon 3,{u($ML,$MR)}%,{u($MT,$MB)}%,{u($ML,$MR)}%,{u($MT,$MB)}%,{u($ML,$MR)}%,{u($MT,$MB)}%,{u(.5,1)},0xFFFFFFFF,${-rcol} }
  repeat $7 {
  CR:=u(1,10)
  CX:=u($ML+$CR*2,$MR-$CR*2)
  CY:=u($MT+$CR*2,$MB-$CR*2)
  circle $CX%,$CY%,$CR%,{u(.5,1)},0xFFFFFFFF,${-rcol}
  }
  shift 50%,50%,0,0,2
}
# shift 50%,50%,0,0,2
if $10 repeat $10 { . a x .  a y } fi
if $8
  if $8>0
    dilate $8
  else
    erode {abs($8)}
  fi
fi
um rcol

Now, i have to make random line “patterns”. Oh joy. how am i gonna do that? Or should i give the user a selector? Not sure, since this version is almost pure chaos.

This could have been simplified to just repeat $10 { . a x . a y } . repeat 0 means the code block does not get executed. The last code bit could have been simplified with elif.

I like your progress anyway.

Yes, i think so too, but i’m alays unsure about this. Repeat 0 sounds kinda bad to me, don’t know why. But if you say it doesn’t hurt, i’ll just remove the if.

I’ve been out of g’mic for a few months actually. Just came back to it. Just me being random.