<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Patterns of polygons: Use SAS to create mathematical art in Graphics Programming</title>
    <link>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/760138#M21806</link>
    <description>&lt;P&gt;Hi Rick,&lt;/P&gt;
&lt;P&gt;Many thanks for the inspiring blog post. Below I am attempting to combine your 2nd and 3rd suggestions from the end of the post.&amp;nbsp; So I have modified your code to look for a random 'artwork' with no adjacent polygons of the same colour, that also uses all 16 of the pinwheels.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;/* Rick's Code */
data Shape;
input ID x y @@;
datalines;
0  0 0  0  0.667  0.333  0  1  1  0  0  1  0  0  0  
1  0 0  1 -0.333  0.667  1 -1  1  1 -1  0  1  0  0 
2  0 0  2 -0.667 -0.333  2 -1 -1  2  0 -1  2  0  0 
3  0 0  3  0.333 -0.667  3  1 -1  3  1  0  3  0  0 
;

proc iml;
/* actions of the D4 dihedral group */
start D4Action(v, act);
   /* the subroup of rotations by 90 degrees */
   if      act=0 then M = { 1  0,  0  1};
   else if act=1 then M = { 0 -1,  1  0};
   else if act=2 then M = {-1  0,  0 -1};
   else if act=3 then M = { 0  1, -1  0};
   /* the subgroup of reflections across horz, vert, or diagonals */
   else if act=4 then M = {-1  0,  0  1};
   else if act=6 then M = { 0 -1, -1  0};
   else if act=7 then M = { 1  0,  0 -1};
   else if act=5 then M = { 0  1,  1  0};
   return( v*M` );  /* = (M*z`)` */
finish;
/* read in the pinwheel shape */
use Shape; read all var {x y} into P1; 
read all var "ID"; close;

/* Modifying Rick's code below to output all 16 pinwheels.
   Define ID2 where the odd colour numbers are switched */
ID2 = ID;
do i = 1 to 20;
  if mod(ID2[i], 2)=1 then ID2[i] = 4 - ID2[i];
end;

/* write out the transformation of the pinwheel under the D4 actions */
OpNames = {"I" "R1" "R2" "R3" "S0" "S1" "S2" "S3",
           "ZI" "ZR1" "ZR2" "ZR3" "ZS0" "ZS1" "ZS2" "ZS3"};
Name = OpNames[1];
Q = {. . .};
create Panel from Name Q[c={'Name' 'ID' 'x' 'y'}];
do j = 1 to 2;
  do i = 0 to 7;
     R = D4Action(P1, i);
     if j=1 then Q = ID || R; else Q=ID2 || R;
     Name = j(nrow(Q), 1, OpNames[j,i+1]);
     append from Name Q;
  end;
end;
close;
QUIT;

/* get colour by quadrant for each of the 16 pinwheels
   Q4|Q1
   -----
   Q3|Q2
*/ 
data quadrant_col;
  set Panel(where=( (abs(x) + abs(y)) = 2 ));
  if x=1
    then if y&amp;gt;0 then quad=1; else quad=2;
    else if y&amp;gt;0 then quad=4; else quad=3;
  drop x y;
run;
proc sort; by Name quad; run;
proc transpose data=quadrant_col out=quadrant_col(drop=_:) prefix=Q;
  var ID;
  by Name;
  id quad;
run;

proc iml;
  start grid_eval(x) global(c_LR, c_TB);
    /* return the number of adjacent same coloured polygons in a grid of pinwheels */
    nr = nrow(x);
	nc = ncol(x);
	count = 0;
	if nc&amp;gt;1 then do i = 1 to nr; do j = 1 to nc-1;
	    count = count + c_LR[ x[i,j], x[i,j+1] ]; 
	  end; end;
	if nr&amp;gt;1 then do i = 1 to nr-1; do j = 1 to nc;
	    count = count + c_TB[ x[i,j], x[i+1,j] ]; 
	  end; end;
	return(count);
  finish;

  use quadrant_col;
  read all var _num_ into q;
  use Panel;
  read all var {ID x y} into pdata;

  /* create two matrices that count the number of same coloured polygons next to each other
     when 2 pinwheels are either side by side (row indexes left pinwheel, col indexes right
     pinwheel) or when stacked on top of each other (row indexes top pinwheel, col indexes
     bottom pinwheel) */
  c_LR = j(16, 16, .);
  c_TB = j(16, 16, .);  
  do i = 1 to 16; do j = 1 to 16;
    c_LR[i, j] = sum( q[i,{1 2}] = q[j,{4 3}]);
    c_TB[i, j] = sum( q[i,{3 2}] = q[j,{4 1}]);
  end; end;

  /* start with a random assignment of 16 pinwheels to a 4x4 grid */
  g = shape(ranperm(16), 4, 4);
  cc = grid_eval( g );

  /* consider swaps of one pinwheel for another that might improve the artwork. Use
     matrix b to keep a list for each cycle of swaps that give the best improvement */
  b = j(100, 2);

  do cycle = 1 to 200 until(cc=0);
    bestcc = 1E20;  /* best cc this cycle */
    do i = 1 to 15; do j = i+1 to 16;
      h = g;
	  h[i] = g[j];
	  h[j] = g[i];
	  newcc = grid_eval( h );
      if newcc&amp;lt;=bestcc then do;
	    if newcc&amp;lt;bestcc then do;
	      bestcc=newcc;
		  nb = 0;
	    end;
        nb = nb + 1;
	    b[nb, 1] = i;
	    b[nb, 2] = j;
	  end;
    end; end;
    /* choose a swap at random from those in b */
    swap = 1 + floor(rand('uniform')#nb);
    besti = b[swap,1];
    bestj = b[swap,2];
    t = g[besti];
    g[besti] = g[bestj];
    g[bestj] = t;
	cc = bestcc;
  end;

  reset noname;
  if cc=0 then print 'Found grid with no adjacent same colour polygons after' cycle [format=3.0] 'swaps';
          else print 'Optimal arrangement was not found!';
  print g [format=2.0];
  Q = {. . . .};
  create OptPanel from Q[c={'Cell' 'ID' 'x' 'y'}];
  do i = 1 to 16;
	/* work out which rows of panel data correspond to ith pinwheel in g */
	ridx = ( 20#(g[i]-1) + 1) : (20#g[i]);
	Q = j(20,1,i) || pdata[ridx, ];
	append from Q;
  end;
quit;

/* Show the artwork */
%let teal   = CX288c95;
%let orange = CXeba411;
%let blue   = CX0f5098;
%let salmon = CXd5856e;
%let gray   = CX929386;

ods graphics / width=500px height=500px;
/* for convenience, define macros for the COLAXIS and ROWAXIS options */
%macro colOpts; colaxis offsetmin=0 offsetmax=0 display=(nolabel noticks novalues); %mend;
%macro rowOpts;  rowaxis offsetmin=0 offsetmax=0 display=(nolabel noticks novalues); %mend;

title 'Random Shadow';
proc sgpanel data=OptPanel noautolegend;
   styleattrs wallcolor=&amp;amp;gray datacolors=(&amp;amp;teal &amp;amp;orange &amp;amp;blue &amp;amp;salmon);
   panelby Cell / columns=4 onepanel noheader noborder;
   polygon x=x y=y ID=ID / group=ID fill;
   %colOpts; %rowOpts;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="RandomShadow.png" style="width: 500px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/62367iFEFA03C82A7C1DA1/image-size/large?v=v2&amp;amp;px=999" role="button" title="RandomShadow.png" alt="RandomShadow.png" /&gt;&lt;/span&gt;&lt;/P&gt;</description>
    <pubDate>Sat, 07 Aug 2021 09:49:52 GMT</pubDate>
    <dc:creator>IanWakeling</dc:creator>
    <dc:date>2021-08-07T09:49:52Z</dc:date>
    <item>
      <title>Patterns of polygons: Use SAS to create mathematical art</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/759266#M21778</link>
      <description>&lt;DIV class="lia-message-template-content-zone"&gt;
&lt;P&gt;An artist named&amp;nbsp;Odili Donald Odita painted a beautiful picture (&lt;A href="https://www.artsy.net/artwork/odili-donald-odita-phantoms-shadow" target="_self"&gt;"Phantom’s Shadow, 2018"&lt;/A&gt;) that contains geometric polygons in different colors and orientations. A reproduction of Odita's image is shown below:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Odita0.png" style="width: 400px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/62018i869A01506FCF07EB/image-size/medium?v=v2&amp;amp;px=400" role="button" title="Odita0.png" alt="Odita0.png" /&gt;&lt;/span&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;In a blog post, I show&amp;nbsp;&lt;A href="https://blogs.sas.com/content/iml/2021/08/04/create-mathematical-art-sas.html" target="_self"&gt;how to use symmetry and PROC SGPANEL to create tilings that are inspired by Odita's work&lt;/A&gt;. I analyze some of the mathematical structures in Odita's painting and creates the following image in SAS; see the blog post for its mathematical significance:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Odita10.png" style="width: 400px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/62019iD5FD56B55295189E/image-size/medium?v=v2&amp;amp;px=400" role="button" title="Odita10.png" alt="Odita10.png" /&gt;&lt;/span&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You can create images like these from basic mathematical principles. To simplify the process, the following data set contains the 16 pinwheel-shaped images that appear in the tiling above. The SAS program creates the mathematical version of Odita's artwork.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data Pinwheels;
input Group ID @;
do i = 1 to 5;
   input x y @@;
   output;
end;
drop i;
datalines;
0 0 0 0   0.667  0.333   1  1   0  1  0 0 
0 1 0 0  -0.333  0.667  -1  1  -1  0  0 0 
0 2 0 0  -0.667 -0.333  -1 -1   0 -1  0 0 
0 3 0 0   0.333 -0.667   1 -1   1  0  0 0 
1 0 0 0  -0.333  0.667  -1  1  -1  0  0 0 
1 1 0 0  -0.667 -0.333  -1 -1   0 -1  0 0 
1 2 0 0   0.333 -0.667   1 -1   1  0  0 0 
1 3 0 0   0.667  0.333   1  1   0  1  0 0 
2 0 0 0  -0.667 -0.333  -1 -1   0 -1  0 0 
2 1 0 0   0.333 -0.667   1 -1   1  0  0 0 
2 2 0 0   0.667  0.333   1  1   0  1  0 0 
2 3 0 0  -0.333  0.667  -1  1  -1  0  0 0 
3 0 0 0   0.333 -0.667   1 -1   1  0  0 0 
3 1 0 0   0.667  0.333   1  1   0  1  0 0 
3 2 0 0  -0.333  0.667  -1  1  -1  0  0 0 
3 3 0 0  -0.667 -0.333  -1 -1   0 -1  0 0 
4 0 0 0  -0.667  0.333  -1  1   0  1  0 0 
4 1 0 0   0.333  0.667   1  1   1  0  0 0 
4 2 0 0   0.667 -0.333   1 -1   0 -1  0 0 
4 3 0 0  -0.333 -0.667  -1 -1  -1  0  0 0 
5 0 0 0   0.333  0.667   1  1   1  0  0 0 
5 1 0 0   0.667 -0.333   1 -1   0 -1  0 0 
5 2 0 0  -0.333 -0.667  -1 -1  -1  0  0 0 
5 3 0 0  -0.667  0.333  -1  1   0  1  0 0 
6 0 0 0  -0.333 -0.667  -1 -1  -1  0  0 0 
6 1 0 0  -0.667  0.333  -1  1   0  1  0 0 
6 2 0 0   0.333  0.667   1  1   1  0  0 0 
6 3 0 0   0.667 -0.333   1 -1   0 -1  0 0 
7 0 0 0   0.667 -0.333   1 -1   0 -1  0 0 
7 1 0 0  -0.333 -0.667  -1 -1  -1  0  0 0 
7 2 0 0  -0.667  0.333  -1  1   0  1  0 0 
7 3 0 0   0.333  0.667   1  1   1  0  0 0 
8 0 0 0   0.667  0.333   1  1   0  1  0 0 
8 3 0 0  -0.333  0.667  -1  1  -1  0  0 0 
8 2 0 0  -0.667 -0.333  -1 -1   0 -1  0 0 
8 1 0 0   0.333 -0.667   1 -1   1  0  0 0 
9 0 0 0  -0.333  0.667  -1  1  -1  0  0 0 
9 3 0 0  -0.667 -0.333  -1 -1   0 -1  0 0 
9 2 0 0   0.333 -0.667   1 -1   1  0  0 0 
9 1 0 0   0.667  0.333   1  1   0  1  0 0 
10 0 0 0  -0.667 -0.333  -1 -1  0 -1  0 0 
10 3 0 0   0.333 -0.667   1 -1   1  0  0 0 
10 2 0 0   0.667  0.333   1  1   0  1  0 0 
10 1 0 0  -0.333  0.667  -1  1  -1  0  0 0 
11 0 0 0   0.333 -0.667   1 -1   1  0  0 0 
11 3 0 0   0.667  0.333   1  1   0  1  0 0 
11 2 0 0  -0.333  0.667  -1  1  -1  0  0 0 
11 1 0 0  -0.667 -0.333  -1 -1   0 -1  0 0 
12 0 0 0  -0.667  0.333  -1  1   0  1  0 0 
12 3 0 0   0.333  0.667   1  1   1  0  0 0 
12 2 0 0   0.667 -0.333   1 -1   0 -1  0 0 
12 1 0 0  -0.333 -0.667  -1 -1  -1  0  0 0 
13 0 0 0   0.333  0.667   1  1   1  0  0 0 
13 3 0 0   0.667 -0.333   1 -1   0 -1  0 0 
13 2 0 0  -0.333 -0.667  -1 -1  -1  0  0 0 
13 1 0 0  -0.667  0.333  -1  1   0  1  0 0 
14 0 0 0  -0.333 -0.667  -1 -1  -1  0  0 0 
14 3 0 0  -0.667  0.333  -1  1   0  1  0 0 
14 2 0 0   0.333  0.667   1  1   1  0  0 0 
14 1 0 0   0.667 -0.333   1 -1   0 -1  0 0 
15 0 0 0   0.667 -0.333   1 -1   0 -1  0 0 
15 3 0 0  -0.333 -0.667  -1 -1  -1  0  0 0 
15 2 0 0  -0.667  0.333  -1  1   0  1  0 0 
15 1 0 0   0.333  0.667   1  1   1  0  0 0 
;

%let teal   = CX288c95;
%let orange = CXeba411;
%let blue   = CX0f5098;
%let salmon = CXd5856e;
%let gray   = CX929386;

ods graphics / width=640px height=640px;
%macro colOpts; colaxis offsetmin=0 offsetmax=0 display=(nolabel noticks novalues); %mend;
%macro rowOpts;  rowaxis offsetmin=0 offsetmax=0 display=(nolabel noticks novalues); %mend;

title "Dihedral Shadow";
proc sgpanel data=Pinwheels noautolegend;
   styleattrs wallcolor=&amp;amp;gray datacolors=(&amp;amp;teal &amp;amp;orange &amp;amp;blue &amp;amp;salmon);
   panelby Group / columns=4 onepanel noheader;
   polygon x=x y=y ID=ID / group=ID fill;
   %colOpts; %rowOpts;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Here is a challenge for SAS programmers: create similar images! Who is up for the challenge? Use these 16 polygons in whatever order you want to create an Odita-inspired image, or create your own polygons.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Post your SAS code and a small image that shows your creativity and programming skills!&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;/DIV&gt;</description>
      <pubDate>Wed, 04 Aug 2021 12:30:02 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/759266#M21778</guid>
      <dc:creator>Rick_SAS</dc:creator>
      <dc:date>2021-08-04T12:30:02Z</dc:date>
    </item>
    <item>
      <title>Re: Patterns of polygons: Use SAS to create mathematical art</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/759296#M21779</link>
      <description>&lt;P&gt;Of course. Calling out&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/4628"&gt;@tc&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/13585"&gt;@GraphGuy&lt;/a&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 04 Aug 2021 12:12:44 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/759296#M21779</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2021-08-04T12:12:44Z</dc:date>
    </item>
    <item>
      <title>Re: Patterns of polygons: Use SAS to create mathematical art</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/759330#M21780</link>
      <description>&lt;P&gt;Rick,&lt;/P&gt;
&lt;P&gt;OK. I post my code here .&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let alpha = 0.333;          /* Odita's work uses a vertex as (1-alpha, alpha) */
data Poly1;
ID = 1;
input x y @@;
if x=. then do;              /* just for fun, support other locations of vertex */
   x = 1 - &amp;amp;alpha; y = &amp;amp;alpha;
end;
datalines;
0 0   . .   1 1   0 1   0 0
;


%macro rotation(dsn=);
%do i=0 %to 7;
%do j=0 %to 7;
%let id=%sysevalf(%sysfunc(rand(uniform))*99999,int);
%let type=%sysfunc(rand(table,0.25,0.25,0.25));

%if &amp;amp;type=1 %then %let angle=0;
 %else %if &amp;amp;type=2 %then %let angle=90;
  %else %if &amp;amp;type=3 %then %let angle=180;
   %else %if  &amp;amp;type=4 %then %let angle=270;

data temp(keep=id group x_rotated y_rotated rename=(x_rotated=x y_rotated=y));
 set &amp;amp;dsn. ;
 id=&amp;amp;id.;
 group=&amp;amp;type.;
angle_radians=&amp;amp;angle.*(constant("pi")/180);
x_rotated=cos(angle_radians)*x - sin(angle_radians)*y;
y_rotated=sin(angle_radians)*x + cos(angle_radians)*y;

%if &amp;amp;type=2 %then %do;
x_rotated=x_rotated+1;
%end;
%else %if &amp;amp;type=3 %then %do;
x_rotated=x_rotated+1;
y_rotated=y_rotated+1;
%end;
%else %if &amp;amp;type=4 %then %do;
y_rotated=y_rotated+1;
%end;

x_rotated=x_rotated+&amp;amp;i.;
y_rotated=y_rotated+&amp;amp;j.;
run;
proc append base=want data=temp force;run;
%end;
%end;
%mend;


proc delete data=want;run;
%rotation(dsn=Poly1)




%let blue   = CX0f5098;
%let orange = CXeba411;
%let teal   = CX288c95;
%let salmon = CXd5856e;
%let gray   = CX929386;
 
ods graphics / width=480px height=480px noborder;
title "Base Polygon";
proc sgplot data=want aspect=1 noborder noautolegend;
   styleattrs wallcolor=&amp;amp;gray datacolors=(&amp;amp;teal &amp;amp;orange &amp;amp;blue &amp;amp;salmon);
   polygon x=x y=y ID=ID / group=group fill;
   xaxis display=none offsetmax=0 offsetmin=0 ;
   yaxis display=none offsetmax=0 offsetmin=0 ;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ksharp.png" style="width: 480px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/62244i6BC737EC5410A2E6/image-size/large?v=v2&amp;amp;px=999" role="button" title="Ksharp.png" alt="Ksharp.png" /&gt;&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 04 Aug 2021 14:09:33 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/759330#M21780</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2021-08-04T14:09:33Z</dc:date>
    </item>
    <item>
      <title>Re: Patterns of polygons: Use SAS to create mathematical art</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/759648#M21782</link>
      <description>&lt;P&gt;Rick,&lt;/P&gt;
&lt;P&gt;Here is another one . the same with&amp;nbsp;&lt;SPAN&gt;&amp;nbsp;Odili's .&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let alpha = 0.3;          /* Odita's work uses a vertex as (1-alpha, alpha) */
data Poly1;
ID = 1;
input x y @@;
if x=. then do;              /* just for fun, support other locations of vertex */
   x = 1 - &amp;amp;alpha; y = &amp;amp;alpha;
end;
datalines;
0 0   . .   1 1   0 1   0 0
;
data Poly2;
ID = 1;
input x y @@;
if x=. then do;              /* just for fun, support other locations of vertex */
   x = &amp;amp;alpha; y = 1 -  &amp;amp;alpha;
end;
datalines;
0 0   1 0   1 1   . .   0 0
;


proc format;
invalue color_a
0  =1
90 =2
180=3
270=4;
invalue color_b
0  =3
90 =2
180=1
270=4;
invalue color_c
0  =4
90 =1
180=2
270=3;
invalue color_d
0  =2
90 =1
180=4
270=3;
invalue color_e
0  =3
90 =4
180=1
270=2;
invalue color_f
0  =1
90 =4
180=3
270=2;
invalue color_g
0  =2
90 =3
180=4
270=1;
invalue color_h
0  =4
90 =3
180=2
270=1;
run;


%macro rotation(dsn= ,color=,x=,y=);
%let angles=0 90 180 270;
%let group=%sysfunc(rand(integer,1,999999));
%do i=1 %to 4;
%let angle=%scan(&amp;amp;angles.,&amp;amp;i.,%str( ));
data temp(keep=id group x_rotated y_rotated rename=(x_rotated=x y_rotated=y));
 set &amp;amp;dsn. ;
%if &amp;amp;color.=1 %then %do;id=inputn(&amp;amp;angle.,"color_a.");%end;
%if &amp;amp;color.=2 %then %do;id=inputn(&amp;amp;angle.,"color_b.");%end;
%if &amp;amp;color.=3 %then %do;id=inputn(&amp;amp;angle.,"color_c.");%end;
%if &amp;amp;color.=4 %then %do;id=inputn(&amp;amp;angle.,"color_d.");%end;
%if &amp;amp;color.=5 %then %do;id=inputn(&amp;amp;angle.,"color_e.");%end;
%if &amp;amp;color.=6 %then %do;id=inputn(&amp;amp;angle.,"color_f.");%end;
%if &amp;amp;color.=7 %then %do;id=inputn(&amp;amp;angle.,"color_g.");%end;
%if &amp;amp;color.=8 %then %do;id=inputn(&amp;amp;angle.,"color_h.");%end;
angle_radians=&amp;amp;angle.*(constant("pi")/180);
x_rotated=cos(angle_radians)*x - sin(angle_radians)*y;
y_rotated=sin(angle_radians)*x + cos(angle_radians)*y;
x_rotated=x_rotated+&amp;amp;x.;
y_rotated=y_rotated+&amp;amp;y.;
group=&amp;amp;group.;
run;
proc append base=want data=temp force;run;
%end;
%mend;



proc delete data=want;run;
%rotation(dsn=Poly1,color=1,x=6,y=6)
%rotation(dsn=Poly2,color=2,x=4,y=6)
%rotation(dsn=Poly2,color=3,x=2,y=6)
%rotation(dsn=Poly1,color=4,x=0,y=6)

%rotation(dsn=Poly2,color=4,x=6,y=4)
%rotation(dsn=Poly1,color=5,x=4,y=4)
%rotation(dsn=Poly1,color=6,x=2,y=4)
%rotation(dsn=Poly2,color=7,x=0,y=4)

%rotation(dsn=Poly2,color=7,x=6,y=2)
%rotation(dsn=Poly1,color=8,x=4,y=2)
%rotation(dsn=Poly1,color=1,x=2,y=2)
%rotation(dsn=Poly2,color=2,x=0,y=2)

%rotation(dsn=Poly1,color=2,x=6,y=0)
%rotation(dsn=Poly2,color=3,x=4,y=0)
%rotation(dsn=Poly2,color=4,x=2,y=0)
%rotation(dsn=Poly1,color=5,x=0,y=0)

%let blue   = CX0f5098;
%let orange = CXeba411;
%let teal   = CX288c95;
%let salmon = CXd5856e;
%let gray   = CX929386;
 
ods graphics / width=480px height=480px noborder;
title "Base Polygon";
proc sgplot data=want aspect=1 noborder noautolegend;
   styleattrs wallcolor=&amp;amp;gray datacolors=(&amp;amp;teal &amp;amp;orange &amp;amp;blue &amp;amp;salmon);
   polygon x=x y=y ID=id / group=id fill;
   xaxis display=none offsetmax=0 offsetmin=0 ;
   yaxis display=none offsetmax=0 offsetmin=0 ;
run;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;SPAN&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Ksharp.png" style="width: 480px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/62293iE68C00B28A92BDDC/image-size/large?v=v2&amp;amp;px=999" role="button" title="Ksharp.png" alt="Ksharp.png" /&gt;&lt;/span&gt;&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 05 Aug 2021 08:42:23 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/759648#M21782</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2021-08-05T08:42:23Z</dc:date>
    </item>
    <item>
      <title>Re: Patterns of polygons: Use SAS to create mathematical art</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/760115#M21805</link>
      <description>&lt;P&gt;&lt;A href="https://communities.sas.com/t5/Graphics-Programming/Advanced-ODS-Graphics-techniques-new-free-book/td-p/235735" target="_blank"&gt;https://communities.sas.com/t5/Graphics-Programming/Advanced-ODS-Graphics-techniques-new-free-book/td-p/235735&lt;/A&gt; \&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;One of my favorites uses arcs and splines.&lt;/P&gt;</description>
      <pubDate>Sat, 07 Aug 2021 00:12:55 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/760115#M21805</guid>
      <dc:creator>WarrenKuhfeld</dc:creator>
      <dc:date>2021-08-07T00:12:55Z</dc:date>
    </item>
    <item>
      <title>Re: Patterns of polygons: Use SAS to create mathematical art</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/760138#M21806</link>
      <description>&lt;P&gt;Hi Rick,&lt;/P&gt;
&lt;P&gt;Many thanks for the inspiring blog post. Below I am attempting to combine your 2nd and 3rd suggestions from the end of the post.&amp;nbsp; So I have modified your code to look for a random 'artwork' with no adjacent polygons of the same colour, that also uses all 16 of the pinwheels.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;/* Rick's Code */
data Shape;
input ID x y @@;
datalines;
0  0 0  0  0.667  0.333  0  1  1  0  0  1  0  0  0  
1  0 0  1 -0.333  0.667  1 -1  1  1 -1  0  1  0  0 
2  0 0  2 -0.667 -0.333  2 -1 -1  2  0 -1  2  0  0 
3  0 0  3  0.333 -0.667  3  1 -1  3  1  0  3  0  0 
;

proc iml;
/* actions of the D4 dihedral group */
start D4Action(v, act);
   /* the subroup of rotations by 90 degrees */
   if      act=0 then M = { 1  0,  0  1};
   else if act=1 then M = { 0 -1,  1  0};
   else if act=2 then M = {-1  0,  0 -1};
   else if act=3 then M = { 0  1, -1  0};
   /* the subgroup of reflections across horz, vert, or diagonals */
   else if act=4 then M = {-1  0,  0  1};
   else if act=6 then M = { 0 -1, -1  0};
   else if act=7 then M = { 1  0,  0 -1};
   else if act=5 then M = { 0  1,  1  0};
   return( v*M` );  /* = (M*z`)` */
