
在第1部分彭羅斯平鋪生成器將其結果存儲在數據表中。 第 1 部分中的圖表包含不同灰度級的線,表示每條線被繪製了多少次。 瓦片不是作為多邊形從生成器發出的,只是一堆鬆散和重複的邊緣。 第 2 部分 JSL 不會使用數據表;相反,關聯數組將使用 XY 坐標作為鍵來收集線段。 每個鍵的數據將是與 XY 位置關聯的所有其他端點的列表。 構建關聯數組後,JSL 將通過它來提取唯一的多邊形(風箏和飛鏢)並識別風箏和飛鏢的橙色和藍色。
// see previous posts...
DELTA = PI()/5;
cx=0;
cy=0;
ca=-DELTA;
repeat=1;
W=function({lev},{sx,sy,sa},// "YBF2+ZRF4-XBF[-YBF4-WRF]2+";
lev--;if(lev>= 0,
Y(lev);B(lev);F(lev);NUMB(2);PLUS();Z(lev);R(lev);F(lev);NUMB(4);SUB();X(lev);B(lev);F(lev);sx=cx;sy=cy;sa=ca;SUB();Y(lev);B(lev);F(lev);NUMB(4);SUB();W(lev);R(lev);F(lev);cx=sx;cy=sy;ca=sa;NUMB(2);PLUS();
));
X= function({lev},{sx,sy,sa},// "+YBF2-ZRF[3-WRF2-XBF]+";
lev--;if(lev>= 0,
PLUS();Y(lev);B(lev);F(lev);NUMB(2);SUB();Z(lev);R(lev);F(lev);sx=cx;sy=cy;sa=ca;NUMB(3);SUB();W(lev);R(lev);F(lev);NUMB(2);SUB();X(lev);B(lev);F(lev);cx=sx;cy=sy;ca=sa;PLUS();
));
Y=function({lev},{sx,sy,sa},//"-WRF2+XBF[3+YBF2+ZRF]-";
lev--;if(lev>= 0,
SUB();W(lev);R(lev);F(lev);NUMB(2);PLUS();X(lev);B(lev);F(lev);sx=cx;sy=cy;sa=ca;NUMB(3);PLUS();Y(lev);B(lev);F(lev);NUMB(2);PLUS();Z(lev);R(lev);F(lev);cx=sx;cy=sy;ca=sa;SUB();
));
Z=function({lev},{sx,sy,sa},// "2-YBF4+WRF[+ZRF4+XBF]2-XBF";
lev--;if(lev>= 0,
NUMB(2);SUB();Y(lev);B(lev);F(lev);NUMB(4);PLUS();W(lev);R(lev);F(lev);sx=cx;sy=cy;sa=ca;PLUS();Z(lev);R(lev);F(lev);NUMB(4);PLUS();X(lev);B(lev);F(lev);cx=sx;cy=sy;ca=sa;NUMB(2);SUB();X(lev);B(lev);F(lev);
));
B = function({lev},0);
F = Function( {lev}, /*draw cx,cy,ca*/
If( lev == 0,
new_xpos = cx + 20 * Cos( ca );
new_ypos = cy - 20 * Sin( ca );
key1 = key( cx, cy );
If( !(aa << Contains( key1 )),
aa[key1] = [=> 0] // <<< new code for Associative Array
);
key2 = key( new_xpos, new_ypos );
If( !(aa << Contains( key2 )),
aa[key2] = [=> 0] // <<< new code for Associative Array
);
cx = new_xpos;
cy = new_ypos;
aa[key1][key2]++;
aa[key2][key1]++;
)
);
R = function({lev},0);
PLUS=function({},ca += DELTA * repeat; repeat = 1);
SUB=function({},ca -= DELTA * repeat; repeat = 1);
NUMB=function({n},repeat=n); // 2,3,4
aa = associativearray();
key = function({x,y}, (round(x,5))|/(round(y,5));); // <<< new code for Associative Array
//AXIOM = "2+2+2+2+";
level=7;//5;//8;
scale=50;//50;
sbscale=2;//.4;//1;
local({i,sx,sy,sa},
for(i=1,i<=5,i++,
sx=cx;sy=cy;sa=ca;
X(level);
cx=sx;cy=sy;ca=sa;
NUMB(2);
PLUS();
);
);
// http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibFormula.html
// seems to be a Fibonacci sequence. estimate the axis size.
size = 22 * (1.61803398874989 ^ level);
pts0 = aa << getkeys;
///////////// new code for Associative Array follows /////////////
nkite = 0;
ndart = 0;
kites=associativearray();
darts=associativearray();
shrink = function({a,b,c,d},{r=J(2,4,0),x=(a+b+c+d)/4, s=.2}, // shrink the polygon toward the middle
r=a+s*(x-a)||b+s*(x-b)||c+s*(x-c)||d+s*(x-d);
r;
);
While( N Items( pt0 = Remove From( pts0, 1 ) ) == 1,
pt0 = pt0[1];
pts1 = (aa[pt0]) << getkeys;
While( N Items( pt1 = Remove From( pts1, 1 ) ) == 1,
pt1 = pt1[1];
pts2 = (aa[pt1]) << getkeys;
While( N Items( pt2 = Remove From( pts2, 1 ) ) == 1,
pt2 = pt2[1];
If( !All( pt0 == pt2 ),
pts3 = (aa[pt2]) << getkeys;
While( N Items( pt3 = Remove From( pts3, 1 ) ) == 1,
pt3 = pt3[1];
If( !All( pt1 == pt3 ),
pts4 = (aa[pt3]) << getkeys;
While( N Items( pt4 = Remove From( pts4, 1 ) ) == 1,
pt4 = pt4[1];
If( All( pt0 == pt4 ),
// keep only CW paths (or CCW, don't really care, but not both)
keep = Det( pt0 - pt1 || pt2 - pt1 ); // x1y2-x2y1 cross product winding
If( keep > 0,
//Show( pt0, pt1, pt2, pt3, pt4,keep,"\!n" )
d1 = Sqrt( (pt0[1] - pt2[1]) ^ 2 + (pt0[2] - pt2[2]) ^ 2 );
d2 = Sqrt( (pt1[1] - pt3[1]) ^ 2 + (pt1[2] - pt3[2]) ^ 2 );
If( d1 / 2 < d2 < d1 * 2,
nkite++;
kites[nkite] = shrink( pt0, pt1, pt2, pt3 );
,
ndart++;
darts[ndart] = shrink( pt0, pt1, pt2, pt3 );
);
);
);
);
);
);
);
);
);
aa[pt0] = {}; // this vertex has generated all of its polys, don't generate more if we come back to it
);
show(nkite,ndart);
New Window( "Example",
Graph Box(framesize(900,900),xscale(-size,size),yscale(-size,size),
Fill Color( hlscolor(.05,.6,.7) );
for(i=1,i<=nkite,i++,
Polygon( kites[i][1,0], kites[i][2,0] );
);
Fill Color( hlscolor(.55,.4,.95) );
for(i=1,i<=ndart,i++,
Polygon( darts[i][1,0], darts[i][2,0] );
);
)
);
下週:如何從瓷磚製作 3D 表面。 第 3 部分將使用第 2 部分中的風箏和飛鏢陣列。
2017 年 5 月 26 日更新:網站轉換後的代碼修復