Square and Rectangle Problem [SOLVED]

After trying to find a solution to this problem, it doesn’t seem to be easy to do. The goal is to create a image with random squares and rectangle. That sounds easy, right? It sounds easy until you realize that you need to consider direction.

EDIT: After thinking of j loop, it seems that I have solved this problem.

square_size=50
mw=${-max_w}
mh=${-max_h}
nvw={ceil($mw/$square_size)}
nvh={ceil($mh/$square_size)}
$nvw,$nvh,1,1,"x+y*w"
msize=2
freq={1/$msize*(iM+1)}
val={iM+1}

repeat $freq
    orientation={round(u(0,1))}
    nsl={round(u(2,$msize))}
    px={round(u(0,w#-1-1))}
    py={round(u(0,h#-1-1))}
    if $orientation 1,$nsl,1,1,$val j.. .,$px,$py rm.
    else $nsl,1,1,1,$val j.. .,$px,$py rm.
    fi
    val+=1
done

You know, there is a rectangle command, among others, that you could use.

It doesn’t run on its own. It requires another input image but doesn’t draw rectangles or squares on it. Is this the expected behaviour? Or is this code a part of a bigger command?

image

That’s pretty much the expected behavior. It’s going to be part of a bigger command. The command below is functionally pretty much done. There’s a bug with expand_xy which I will try to get around.

#@cli rep_rand_sqrrectex: eq. to 'rep_random_square_rectangle_texture' : (+)
rep_rand_sqrrectex: rep_random_square_rectangle_texture $*
#@cli rep_random_square_rectangle_texture: square_dimension,_rectangle_max_length_1,_rectangle_length_2,_frequency_of_rectangle,_output={ 0=none | 1=filled_gray | 2=filled_line | 3=labeled_filled_line },_erode,_seed
#@cli : Create a texture with aligned rectangle and squares.
#@cli : (eq. to 'rep_rand_sqrrectex')
#@cli : Default values: '_rectangle_max_length=1','_rectangle_max_length=2','_output=2','_frequency_of_rectangle=1','_erode=0','_seed='
#@cli : Author: Reptorian.
rep_random_square_rectangle_texture:
skip ${2=1},${3=2},${4=1},${5=0},${6=2},${7=}
if narg($7) srand $7 fi
square_size=$1
if $6 square_size+=1 fi

if $1<2 error ""$"1>1==F" fi

mw=${-max_w}
mh=${-max_h}
nvw={ceil($mw/$square_size)}
nvh={ceil($mh/$square_size)}

$nvw,$nvh,1,1,"x+y*w"

reclength_1=$2
reclength_2=$3

msize={sqrt(sqr($reclength_1)+sqr($reclength_2))}

if $1<2 error ""$"2>1==F" fi

freq={int(avg(1/$msize,$4,.5)*(iM+1))}
val={iM+1}

repeat $freq
    orientation={round(u(0,1))}
    nsl_1={round(u(1,$reclength_1))}
    nsl_2={round(u(1,$reclength_2))}
    min_nsl={min($nsl_1,$nsl_2)}
    max_nsl={max($nsl_1,$nsl_2)}
    px={round(u(0,w#-1-1))}
    py={round(u(0,h#-1-1))}
    if $orientation $min_nsl,$max_nsl,1,1,$val j.. .,$px,$py rm.
    else $max_nsl,$min_nsl,1,1,$val j.. .,$px,$py rm.
    fi
    val+=1
done

label. 0,0

if $6
    {$nvw*$square_size},{$nvh*$square_size},1,1,i(#-1,floor(x/$square_size),floor(y/$square_size)) rm..
    if $6>1 f. "(x!=0&&x!=w-1&&y!=0&&y!=h-1)?i(x-1,y-1,z,c,0,1)==i(x,y):0" 
        if $5 erode $5 expand_xy. {int($5/2)} fi
    fi
    if $6>2 label_fg. 0,0 fi
fi

Oh, I never use expand_xy. What is the bug?

One day, you should release a video with just you pronouncing all of your command names. :joy_cat:

The bug:
There’s something wrong here.

The thickness should be 2, not 3.

Works for me. Could the last column / row before the expansion be black as well?

The last row is by default black. Perhaps, I should just remove that to get around it in case of erosion.


Sorry, I just have one question. Do you have any idea how I would code to detect if nonrectangular shape, then split only the nonrectangular into varying number pixels? This is something I’d like to see for length_1 and length_2 both being greater than 1, so that in the end, I can see only rectangle and squares.

To the problem above:

This should finally solve the issue of extracting rectangle from rectilinear shapes within the microimage. Well almost. I still need to find a way to further define the extracted shape.

to_gray n 0,1
f "
topleft=i(x-1,y-1);
topmiddle=i(x,y-1);
topright=i(x+1,y-1);

middleleft=i(x-1,y);
middle=i;
middleright=i(x+1,y);

bottomleft=i(x-1,y+1);
bottommiddle=i(x,y+1)
bottomright=i(x+1,y+1);

F=i;
if(i,
    if(
        (
            (middleleft&&topmiddle&&middleright)
        ||(bottommiddle&&middleleft&&topmiddle)
        ||(middleleft&&bottommiddle&&middleright)
        ||(bottommiddle&&middleright&&topmiddle)
        )
        ||
        (
            (bottommiddle&&bottomright&&middleright)
        ||(topmiddle&&topright&&middleright)
        ||(topmiddle&&topleft&&middleleft)
        ||(bottommiddle&&bottomleft&&middleleft)
        )
        ,F++;
    );
);
F;
"