finish;
/* read in the pinwheel shape */
use Shape; read all var {x y} into P1; 
read all var "ID"; close;

/* Modifying Rick's code below to output all 16 pinwheels.
   Define ID2 where the odd colour numbers are switched */
ID2 = ID;
do i = 1 to 20;
  if mod(ID2[i], 2)=1 then ID2[i] = 4 - ID2[i];
end;

/* write out the transformation of the pinwheel under the D4 actions */
OpNames = {"I" "R1" "R2" "R3" "S0" "S1" "S2" "S3",
           "ZI" "ZR1" "ZR2" "ZR3" "ZS0" "ZS1" "ZS2" "ZS3"};
Name = OpNames[1];
Q = {. . .};
create Panel from Name Q[c={'Name' 'ID' 'x' 'y'}];
do j = 1 to 2;
  do i = 0 to 7;
     R = D4Action(P1, i);
     if j=1 then Q = ID || R; else Q=ID2 || R;
     Name = j(nrow(Q), 1, OpNames[j,i+1]);
     append from Name Q;
  end;
end;
close;
QUIT;

/* get colour by quadrant for each of the 16 pinwheels
   Q4|Q1
   -----
   Q3|Q2
*/ 
data quadrant_col;
  set Panel(where=( (abs(x) + abs(y)) = 2 ));
  if x=1
    then if y&amp;gt;0 then quad=1; else quad=2;
    else if y&amp;gt;0 then quad=4; else quad=3;
  drop x y;
