P4m Reference Implementation

Aus de_evolutionary_art_org
Wechseln zu: Navigation, Suche

back to Exploring_a_Design_Space_for_Patterns_and_Tilings_Competition_2015

Let $image be an image from which a right angle isosceles triangle part should be cut out and used as prototile for the p4m tile. The triangle has with the width $t_w one free parameter, the hight is the same $t_h = $t_w.

In the following relative translation parameters are used that are referencing to the one prototile that is used viz. to $t_w and $t_h. If patterns are generated with more than one prototile relative parameters should referencing to the width and height of the pattern image that itself is constructed as a function of the widths and heights of the prototile set and a general multiplicator or two multiplicators for width and height. Such a function ($w_P, $h_P) = f($mult, $w_S_i, $h_S_i | i = 1, …, n) or f($mult_w, $mult_h, $w_S_i, $h_S_i | i = 1, …, n) is specified in the design space definition.

If a random part of $image should be selected for the rectangle that includes the future prototile this is made with:

# RANDOM CROP A RECTANGLE WITH $t_w x $t_w 
($w, $h) = $image->Get('columns', 'rows');	
$t_w = $crop_w; 
$t_h = $crop_w;
$x_allowed = $w - $t_w; $x = int(rand($x_allowed)); 
$y_allowed = $h - $t_h; $y = int(rand($y_allowed));
$image->Crop(geometry=>"$t_w x $t_h + $x + $y", background=>'transparent');	print "crop rand rectangle from image with  (geometry=>$t_w x $t_h + $x + $y)\n";
$image->Set(page=>'0x0+0+0'); #$image->Write(filename=>"$output_meta_folder/image_AfterRectCrop.jpg");


The right angle isosceles triangle mask is generated with:

# GENERATE p4m MASK/S
$mask->Set(size=>"$t_w x $t_h"); 
$mask->Read('xc:none');					
$mask->Draw(primitive=>'polyline', points => "0,0 $t_w,$t_h 0,$t_h", fill=>'red');	$mask->Write(filename=>"$output_meta_folder/p4m_mask_AfterGeneration.png");


Fehler beim Erstellen des Vorschaubildes: Datei fehlt


The prototile is generated with the triangle mask and the image and the rusult is pushed in a image list for all the prototiles to reflect the general case that a pattern is made of more than one prototile type:

# GENERATE PROTOTILE/S
$mask->Composite(image=>$image, compose=>'in', color=>'transparent', matte=>'true');     print "generate prototile \n";
$mask->Set(page=>'0x0+0+0');	 # $mask->Write(filename=>"$output_meta_folder/mask_AfterCompose.png");
# PUSH PROTOTILE INTO $Shape_list 
push(@$Shape_list, $mask);#$Shape_list->Write(filename=>"$output_meta_folder/Shape_list.png");
$nr_Shape_list = @$Shape_list; 


In the next step an empty p4m tile is generated for example with transparent background. It has 2 times the width and 2 times the hight of the prototile:

# GENERATE EMPTY p4m-TILE $tile AS A FUNCTION OF $mask or $prototile
$tile_w = 2 * $t_w;										
$tile_h = 2 * $t_h;
$tile->Set(size=>"$tile_w x $tile_h");  print "generate empty tile with tile_w x tile_h = $tile_w x $tile_h \n";
$tile->Read('xc:none'); #$tile->Write(filename=>"$output_meta_folder/tile_AfterGeneration.png");


What follows is a sequence of 8 image processing operations, the CRMT commands that takes a clone of the prototile, rotates it, Flop and/or Flip it and makes a composite operation with compose=>over that includes a translation of the prototile over the tile image. The images are shown in jpg which means that the transparent background is transformed to black.


# CRMT-COMMAND-LIST_01: (C0, x0, y0)
@$prototile_crm = (); 
$prototile_crm = $Shape_list->[0]->Clone();
$tile->Composite(image=>$prototile_crm, compose=>'over', x=>'0', y=>'0', color=>'transparent', matte=>'true');
$tile->Set(page=>'0x0+0+0');
#$tile->Write(filename=>"$output_meta_folder/tile_after_crmt_01.png");
 $tile->Write(filename=>"$output_meta_folder/tile_after_crmt_01.jpg");


Fehler beim Erstellen des Vorschaubildes: Datei fehlt


# CRMT-COMMAND-LIST_02: (C0, Fo, R-90, x0, y0)
@$prototile_crm = ();
$prototile_crm = $Shape_list->[0]->Clone();
$prototile_crm->Flop();
$prototile_crm->Rotate(degrees=>-90, color=>'transparent');													
$prototile_crm->Set(page=>'0x0+0+0');
$tile->Composite(image=>$prototile_crm, compose=>'over', x=>'0', y=>'0', color=>'transparent', matte=>'true');
$tile->Set(page=>'0x0+0+0');
#$tile->Write(filename=>"$output_meta_folder/tile_after_crmt_02.png");
$tile->Write(filename=>"$output_meta_folder/tile_after_crmt_02.jpg");


Fehler beim Erstellen des Vorschaubildes: Datei fehlt


# CRMT-COMMAND-LIST_03: (C0, Fo, xt_w, y0)
@$prototile_crm = (); 
$prototile_crm = $Shape_list->[0]->Clone();
$prototile_crm->Flop(); 
$tile->Composite(image=>$prototile_crm, compose=>'over', x=>$t_w, y=>'0', color=>'transparent', matte=>'true');
$tile->Set(page=>'0x0+0+0');
#$tile->Write(filename=>"$output_meta_folder/tile_after_crmt_03.png");
$tile->Write(filename=>"$output_meta_folder/tile_after_crmt_03.jpg");


Fehler beim Erstellen des Vorschaubildes: Datei fehlt


# CRMT-COMMAND-LIST_04: (C0, R90, xt_w, y0)
@$prototile_crm = ();
$prototile_crm = $Shape_list->[0]->Clone();
$prototile_crm->Rotate(degrees=>90, color=>'transparent');													
$prototile_crm->Set(page=>'0x0+0+0');
$tile->Composite(image=>$prototile_crm, compose=>'over', x=>$t_w, y=>'0', color=>'transparent', matte=>'true'); 
$tile->Set(page=>'0x0+0+0');
#$tile->Write(filename=>"$output_meta_folder/tile_after_crmt_04.png");
$tile->Write(filename=>"$output_meta_folder/tile_after_crmt_04.jpg");


Fehler beim Erstellen des Vorschaubildes: Datei fehlt


# CRMT-COMMAND-LIST_05: (C0, Fi, x0, yt_h)
@$prototile_crm = (); 
$prototile_crm = $Shape_list->[0]->Clone();
$prototile_crm->Flip(); 
$tile->Composite(image=>$prototile_crm, compose=>'over', x=>'0', y=>$t_h, color=>'transparent', matte=>'true');
$tile->Set(page=>'0x0+0+0'); 
#$tile->Write(filename=>"$output_meta_folder/tile_after_crmt_05.png");
$tile->Write(filename=>"$output_meta_folder/tile_after_crmt_05.jpg");
Fehler beim Erstellen des Vorschaubildes: Datei fehlt


# CRMT-COMMAND-LIST_06: (C0, Fo, R-90, Fi, x0, yt_h)
@$prototile_crm = ();
$prototile_crm = $Shape_list->[0]->Clone();
$prototile_crm->Flop();
$prototile_crm->Rotate(degrees=>-90, color=>'transparent');													
$prototile_crm->Set(page=>'0x0+0+0');
$prototile_crm->Flip(); 
$tile->Composite(image=>$prototile_crm, compose=>'over', x=>'0', y=>$t_h, color=>'transparent', matte=>'true');
$tile->Set(page=>'0x0+0+0');
#$tile->Write(filename=>"$output_meta_folder/tile_after_crmt_06.png");
$tile->Write(filename=>"$output_meta_folder/tile_after_crmt_06.jpg");
Fehler beim Erstellen des Vorschaubildes: Datei fehlt


# CRMT-COMMAND-LIST_07: (C0, Fo, Fi, xt_w, yt_h)
@$prototile_crm = (); 
$prototile_crm = $Shape_list->[0]->Clone();
$prototile_crm->Flop(); 
$prototile_crm->Flip(); 
$tile->Composite(image=>$prototile_crm, compose=>'over', x=>$t_w, y=>$t_h, color=>'transparent', matte=>'true');
$tile->Set(page=>'0x0+0+0');
#$tile->Write(filename=>"$output_meta_folder/tile_after_crmt_07.png");	
$tile->Write(filename=>"$output_meta_folder/tile_after_crmt_07.jpg");


Fehler beim Erstellen des Vorschaubildes: Datei fehlt


# CRMT-COMMAND-LIST_08: (C0, R90, Fi, xt_w, yt_h)
@$prototile_crm = ();
$prototile_crm = $Shape_list->[0]->Clone();
$prototile_crm->Rotate(degrees=>90, color=>'transparent');													
$prototile_crm->Set(page=>'0x0+0+0');
$prototile_crm->Flip(); 
$tile->Composite(image=>$prototile_crm, compose=>'over', x=>$t_w, y=>$t_h, color=>'transparent', matte=>'true'); 
$tile->Set(page=>'0x0+0+0');
#$tile->Write(filename=>"$output_meta_folder/tile_after_crmt_08.png");
$tile->Write(filename=>"$output_meta_folder/tile_after_crmt_08.jpg");


Fehler beim Erstellen des Vorschaubildes: Datei fehlt


Because a square is used ($t_w = $t_h) for the prototile there are no gap artefacts. The diagonal has a 45° angle and this non rectangular angle produces no (or the less) gap artefacts if an other object with 45° is composed over it along the diagonal. Therefore no correction of gap artefacts are necessary in contrast to other prototile types from other eucledian plane groups that are based on 30°, 60°, ... angles like p3m1 or p6m.

If the image processing commands were combined and integrated one get a string that codes the building of a p4m tile from a given prototile triangle:

$CRMT_string = 'C0, x0, y0, C0, Fo, R-90, x0, y0, C0, Fo, xt_w, y0, C0, R90, xt_w, y0, C0, Fi, x0, yt_h, C0, Fo, R-90, Fi, x0, yt_h, C0, Fo, Fi, xt_w, yt_h, C0, R90, Fi, xt_w, yt_h';


back to Exploring_a_Design_Space_for_Patterns_and_Tilings_Competition_2015