run;
proc sort; by Name quad; run;
proc transpose data=quadrant_col out=quadrant_col(drop=_:) prefix=Q;
  var ID;
  by Name;
  id quad;
run;

proc iml;
  start grid_eval(x) global(c_LR, c_TB);
    /* return the number of adjacent same coloured polygons in a grid of pinwheels */
    nr = nrow(x);
	nc = ncol(x);
	count = 0;
	if nc&amp;gt;1 then do i = 1 to nr; do j = 1 to nc-1;
	    count = count + c_LR[ x[i,j], x[i,j+1] ]; 
	  end; end;
	if nr&amp;gt;1 then do i = 1 to nr-1; do j = 1 to nc;
	    count = count + c_TB[ x[i,j], x[i+1,j] ]; 
	  end; end;
	return(count);
  finish;

  use quadrant_col;
  read all var _num_ into q;
  use Panel;
  read all var {ID x y} into pdata;

  /* create two matrices that count the number of same coloured polygons next to each other
     when 2 pinwheels are either side by side (row indexes left pinwheel, col indexes right
     pinwheel) or when stacked on top of each other (row indexes top pinwheel, col indexes
     bottom pinwheel) */
  c_LR = j(16, 16, .);
  c_TB = j(16, 16, .);  
  do i = 1 to 16; do j = 1 to 16;
    c_LR[i, j] = sum( q[i,{1 2}] = q[j,{4 3}]);
    c_TB[i, j] = sum( q[i,{3 2}] = q[j,{4 1}]);
  end; end;

  /* start with a random assignment of 16 pinwheels to a 4x4 grid */
  g = shape(ranperm(16), 4, 4);
  cc = grid_eval( g );

  /* consider swaps of one pinwheel for another that might improve the artwork. Use
     matrix b to keep a list for each cycle of swaps that give the best improvement */
  b = j(100, 2);

  do cycle = 1 to 200 until(cc=0);
    bestcc = 1E20;  /* best cc this cycle */
    do i = 1 to 15; do j = i+1 to 16;
      h = g;
	  h[i] = g[j];
	  h[j] = g[i];
	  newcc = grid_eval( h );
      if newcc&amp;lt;=bestcc then do;
	    if newcc&amp;lt;bestcc then do;
	      bestcc=newcc;
		  nb = 0;
	    end;
        nb = nb + 1;
	    b[nb, 1] = i;
	    b[nb, 2] = j;
	  end;
    end; end;
    /* choose a swap at random from those in b */
    swap = 1 + floor(rand('uniform')#nb);
    besti = b[swap,1];
    bestj = b[swap,2];
    t = g[besti];
    g[besti] = g[bestj];
    g[bestj] = t;
	cc = bestcc;
  end;

  reset noname;
  if cc=0 then print 'Found grid with no adjacent same colour polygons after' cycle [format=3.0] 'swaps';
          else print 'Optimal arrangement was not found!';
  print g [format=2.0];
  Q = {. . . .};
  create OptPanel from Q[c={'Cell' 'ID' 'x' 'y'}];
  do i = 1 to 16;
	/* work out which rows of panel data correspond to ith pinwheel in g */
	ridx = ( 20#(g[i]-1) + 1) : (20#g[i]);
	Q = j(20,1,i) || pdata[ridx, ];
	append from Q;
  end;
quit;

/* Show the artwork */
%let teal   = CX288c95;
%let orange = CXeba411;
%let blue   = CX0f5098;
%let salmon = CXd5856e;
%let gray   = CX929386;

ods graphics / width=500px height=500px;
/* for convenience, define macros for the COLAXIS and ROWAXIS options */
%macro colOpts; colaxis offsetmin=0 offsetmax=0 display=(nolabel noticks novalues); %mend;
%macro rowOpts;  rowaxis offsetmin=0 offsetmax=0 display=(nolabel noticks novalues); %mend;

title 'Random Shadow';
proc sgpanel data=OptPanel noautolegend;
   styleattrs wallcolor=&amp;amp;gray datacolors=(&amp;amp;teal &amp;amp;orange &amp;amp;blue &amp;amp;salmon);
   panelby Cell / columns=4 onepanel noheader noborder;
   polygon x=x y=y ID=ID / group=ID fill;
   %colOpts; %rowOpts;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="RandomShadow.png" style="width: 500px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/62367iFEFA03C82A7C1DA1/image-size/large?v=v2&amp;amp;px=999" role="button" title="RandomShadow.png" alt="RandomShadow.png" /&gt;&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Sat, 07 Aug 2021 09:49:52 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/760138#M21806</guid>
      <dc:creator>IanWakeling</dc:creator>
      <dc:date>2021-08-07T09:49:52Z</dc:date>
    </item>
    <item>
      <title>Re: Patterns of polygons: Use SAS to create mathematical art</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/760169#M21816</link>
      <description>&lt;P&gt;It is possible to make a slightly more interesting pattern by modifying my code above as follows.&amp;nbsp; Replace the grid_eval module with this:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;  start grid_eval(x) global(c_LR, c_TB, p_pen);
    /* return the number of adjacent same coloured polygons in a grid of pinwheels */
    nr = nrow(x);
	nc = ncol(x);
	count = 0;
	if nc&amp;gt;1 then do i = 1 to nr; do j = 1 to nc-1;
	    count = count + c_LR[ x[i,j], x[i,j+1] ] + p_pen[ x[i,j], x[i,j+1] ]; 
	  end; end;
	if nr&amp;gt;1 then do i = 1 to nr-1; do j = 1 to nc;
	    count = count + c_TB[ x[i,j], x[i+1,j] ] + p_pen[ x[i,j], x[i+1,j] ]; 
	  end; end;
	return(count);
  finish;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;where p_pen is defined in the main program as follows:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;  p_pen = j(2, 2) @ {1 0, 0 1} @ j(4, 4);&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;This modifies the criterion to penalize the number of times polygons meet at a point along the edge where two pinwheels meet.&amp;nbsp; The algorithm does not always converge to the optimum, but when it does it finds a pattern where there is a 3x3 sub-matrix of hourglass shapes visible.&amp;nbsp; For me this pattern seems to dominate, so much so that it is difficult to focus on the original 16 pinwheels.&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="RS3.png" style="width: 500px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/62372i2ABD398F288BF4CC/image-size/large?v=v2&amp;amp;px=999" role="button" title="RS3.png" alt="RS3.png" /&gt;&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Sat, 07 Aug 2021 16:57:09 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/760169#M21816</guid>
      <dc:creator>IanWakeling</dc:creator>
      <dc:date>2021-08-07T16:57:09Z</dc:date>
    </item>
    <item>
      <title>Re: Patterns of polygons: Use SAS to create mathematical art</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/760200#M21817</link>
      <description>Name it "Hourglass Shadow"! &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;</description>
      <pubDate>Sun, 08 Aug 2021 00:17:34 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/760200#M21817</guid>
      <dc:creator>Rick_SAS</dc:creator>
      <dc:date>2021-08-08T00:17:34Z</dc:date>
    </item>
    <item>
      <title>Re: Patterns of polygons: Use SAS to create mathematical art</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/760220#M21818</link>
      <description>&lt;P&gt;I was not really thinking about taking artistic credit for the two images above &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;,&amp;nbsp; I shall rename the first image "Mangled Shadow" and take your suggestion of "Hourglass Shadow" for the second.&lt;/P&gt;</description>
      <pubDate>Sun, 08 Aug 2021 09:12:51 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/760220#M21818</guid>
      <dc:creator>IanWakeling</dc:creator>
      <dc:date>2021-08-08T09:12:51Z</dc:date>
    </item>
    <item>
      <title>Re: Patterns of polygons: Use SAS to create mathematical art</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/760336#M21820</link>
      <description>&lt;P&gt;I have worked-up my earlier sketch above into the final "Hourglass Shadow" &lt;span class="lia-unicode-emoji" title=":winking_face_with_tongue:"&gt;😜&lt;/span&gt;.&amp;nbsp; The algorithm I am using can just about cope with an 8x8 grid using your 16 pinwheels exactly four times each.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="HourglassShadow.png" style="width: 500px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/62396iCCFAF777A472DF4C/image-size/large?v=v2&amp;amp;px=999" role="button" title="HourglassShadow.png" alt="HourglassShadow.png" /&gt;&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Mon, 09 Aug 2021 10:25:33 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/760336#M21820</guid>
      <dc:creator>IanWakeling</dc:creator>
      <dc:date>2021-08-09T10:25:33Z</dc:date>
    </item>
    <item>
      <title>Re: Patterns of polygons: Use SAS to create mathematical art</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/760341#M21821</link>
      <description>&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;ods _all_ close;
ods listing;
data polygon;
    file print;
    put '/\' / '\/';
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;It's a style of art that is called "minimalism".&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Do I win?&lt;/P&gt;</description>
      <pubDate>Mon, 09 Aug 2021 12:13:06 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/760341#M21821</guid>
      <dc:creator>PaigeMiller</dc:creator>
      <dc:date>2021-08-09T12:13:06Z</dc:date>
    </item>
    <item>
      <title>Re: Patterns of polygons: Use SAS to create mathematical art</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/761121#M21832</link>
      <description>&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data Pinwheels;
input Group ID @;
Group = rand("integer", 0, 15);
ID = rand("integer", 0, 3);
do i = 1 to 5;
   input x y @@;
   output;
end;
drop i;
datalines;
.......&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;I decided to introduce randomness by changing the variables GROUP and ID using the RAND function.&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="random.png" style="width: 400px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/62508i56EE7DE4C8965EE6/image-size/medium?v=v2&amp;amp;px=400" role="button" title="random.png" alt="random.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt; &lt;/P&gt;</description>
      <pubDate>Thu, 12 Aug 2021 11:57:09 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/761121#M21832</guid>
      <dc:creator>hw</dc:creator>
      <dc:date>2021-08-12T11:57:09Z</dc:date>
    </item>
    <item>
      <title>Re: Patterns of polygons: Use SAS to create mathematical art</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/761168#M21833</link>
      <description>&lt;P&gt;Interesting to see some of the dart shapes colored in.&amp;nbsp; Presumably where one polygon has overprinted another?&lt;/P&gt;</description>
      <pubDate>Thu, 12 Aug 2021 14:58:38 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/761168#M21833</guid>
      <dc:creator>IanWakeling</dc:creator>
      <dc:date>2021-08-12T14:58:38Z</dc:date>
    </item>
    <item>
      <title>Re: Patterns of polygons: Use SAS to create mathematical art</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/761402#M21848</link>
      <description>&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;/* Uisng a random number to generate the pinwheels dataset */
/* Depends when the program is run, the shape can be quite different */

data pinwheels;
     rand1 = rand('uniform');
     
     group = 0; id = 0; x = 0; y = 0; output;
                        x = rand1; y = 1 - x; output;
                        x = 1; y = 1; output;
                        x = 0; y = 1; output;
                        x = 0; y = 0; output;
     group = 0; id = 1; x = 0; y = 0; output;
                        x = rand1 - 1; y = rand1; output;
                        x = -1; y = 1; output;
                        x = -1; y = 0; output;
                        x = 0; y = 0; output;
     group = 0; id = 2; x = 0; y = 0; output;
                        x = -1 * rand1; y = -1* (1 - rand1); output;
                        x = -1; y = -1; output;
                        x = 0 ; y = -1; output;
                        x = 0; y = 0; output;
     group = 0; id = 3; x = 0; y = 0; output;
                        x = 1 - rand1; y = -1 * rand1; output;
                        x = 1; y = -1; output;
                        x = 1 ; y = 0; output;
                        x = 0; y = 0; output;
     group = 1; id = 0; x = 0; y = 0; output;
                        x = -1*(1 - rand1); y = rand1; output;
                        x = -1; y = 1; output;
                        x = -1 ; y = 0; output;
                        x = 0; y = 0; output;
     group = 1; id = 1; x = 0; y = 0; output;
                        x = -1* rand1; y = -1 *(1-rand1); output;
                        x = -1; y = -1; output;
                        x = 0 ; y = -1; output;
                        x = 0; y = 0; output;
     group = 1; id = 2; x = 0; y = 0; output;
                        x = 1 - rand1; y = -1 *rand1; output;
                        x = 1; y = -1; output;
                        x = 1 ; y = 0; output;
                        x = 0; y = 0; output;
     group = 1; id = 3; x = 0; y = 0; output;
                        x = rand1; y = 1 - rand1; output;
                        x = 1; y = 1; output;
                        x = 0 ; y = 1; output;
                        x = 0; y = 0; output;
     group = 2; id = 0; x = 0; y = 0; output;
                        x = -1*rand1; y = -1 *(1- rand1); output;
                        x = -1; y = -1; output;
                        x = 0  ; y = -1; output;
                        x = 0; y = 0; output;
     group = 2; id = 1; x = 0; y = 0; output;
                        x =  1 -rand1; y = -1 *rand1; output;
                        x = 1; y = -1; output;
                        x = 1 ; y = 0; output;
                        x = 0; y = 0; output;
     group = 2; id = 2; x = 0; y = 0; output;
                        x = rand1; y = 1 - rand1; output;
                        x = 1; y = 1; output;
                        x = 0 ; y = 1; output;
                        x = 0; y = 0; output;
     group = 2; id = 3; x = 0; y = 0; output;
                        x = -1 *(1- rand1); y = rand1; output;
                        x = -1; y = 1; output;
                        x = -1 ; y = 0; output;
                        x = 0; y = 0; output;
     group = 3; id = 0; x = 0; y = 0; output;
                        x = 1 -rand1; y = -1 * rand1; output;
                        x = 1; y = -1; output;
                        x = 1  ; y = 0; output;
                        x = 0; y = 0; output;
     group = 3; id = 1; x = 0; y = 0; output;
                        x =  rand1; y = 1 - rand1; output;
                        x = 1; y = 1; output;
                        x = 0 ; y = 1; output;
                        x = 0; y = 0; output;
     group = 3; id = 2; x = 0; y = 0; output;
                        x = -1 * (1 - rand1); y = rand1; output;
                        x = -1; y = 1; output;
                        x = -1 ; y = 0; output;
                        x = 0; y = 0; output;
     group = 3; id = 3; x = 0; y = 0; output;
                        x = -1 * rand1; y = -1 *(1-rand1); output;
                        x = -1; y = -1; output;
                        x = 0 ; y = -1; output;
                        x = 0; y = 0; output;
     group = 4; id = 0; x = 0; y = 0; output;
                        x = 1 *rand1; y =  1 - rand1; output;
                        x = -1; y = 1; output;
                        x = 0  ; y = 1; output;
                        x = 0; y = 0; output;
     group = 4; id = 1; x = 0; y = 0; output;
                        x = 1 - rand1; y = rand1; output;
                        x = 1; y = 1; output;
                        x = 1 ; y = 0; output;
                        x = 0; y = 0; output;
     group = 4; id = 2; x = 0; y = 0; output;
                        x = rand1; y = -1 * (1-rand1); output;
                        x = 1; y = -1; output;
                        x = 0  ; y = -1; output;
                        x = 0; y = 0; output;
     group = 4; id = 3; x = 0; y = 0; output;
                        x = -1 * (1-rand1); y = -1 * rand1; output;
                        x = -1; y = -1; output;
                        x = -1; y = 0; output;
                        x = 0; y = 0; output;
     group = 5; id = 0; x = 0; y = 0; output;
                        x = 1 -rand1; y =  rand1; output;
                        x = 1; y = 1; output;
                        x = 1  ; y = 0; output;
                        x = 0; y = 0; output;
     group = 5; id = 1; x = 0; y = 0; output;
                        x =  rand1; y = -1 * (1-rand1); output;
                        x = 1; y = -1; output;
                        x = 0 ; y = -1; output;
                        x = 0; y = 0; output;
     group = 5; id = 2; x = 0; y = 0; output;
                        x = -1*(1-rand1); y = -1* rand1; output;
                        x = -1; y = -1; output;
                        x = -1 ; y = 0; output;
                        x = 0; y = 0; output;
     group = 5; id = 3; x = 0; y = 0; output;
                        x = -1*rand1; y = 1 - rand1; output;
                        x = -1; y = 0; output;
                        x = 0; y = 1; output;
                        x = 0; y = 0; output;
     group = 6; id = 0; x = 0; y = 0; output;
                        x = -1*(1 -rand1); y = -1* rand1; output;
                        x = -1; y = -1; output;
                        x = -1  ; y = 0; output;
                        x = 0; y = 0; output;
     group = 6; id = 1; x = 0; y = 0; output;
                        x = -1 * rand1; y = 1-rand1; output;
                        x = -1; y = 1; output;
                        x = 0 ; y = 1; output;
                        x = 0; y = 0; output;
     group = 6; id = 2; x = 0; y = 0; output;
                        x = 1-rand1; y = rand1; output;
                        x = 1; y = 1; output;
                        x = 1 ; y = 0; output;
                        x = 0; y = 0; output;
     group = 6; id = 3; x = 0; y = 0; output;
                        x =  rand1; y = -1 *(1 - rand1); output;
                        x = 1; y = -1; output;
                        x = 0; y = -1; output;
                        x = 0; y = 0; output;
     group = 7; id = 0; x = 0; y = 0; output;
                        x = rand1; y = -1* (1-rand1); output;
                        x = 1; y = -1; output;
                        x = 0  ; y = -1; output;
                        x = 0; y = 0; output;
     group = 7; id = 1; x = 0; y = 0; output;
                        x = -1 * (1-rand1); y = -1*rand1; output;
                        x = -1; y = -1; output;
                        x = -1 ; y = 0; output;
                        x = 0; y = 0; output;
     group = 7; id = 2; x = 0; y = 0; output;
                        x = -1*rand1; y = 1-rand1; output;
                        x = -1; y = 1; output;
                        x = 0 ; y = 1; output;
                        x = 0; y = 0; output;
     group = 7; id = 3; x = 0; y = 0; output;
                        x = 1- rand1; y = rand1; output;
                        x = 1; y = 1; output;
                        x = 1; y = 0; output;
                        x = 0; y = 0; output;
     group = 8; id = 0; x = 0; y = 0; output;
                        x = rand1; y = 1-rand1 ; output;
                        x = 1; y = 1; output;
                        x = 0  ; y = 1; output;
                        x = 0; y = 0; output;
     group = 8; id = 1; x = 0; y = 0; output;
                        x = 1-rand1; y = -1* rand1; output;
                        x = 1; y = -1; output;
                        x = 1 ; y = 0; output;
                        x = 0; y = 0; output;
     group = 8; id = 2; x = 0; y = 0; output;
                        x = -1*rand1; y = -1*(1-rand1); output;
                        x = -1; y = -1; output;
                        x = 0 ; y = -1; output;
                        x = 0; y = 0; output;
     group = 8; id = 3; x = 0; y = 0; output;
                        x = -1*(1- rand1); y = rand1; output;
                        x = -1; y = 1; output;
                        x = -1; y = 0; output;
                        x = 0; y = 0; output;
     group = 9; id = 0; x = 0; y = 0; output;
                        x = -1 * (1-rand1); y = rand1 ; output;
                        x = -1; y = 1; output;
                        x = -1  ; y = 0; output;
                        x = 0; y = 0; output;
     group = 9; id = 1; x = 0; y = 0; output;
                        x = rand1; y =  1- rand1; output;
                        x = 1; y = 1; output;
                        x = 0 ; y = 1; output;
                        x = 0; y = 0; output;
     group = 9; id = 2; x = 0; y = 0; output;
                        x =  1-rand1; y = -1*rand1; output;
                        x = 1; y = -1; output;
                        x = 1 ; y = 0; output;
                        x = 0; y = 0; output;
     group = 9; id = 3; x = 0; y = 0; output;
                        x = -1 * rand1; y = 1-rand1; output;
                        x = -1; y = -1; output;
                        x = 0; y = -1; output;
                        x = 0; y = 0; output;
     group =10; id = 0; x = 0; y = 0; output;
                        x = -1 * rand1; y = -1*(1-rand1); output;
                        x = -1; y = -1; output;
                        x = 0  ; y = 1; output;
                        x = 0; y = 0; output;
     group =10; id = 1; x = 0; y = 0; output;
                        x = -1*(1-rand1); y =  rand1; output;
                        x = -1; y = 1; output;
                        x = -1 ; y = 0; output;
                        x = 0; y = 0; output;
     group =10; id = 2; x = 0; y = 0; output;
                        x =  rand1; y = 1 - rand1; output;
                        x = 1; y = 1; output;
                        x = 0 ; y = 1; output;
                        x = 0; y = 0; output;
     group =10; id = 3; x = 0; y = 0; output;
                        x =  1 - rand1; y = -1*rand1; output;
                        x = 1; y = -1; output;
                        x = 1; y = 0; output;
                        x = 0; y = 0; output;
     group =11; id = 0; x = 0; y = 0; output;
                        x = 1 - rand1; y = -1* rand1; output;
                        x = 1; y = -1; output;
                        x = 1  ; y = 0; output;
                        x = 0; y = 0; output;
     group =11; id = 1; x = 0; y = 0; output;
                        x = -1 *rand1; y = -1*(1- rand1); output;
                        x = -1; y = -1; output;
                        x = 0  ; y = -1; output;
                        x = 0; y = 0; output;
     group =11; id = 2; x = 0; y = 0; output;
                        x =  -1 * (1-rand1); y = rand1; output;
                        x = -1; y = 1; output;
                        x = -1 ; y = 0; output;
                        x = 0; y = 0; output;
     group =11; id = 3; x = 0; y = 0; output;
                        x =  rand1; y = 1- rand1; output;
                        x = 1; y = 1; output;
                        x = 0; y = 1; output;
                        x = 0; y = 0; output;
     group =12; id = 0; x = 0; y = 0; output;
                        x = -1 *rand1; y = 1 - rand1; output;
                        x = -1; y = 1; output;
                        x = 0  ; y = 1; output;
                        x = 0; y = 0; output;
     group =12; id = 1; x = 0; y = 0; output;
                        x = -1 *(1-rand1); y = -1* rand1; output;
                        x = -1; y = -1; output;
                        x = -1  ; y = 0; output;
                        x = 0; y = 0; output;
     group =12; id = 2; x = 0; y = 0; output;
                        x =  rand1; y = -1 * (1-rand1); output;
                        x = 1 ; y = -1; output;
                        x = 0 ; y = -1; output;
                        x = 0; y = 0; output;
     group =12; id = 3; x = 0; y = 0; output;
                        x = 1 - rand1; y = rand1; output;
                        x = 1; y = 1; output;
                        x = 1; y = 0; output;
                        x = 0; y = 0; output;
     group =13; id = 0; x = 0; y = 0; output;
                        x = 1 - rand1; y = rand1; output;
                        x =  1; y = 1; output;
                        x = 1  ; y = 0; output;
                        x = 0; y = 0; output;
     group =13; id = 1; x = 0; y = 0; output;
                        x = -1*rand1; y = 1 - rand1; output;
                        x = -1; y = 1; output;
                        x =  0  ; y = 1; output;
                        x = 0; y = 0; output;
     group =13; id = 2; x = 0; y = 0; output;
                        x = -1 *(1- rand1); y = -1 * rand1; output;
                        x = -1 ; y = -1; output;
                        x = -1 ; y = 0; output;
                        x = 0; y = 0; output;
     group =13; id = 3; x = 0; y = 0; output;
                        x = rand1; y = -1 * (1-rand1); output;
                        x = 1; y = -1; output;
                        x = 0; y = -1; output;
                        x = 0; y = 0; output;
     group =14; id = 0; x = 0; y = 0; output;
                        x = -1 *(1 - rand1); y =-1 * rand1; output;
                        x =  -1; y = -1; output;
                        x = -1  ; y = 0; output;
                        x = 0; y = 0; output;
     group =14; id = 1; x = 0; y = 0; output;
                        x = rand1; y = -1*(1 - rand1); output;
                        x = 1; y = -1; output;
                        x =  0  ; y = 1; output;
                        x = 0; y = 0; output;
     group =14; id = 2; x = 0; y = 0; output;
                        x = 1- rand1; y = rand1; output;
                        x = 1 ; y = 1; output;
                        x = 1 ; y = 0; output;
                        x = 0; y = 0; output;
     group =14; id = 3; x = 0; y = 0; output;
                        x = -1 * rand1; y = 1-rand1; output;
                        x = -1; y = 0; output;
                        x = 0; y = 1; output;
                        x = 0; y = 0; output;
     group =15; id = 0; x = 0; y = 0; output;
                        x = rand1; y =-1 * (1-rand1); output;
                        x =  1; y = -1; output;
                        x = 0  ; y = -1; output;
                        x = 0; y = 0; output;
     group =15; id = 1; x = 0; y = 0; output;
                        x = 1-rand1; y = rand1; output;
                        x = 1; y = 1; output;
                        x =  1  ; y = 0; output;
                        x = 0; y = 0; output;
     group =15; id = 2; x = 0; y = 0; output;
                        x = -1 * rand1; y = 1-rand1; output;
                        x = -1 ; y = 1; output;
                        x = 0 ; y = 1; output;
                        x = 0; y = 0; output;
     group =15; id = 3; x = 0; y = 0; output;
                        x = -1 * (1-rand1); y = -1*rand1; output;
                        x = -1; y = -1; output;
                        x = -1; y = 0; output;
                        x = 0; y = 0; output;
 run;
 
 

%let teal   = CX288c95;
%let orange = CXeba411;
%let blue   = CX0f5098;
%let salmon = CXd5856e;
%let gray   = CX929386;

ods graphics / width=640px height=640px;
%macro colOpts; colaxis offsetmin=0 offsetmax=0 display=(nolabel noticks novalues); %mend;
%macro rowOpts;  rowaxis offsetmin=0 offsetmax=0 display=(nolabel noticks novalues); %mend;

title "Dihedral Shadow";
proc sgpanel data=Pinwheels noautolegend;
   styleattrs wallcolor=&amp;amp;gray datacolors=(&amp;amp;teal &amp;amp;orange &amp;amp;blue &amp;amp;salmon);
   panelby Group / columns=4 onepanel noheader;
   polygon x=x y=y ID=ID / group=ID fill;
   %colOpts; %rowOpts;
run;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="jl3_0-1628857424640.png" style="width: 400px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/62554i53A571E6DD24A3BC/image-size/medium?v=v2&amp;amp;px=400" role="button" title="jl3_0-1628857424640.png" alt="jl3_0-1628857424640.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 13 Aug 2021 12:24:05 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/Patterns-of-polygons-Use-SAS-to-create-mathematical-art/m-p/761402#M21848</guid>
      <dc:creator>jl3</dc:creator>
      <dc:date>2021-08-13T12:24:05Z</dc:date>
    </item>
  </channel>
</rss>

