From 02f4a125d0d1051e790b328b74be902aad81999d Mon Sep 17 00:00:00 2001 From: Iker Ruiz de Infante Gonzalez Date: Sat, 17 Jun 2023 15:01:17 +0200 Subject: [PATCH] Version 0.2.0 (#2) * Prepare version 0.2.0 branch * Updated 1-dimensional examples * Added 2-dimensional euclidean API * Added 2-dimensional toroidal API * Updated README.md --- README.md | 5 +- assets/1-dimensional-euclidean/result1.png | Bin 0 -> 7967 bytes assets/1-dimensional-euclidean/result2.png | Bin 0 -> 8100 bytes assets/1-dimensional-euclidean/result3.png | Bin 0 -> 8062 bytes assets/1-dimensional-toroidal/result1.png | Bin 0 -> 5315 bytes assets/1-dimensional-toroidal/result2.png | Bin 0 -> 5245 bytes assets/2-dimensional-euclidean/NE.png | Bin 0 -> 4913 bytes assets/2-dimensional-euclidean/NW.png | Bin 0 -> 4925 bytes assets/2-dimensional-euclidean/SE.png | Bin 0 -> 4918 bytes assets/2-dimensional-euclidean/SW.png | Bin 0 -> 4926 bytes assets/2-dimensional-euclidean/result1.png | Bin 0 -> 6742 bytes assets/2-dimensional-euclidean/result2.png | Bin 0 -> 6717 bytes assets/2-dimensional-toroidal/BTBT.png | Bin 0 -> 8520 bytes assets/2-dimensional-toroidal/BTLB.png | Bin 0 -> 8338 bytes assets/2-dimensional-toroidal/BTLR.png | Bin 0 -> 7315 bytes assets/2-dimensional-toroidal/BTLT.png | Bin 0 -> 9141 bytes assets/2-dimensional-toroidal/BTRB.png | Bin 0 -> 7460 bytes assets/2-dimensional-toroidal/BTRT.png | Bin 0 -> 7935 bytes assets/2-dimensional-toroidal/BT__.png | Bin 0 -> 8647 bytes assets/2-dimensional-toroidal/LBBT.png | Bin 0 -> 9316 bytes assets/2-dimensional-toroidal/LBLB.png | Bin 0 -> 9209 bytes assets/2-dimensional-toroidal/LBLR.png | Bin 0 -> 7738 bytes assets/2-dimensional-toroidal/LBLT.png | Bin 0 -> 9656 bytes assets/2-dimensional-toroidal/LBRB.png | Bin 0 -> 8078 bytes assets/2-dimensional-toroidal/LBRT.png | Bin 0 -> 8172 bytes assets/2-dimensional-toroidal/LB__.png | Bin 0 -> 9423 bytes assets/2-dimensional-toroidal/LRBT.png | Bin 0 -> 7228 bytes assets/2-dimensional-toroidal/LRLB.png | Bin 0 -> 7535 bytes assets/2-dimensional-toroidal/LRLR.png | Bin 0 -> 5923 bytes assets/2-dimensional-toroidal/LRLT.png | Bin 0 -> 8276 bytes assets/2-dimensional-toroidal/LRRB.png | Bin 0 -> 7583 bytes assets/2-dimensional-toroidal/LRRT.png | Bin 0 -> 8232 bytes assets/2-dimensional-toroidal/LR__.png | Bin 0 -> 7427 bytes assets/2-dimensional-toroidal/LTBT.png | Bin 0 -> 9295 bytes assets/2-dimensional-toroidal/LTLB.png | Bin 0 -> 8272 bytes assets/2-dimensional-toroidal/LTLR.png | Bin 0 -> 6971 bytes assets/2-dimensional-toroidal/LTLT.png | Bin 0 -> 9694 bytes assets/2-dimensional-toroidal/LTRB.png | Bin 0 -> 7455 bytes assets/2-dimensional-toroidal/LTRT.png | Bin 0 -> 8494 bytes assets/2-dimensional-toroidal/LT__.png | Bin 0 -> 9394 bytes assets/2-dimensional-toroidal/RBBT.png | Bin 0 -> 8516 bytes assets/2-dimensional-toroidal/RBLB.png | Bin 0 -> 8934 bytes assets/2-dimensional-toroidal/RBLR.png | Bin 0 -> 7743 bytes assets/2-dimensional-toroidal/RBLT.png | Bin 0 -> 9119 bytes assets/2-dimensional-toroidal/RBRB.png | Bin 0 -> 8408 bytes assets/2-dimensional-toroidal/RBRT.png | Bin 0 -> 9817 bytes assets/2-dimensional-toroidal/RB__.png | Bin 0 -> 8710 bytes assets/2-dimensional-toroidal/RTBT.png | Bin 0 -> 8145 bytes assets/2-dimensional-toroidal/RTLB.png | Bin 0 -> 7883 bytes assets/2-dimensional-toroidal/RTLR.png | Bin 0 -> 7010 bytes assets/2-dimensional-toroidal/RTLT.png | Bin 0 -> 9214 bytes assets/2-dimensional-toroidal/RTRB.png | Bin 0 -> 7940 bytes assets/2-dimensional-toroidal/RTRT.png | Bin 0 -> 9597 bytes assets/2-dimensional-toroidal/RT__.png | Bin 0 -> 8216 bytes assets/2-dimensional-toroidal/__BT.png | Bin 0 -> 8649 bytes assets/2-dimensional-toroidal/__LB.png | Bin 0 -> 8287 bytes assets/2-dimensional-toroidal/__LR.png | Bin 0 -> 7198 bytes assets/2-dimensional-toroidal/__LT.png | Bin 0 -> 9029 bytes assets/2-dimensional-toroidal/__RB.png | Bin 0 -> 7585 bytes assets/2-dimensional-toroidal/__RT.png | Bin 0 -> 8065 bytes assets/2-dimensional-toroidal/result.png | Bin 0 -> 2442 bytes examples/1-dimensional-euclidean.md | 8 +- examples/1-dimensional-toroidal.md | 6 +- examples/2-dimensional-euclidean.md | 98 ++++++ examples/2-dimensional-toroidal.md | 124 ++++++++ pom.xml | 2 +- .../api/WaveFunctionCollapseEuclidean2D.java | 120 ++++++++ .../api/WaveFunctionCollapseToroidal2D.java | 120 ++++++++ .../core/AbstractWaveFunctionCollapse2D.java | 283 ++++++++++++++++++ .../eu/irzinfante/wfc4j/enums/Side2D.java | 40 +++ .../eu/irzinfante/wfc4j/model/Cell2D.java | 94 ++++++ .../eu/irzinfante/wfc4j/model/TileMap2D.java | 125 ++++++++ .../eu/irzinfante/wfc4j/util/WFCUtils.java | 43 +++ .../wfc4j/test/TestWFCEuclidean2D.java | 80 +++++ .../wfc4j/test/TestWFCToroidal2D.java | 103 +++++++ 75 files changed, 1240 insertions(+), 11 deletions(-) create mode 100644 assets/1-dimensional-euclidean/result1.png create mode 100644 assets/1-dimensional-euclidean/result2.png create mode 100644 assets/1-dimensional-euclidean/result3.png create mode 100644 assets/1-dimensional-toroidal/result1.png create mode 100644 assets/1-dimensional-toroidal/result2.png create mode 100644 assets/2-dimensional-euclidean/NE.png create mode 100644 assets/2-dimensional-euclidean/NW.png create mode 100644 assets/2-dimensional-euclidean/SE.png create mode 100644 assets/2-dimensional-euclidean/SW.png create mode 100644 assets/2-dimensional-euclidean/result1.png create mode 100644 assets/2-dimensional-euclidean/result2.png create mode 100644 assets/2-dimensional-toroidal/BTBT.png create mode 100644 assets/2-dimensional-toroidal/BTLB.png create mode 100644 assets/2-dimensional-toroidal/BTLR.png create mode 100644 assets/2-dimensional-toroidal/BTLT.png create mode 100644 assets/2-dimensional-toroidal/BTRB.png create mode 100644 assets/2-dimensional-toroidal/BTRT.png create mode 100644 assets/2-dimensional-toroidal/BT__.png create mode 100644 assets/2-dimensional-toroidal/LBBT.png create mode 100644 assets/2-dimensional-toroidal/LBLB.png create mode 100644 assets/2-dimensional-toroidal/LBLR.png create mode 100644 assets/2-dimensional-toroidal/LBLT.png create mode 100644 assets/2-dimensional-toroidal/LBRB.png create mode 100644 assets/2-dimensional-toroidal/LBRT.png create mode 100644 assets/2-dimensional-toroidal/LB__.png create mode 100644 assets/2-dimensional-toroidal/LRBT.png create mode 100644 assets/2-dimensional-toroidal/LRLB.png create mode 100644 assets/2-dimensional-toroidal/LRLR.png create mode 100644 assets/2-dimensional-toroidal/LRLT.png create mode 100644 assets/2-dimensional-toroidal/LRRB.png create mode 100644 assets/2-dimensional-toroidal/LRRT.png create mode 100644 assets/2-dimensional-toroidal/LR__.png create mode 100644 assets/2-dimensional-toroidal/LTBT.png create mode 100644 assets/2-dimensional-toroidal/LTLB.png create mode 100644 assets/2-dimensional-toroidal/LTLR.png create mode 100644 assets/2-dimensional-toroidal/LTLT.png create mode 100644 assets/2-dimensional-toroidal/LTRB.png create mode 100644 assets/2-dimensional-toroidal/LTRT.png create mode 100644 assets/2-dimensional-toroidal/LT__.png create mode 100644 assets/2-dimensional-toroidal/RBBT.png create mode 100644 assets/2-dimensional-toroidal/RBLB.png create mode 100644 assets/2-dimensional-toroidal/RBLR.png create mode 100644 assets/2-dimensional-toroidal/RBLT.png create mode 100644 assets/2-dimensional-toroidal/RBRB.png create mode 100644 assets/2-dimensional-toroidal/RBRT.png create mode 100644 assets/2-dimensional-toroidal/RB__.png create mode 100644 assets/2-dimensional-toroidal/RTBT.png create mode 100644 assets/2-dimensional-toroidal/RTLB.png create mode 100644 assets/2-dimensional-toroidal/RTLR.png create mode 100644 assets/2-dimensional-toroidal/RTLT.png create mode 100644 assets/2-dimensional-toroidal/RTRB.png create mode 100644 assets/2-dimensional-toroidal/RTRT.png create mode 100644 assets/2-dimensional-toroidal/RT__.png create mode 100644 assets/2-dimensional-toroidal/__BT.png create mode 100644 assets/2-dimensional-toroidal/__LB.png create mode 100644 assets/2-dimensional-toroidal/__LR.png create mode 100644 assets/2-dimensional-toroidal/__LT.png create mode 100644 assets/2-dimensional-toroidal/__RB.png create mode 100644 assets/2-dimensional-toroidal/__RT.png create mode 100644 assets/2-dimensional-toroidal/result.png create mode 100644 examples/2-dimensional-euclidean.md create mode 100644 examples/2-dimensional-toroidal.md create mode 100644 src/main/java/eu/irzinfante/wfc4j/api/WaveFunctionCollapseEuclidean2D.java create mode 100644 src/main/java/eu/irzinfante/wfc4j/api/WaveFunctionCollapseToroidal2D.java create mode 100644 src/main/java/eu/irzinfante/wfc4j/core/AbstractWaveFunctionCollapse2D.java create mode 100644 src/main/java/eu/irzinfante/wfc4j/enums/Side2D.java create mode 100644 src/main/java/eu/irzinfante/wfc4j/model/Cell2D.java create mode 100644 src/main/java/eu/irzinfante/wfc4j/model/TileMap2D.java create mode 100644 src/test/java/eu/irzinfante/wfc4j/test/TestWFCEuclidean2D.java create mode 100644 src/test/java/eu/irzinfante/wfc4j/test/TestWFCToroidal2D.java diff --git a/README.md b/README.md index 754e87d..9c9a919 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ To use the ```wfc4j``` library in your Java project, you can include the library eu.irzinfante wfc4j - 0.1.1 + 0.2.0 ``` @@ -24,6 +24,9 @@ Here are some examples that demonstrate the usage of the different API of the li - 1-dimensional: - [Euclidean (linear grid)](examples/1-dimensional-euclidean.md) - [Toroidal (cyclic grid)](examples/1-dimensional-toroidal.md) +- 2-dimensional: + - [Euclidean (planar grid)](examples/2-dimensional-euclidean.md) + - [Toroidal (toroidal grid)](examples/2-dimensional-toroidal.md) ## Contributing diff --git a/assets/1-dimensional-euclidean/result1.png b/assets/1-dimensional-euclidean/result1.png new file mode 100644 index 0000000000000000000000000000000000000000..dde78e7d689451a6e8199f19d67ebddfdc6db0db GIT binary patch literal 7967 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 HF$?|!aY01* literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-euclidean/NW.png b/assets/2-dimensional-euclidean/NW.png new file mode 100644 index 0000000000000000000000000000000000000000..19dfc65e03429500db4f7001629ab8abdfb18e4c GIT binary patch literal 4925 zcmeHLX;c$g77i++h^Vay3TSl@MX{1fNFa$s#DFAdBw|n&MJiPlC_| z`)*z(LoqXGpzTOo27@tBCJhJ$-=pZWUte&YgyipLFnYVCD#NKzG#N4&^=dMKfT$D$ z0TE_W&0v^sJ=-)Z_qK=K%DckAtR-WXmwkt9K71Q0zdmTcxMux~X9-E8UsmnEwWKt+ zYTV7*#t$zRE!UqG#M{a$O;?0X!R`+EPUfHUu{-1UCzgzT7`-Pp<+P&{)1O^e*tT&; zHa25nbkUI1r;9z#z+sucYIpq;_S@cEKIii9v#Q@rd33_%{a<1{ziAk?Pt#BoRD4?O zdhC=|sLd&9&vlBe#QVQ3tDfkXnTK)93POT{?wuIc;!qXUw%M;1_x2tLW_5qnx|#`sTfZ0@qm=KWkf9(V(jcF|MyK%c`Dq8>2=)sS*UrM;yQW zUa@Y^(IIbKy;eUtl&R*};Kwi|%Kue3CYkyAUkcLZ(h8@iHtvs=WL5ER(+0A}PQF>? zb*l8la(n5DtyghrL3PY}=6shCHFNCU8|xh-)fL>j%h;gfLyNfnBN}u3bd5)x%Qv44 z7}lQU@S$l-OB?f>w(IuwQur7n|k+=em`m3{V};#Hnmpu=1Xx}qIr7e zsR^rx*KVCvXg}5A$I#IG>)eCv!yM#?f2h52GOjW=wz)YW<=plo8Sb+y)DM1H9p)I4 zzx~ebvu1c+pTFthgEdY2HbkO@Q%x6Z9Gv6D@3P%oQ}17}_X`%pOMWZ7QP`}mj3Q5( zHf8l{EslB{ohoh#n2^_U!)r&m|%V8ef1@$UH2BmyzAez>*Dw2CDMxwhSdsEB2maBl26M8ERt=Da>UXLQ=C@bE!wzR z>G~9E%HAc47<{DZV3^0$6$;P7$1%p1(L7QbI?u(rZs{_=HDNZ6vGZN$S^Kxyl+|98 zRR;!tV2v+Kf01=>RKxp*O+U3V7VkN)EYP?p_!ZJ|L#KM5ny@^2NWkby!TvGo$EMwz zmp*)VX4SgZWX|^H`EMUS3VS)WcUrF(6Ke*pF)uTx*8D@*Iy5L;7MgxNqulNc^un!< z*mPIm==$c>)$||nNw-@DNto*#=y z4>>Js>@zs+__K9Gpuz#XCq?ax66!05LTz^QNbTa2R#($Uduvpy^3I&wFc1N7z|%OvjN341O=&xSW+iu zw*FMYgh*V>oXeLZa)X43Bc-WEVs`3GC6=neggDc0vaPRK1OT)Ig+gX+g3cr|iEY=1`(T` zoSe)`_G0Ocv22b|C}bmCHkS(n4cL^Tqfj%fGr7?a9T)+G2{V!giqz{M8WUCN6Dcv1 z3C5vM{%H+zc^ACS)X4(igKb6)Yz_-yYqjj27A7h%34nAu^oJHECHNU&hY}`zq7fqk zlL#H<))NB9y6g>!#so_^IL0Ot2rW=Gfmu19O&KJUE4nOb3SvpE!D0o-{!Ei1)!k%$ z<{Ld?38$wcz`P6hGwn~YTaj5RxnJ83;5i}G4XORF$CFFBdJPd;|geQb~DzyL> zcym=SLJ%BpHBYF*RNNjAAx08ZC7RIFD;f$1P?!+G2@FMGt`7>Jy!mPv#Xy;$K75?x zjbnTS6AJv2+@^1rm{#RK_vq+Cjx!2Br|QOAm!O?=n!)bW@=T9y(7Sr&x|#X3STp-BX8@e^Qm z3}JDoE|vh@qqAH;$;m$`1s|ahQxTX7Ce%I%%;O4uV1e2jh1EEL^9e-FBLp4!>q0l_ z)l@QSB>ZCmkAN#so))ek4@;uPf9^|i96@IR5C$WBxSKFxCt>W)fZ24<_!O}(`@cBx zwJ7vxGQh4w2AUV>h3u|o*vT32_s{%v=Hkzs0)oCy@4wYvUqblG;lP7yk=3rYqrOJ=>C{zIv+YI;xr<0F0SJbPe0kn}f5BTNhi%Z)y* z%=`S3fY64L$pdX3TH6o$c3dU4JpqVDP=Vo;M6acH?9&%{R+W5vOPQ(K71VUcJtBk&VDx<%L UEOPV~Fd0J@I5QxBYRuCA0O=`5L;wH) literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-euclidean/SE.png b/assets/2-dimensional-euclidean/SE.png new file mode 100644 index 0000000000000000000000000000000000000000..9a657fbcdd86a5b74afbbae8eac3e97e2e04e7ea GIT binary patch literal 4918 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 TtCCs>Fd0qiH$!~HCwk?d2_Q@& literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-euclidean/result1.png b/assets/2-dimensional-euclidean/result1.png new file mode 100644 index 0000000000000000000000000000000000000000..6fdd5365f7b7a62957ac979801511242291a255e GIT binary patch literal 6742 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 J*v@~~e*x!ps2czP literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-euclidean/result2.png b/assets/2-dimensional-euclidean/result2.png new file mode 100644 index 0000000000000000000000000000000000000000..b2ee95f3998b582734241f1ed23bbb8be62ab88a GIT binary patch literal 6717 zcmeHLdpJ~WyB~z2QhLQp7^A2db3SH_oTnNoLy9nmH4Mg#nQ=~`(pd-b${`erl2a%l zda0KVhzOBN4y7nc2W79J7surP*;WFs>eDijI0JU;*`2^9iRAcV(-KteiS zB)A?MHkcdpaIhYRx_BnQ#Mmq<;dyRP2<%{CBZVgsW3uq*5dr4=j`Fbw*|0 z;}y}4>cy@cx)O72R9l%}23&dG7qE*sJ9iz@CZtbyVsvXANnLm<{^sX@)E+-}8rlm} z9nGKP1GN}i>J%KE_Q}`PO@3D3nU2C5P1le_?=`x0%e2O?olDd`bJA~#oZUhWEs16~&l5^^zS;AcaJD()dUET=i^-aq-1Untx*L`!Mrjzz z3gvJMESU&y^NMBeeTy;M4hvTvUzlk^+_@OFV4ZrQeR+qrNM`fo`b+X-w+~IhFBddL z#639tV7m>!^%E?C?ydcIeCu*z#HAgfK>qWw4>w7Z@z;U}$}+wlQ7Sk5l1O@f159<^Kf13v~s@lf`ES<x=EnzV zr)}#`%pILmTfB~7{CM8uA^O^ZiuFsF)-*jcLmkXubnRiczqW3F;wHS`h|#wpQbv}HT%d0>p6hS z-saq+ESUAj0F|lqC+hXf;?B*oiIr!hTZkrmcZ^+eH<%Q+m2Pdb+N9C4Kq?p|^?>^`D%W1%b?W<$>+X zg}#o=7Vu4&903b33E>OD_6C8NQbUAHwl5%ovH&lhKLs{&abQ$4CDRZx2*3v6!vjDSI>T_nB~m~5r<3OXl3&S0=%NYyd@GL8G#564mJtKmnyegGeI6@#;)ewxyjMtArYA*H~J#}`gVfn@*WDdBOyll4<>(vj(M zeoO=m|AzaM_t)B|ok1@;ooppw2TIeUSy5op`NptwX96V1WHQ7kqVj%8u-a3%_a zgJaPI5)#KGFiE%{A=Zm{pemVuKV~I`;($;DE)j)eGf{9h7YAkoFo|F`NF3m5D5GzFlkCqY2>$II=G!UObOG9DFHxGBpO3T;>c(e14SSsv1BCC z2#F>mfAAM@c-+wc$y>U4pr$iRZpRaY^M_8GW_FY#5HNE!bLq#M-bzsD^rj#)*)t`G znLz+&I!_R5W{B<0^!Eb5?(s#gU+uhqAq6bJCLmFG6r6-)W8hdMn*%4YQD`^|jV2&5 z7z_@FpQ-8_x>&%K1T#gzYA=vSkSkE0(_BH9PcPJppK}TJ2BfP15(Y=&;3%w=FbtZE zLVh6(@&8aF5rgBBSR7E393&h|02>$+&1Qj;$Kuc=0vBL$XO#1ADe=1|NI#coijcO& zuZwDm_;1TTSB7rFf>r+`9#Px4Fr{-*0UUBAS@ zFFF5K*KfLhiGg2o{;jTm8(m7@pBMpu@J25fd>(YmFwp^@B^6j}ZLJ_v(j&d{OdM#L zBedHrhCod8rEi&#ENT#FRFu%@)`|o2YAUnlY1RY12TO-3~->q zJc&0{dOy4=YQ8#%zJq49ngRaX*6kXU=`z=9gV6xhD@^u65c#&H(u=XpzD^>`o-%r?ZpRAzN{_ z!hyUx-_<8WsSO$J4ux&|@5PseKP4tz_^6?|epmmPZ@NpohUnDhI-)|}dkqbbUHx`A zwRlNQ2kYg|o{!>mg}uW`kowLGv8&VV>(V?&GV%OQ3wmdJ$Qk^3IW#E^?4%22l zu2E1};NvN^R_gG<@AN}$7IHt9-&nx+(J3NroafdS4YjY=gJaWo$NHTvY4lEOR5LIM z@X>jj^yY?JI9w^F;lQPB_T4=gFd#^)q?FNnm9ZgS{mJXg35i&yk4{3_&4*7}5o5YW zjByXU{rl!U-TC@*RX;U=lGwgCE^nZy3XM0SCM2~VDSSFmQdRU)F12@Ew@H)XpDt^M z5~6x+P-j)-`ZDaf=->nU_8h0yW`16P%y;@=Aim~{$)7WI$vf^H_e7cIq(LQNjCE)B zv+OC$k!tgIAA5(x-|-!xr(eGhJXVi7qe?fs+BJT1<#j?)Wv*bJ+2Trqv!}uB^Hy

0cZw!LiV-gjz{$bznFcXdi*sdRCB9HJ`S z$!Yu+4SHIu)ak|89sGxMLK%H**~Z2`ddhY04}JA&E>CY?Sf^NdS?#|65{xQgT1bWr z&v?QWwDx$vlV?{0cWE9U_^S_81%J4QWPlHv(lf9*H{6WJDcGD#A#SM?77u6QANVEu zKd~M<*=kX4K6STx%bK#esZo^H6RCq;J>B`+?KamKzSK^2Pi9KY49gs{+x5)S z9I1xb%K1jGLs@r|+!ZHAGt};nlg~E{@alcSv`ZNe%S6UmvdQjy;!`szg^@Mu&;>(* z_wSn7YQEd&yh-a&+xzpo6)rYGG&CS!mjJiN`o{$ZvjY4uqgU_aaVj0HcsXh1#duAO znEU$WwvrI|KbR3)(zxczwk?I_uY>ZJbY=H5%R;GllH1J-SEBl?iuV_SVo7{^d`V9B zsbeNY*IRtc_llzbbC>AA%ZqMZK9^hjkteU;-hkF3E=PmY9|J z!I!bQ?hH+i*l5Hz`2f*yItwB=PEkl zhtdi8vRyE|K94_AzBKLm-$st|%eL=Mde`7;6qa1uw@7Z2@Ra%@ts(SK%2Zo*$Q{()K95}XMKTW~xy!_hE0XsQr^E02*&E&L_rpU#b d)r%$-sRP&5Z+X1(2Y;_1G;4dS3l^Ty{{=8jl)nG~ literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/BTBT.png b/assets/2-dimensional-toroidal/BTBT.png new file mode 100644 index 0000000000000000000000000000000000000000..30677898842393e6ec4d44f05090dd159fc8f0cc GIT binary patch literal 8520 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 RYLpoj0BdArSfcM1^FN>5{d)ia literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/BTLB.png b/assets/2-dimensional-toroidal/BTLB.png new file mode 100644 index 0000000000000000000000000000000000000000..994384c49b0ecdb219210233981103c1c6cc2060 GIT binary patch literal 8338 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 GG2}njDd+b9 literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/BTLT.png b/assets/2-dimensional-toroidal/BTLT.png new file mode 100644 index 0000000000000000000000000000000000000000..26b67d2ef9bf8d66d33945902a035c5ea298a8f3 GIT binary patch literal 9141 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 literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/BTRB.png b/assets/2-dimensional-toroidal/BTRB.png new file mode 100644 index 0000000000000000000000000000000000000000..4a6b5ca18baa1af16a55fa6a283963db4631381f GIT binary patch literal 7460 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 literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/BTRT.png b/assets/2-dimensional-toroidal/BTRT.png new file mode 100644 index 0000000000000000000000000000000000000000..6377e66a3708b4c8b4781d7073b5da92b885f399 GIT binary patch literal 7935 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 Wr|!O8)AeisfQ6~GNtKb;k^cf1Z~L|Y literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/LBBT.png b/assets/2-dimensional-toroidal/LBBT.png new file mode 100644 index 0000000000000000000000000000000000000000..5753493e2237e6710c6517d14a16a89c4bc5cca6 GIT binary patch literal 9316 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 Y4pttmxNA07DPaLLRrOSgl&k~)1Df{Dz5oCK literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/LBLB.png b/assets/2-dimensional-toroidal/LBLB.png new file mode 100644 index 0000000000000000000000000000000000000000..b4aef8e9b190d1b6180b7786de8e984013d7e2c6 GIT binary patch literal 9209 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 literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/LBLR.png b/assets/2-dimensional-toroidal/LBLR.png new file mode 100644 index 0000000000000000000000000000000000000000..4b1bbf7dbde1990eff3cffde4770b8ed3cfe6707 GIT binary patch literal 7738 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 Uw!sHxaN+>q49&4@{o@h;1z?Yw(*OVf literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/LBLT.png b/assets/2-dimensional-toroidal/LBLT.png new file mode 100644 index 0000000000000000000000000000000000000000..a703d8a672a882851a48e8f74e523c053c89c296 GIT binary patch literal 9656 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 z ziE>2a0M=+bjEgk;Mnf|@0AnM~ZVb@^X}Kw)?J;V8ShRtkHUj16h=SR$%gT^T`M~i2 z&S)GG;N$G%;sN)OX8(x`$3LHmh1mf=Rd9~d>?T^e07X|U8XzVlCIkX1`(V7l>@ws4 zDXfhxTwh7$Hwb)7n%y3UbAt;DdwY8ed5a3UV(o-QU@(|42rLW+1MwO_4__A?(g*0` z!Epxh3quL*fx=?ka2Qt?z!@ge+SL;$&CZVR2mJ1zvzwOIAMh?7zp;SlL)ZuDCM+TZ z5_WbL{;P!tPT30&@|#2dqlE_of6*?jIIs6xd;$-F{l($^M%r4rBW#S%35GtmkJqe{}?J{s->g zw11ENr!rnkOAD^#it;>jPhClx{cL==jVlUc1ONGm6hnzYC7=>O6j%ZR6cZB_2TFjT zFrc`tI1D8!AtHf-fc^rd?&5(%x}eZ!PGW5x&Y*1YP!eDfYcRwb3=~B{#PLu_aiFyX3p)C|nFA00P57f6;ff!Pxr#Z`x;*2O#w;sQkW z^K&Wz06!-M9EtiBf(OzIZS&JlJl3x+ls(eL4vk+uek<4C<(U7W6hv*rtRdnk2oMF5 z5CMweD+6eago1%6s5MMn6m4rOA^Iz-KhQl~ZE@a6ELz?U&m*2Ie0l!l3c&j_QG9>* z#oHczmIXXvK#&*^ERFzy;9vD<*A~qn1t@YoX{=bI^0sdJN;J=3`C49Cl{+?7R;s2KQUkZO&NAcABlHu29{Bke+ z$9n%8XZV!-Cttsn+kbKh0N~$2{t>_b()BN0|A>Kqr2KDn{Y%$BV&ESs|65)EZ*-CW zd16Gn;5T~S`14?hg~CJpS@OJ{yp}uxK}EvFBP21teZg8oRf*vA?48|Ma1Spbb5k?* zARrLpIQyLQ$&>ZM3rTS5TFN8~#MiGu`01^j&i-RWk5e|mDY`nJ9YhFz?vK$n0B;P= z9&ollHV(c_i@#kSaOeTEC4JFfym3)KaKdf3ZlYB1^H&wM2C| zm$ehl_hIz#W!_`6-OP^T7ITs71?;x&DVxMSbtz*+p@ikymg6&ODIFdl)QzC?a+GyL zDio;~KU=1~bD+Bu4%r;WHWJN$yLwr;`weYd{bOs3Szw}FgOn<>L9TM6#xqCZ4SCOa z^R*Tr&o>D!=9jV+G_XeQ+2SOk#XVH&J%`8%a|Ll3EN8rc_j-@fQ&5m z)2iG|)%lS_SJyLRE6qN%Fn~7G?%3%Tftg+ra)E%x9YhVt@osre5cC7-^Tv$)mdge4 pdQN%`EY%T{M~g_v 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 literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/LB__.png b/assets/2-dimensional-toroidal/LB__.png new file mode 100644 index 0000000000000000000000000000000000000000..3220e98456eddd7b8e887c49e3e5d163bc48f815 GIT binary patch literal 9423 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 Tt-X!p-T;~?J=M}nS8o3o;Tzl( literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/LRBT.png b/assets/2-dimensional-toroidal/LRBT.png new file mode 100644 index 0000000000000000000000000000000000000000..3170d10aceb46472ea776b7b21438a67d55fb801 GIT binary patch literal 7228 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 BNpt`J literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/LRLR.png b/assets/2-dimensional-toroidal/LRLR.png new file mode 100644 index 0000000000000000000000000000000000000000..ffb409686349f0a97152e658d73cf17464f45400 GIT binary patch literal 5923 zcmeHKXH-+!7LFpqAVow)9FY(N5lruqPz*>70)m2ocyn_DR|pA72oZIBQluy-pcKK1 z-I0zuB7>(J(LNMvqIs;Zzsv`SL5n3K0UQCLWvj&y8dAUl6iU(d z!apGM7-RBK@sc|I3ViL2nM8W-!^PQ?Zy$`J-~W_rNVM3@H=UPNXSKoO#qOE~9}~BD zH*77nJ=I-sw${&C`yUgcXR&8zPpYTMP7VD)_N4(*Ddtxh}Do;WV&E)u*CwlFh{U;kU>a*MJ&?t?yR zn|0{UHxok(69#bmW^W_Rj$LZewkZ|FRB4{3{#w&oq*dVC>@%sLa_J=Z`jF!WZkxzY z_h&yzD3S*ya}?vO9maV)oZ!YYcpZ?Rv`Azd8tIPOU;gaLmCEDyF4iy2619cSh$vF0 zbzUJkdWv`mUU@7;KLZ^UK%i`+eS?hcLeffXDRdRmpsC5K6L(W>h0-kh2` zt8{POB*XN{mE)$_V$#u>mdQt~v`E;(*$3hVf@cOmnZYN#rw7>IIDF8??SR%i_DnU8 z)T3vAIih1yW?fuZ#6sI#O*SpOb;(KhHsgM(_P)%+Q-Zf&;7{R1n#fLoy#?+*sU@)b zic~Y>`3VUhgZBJ9D`Q>is-&~eN{35|XX>_@O3&(8WWaft!1tOs_U4xEFmGG{e%($3 zdyIYH){L3Dno0LEbvK{!S>dK>w9;#Q^ntXiV*BOCtX!-LE904$bytF$a|(}@t%5Hd zJ*s2sx3m8*i>DLHH!h2O+#&1lC#LQM8~?IdxYS=gGrRssrg41yL072i z-kJOcecz#JotKjyKM?~FtF8W z*;0z(L}XY}PG8D1xXJ4qdearc!@`~7lS672nbV);c~35R+@bwOdc9byMXxbAdD-&3 zjZMK1Kh_=m)%-MV73*PCe5?Q41A{q6IWAbP%N{=2nNLleIa9$ag? z@!+%Dwby0FgEMx#Y^zQ>SS9b>+f&rOChT#;l&7E6JQw!!n#O83yK~b^r>(BpsG)gc z?s4jby>jC!LHilEAyUx$ryI+7^EIp9rws25M3;OFv`3XrkX#C#C~?pP-EU^~S3fwC zm~U@xX|qGYcj`B@i#>ch2jo5ITiRe)vb$K9?Y!=uBno?`%n<*m$8hS*H$9Z$HjUL` zC$1ab)zSVyc}E^h99;0k?y9F=%kC?ldhK>uJ6GIZk6yr*4SUFAyFcYUmrZ>c!#`9g zt}$Cs4Xh84v$O^llr?*w>de^rdkEBU&9k$Z)CC>tU6%K{ta;#Ao%Q4td=4(^DfA>pQ?&+4}D zv@YJzP|viReaST8mtDK*hoOn4)7RHH?tSjwe<6=ukGpby@Lq<^KD@WT*4!=5xltui zS^>o+A=Y(&{!vgKDhbKMH$8WezM5ZQVoXKd^|k)7&0>sS8^rkv<9wAG)7{VW$IdRbRIT`B1?p};Oa zL9^6bAu{!u6L)Cw)DnC?Rp$M(ADkt%0g}J_`dngI-3;n zirD5RX0L&>zpGDjV@j>|X>^}iE0oj8Ff{IeU6-8U+GyaMoXFF-W?bjC(apwb))L>e zS04j%rZof>+;U5+e0e2gMnkyuwV*@P&2y%gPS79Ezv;C|efpmj;rnx4npdAYZ};e( zljO=HtN09XoZsQCv+UlP481%akXs4M`=a@E42NWB9ux{kvN63?H5fF^XJeL8xdg751BJmZu@Y!Wtfwy+8xAu0 z7&}`n8wCpi5JEBltq?{;N?8gvMup2l-j!lJ2CY(&g|jjKTrV_7B!SQr90f?&nMi_2v> zioj^4d#;XbjB#y~8Vz(`dB z5o5hlLh%tO28qZcQF$aR8Kly&6goi1@)%447NP?XfzAT}0)eE0;)AS3B8d<{(g_QJ zPzW!M3{`a~31>NYxw0`N+=$~UiB|+56Ceg`j0YSUt@x_y3k#toGC;{Dk;b4fXjD3p zNMbN3#1WrW)=MFY6sbfdCXs+6kGP;r3kwMbAr?^9DFW~%N)|@~0Wy)qS0svHW0VkR zrR8Wh7nx3cKn6GhG6(@BkjN|ol|>@^k_ap!l|^7$6G$w=7<~~R7Oehn+RDj;wi!ve z3oJ#(U#$|2%%~+$)JSWj83C)N5*n?V6f6K72|)_TA->8_1Z$)V3m26-f^QFN(DAd3MckV7cKBf=F@ zo+_@;ma0U}`_`A3Fi4pNgfJ|Df+f*?2?Q32!J^VW6NdliLu4{|0G&)lMrSbiNQok| z29fZvd_EGWfDD0567^fB|Mw87*wLCG62A@62CrNeza-TL{~u`|Q5dt1BGin?ko6f^ z?(w7R{b$aQl>C#Q&*k<{4uMAh805S7{Xy3cy1t8n?^6CzT|emhE(X3!`A2pA-{{i% zdSiqlk%L|gavyZs!%0K#k`qE5xDF^(>6S@DfI8Bi$a8mgL=7vyd#Vp*A(EfOE&);$ z3TLMLjZ+-3lOsY6nJd>xqf6azir%F9CC%Frk&(>FU&av$l@}3|>U<3G(J`Jiq7jdw$>lJ~PjIx#ynqy63#kx%YYB8)sp5NKjz60000G zG&0n)% zI3fMjns}EDQ$(zEX$XJaH_hyEm5MY>uvSNzU8Tu(V06OP{hmMO>W#n0*zVI;m9tDz zGH7cRcV$c{zJ1;Mspwhg30c?4<&5CFWo24+U~JO+FAlT8$JtqaexZ;e5kJWj7pC`@ zuy^@r^@O-Ellxy{bK2zg;*hM#(^s2<8?Y%iiVS{y88%NOwY(wH^Dd`;4^|oZan~3X z?U6dw?U-eGAk)3{_`^$hG3TMP8b>hOLh4w{p^~1@TFl%tC%dsnJ>HCW)I3r9&{9*` zH1VXfTB{p%_wkwHu)+y3!cy<~&s8-qrXRiC+uF6+e$4;G)UCJk_(7+RrwMP}C7kNc zzFt0glvA42|GN9FvXgS{x6v~8Y~A?a^;EesVdld+m7cmg{kwzT>EDQ-QK*WY$^{$0 za6jcmdUV`&Jc~on^PbcjjtcCv4kUR_n-wD46Dq!hN;0EMXcuadhd6}AfPuzm17%lV zio?zJSMAvRI5;?inx^VgZ4$I7gCBlT3Z^B19G%ei!UZwJVx$SJdZM4X)E(|+1eVNO z=(U-qDs?^6l^TTbN59&B!z?e_d$e`sweh!^4{pzC?FY(d3X@bEptncaFP|lahrdo) zQcm>SU=leU27CO9M<#Kra_*5zl;p`haG@*3K3TT~h0lx3Y8$=HO2EX-YNI|Y-iR4+ zOK#1+vJgL;2!53@w!i(OrifOHJE?e+__57_9X%=v&N?2s7VxlWMK)x% zWXdH(CZJj;A{o=woOcS>rkGxMnfUku?Gm+5zZi7;n}BLrzKsjDx3u5vc4$cbE2LjY zn~!S^qz#}IV+<3&q$g`ea0qUuGmz`doO6Wiy zpZ4PIj&P~DE}|FdZ5$rk=BfyGw4bSNZuM$?`Ek2@ld03inCeSam>cQMsugXG(hawy zyLJs2?90k1?2c*Pa`o$pc7yBQg_^tH-9}l-C4O?uC`mS0xz^TG{iE*!sC07TAwRCeN$+|-iS;G*8s-R@P&ziX-$XHC;Or= z8R9GZPj|L$A#yrTQ92 zPS4KurZM-lUs}9L`*5pS-qSAcK$^{dSRFh;sw=)^p}}M;8EhFsgVpqvU@xIOjL_>hF#8{WYHYwusrT`uh+Z`K^T1UEl+jQ<+LNi)**Cv5e!k9ee;kPa< z5wwZ*vB&$BZ$^ja$PTF0yqy3gl%ky$M&tOkM){VW2y!g0e`kddi<;l?`}^|lGIIYh zc<^=1z3lmegF4NFcV17P%7D0xkG3Sw&oNIaT`=gJsdw`OK=(@P(nxh=Hmk*eFYmcFK3QG2g;n(y-|38y8~i?Tp@x zz?ZfWy?0Vwx7f@b4pp+NQ(ZnYdLp3$qz`$i-6nOjKIBLCWQpAN4kfBZcVmyvp(sMU z8_(8F+g&$J%jND@>^u|KHE{D=TwLgp`K#^L0|(yiRGQuw+*=EIuoH0s>5t!%&d##1 zFs>;)n(MH4f}M+YLeX*x@LNGS_WL_GDctOF1e=%ih3PQBhbOwc6YZjyJ-skmsvz%P zlL_CTdl^SiUE|$^9OSfwr(bl1pXd92@v5t$s;mC|zJUZehxkMFns1a{(p!q}F&ta8*UTaRPnTXB??x$deh%8FT4#vGXDHb?jd z%)JXk0pePf7rv73tQIDQy21V7yBWJDE3$Qmq6LB5mSmF58;GxD1kHMya+d□JQ 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 literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/LRRB.png b/assets/2-dimensional-toroidal/LRRB.png new file mode 100644 index 0000000000000000000000000000000000000000..190ca731e3181d29d6714c8153a67a4db385f585 GIT binary patch literal 7583 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 literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/LRRT.png b/assets/2-dimensional-toroidal/LRRT.png new file mode 100644 index 0000000000000000000000000000000000000000..b65304268501105c5ba6cfecd9c3c5390863c2e2 GIT binary patch literal 8232 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 literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/LR__.png b/assets/2-dimensional-toroidal/LR__.png new file mode 100644 index 0000000000000000000000000000000000000000..85231c5d3c8511a02ead104b9c323ce1d1cf8723 GIT binary patch literal 7427 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 literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/LTLR.png b/assets/2-dimensional-toroidal/LTLR.png new file mode 100644 index 0000000000000000000000000000000000000000..a40c58da77e25a61cdbe59eca09bb0403268e5d1 GIT binary patch literal 6971 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 literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/LTLT.png b/assets/2-dimensional-toroidal/LTLT.png new file mode 100644 index 0000000000000000000000000000000000000000..ef50bc361a6077f6b59e04fb585eda8ab5c71942 GIT binary patch literal 9694 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 S4?UqDA~hu~#j@+Sg8vHuv9Nmp literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/RBBT.png b/assets/2-dimensional-toroidal/RBBT.png new file mode 100644 index 0000000000000000000000000000000000000000..6a884b50e542a15b5cfe5c6392b15309114758a7 GIT binary patch literal 8516 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 literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/RBLB.png b/assets/2-dimensional-toroidal/RBLB.png new file mode 100644 index 0000000000000000000000000000000000000000..c5a544a8c2b1a687698515060681d8b5cb65f9fe GIT binary patch literal 8934 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 literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/RBLR.png b/assets/2-dimensional-toroidal/RBLR.png new file mode 100644 index 0000000000000000000000000000000000000000..e9d7ae6cabec0f57343dd17143fc90b1caeee0a9 GIT binary patch literal 7743 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 S8gP0f0DbMVS_K;CF8&wJD$CCR literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/RBLT.png b/assets/2-dimensional-toroidal/RBLT.png new file mode 100644 index 0000000000000000000000000000000000000000..0e641a65b2bce548848dfbeb048035bdcdba0dcb GIT binary patch literal 9119 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 literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/RBRB.png b/assets/2-dimensional-toroidal/RBRB.png new file mode 100644 index 0000000000000000000000000000000000000000..80b7937ee8adb990e0bf1745025caf660cbb1939 GIT binary patch literal 8408 zcmeHLcT`i$w+>B;q9W2;=*>U^36MzdpcE-m1=D~4DJG!{DvE-1Pywk5B1%(=AXO3R zC`b{M4pJ-#0@C3Hymh^|)?4?j_xtZA>m+CPeEXZdzu7bE%!#lxH)3bwX9EBL>?X$g zR8vx+{;q_fy!X%<7 zY?s1S%a|}$DHy|1d$nR~N4xb+t3yQz!JvkE3)_B-m7bZI*(PP>((drI)|LUWkQI_- zV_mWp#{ZajQRe5ymzm)~(nzu5mz~aFbz+8=zd5VX^SZN_GF{VVN~`PN2OV3j+<|ma za+@Bm{nYbXUEf)}SkJutX-T_+X`(3QTMe<2`Pe0=<3-;mpULzkXq~{v1Wl7N<%qkX zm`oHIz93xF3AfecA?h_{TC)$odarC*BeV5wX6Qhn)(b_u6!;Sqyx0bAEnXQWp<*98u| z&AUzA1&X}#>{(j-Q4<+^MOdqaBD@4aPLJ`1 zmc_Qfq!|r>0_t-(#60}6nfd)w_P1)^z8P=Pz098*#9GHm$CI7OJ9pJsObx?Kp;-9N zScz==@SnYX-nd61WgxDEQT`fB2wCQQUi?eZresu%WdA^dL}$${vQ;3#f!qRlm_~s- zpFW#&?bs=~=eMj*<=3$-3&{sKo+>PdN#Uc0DyuK(cn$l_-D}PWoPS`~^AVsa9;NoK zB|8f7VcA-WRkNp~v;*;xd{CzF$%LtVami;-fjs;mvN_#XrTS~tM`cex`}&%YqcA_C z&P?OEuysDzo9Qjy2HAA|Xg-dmmmCYHd&7BO^d}Ea=q~WXqxn|C3&MrPvk$l6&J_raLKw++=B z_466Pq+W47Rlit4%$Le_epMfn;Daw3w?3PWicUeF&Xx3(ox36N@r~-{jM38Ykz#JA zpoUf7-m(w81m0L%^H1=U?gS zHN}qwh&)VDf4OLx`MUC%QTtIKEQITa#P_QbaC8y*B7yTNe08(IMWQv)9-F2d_RYdEzcS;gH)?2%4 zc90vjO;Sz4N4?vM@g*nQhYo^^C0b-(4`x7O;;TnuVW-}#!X$y0elDEh)Xs! z)o(A!;K%x`EFB+&d1CMON-^0EzC>WoMJ+cvVD?J z)51L4lf~7@_297EqXCk($Qj1E_!;xzx&F`gi4`Shz6)KCW6a`@e^8`~6;Q?&OrXvj zN3m;L=n?OzOXS=<=xmYtH%I@p!w;wy-&V*=`udfdkKUC4m++69Mj-9^**)zC4 z><>L(XLGFreOmDyoleb9K>2xs@H@vB%1}z%u!MnKa;>v!k_7sV680p zcqe8H6(u9$eLZa7*BHHwj4F>TofWrPE~#|Mh}(JU^hwcHNo#I|4>&ifU)kCIjA$t8xkDP6 zJLE=L=l7DJFWK(lM;_&}wca>%vPhjC<{W)b+v>P@KhV|w#CUYHn-SVIaCC(EW3}Z= z=$g3ch=za7!?XwlFKbBJLN(H$l9}o1#-lYxs<#8^gQ)JTrS%?c}WE*l?j& zH=l=c+@X(FYs@ya(9gY(Lp%$PWN#b`&fW?Ymk>RO$8<@t%S7YuJfLU5t7&Lzz&RZR zw--f&HYYslHpkyL^V%2pT|7G&7DX~Vwb%>>cD_hC%YG};4Q~4I#ShkVj}9%$dca~V zFG9IqKGtz+m@v=f@U1Xmor;=Bs)D1rt8P|$jROFC2ZfC1?AYkl?&OA_F^?KP9y&t9vZ>(ZD-Tk7-CPWHJe7Dda2d%y!+GPDY2v)+Q=PlJldzGECaf+)!A! z?8mMmDB*D*#o%kZm9h2G{QM`GH!Z%)EG5;`(RMPQJlt(26sQHqjrr4^utDLcP~WOJ z{f~oyr{v0KE=L}CzTg?|#kdr}qFFOMzcWs#U9aogYOO7nQqf9Zua4-naNi-ImU>cl zGt+{lIoitVxm@JfSNJ4~xWrb%zn-Wm5+Ua6DX{ zrwQmJH`W-ixNC+k zpY1va6Sro5wC-RoqEaT45G!-sD4^B#wn|3Mw}-d6m#^?t%l4MdUiYCM>8^M#-pQ{} zJ^)0T)>J93+?MX#y#nowb@&;OBlxUF_4o%_UpEx}n>3Px2D@5*@_V^k3r}-7QKrpu z4E!UF_gq8n^Bc>?dU`wJwI{))o=1iJTqf&&9MbE$_1P)uXO{ z>=O#|nH*hSL5U%HlnVY>PHXBP(jQuPJLjlcV#BRbnyt0n1aMnKErDLui z)xk;(O=c-J7(S#60orx#R)5auCa`={L_40WfWK18%e5>$(sFOyZK7>y-QP1O%n|Mx zr*OFNRbFdE!B?WTLZ4x#3h(O7haW@8E#FJsTayPSYgbl6X1?@|+zDhJ)eH8L-QZ_meu*x@a*M#kR=NL*X79It9!mnh4u&a80zVQW7}zjXhE~D7N*nQ?pEo zQt-RZDRVm%V*fyPp0kw?rsAr-D&LV(oMlZ2 zk3`CvkA-9GPcJ`IxTzYEj>5Rpu|B z^rOlbL(S=g5H{Ji!lF-bDQ_VyYm-vBTx3w@?Ge9E!&^CZyN_#9GkaHEZ~HBorCd+W zQgt|ba6Ey9f8yF(Tch^-t}8xSuQ_I2fVE+~_|kcPknZU1sCFFBjzRASI`$PHF(CZ%Sjpez#!J)Th9;V_ov$`9zd!k?V>$@EP!!{+j3LKi21bdp$`@B{*1O3v?c`5|yfX8|HG% zDZ`J)uMGQa7AKk%Mme_z;?7dJ+ZOIlFgOgM?lFDwiSVlQ#5Uz3s|dsTCH7DC9qH8b*a^%y09iQV99!d4Y<}`py8L7! zBz72dc^MMWG0M>#oLVm)Q=2Rjj_wPdmpgn-;Y&=`aDa*lU}(XRLGZQja2gf#{K_*i zDcu5N{$56(FKW9y1FM6^0s+_Q0tFj|9%H~F;}=uM@So9L#<{+>LlJJ4X@fTbGL5W6 zF>BA2>&NcOX)jdb*jt&JCm6Ow9)%fp*FDL4k~L|Zf8^~IEPm|3 zRvuD5^pXBtccC@->@yJ=yGC8R25l?EvUySI6;vEf$UGn}WeKU*@TibKou zt)56JAy`GEjN3E1{n#0AEZc{r5%D44*WZ064xY=81s2VGo&Kg%J^us>Z@nt_Kv#0W zLow2+sK#S3df}PV=9$5}U!KBq>q6R!f}R>AMLqdf4y8dH$`AC3Vox>~lVu{=!(}NRQJ=y;5R8KcP(?L6w?!fk- zgg2mYyy~Iy#_}rL`;_k-;B>`eFHPOz9>~d_zTWa}?a-C{U~TFf`y1oAlCiLQ;wfN) zLqyXq0PMG0-keyj4FJ%E;q>$@P4x7BKTy+-(P_c)8pf}*d9RN?yK~boRBk<&H{5|-)oa@1Jf-9*|PA( zm`UN0&5@+)?|@6$4K}4-f|js$V`)xZl?u6QE*y=3P91$ox6hRO$)PiARX1Y4`(4QR zbZ&KK*7k=K!$tbV6Fuya{#X42d)~pna~j#3ScSihXg*X0ToiwgO&V3>5&F5*5gu>y zmeVLa48`0o)M0wvRNX+(+9vwPwnGxv8>h5B)9CW~R#)CPUh?hE4`ERf+)o)f=rO&P zhD_WOWnMYS#ytTIue7Gt49Klha#!QgbhdeMf?8`LTl0ku$!Vm-23Fu2>Z6Fbwg-<# zKYnv_;907)_84E~yAL~_49V*fwIlr~BkfTY(uLvvDUC5QbGYVQf+*bT@|}81z{uO# zRI>IisH=4PXQ59_4>M4&)^r%aeB*^je93!_k>TONic4OO+naRG4djee-y=T&fWuBW z+8Yjgv(pGP5wC#65K&kKe>{oy1_S_5*YYPJ(Oy_85QTNe5j4cUSJ#UHaTpCTJD3^R zjHHM4z!?XUvDSg+Ht0YvG#n$QrOBr5kDw9Yu~a0`AMZ_|ApAAN_IVMs`#rOw7;qm# z_0kZtH?sul5y@B}Q~|001{wI{e3isB*?{U~j2psA-|#mIT1!LBgGwbK6czpa{1p6@ z6^LYaMF<=YR|G35Dk*_z2oNQJKt=k42o&)>ieDW1SPGhqBT;cg0&tHLi6Z(?HN?bd z{lMSj!;{R+{-7sNep7*_hoV1{qzF*}E8_8rfAyeH4SZ=NzXkL^dQfa=FNzecuoR*X z8I3jY#S*CEf2F{n|L`aIkiGZQ!Jrkf-dH>hN}-Jk`P-02CT5m@cD7oy=Y?p z4N1kh{VCSpV%zK4Pv@_J(A@vv{TurC-1osWl$jYqpNRI^3(rJfLu_w+1cr#lVG#Sb zNGKYrqNbt-LMy4kKv1Z%Do72i0tczOslw69Y7jLv4Ez@=69R>bB%rZ-R5Wr09F0fC zO$no{3c-NDSTz&~ibSGl6i7Ho1&&n0qTN)mYD%!bP*{+0w5mjU|23*TDh!QEO$mZh zf}xZ^%4nD>2&#%y1)&wcqDB)ad@OVR*^(--|yHH z9HC=rq9LZF@GJ0ri={V`>PBP!4nh+H=sG6!W1g;8&!qp(q zKS5`)WD2bk_c$S71?68M>`e=TmJCf;nUij7e)%3>gFC`#we^DTi=wB&NkiJ;Vew;L}UtMSqB*7g^+dY0O z*Wc~9|DhC=F;Emt6%7NS!DP)HRe5LyKVS5?Nkxv44t%IXhx3ek<~ha_Wl z+-W+}w4#;gzE(h){fUzOdn|q)*u7bx2?hc~K}xDNU@$^S4FOa6O)$m(e2N$dTnP)? zTP9EyT8X0JSP)W81qMQ5l`&|fG8m$wqWbrs|L-ZnK!4VR>fcjTSKQkcf1gx!#s4<# zzW{&PM`_ahveEWu+IFw_$A15tX0$2!Pkw$YxBui2K;XZF{3Ct;mFr)*{*eOz2>fq# z{VUf$Qs5tf|E;e7H@VpUJTYPkvo`gD$61s-Cuyb!o6@07qH)g>Yx zH=A38U{PPX3d1iTUU<->m-IHb-j&}jehI8!OP0;I5a88K<(s}%&ECT06m&rbl>pln z9=07)OvpQ8e=YJA*NtOEFP_T0JlDGtm-&37NnU`}MY=BCfW7Zd3;x^aED47iDZJla z^$v~Mym#vcef}AcoujXCSf4b1?cxn1&eV)u$KF|ujG_knftqZK7hLL$LhQ6etJs4ny2QYc`o#l-}1pk XfDGK29_d9(8DL^yu3w~kKJ>o;(=GuI literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/RBRT.png b/assets/2-dimensional-toroidal/RBRT.png new file mode 100644 index 0000000000000000000000000000000000000000..f2c86f7f73c37066df88503d52ab46bcfba15b31 GIT binary patch literal 9817 zcmeHrc{J4D|Nq#xC|V@ZG$djeGlsE@eVMUjUn9mWjAh7R7&}=a*(z&9wuFj^K`N!P z?-QX_LY5G+)OXZ-J-^R6zw`c{@8`ew%y}*Md7sb6eLf%0=e_53?*+5d2E5!yxB&nF zFB+w5!FY=9UYzWVyDFr*2mm-xO|`P~x4=+dU0ZE%38azIsiEwN02UttY(uy53-L*)vVfGWY$0^5n5A zDL>>BdZkn^Y+ss8{Lr!W&ilX!c~*0M>8rx!YPPWOrH!p~H{FcG*#u=;b(ZLoG2izV ze#zPB4!I$?d?TV^C03QkhwFrnOYzr*^3iG6@UyuoaO%pUX(@gN=Q;GgtQ_g=?7I>= zJsBF__C}~KeNpZ){m$5S=*}8BQ<>hpU&TeE6+U(3>Fa$b?H(ciM` zTnrC>JG_NSpoQCUT71=MJ680)VgAGrM2G3{dlyOeA4ii^Cq@P*T+#<$&NK|E9wBp> z|JcBOUwzyH&&;cxYP7l7DLo(*8*tv)x#40$LztY03eWaN@J`t|UR}sFysYt^QBt)8 z)$iCF?vs5{Jo|6kj;Ll+SY-H}PO`se=D#x<`vEE@u=rH@P|d#U?R{Yh5B4)j^NjKY@b&+d36#C`78N-*I~c6plhFy#qzoCCL1>E-JmtSn5x@s-(` zwYZXL39TaW7a)s^R>TvR?JQpC8A{dNoAr!*V0psS^JZPWep&KWVTzKhd)1aG_4CbX z*_Krgs_;X%Cu#bk(2nvOCK_$xkKFR1ot3rV`;h~Q(pAm4E7rEJG`-_RC}Y7%qj>s6 zzIjvIW@oRnZuf-w%1H}qq1ui1GEj;{-T-uwyW&kQiXMn>E?pC+qeE}mA9IX zm#N-QUb7`TYYW3x(?9r+xmCpE+T5|te-G&Hnk(9w%gLteZPDRd zbMT7bqO03>RTojjlI5zL=XDcp%OO!;udsOB>Q(c))N=2*6sn`-xaSDYoXQiTe~s7L z`uTX*w!>I0$w0?KiKjL*sit<1x^oSOCEmu~Hs(Vm-i_I!EvGZQ@yB>I_fY67=K1<| zPPZ#uo#7$tM$;dkh2UwYBWRQIYb9ZnGaTIyrF3uf)Mb?>d1ei`;&GOCH6k~fpLX+E z>Rfd>!Fg_zR)0%9y0EWt;y|K>NkJql?CUa5D(P@k0S~IRIKN-6m6?m~tAnQPdoSw1 zGkcg_d?dY6qRqQp-~@P2e~(@_e90^GXdLZeJ@E ze^k}4Ro`(_{d1PF%o<&|qfBvl;FFIxrBwH_iji{9y#As_s$l7l{WWJ?i!fdtZyjna zlh~oMb?9uv2f664g`ib)`yw@@|*uY@-Btog~>{OI)RNc=lia| zfN-)am`RbN(h=1&)$dxDOWt;ut4!9YO76|I$`AaW;D$)HOAQLG+j}`WYaLZ>(A`Z9B~Ae}Ddf=@wU;xEn-G|fO1pffH!hqKY7-|Peg-fZ`E*;vVKU}F z+?x%OGSl501a^QPAM%A!9X`x?wnz`w+>U5j_LPkt9zO7m>(@ABZ%XV{14-}Ac=F=@ zon>Zrc=vJM`v)IQ+Vs?KDxTItnevp}$>U+l+Yb)j+lamtTTi=R!q&=u>3HPS1Bz_g z03zTkE|=Nqcn}Qk(PNl;^Q8NxfQ{*um&!NEs;YyLop%GC$3anCnwcf?J@-PGnDs%k z;ojq-3P+I5tyajp8$y!>HlqjKt-2m~mT8(b9FXitaBQ+kP*wH(-Vn9?HSiWCf;JjT zxld~QwCKhox4t!GRA+VC!>zwViYRP2?Z3cNJDFXCKr}Kx&d*u7^``m5$8`0YrAVBRb2#fsW5 zm^5D`mp8Cbrr4Y~-z7WqvW{?M!P+EZrTm==5>A{20=zVUQ8c3TLO+vTVN4_s_ zx(0XMnl?8!dvX)xVY$gebQAT9GHmRHCc355p$wtBEp*e#K&0{+fMfw2>Ru9$U4~2+p_ft1TXwJ^9 zh=VImcfT8J`XCpZw-y7GuE1%Y4jPD)mhcYMp5T%^gLns8cS?PxfcvZ1vg)&9<&KBH z7u7PDF5o|%qJB+1TJAL*1XjeT>^GLwGoLB+!Yd{da<@v%_$jF}!I zop<~1%I$sro@y&qE?>o=w5k2#{e7wRRnM)m;*jF;YrZ4l=*A4+kGSz;;^QG9K>_X$ z+{>k>szseG7I2%enXEyhv1}#S54e7BaR|RQWgt6jYW!H)xR~KFG$nGN+f8D}bfBmC z^S)5ab@@B-V4jK$&pelEsngXbwM8sahUpF_yp^lt?x9zMPV5ou=d2(gnIm85CuWcl zbVLhE_s&4T(Lvj@kBEtsPqSl9(i&@;z9(DW#u}{lwcBY@__C_vCEZV zmbV1s1Dzk3{jwg-Tqw++-#8@l=xQ>6+nsEQu4s%mO(v{vU&^^94TL;{TY05-Oavvdoc0l2W_DRpg zh&qYU?T;Eg7gYXae=qkARbpitBPO%2JkN+j$AMj!44bIqdT8;O8$%)+Kms*+s@$3v zU`glBocL~r=)QlYw*La*@aapTnDYo)w4$!s4ZtAaW`h^<^-=rvFGlt3Y;sb{5H0pk zq@z0G9H*k}EV~a&e^y0XoKIY1^(<<@+}OP*68-w(uhPluedsq$m1XR{e%|(8ESRSGdD=? zV&6p$(Q6TQG~f0rV%U*5iFKFNtGWX$6G980D+wHq1@0G)(8_KNWE<;p2g78I8>EtJfVsnEY=t$zBPU9%9T%K|V-!CAc%4t}k&dp7lF6ETeOr@8lzf;; z+#H>6V#?mX{9=Qx-G0+XpK%fY#OhuB2)I(!VcrQj#l0gSToe+hPq`vw)+SzpOixF- zXqph7YH6P5C+x*0Ts+&qZTPu_y`n}EGdaB{ckFf-T2ZA6sGR>hnGqPlr(4q#aCaWXGr9^6}Bu>jk;Tl2v<3X-)W zD_ip9aUC9p7N80kK3}4qy>QC0@LeA42g|*wBpDprdBfy>tm;U}f=By6w^J-hta$v9 ztM&8i0ge_2{mb)@bmbVhQ$13pBupF{N_Y(SWTjRkP#e-N9vhz?8Yu;;VxJc`oH=7( zU8e18$(r9^eQovO?JNE1CC}S+?ebtMr0E##dKZqWO)hHXEgO*iHLGEi^j&J>kgmu> zX%<#hb{-QUV~0cKJ9To$3WoNB2Q@9<9kf4n=v+7`-^<`mnqjB!RT8Jj1+v&=bIf)T zf$dnPfrXeM^BVN}9#5|`gtI_88J!u4GL<#;9XeqC12$3k zdiL6JvzyT#8ngkO*YUGmpEprsiG67>@;c8AwXin2^k=xrHXblP#=lRZ5pEoNWZ{-b2fcxiE{ z669Gi0M~wB1M8^;(h9U~PB%UaOvp-$is-3Um+RVTj;nb& z1(H4q`$de){tHsrVQ+&(khUT;)+Ws0j`2hdOXCJp@0ji|qM#w&&~t_A zsc>w~RH>;|d;+cPvT3ZcGFx`=>+S3vvTKHPkf)ByQrzRPo7{Wvw-K(D*Xa?NxYCp@bCEcT-a^m&>@YLLbj9>MP-#4wOQ;GRCFqrB zAmfFcBp=QWtd9Z{8>1a=@>m(Og{%P%CKPjMFkMkDUw&o1Y&vLM*ggB0b)NO*?6;}@ zz&?CGL8uNtqFC8+W5ky zeT9{=`3|U?)6X;b@0JSN7rW)VOx%wfFRXMqxz0rv%A~5@bmhP3*^u0_TETgTiu%ZR z7t@yZ#j&`oi_Csy0q!K85^Y>>p5=MNz64!t5daZtPDKe%AkI-0KS>#wq|l@*RL4Ez zSqy44*{l<59NQ=FaDsSmsM-sgfN6af#oMe)v2RVjBT$LP)vqz1IIbneY4dh+BUjXLyz ze`(YGna$F^M3|PJ=*_k+0Sh-=OSw!K&~WIeEYhha15v)F_>Qf}qS4Y{urf0-pqHh} zY3FU9-h&SS*@yPjQIic;yA^5Ix8I8P`Zmm6@9Cg@i1A48Oc?QR`ovy1hdlur{iFk2 zS{m{_8nvopu{{*~ZNMNj5J)raJ0A35VRZ4FoB5r=*-{QgJ7#=F!>!ynALDyj;Z8AT z0UD(A!+x)3W@)N*HKfen@`Ka{8qVRa;s-HbL}N7VHT*RbMp2@skZ4 zbruwq3>5pEP>36SBY;AxnasA#uICK)T{tx-5|OghiH=!WdC5t*qRT>ezw0vjb?LrH z*1!XW+omNKU$scHUJ7}(v zO+z1k!aP)6C@Hd834J_zJ82xUw}K>4v8R`X z`FZ7Y**}d*zUG)E@%uVPZAJ-o9W1R*;SP<|ocg}r`_3slq(1U?*?9H1$Y5TXu`^Ue znTmX$nU+xvk_f!(MC!DTZlcK3S&V0Qlq{3u&-eJ1 zJ@cC*TodR|ox5qWEb-wvSR!1xCo*dT+r~#gOS8gq-9cw0iZ`Q?c=9mHzW#M>~ zjUFANkz~yw=;kEi$fmW#@nrZZx?j(5TUP2`!k0_$MJKl=Gn*Cx5jP%N)p{N^gLk4% z?$=hlf9m{M{wIKLE!`7@S#nWU^z;TTK4p<|E`Q2tefpF2vII*g^B0*x-lU+IAnM?N z^5T92JG4bY?}cZ3XuvOGbbRJ(grLaUN>@S}x_7@pLaZxCr%0D!oS~ZDQA?}jRh7FVJ7G5|X?(vlFbS#5k6hCyAm7f_mWTww{=-oZf;w;o)@Z&a(4;y-ZFFu@# zNy9Q(m!}@p*f_SmP-UN$=bQ1E3%KF>>X?|OyP*4s_tw_S`rMP6Z-g2K#=d*7WPKBF znH+I7(0r}vdv0Rn1M-a@M}qoH`f+88$g8bpfXUuZxqg~Iz4`w^ZFJ6lYSkNxs<1NSZi0DNbNjH6^b6Jr&ukGCua=i`c(4f6J7 z95n*~Y8pYl7_2AWALxpABa)Dy#imvekcdNqY~dyl6JH&?I}t_o!&_2MTVbi5SY;eY zL!DbKNQD95jrYd@gS@>+WR)N!=qIiU<9$~w2Lk?7@%Kc6>`csnIzE1Qpn|M|ECj3< zL=1$2)VYCbemH`Pg|7Z@5R4WQ^D zV3I#32uvc2?Lz#*(8ZInenek?q7MnUi-~dd3GhdPK#YFi@BVrFnwb0nPa^-u0)r2^ zAdIh^yeve{+gt9h7G!_DKnBQf4*f?9vK8Y*Ud{qf_6hLA;`IXYB!98LLg27}*!u?f zdHoCrhn2&7;k_BEWX7oSe;d*OZDRI^#V!SIL~q}pRt&QLrs+>4{7Kf|eB15$8O~oF zVVM7c`#0_1WB;kl&@wSm(e=Rw?7D~6MS^z6SHbyUi8z&?uNVcaf+9i@0mecRaIk^` zObLvDC@O=M2ujLW7(yO_g+u-Vg(i{xF(fR07m5KcOJv}{6cq7LhyoUjCtwx93V2sV zFh&6n1w-*l7&r_fuLOZ8{RP6*kI1M>jMrbi+J(X~pb$`bS18;S3Wj0fN?-*gj1t%t zp$q{tknj*CR}2OMf&PTTVO8{f{Jb%YbP~NWZg@FglH1RYUBXqg%+N>>RQ8wSKP6^f z7=Hr800}ZCk^+MMRJ9^{<1PI$yKKrUA`}oxFsPyeOc4fCQ20~H2Jc5^RN^kCJVX}u z%Z1&vs4#+I5R2KZQwG3K3q~v|I(~SJzmK1lkB=7;wCezH*Yb~U6UKDHVf-<=7=Jti z6as~*K;SA+m=zSN0+m;R$V)?@Dv-bE`{0O#;QycY?&JZg{Yp8CNM?*5{8RL6Mp@#| z{c8PcdJ%t4B_QzUq)@?Ne}zEC1mbZ&{bXSM>cYBXNN#w>>hW8-{w^o}r&7QvxWbjN za4;5vkOwQsW0k?K7)2-;tLUn%1j7>u2-vTv{y-=D5d0|^KfIP3gGUBejPm@+6;SeL zqNM)r3&kD3n*|18V2A=3s$>O$s6Y`aaK+yUll$+7h{G!25b_XtFczT%0W(Sk4@SV` z31Eye4hzL7x*`;nl>hGZ|2{-G_|KY9_{b1pYh7KjQaay8fl>A2INcl>e=+f9d*14E!VIf2-^N zj4tj!cZ_%v<3o?a*bn}2e(lECOR~CYnP>q3cT;$_F>H)ByQ`6bF5t)R|9VSV21CN- zi?SyJ0J37c7gJD)Mj%7T;g2@aJaCY8#u(+z5DEF~+4<}Ec<*jR06)Kv@i-ub z=yM&w*9E?~<;?(1_5faihfha~&? zgM<%6-Ph*YLr}|+asVoL&Xh$NJW=%s5bck;J#*4>r9j)f@fsi4)~(BE)^^&2N z`xZyrTIkIK!gG_ep=0}$Yb?>RO;J)CJ3=k5i=_pTPj4Z`h(fk|=fB!)n#zwg;M(z| zgS8(lhRXp1O)+F<%LdgfYwovW1-dh117Up*(a(zB!$#^;*DRyd*(AAdp;!ZMz0?%c jqxHT_)r1Bg+h94k2+?}w@&AX21Dmq-mM5K00hQ~{+)5d@?N0*Xi#L8U59 zP!RD;BE<$GMUfZq6wkPKj5p33_r70eXC&Esu5W&8&Tq}N*WN46%=8!!mnati z0N^pu*Rf#!OKyER*qFa+kcxZ&fDaaIWy`R@2LQc&X=I8g3CIZYCILx-6fyu1I9z^- z;wufUh}v8dr0@LD>2pV~QLJ&Yo4xX2XU2kmSvzl8fyF+p9dSAlB*fobk_+UFH?NnNNl5W;il!< zWOoCR5PK-dv8hk4?fy5v( zM?@>uUDeU)PB*^qb67~wc+|*|I_1%^^P$x_-^Lb;m*AP7-f=C9e5lcLJk@g}e?3-t zqNZfT;;UMP$3$D`i7C`<$q}!&iQk37sw(OuORuVB^#?j7$b9V#gc~C|yFwR=;JUP8 z6Y=u*9rd9wfdZEX0Z8B)qVv#+QSbc^za$>`xDcvD&IXUzqi}l)W8PSJh;(^(j@+B8 z6RwcCOH6nc-~?4x(03IY<_lBx-p>!6_jMoSZQcmmNV$UniPUDpxo^~$!gaXcvf5MG zhkfv`11rZ1e0a{BgGgj1_~;xtHW?AuC5y{WXidoiSQk-q>k>IK`4*fn^s5PT@(zW2 zeJ~(9xkqA)@zyix+*33VvdubTIuxM!#1&!{$*mE^r_H6BW_In|g&=5=>=*k~BaLW5 zOG8}Y1$Y0UnPh^g>dXa?+ihB}t|k}DT(od+b0bZ4jHPqCd)3~3Yv*>mFvHHg-2e5< z&^_3%y>#U!UbRtR>oIZ4l(}9mc}L-_YoshP2Ku7KZbm1>h3*J+%ykg?xTEMHxBh1ZqWGVA(f6cGpg;r z)KFY)u}0>c8g{1+BU;xJcx(Ff7BK4>9>-e?`RKa+UE!7|{X7D3Jl2SmyD7_kxAbsl z!!2-VvdQGj_)>aUQ6EmeEPjILLe@+=RjBL3pmrQFDQJFF;|-ruTJiQGjVF`^n=159yDW;e)=&46bUDgGDW8o`Pj|(> z>V`0)r;C%D7LPy07qdC7Aza5l`ib6NHou*MoDPG@nW*0Pf2uYG5*K6QB5fwFtd7tQyymlPiled}0|t#ZEH{ zsNJw(f5N}xkQn2|1Mb-C9|fimjaXuh{dtG+HK13YhWtk0j(Cd1MZZNwUCb?wR5`zg z;tVj}LYlRPcZW_f%Y6Ut@%|cRg)`OpppI%kb=~KE(3ttV?}P?K+NLBWTmTEf17%f3 zY-18R#h3~OdPTFkvp=tdFmM>^DkjRa^NP%5RrsJUG&OjPv`fFk;Noz|QMcnx5>I_N zo{zojr7R{!4H=n8wr&n_YfANd|vfzd^TsvSveh$q0!1JWdV?Uo)v}7S4`rdqM0$ zw4GerQ9)F^Lm@W4^yax@b$$J0>=pCPbUO`+zIo*^e}P$+V@feXyDN81EGAsH0A9{G zo0r;q1{Sqxd9AGi94+${h*8RiW256L)7InZt#R_Z3JzPdo1==wPH@`QJokItF!-Df zY##U7-hA_mYzJlS?O9_+;$`(&Jg21RK{?*&N+*U?uJqa4R1FUaCIsx z_wZ2NybM~7I)3-P;hKutGPKE1OI0TM$BvR*`3r0zIKzua*N5`f1c5a((K(q` z9SR~K#}aWr?l_~y=jDjFwtl5#^}Q{z{y09xbl9$a3!M6CXKZ&&7%1&2X!v^W%+8F7 z(+M$YAIkO2U=6k%rDoZ1d(9s1)9j|p`vy^$zFD!dE~+Yxcz8rN2JrF8Jo`{|UbX=W zn95uYJ2!LzSW9BV^ta1bI}Uq`2n8K8G7wffd+1;mDD%M3C{G$#(X(oAjTAAGqp|}% zW>w76^ofs4Vq%UXTH9hU)j`Rw>7ugS8$njP`FDbF-E_~V`T5$HEAK^2Tzyac%)zEU zWR@E2igT?DK6G+ii2_?bSbd|vZK#D~n&V~=IXPyDRkR_bfX=mUZ7|ZV6AePXaD-ro zlZ%q8#O{p*ovT>AMqeLAI+(l!@bA5;cUTd&-@m|wS{z@nADsBTTu;B9P*AqlBU$f( zZGA#CJK+Trnz|r)rFr(M$8|Z%kYcOb4x1Ng%h@22{;7+IQQ05?qtVVt_P4;N-lFnR zCne`DbB57oR~;IwzC5BAQw!%}moBFuKQopYu31qdW48UZ9g6`=z@P(!29E_{e%%4N z*|!mm%JykxoDxym|iS)tO@^H7}!xC2gVJ$Vx0oEy{G z)F+<}o|Pt9-;3wJtbPDXy%)n+tA2k=y?VB5N_4$ida{BnVLTn;5$zGge_$xgCC(}0 zZhVLElzCep#?XFlfDwMUez|V8Hni9Dev^J3ZAI>~g{gz;%DFT(wwK6N#B@P?$USQx zncUa2-IU_y8{bI@A1EvGvlVHUhiAf!??}B!oOXO;r8Y@T-i%4RR?##n9&B81*Wth! zBN}LYSK&?XvpbrHMxiSyzA7tD7fi>hsCHfRm8&w-{zb1+&m*vfV|@}{nIAq_UpctQ zwg<*?l~+i(P_sCZQQei@rZNSi(tF*iLlPs}t(V0(gpSGp$J*KhH`rvBQjVyD5= zW9KBlR9i4o^u7cXq=yTnLt4ATv5v=va}G+JBtJDS#Eq5V$3x|I!pqfwhvN=azi4Rk~IhSEqd>+)0G%E6Xw*}jRh#i?8Z z7Quo^buL8}?uXP~J1__wha-B#Z@W6A_s_M<3(qzPI;by|G$hjQFSns9o-F$egx(q6 zyft4Dwp22KYWOfm8Ib_=r@kJG`}kodI%tgFS!Ok{GG$jYRmaLK)z$0W z#m*o&UTy5%XYs!GJV#PWHeTndY5u)Th!mGMFUBk@7h^RFV`uygg@YyHF;J@?9aHT>u@ z4bpgCM#TCrrkkHls#NlJ+3QyG zuca;5VtK`aKU?I;gvH3vY)OwI`nzqLq^+?>YR)<9NV`3Z{~QP7*ID(C*C{l*YIjSa zqe|ob;*t5@7gc&`y_b$4wTxbAuI1#3iDtwo%6jh+@_2q(el(R^Dei0&hHotf-6)&1 zv{^VWg=-pF&h|Uyl1ny#4&+EK{-QKfSTiWu;g~{Pv0zS)T-pM%yCOo~T(@*gtkMYHudwr&Zc6WnxuX>$5c$g z_mwocR|arQLfcbL?XT?$4@!1*hqE5KHXyO_B2;;@)bxl<>C~IiKH75*&#{5ym=)p( ze+l=@gE>yl!RcAagQM%nyfD2kWuBa(w+{fK^sCS$MIk=>N|7S<%FM7IIu)L{kZ`KD zX=v*g{??f|>GhXTv4HH2J>FfZJF*I0?g})%BwGzNKRvigfxAhZl6`PRiM4uPX=V#e zh7#aQ!k&Dx$+21ya|>6iQ{1u1A($oj9{1^+l;7ggqsf6pzUAy(zKuKlE=~b2=bARk zX5K3-kN@af`kEe0+nfvfX4q7Bdbu&QaD3!mFx>qWb-$*kQ|Zdro0r=%{uMCZZ1M5E z6L#MIUnpeAaT*T`esH6p-51t9&qM$KEYTEgZ8HOH?ca9~n0p2}p($AX2S>!)oGd+b z6+kw8K99|E6=UPk?)&1+4)k)BV>0d652#S|E$qd24MaprowH^ac6E@j-=+15^ney@-Cc=#$idsY{bJP`xEM6 zlQ{vn*I9UYdX6-&z`36q&@vM*MR zLJQsE-~QMR&ZYLLP*m7^?&0l<6nC!utAigB46}hn9y7@Yw&W7qTYQ)uc zrsdpZ$ZpnFhddjfoR5U|(pQX_0%th+ULYsup=#Pe%h8_&vZ&SzkZTz zGL-&ZCEA`hQ1cqC0}xtwWaj#SU8q#?o+I(~hNA%Xm=^uZl>;Xm8?N20JKf#;?Hdbw zmv4x@nTjd^ut$T!+|IEzF~$&RUP^c(&4r{C=;h7a?g0SQH3Plz1P>Ae=t6R(P_dwo z4fjAm3K0uBfiQuXcx#i~DEh&^B+Fn^D?+dbL6r#7)ZkJN#4riGNDMqM(94rb#{^0~)yuyOq z7z}TWvT{H`fKmWliRSC73{_QCRffQnVK6Wg0j3908Tddjl`g$S@smS`L?`%CycrZ4 z6}ZKTccJ+)upkh#9r$~EUfw1qf6!Cuzp22~Lpc!dtqfIyD0_J+|LQ?!==w8BehcW| zdeE(yyJE@~Bs$H{mq60>Cs7&FzfuqhfB1X*`Fd`rLnJ7ZJV{q@hSurBpQhZ6JTfrSVaYn0;3^FRWOQ-QYFCAP&5Gn`Gv}WN@w7y z1kx52lU#|y@6xao=3IUT)coGEVg2zK3ux%g;7B$KwuciFL)Y}LJs=h&|8xS zsQz=v^(k~_|3TZPpEJsmN5K*{|zmH;=>)+jIq14C56Fq9Ppf`Oqi2;^^qDgXCVL?KWp zA{>DLL!qk72}8sqz-TBE0!FFe$q*N)DwK>?`D@Vs_Y@Ie7~Bd5!@!^zxa$93iUb!j z5k^MCz$iGJIf@Vh8jOay5Wz?!3XdeAA*u*fZ;H zm&*PL_+_bJj{Z*@a|vRuXv%*qX}^^Pv+Dkv$8R(0zu5&4_)jN)OW%Lw`bVz6rNG|; z|5IK6$o01r_*>wAs_Q={7uTOJ#Uv{8SvG+A${P_v6=uFJv$+@@(*bO5ee#-$Q<)Y{ zZ+#pc08olZe0o z3d0S!^~irBoOg@f+CWFkO27SmZ!0GN!ok`iJ9e7XpjFnpD*MC^4FctTmsEJxt|C5G zJKZDVfY{a4s`6#0r8&TMnH4E29=8iSf0^b{o}T;Nd)S#nNYVC|b8Ey%70cQNufh<@ Sq@39Sz(Chjr{bt{#Qy+yd0v(P literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/RTBT.png b/assets/2-dimensional-toroidal/RTBT.png new file mode 100644 index 0000000000000000000000000000000000000000..011b95b73407ffa97c0dbeac14f3fa743980b8d0 GIT binary patch literal 8145 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 literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/RTLB.png b/assets/2-dimensional-toroidal/RTLB.png new file mode 100644 index 0000000000000000000000000000000000000000..536afb6e7da0508f31644b4f35f1df2d25484b4a GIT binary patch literal 7883 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 BIrRVl literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/RTLT.png b/assets/2-dimensional-toroidal/RTLT.png new file mode 100644 index 0000000000000000000000000000000000000000..44a4dc6755acf124970175bea177013f2cc95e2d GIT binary patch literal 9214 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 F{{huCid+By literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/RTRB.png b/assets/2-dimensional-toroidal/RTRB.png new file mode 100644 index 0000000000000000000000000000000000000000..e4ad3636e60da4c782c6f619cab29f4a747aa82d GIT binary patch literal 7940 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 F|1aQ4{e1uc literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/RTRT.png b/assets/2-dimensional-toroidal/RTRT.png new file mode 100644 index 0000000000000000000000000000000000000000..b5553cc69af31fc33d70c21460673b9df1a53a04 GIT binary patch literal 9597 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 SM-`PafS#7IX1V(H;Qs*&>s_1x literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/RT__.png b/assets/2-dimensional-toroidal/RT__.png new file mode 100644 index 0000000000000000000000000000000000000000..6231b419293aa4cd89f8a52b86f1f4786df9179f GIT binary patch literal 8216 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 literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/__BT.png b/assets/2-dimensional-toroidal/__BT.png new file mode 100644 index 0000000000000000000000000000000000000000..4ae36029a9ff5698d99e8410acf3af71d968d285 GIT binary patch literal 8649 zcmeHLc{r49+aGK8og_3yB{9s58M82U*&h48*36h;Vyt7QY}rd8QnG}HN{U2wvQrX? zgp_0}Mig1<8+w+W?|YBqJD%@&-|w$yX70J~`@DYV?>f)lbzb*!C7PM&adU`q0001P z1AQF}`d)H(V`HWNt3b+c004Y~p;mTO3tSM;$IqKY_9OzSAwEPPF_=sO0D{NvIM@eH zL&|r$j)$`6Xez`{qZ?ytwwr*m_L9?9E>6NKl{%3vEItg0o8NbW2F}t1ol@SZc3spm z+wko$By1?>pn$jo;?BR3gsi^eb}l*f+fT>;~Hk?(z+Pv9(-vZf<&;P+)1% zDRXuUG#k+{en>G)Q}EFKF)_Qw!?&vyM>*~9Bm5SZ>ku5WpC(>7Or%Yy33-3NP819u z_&|GgphH|hO|MYAE!S8`Vz{XG;z?F4ulU(RC1P`~b;CAqY95ft?(k?OBKjWoOY?$#%d^snz5&&gZ6Hhqw_WCTBY zax|>wmQPc&YWYsZz{)x7%$3{k>`Z%tx^9nzBUqd#uqToUUSjp#3N0cy?}gFc?by{M zJ6{)J8eW*K^!x_!Zmg}9z4fVEHmg58K=F8%jRvQ;Mgs;!Xt$6)%gfQF6 zCUeB{PGoD35pSFFOOiCuTqZ6DQKAru!np0+BixYBv#`}PfQQ*mv)frqfE zqo$&?e!Pfb+s>!Bp(%cBwfPR5wi3F{-|P@PV5+3&3AwH1k@)sAw^JZy?5$4fy71?# zuUr5}quqIlRp<6u4ZK(coF5f^Ar_b7V-~m2iLsnw_}EA`8$@|9<;2WIdOEd*=ALe_ zkH2JnM|zRJnd|l8Yj5OdRcUPsjM^_9mmAhw@29GL75BW@%^4L_H2XMHB8=y;c%tB} zdttI#TsO2+$RE}Nir9)p8AFRRlwwI`Ilcj%?CAZLp1vJfW)IubO5bs8SlLE!U-l@w z`JQx@!bTGjs~NTEa}LtDS-%uEH%>6c@@h~<-^3llLC&KFyGur@9rIk8X;&v*l!h$* zKzS~0=I;sY;Q99Cr&G{rxOhKJOqKOi@>8ql{RdWZHn={snZM!ASbLlEYX^arzc{v0 zVEUT!l)r4_`&;B&)DG#}0$N}sV!qa`x$%=j`f>A;E*sG#^UJzxZ?+`wC))Qeo{5+A z>JIYt5sm4~FY}{VHibWO3v1KV>*1t1M|Q9Ox1gvSwwkW%4arT|VRp z=P8`xvK?lzvGTt5i`T!gPDdw(fIo|_;Bg)=fH%+ zj{ft3v<%S?83`7ZhcmC~V0#5hd81TWLSI_MohT3bNF4Eu<1NEY*kuK=(r&)?-kj8| z!ZI6~q$;$CG$MNo?EhF1y{P_voz8f%RU!(E}+B;-PhdnQyN2 zF?YB-)G)Sbstf2Exeeb4(V0kWl04Xu5|J+udgZ?ENI``5R9Lx0lYf*Mam~W%V1=75 zH)wN#u6(8?`1(PXl% zh{dtPQO>%xTc8B>eQ7P&KC^t$MdaSrCQGJ={Omh9Rg#5~*!gJ20}|Yhi&*2exyggE zD;fg*+7C!+Bf?+1i+B_S$1e^*YQHdWZB=qFr8#dLd5Nub)=BZnzGOY-e(T)8;j9I4 zk-SuQLv57&wK4xPp2r;RB{J$}Bciq9gG@zXf^859=!@`F@s=g6HS2s@>*GF8>Xicx z9bqS$Zgw*zn4LI(tY4at+A`dxA)kNZ)=*(_L5NRUN13Fv%89tgEPeX`%Ac}q4~1vgU8JuT1Bw?4s(ssg+%f>g=2uwI*fNTG0qSDH3v# zebqb%CkF}UjfZ;JUtU@oDzuQ(1Q|4&UR1#vUbx0y832sVmAW)!HhvUTRqB2~7`c_} zm@Hw>C6#yYWqf|YY-w!)bBp}QLrnn=?I^aU7GW&oVv3%4GlNkNhv|F(X=LixLiT6e z%@?jR?97&~T1=RKx^#CSJ1R3JDUq|pkB?iLb5g?*Mi(sV=RTxKrzcnk#0h&yR>%5rQ=%9P?7yv~v4;Bb+dOL$ zS{bUA7O6qVZg!?E^Jfeh!b15jfKFa>LamPJM;W+HvNlg&I%->%AVo`@@wukbZ_Qry z`Ea!PSQ)3_wum<0mYKr9(4)#gXC4#eotGRzeVVs@=;^<5uP0GJ1lneNciAA zMdF12%UjVjKUKJ3%h}#!>~r01n=6C-z&x^%fRf93I}Ppu5&79j(aYJRPJ#D02VDde zDVF$<3Fn3op+3=fYCYmpiHH_KV}lDhxrOkNoHd`cdx_IdW$&&|QZ)6ZGY-G#)9pfx zJRmE$9OjOB5$hzQY*^(N!66|5y2Z2*lY*yebH2?!iOX^E%a6v`3|yGWgiV4C9qx<< zwN@8@H~JVi&+PvQu*N@>04c<0N}8iH+*|{)j6!sy*~a2*o*idh9yNS*(}<`q{Ds4Y zRk)7F#&9&uvCSP`ef`{v9A(xs1IOLWlFH7V_yx@EhtVR&&e3$!*%(LoPE@;dU->Z3 zM^I0-J=^qU$zt=)JH1xcz{E}&tyhaxK<9_Dc<{GT`GzH7_u)ha-k9R#HtB@B`_fsC zaFk{j7qObK9E}r-2;_C|?R(kq_QIl_9^V7(0-WicCy`lANXi{d1tk*e@EPBO=Co|VHG`kR5bA6Gj#P9X53{6T*tLk&QQ}v zsVs18iC{yXUT6N6_sW894QzRW`X12z?0)=($a)jJ;+ro=M-!U4s`r0gRhXKCJ>0Tx zx#JMbiN4xFtC0Mz-TiE0Zi%aQ{lU5bHAqTtT6q`1u15TD!{&nyEcCPL+(1;|K-N)) z>%w)NF#l@SineUIv!+h*3R@W-X0e=S%wi7;A3MpS_f#u01g6I|J6O{ z*2vVQ(d-y)%?Z4Bt&+Y<(k}TtQ@pVpuA--w2F$hfJXsG{g%;&r$;aPS z-e0?jFIeZ=36d-xDptbj+_iDPvCcN=5Y;ILMXi}c_&Rhxy%J%7&;(+1&AuK$s3+Lv zWLE>Ep2!+34Jxs^vJ2wiwFirGKKqDk8y>2RC@w9$D?=l%$yX}W2n)l$de9D$90+E+N<396ru5jPROoO0)5<6wa1So&bPS5vrzo2`8LLJZ1XcNha z{a7CBYcpaZ+;BAIrEV^5pfu9+4p-AsrwfyTAz5oF!_#`~oyrp+f326H#_Pbz?Z|@* z8>mwh5zhHDz40nyI*HV2-A%Ntoj+qBMZYIkB_&zvL5FQOx)uxK%}l8~tx_fDSRcFj zVMY>KdH=PxIA_lhwa2Z`8>VI2P4l;Vl+n$K?>%70?^tR%>~Dv!7^U!ILcXb5_Z^RQ z9<$U|t`E*x(i_}BtzHe1${4_!bIcbfhvZwqEN`x#&(isL{pCDq zog7&D;bQ^pIDhC|Y-}{)k>~i6ISIwH73c|GDbs6*MDo6fSomvCw~2}*@I4+18&Jnf zX0`h3=LH`MVeT1cmwnVZ&If`F`^H2HYxosa+ai~9X~%5rA3YP--jwS;s}a86BpT?Y zig?v+5*5;~@6RZ;*0-J@-@oJYZF;NENu$I$^xLS8zQ9Qv_~g^rbKJ>}l?4lK!lYTWKFO@^>mMeeE=#%QKp6Ad5*34OUd@!8H( znWFq^ha@2Jm3{cObe~M^Vj?Iy4RKqqI7r}(lt$kIRi2kIQvNO9N`U)}(x#*%(-b&m zXklz%E1%QAiF)d8i(u9ot%?IqhMy1x2?bqAlkTw_Z= zj_CzkUv=i)@M0j?Ih*!-W@MJjd|uHBI#iOe+HalSGnXuRriONE=abpE>*f3o2fJeA zqvPf$jWn03vX2iVjdG8#MmRS~*PpmfIi|61n{=&+vlvvr&vS-di>#fTDC~QTQVQn2 zKDSkDo9u1Kg+*WWlsv>b+JNW|W9vH>mBNu{a$|Gyqu#FtK?5gmvQk!#q-U>42CS)! zHtJqibzD^?hGr+8xiUTY^l3~4va2{RZ{L*QnK`Q+K;rmNF~2k?w3MM68gpYF+g z)gjJa2LKq(k+rqW479a>Uml<@3gkpw!s@qahGvpvxF0iCXK0mxWnL?uHp7c3wQp-R$ukWiLmiT zrr6V$$TqJ;^XIFxQ@YxzBweni8xoCkT7Vtc{SAgk0F$|0dH>_znW?=6(_OSA5oK$M9fFGr#jiHo|(=GvY*PvDP7Ky<`GQ(der9X z72#jb2dANKoW{&>l2fhw9djPwvxk>^PKx#}^cgvopkq-Y_t@A$LKziNAWt3gutCMe zq8&TV@A->a-NhF@m{P=7k7>qy*lhhi6;xy6g&#NK=!k4do(|_?YIV-H@y%H#bltoT z_~tfc=)GZNeQGm(%}_g8oB{i)r6WMw@=Ii&#Hp#Ci^eZ6Z^O?y@dT?EdiMe%YBXkV zjW|XeD&f^gsxur1?2B*F&#fGBXs9o&tvUPj`PLT0zQ=yyPG)d40Klt8rmxr78UKPI zcvBQ`uHJZ}LNLXLzMcaBsHzA1;0PW>DiBX}BYR;%%k|A5AlVfQvPBp}jD56;?qvN? zKcZ!*i4`H#gMfAgsjG3Q24m<16e1M|45oN``D22ypgmp;{dm``2m@29l7hFNn<5mA zMk_*KiZB?MjsW|Icu{e|U@w2^U5XzZIz)ehAK8aW_Vxnqa^mpb0aPpqL~jTF9v{WW z*!T~6FaO_EpzEO+jPp^1DnJw|6vdxC{HeNubdui!`j;O5R`g{rMGK<8cYq&(s2fQ1 zqDucv;Y#?!-zUJ&b1xlNf+EqANTEah>Agb#(xsk(vDqIUyArsODL#8%bg}<}q>@R0 ziuIS+c3bw+`8g1}`yaf2LI0ln9+-|YHpb|969RU_Gtj|;cKgS;dK1X5n7uz;HYo0Y)pM31Ao;NkqX=NGK6S_=&>Qk4&#hoafI`?NYhYsZcN|9)`ffz)A!J z5)4P;kYGFt4FMC8I3fgz$KfCl*dCQD0dvCJkAkBQCz*nCBP#lMx$QOV3Xah<$Zto(x@B+-{xH3HChbxnQ*Yh&ZaZpOv?_Cl<6D0C3myk7i@~baKT} zaXL6EkxmMMDPbVW7%0*Ts)V8cV9Ih37zXka-rJQ-3i;pAyORf~`eVrT$^P{IL-tHR zW|Sq-_s7|fQ%~~VR00C`CItpZ_>qD?E|BQD7bl(TM-#yv=jBGEUp;;+*Wc~re^Clb zu5dg8NkD)J5EK*)hZ4|WJWd$~CMe_4NF^ePgi`vE)gSEs-Xv-e&X1_+M%R(96}>$7 zv;rR68z|Yo#uDUC+#LnFU|Z&DAC>(B@YAh=KKegw z^ji@9j;8p>E$z3mpjX|0^7Gq_`cHNN1pd>>-_rLVx&D#sZz=G%!2eX&KXUyo1^yQJ zpX&Oz$;I*KOEJ-l{wy0rf8~8CJKRBkU1r4_>FEHz?|$;hu8~0HSjCJ?Tvhs6sA532okEELpP<8F7+TN7icPqf&BR|m<7(}MJ19u8Iu-q2Y#tNB literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/__LB.png b/assets/2-dimensional-toroidal/__LB.png new file mode 100644 index 0000000000000000000000000000000000000000..43ed37336a4319cc175a9df23d12fee2654ee3a4 GIT binary patch literal 8287 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 G@_zuEHU$&_ literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/__RB.png b/assets/2-dimensional-toroidal/__RB.png new file mode 100644 index 0000000000000000000000000000000000000000..efbf8d2318c26664f6a5cec374e0a3a5496753d0 GIT binary patch literal 7585 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 literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/__RT.png b/assets/2-dimensional-toroidal/__RT.png new file mode 100644 index 0000000000000000000000000000000000000000..1655df10040a98d1b4b173699326b5ebfb173ea5 GIT binary patch literal 8065 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 D+~okq literal 0 HcmV?d00001 diff --git a/assets/2-dimensional-toroidal/result.png b/assets/2-dimensional-toroidal/result.png new file mode 100644 index 0000000000000000000000000000000000000000..f7552940c59c0a2f0025293edc00aa8cb18e00e2 GIT binary patch literal 2442 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 IM6N<$f-7~Q@Bjb+ literal 0 HcmV?d00001 diff --git a/examples/1-dimensional-euclidean.md b/examples/1-dimensional-euclidean.md index a31d60b..ba41ba0 100644 --- a/examples/1-dimensional-euclidean.md +++ b/examples/1-dimensional-euclidean.md @@ -83,7 +83,7 @@ We will perform 3 executions of the `generate` function in order: System.out.println(WFCUtils.WFC1DToString(result)); ``` - + - In the second one we will impose some constraint on the left end: @@ -98,7 +98,7 @@ We will perform 3 executions of the `generate` function in order: System.out.println(WFCUtils.WFC1DToString(result)); ``` - + - In the third one we will impose constraints in both ends: @@ -111,6 +111,4 @@ We will perform 3 executions of the `generate` function in order: System.out.println(WFCUtils.WFC1DToString(result)); ``` - - -Following this examples, and designing other tiles and adjacencies, one can play with wfc4j library to generate very diverse braids (topology). For more information about braids you can follow this [link (Braid - Wolfram MathWorld)](https://mathworld.wolfram.com/Braid.html) and DYOR. + diff --git a/examples/1-dimensional-toroidal.md b/examples/1-dimensional-toroidal.md index 99a9ca4..6fe8734 100644 --- a/examples/1-dimensional-toroidal.md +++ b/examples/1-dimensional-toroidal.md @@ -75,7 +75,7 @@ We will perform 2 executions of the `generate` function in order: System.out.println(WFCUtils.WFC1DToString(result)); ``` - + - In the second one we will impose some constraint on the fifth cell: @@ -90,6 +90,4 @@ We will perform 2 executions of the `generate` function in order: System.out.println(WFCUtils.WFC1DToString(result)); ``` - - -Following this examples, and designing other tiles and adjacencies, one can play with wfc4j library to generate very diverse types of rings, bands, bracelets, etc. + diff --git a/examples/2-dimensional-euclidean.md b/examples/2-dimensional-euclidean.md new file mode 100644 index 0000000..7acaeea --- /dev/null +++ b/examples/2-dimensional-euclidean.md @@ -0,0 +1,98 @@ +# 2-dimensional euclidean grid example + +Let's see how to use the wfc4j library to generate a planar pattern. These are the tiles we have available: + +| NE | NW | SE | SW | +|:---:|:---:|:---:|:---:| +||||| + +```java +import java.util.HashSet; +import eu.irzinfante.wfc4j.model.Tile; + +Tile NE = new Tile<>("NE"), NW = new Tile<>("NW"), SE = new Tile<>("SE"), SW = new Tile<>("SW"); + +var tileSet = new HashSet>(); +tileSet.add(NE); tileSet.add(NW); tileSet.add(SE); tileSet.add(SW); +``` + +So, the logical adjacencies between tiles are the following: + + +| Tile | Left adjacent tiles | Right adjacent tiles | Bottom adjacent tiles | Top adjacent tiles | +|:----:|:---------------------:|:----------------------:|:----------------------:|:----------------------:| +|| $~~~~$ | $~~~~$ | $~~~~$ | $~~~~$ | +|| $~~~~$ | $~~~~$ | $~~~~$ | $~~~~$ | +|| $~~~~$ | $~~~~$ | $~~~~$ | $~~~~$ | +|| $~~~~$ | $~~~~$ | $~~~~$ | $~~~~$ | + +```java +import eu.irzinfante.wfc4j.model.TileMap2D; +import eu.irzinfante.wfc4j.enums.Side2D; + +var adjacentNWSW = new HashSet>(); +adjacentNWSW.add(NW); adjacentNWSW.add(SW); + +var adjacentSESW = new HashSet>(); +adjacentSESW.add(SE); adjacentSESW.add(SW); + +var adjacentNESE = new HashSet>(); +adjacentNESE.add(NE); adjacentNESE.add(SE); + +var adjacentNENW = new HashSet>(); +adjacentNENW.add(NE); adjacentNENW.add(NW); + +var tileMap = new TileMap2D<>(tileSet); + +tileMap.setAdjacents(NE, Side2D.Left, adjacentNWSW); tileMap.setAdjacents(NE, Side2D.Right, adjacentNWSW); +tileMap.setAdjacents(NE, Side2D.Bottom, adjacentSESW); tileMap.setAdjacents(NE, Side2D.Top, adjacentSESW); + +tileMap.setAdjacents(NW, Side2D.Left, adjacentNESE); tileMap.setAdjacents(NW, Side2D.Right, adjacentNESE); +tileMap.setAdjacents(NW, Side2D.Bottom, adjacentSESW); tileMap.setAdjacents(NW, Side2D.Top, adjacentSESW); + +tileMap.setAdjacents(SE, Side2D.Left, adjacentNWSW); tileMap.setAdjacents(SE, Side2D.Right, adjacentNWSW); +tileMap.setAdjacents(SE, Side2D.Bottom, adjacentNENW); tileMap.setAdjacents(SE, Side2D.Top, adjacentNENW); + +tileMap.setAdjacents(SW, Side2D.Left, adjacentNESE); tileMap.setAdjacents(SW, Side2D.Right, adjacentNESE); +tileMap.setAdjacents(SW, Side2D.Bottom, adjacentNENW); tileMap.setAdjacents(SW, Side2D.Top, adjacentNENW); +``` + +Now we can instantiate the API class with an 8 by 6 grid: + +```java +import eu.irzinfante.wfc4j.api.WaveFunctionCollapseEuclidean2D; + +int gridSizeX = 8, gridSizeY = 6; +var WFC = new WaveFunctionCollapseEuclidean2D(tileMap, gridSizeX, gridSizeY, 148576907989080L); +``` + +We will perform 2 executions of the `generate` function in order: + +- For the first one we won't impose any restriction: + + ```java + import eu.irzinfante.wfc4j.util.WFCUtils; + + WFC.clear(); + var result = WFC.generate(); + + System.out.println(WFCUtils.WFC2DToString(result)); + ``` + + + +- For the second one we will impose some constraint on the center of the grid: + + ```java + import java.util.Arrays; + import eu.irzinfante.wfc4j.model.Cell2D; + + WFC.clear(); + WFC.setCellConstraint(new Cell2D<>(new HashSet<>(Arrays.asList(SE)), 4, 3)); + WFC.setCellConstraint(new Cell2D<>(new HashSet<>(Arrays.asList(NW)), 5, 4)); + result = WFC.generate(); + + System.out.println(WFCUtils.WFC2DToString(result)); + ``` + + diff --git a/examples/2-dimensional-toroidal.md b/examples/2-dimensional-toroidal.md new file mode 100644 index 0000000..e796318 --- /dev/null +++ b/examples/2-dimensional-toroidal.md @@ -0,0 +1,124 @@ +# 2-dimensional toroidal grid example + +In this example we will see how to use the wfc4j library to generate a 2D toroidal pattern with programmatically constructed tiles. Each tile will be the combination of two components. + +- First component: + +| LR__ | LB__ | LT__ | RB__ | RT__ | BT__ | +|:----:|:----:|:----:|:----:|:----:|:----:| +||||||| + +- Second component: + +| __LR | __LB | __LT | __RB | __RT | __BT | +|:----:|:----:|:----:|:----:|:----:|:----:| +||||||| + +And therefore the adjacency of the tiles will be based on how the two components of each tile fit together with the components of the adjacent tiles. In our example this is computed like this: + +```java +import eu.irzinfante.wfc4j.enums.Side2D; +import eu.irzinfante.wfc4j.exceptions.DimensionException; +import eu.irzinfante.wfc4j.exceptions.TileException; +import eu.irzinfante.wfc4j.model.Tile; +import eu.irzinfante.wfc4j.model.TileMap2D; + +final String LR = "LR", LB = "LB", LT = "LT", RB = "RB", RT = "RT", BT = "BT"; +final var components = new String[] {LR, LB, LT, RB, RT, BT}; + +var tileSet = new HashSet>(); +for(var first : components) { + for(var second : components) { + tileSet.add(new Tile<>(first + second)); + } +} + +var tileMap = new TileMap2D<>(tileSet); + +for(var tile : tileSet) { + var tileFirstLeft = tile.getValue().substring(0, 2).contains("L"); + var tileSecondLeft = tile.getValue().substring(2, 4).contains("L"); + var leftAdjacents = new HashSet>(); + + var tileFirstRight = tile.getValue().substring(0, 2).contains("R"); + var tileSecondRight = tile.getValue().substring(2, 4).contains("R"); + var rightAdjacents = new HashSet>(); + + var tileFirstBottom = tile.getValue().substring(0, 2).contains("B"); + var tileSecondBottom = tile.getValue().substring(2, 4).contains("B"); + var bottomAdjacents = new HashSet>(); + + var tileFirstTop = tile.getValue().substring(0, 2).contains("T"); + var tileSecondTop = tile.getValue().substring(2, 4).contains("T"); + var topAdjacents = new HashSet>(); + + for(var adjacent : tileSet) { + var adjacentFirstLeft = adjacent.getValue().substring(0, 2).contains("L"); + var adjacentSecondLeft = adjacent.getValue().substring(2, 4).contains("L"); + if( (tileFirstRight && adjacentFirstLeft && tileSecondRight && adjacentSecondLeft) || + (tileFirstRight && adjacentFirstLeft && !tileSecondRight && !adjacentSecondLeft) || + (!tileFirstRight && !adjacentFirstLeft && tileSecondRight && adjacentSecondLeft) || + (!tileFirstRight && !adjacentFirstLeft && !tileSecondRight && !adjacentSecondLeft) + ) { + rightAdjacents.add(adjacent); + } + + var adjacentFirstRight = adjacent.getValue().substring(0, 2).contains("R"); + var adjacentSecondRight = adjacent.getValue().substring(2, 4).contains("R"); + if( (tileFirstLeft && adjacentFirstRight && tileSecondLeft && adjacentSecondRight) || + (tileFirstLeft && adjacentFirstRight && !tileSecondLeft && !adjacentSecondRight) || + (!tileFirstLeft && !adjacentFirstRight && tileSecondLeft && adjacentSecondRight) || + (!tileFirstLeft && !adjacentFirstRight && !tileSecondLeft && !adjacentSecondRight) + ) { + leftAdjacents.add(adjacent); + } + + var adjacentFirstTop = adjacent.getValue().substring(0, 2).contains("T"); + var adjacentSecondTop = adjacent.getValue().substring(2, 4).contains("T"); + if( (tileFirstBottom && adjacentFirstTop && tileSecondBottom && adjacentSecondTop) || + (tileFirstBottom && adjacentFirstTop && !tileSecondBottom && !adjacentSecondTop) || + (!tileFirstBottom && !adjacentFirstTop && tileSecondBottom && adjacentSecondTop) || + (!tileFirstBottom && !adjacentFirstTop && !tileSecondBottom && !adjacentSecondTop) + ) { + bottomAdjacents.add(adjacent); + } + + var adjacentFirstBottom = adjacent.getValue().substring(0, 2).contains("B"); + var adjacentSecondBottom = adjacent.getValue().substring(2, 4).contains("B"); + if( (tileFirstTop && adjacentFirstBottom && tileSecondTop && adjacentSecondBottom) || + (tileFirstTop && adjacentFirstBottom && !tileSecondTop && !adjacentSecondBottom) || + (!tileFirstTop && !adjacentFirstBottom && tileSecondTop && adjacentSecondBottom) || + (!tileFirstTop && !adjacentFirstBottom && !tileSecondTop && !adjacentSecondBottom) + ) { + topAdjacents.add(adjacent); + } + } + + tileMap.setAdjacents(tile, Side2D.Left, leftAdjacents); + tileMap.setAdjacents(tile, Side2D.Right, rightAdjacents); + tileMap.setAdjacents(tile, Side2D.Bottom, bottomAdjacents); + tileMap.setAdjacents(tile, Side2D.Top, topAdjacents); +} +``` + +> Please, take your time on understanding the code above. + +Now we can instantiate the API class with an 6 by 6 grid: + +```java +import eu.irzinfante.wfc4j.api.WaveFunctionCollapseToroidal2D; + +int gridSizeX = 6, gridSizeY = 6; +var WFC = new WaveFunctionCollapseToroidal2D(tileMap, gridSizeX, gridSizeY, 103478937644546L); +``` + +Finally we will perform the excution of the `generate` function: + +```java +import eu.irzinfante.wfc4j.util.WFCUtils; + +var result = WFC.generate(); +System.out.println(WFCUtils.WFC2DToString(result)); +``` + + diff --git a/pom.xml b/pom.xml index 69e3064..b66ad78 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 eu.irzinfante wfc4j - 0.1.1 + 0.2.0 jar diff --git a/src/main/java/eu/irzinfante/wfc4j/api/WaveFunctionCollapseEuclidean2D.java b/src/main/java/eu/irzinfante/wfc4j/api/WaveFunctionCollapseEuclidean2D.java new file mode 100644 index 0000000..39adc63 --- /dev/null +++ b/src/main/java/eu/irzinfante/wfc4j/api/WaveFunctionCollapseEuclidean2D.java @@ -0,0 +1,120 @@ +/** + * Library to use the Wave Function Collapse strategy for procedural generation + * Copyright (C) 2023 Iker Ruiz de Infante Gonzalez + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package eu.irzinfante.wfc4j.api; + +import eu.irzinfante.wfc4j.core.AbstractWaveFunctionCollapse2D; +import eu.irzinfante.wfc4j.exceptions.DimensionException; +import eu.irzinfante.wfc4j.exceptions.TileException; +import eu.irzinfante.wfc4j.model.Cell2D; +import eu.irzinfante.wfc4j.model.TileMap2D; + +/** + * @author irzinfante iker@irzinfante.eu + * @since 0.2.0 + */ +public class WaveFunctionCollapseEuclidean2D extends AbstractWaveFunctionCollapse2D { + + /** + * Creates a 2-dimensional euclidean grid on which to apply the WFC algorithm with the specified tilemap + * + * @param tileMap The to use for the WFC algorithm + * @param gridSizeX The size of the grid in the X axis (2-dimensional) + * @param gridSizeY The size of the grid in the Y axis (2-dimensional) + * @throws TileException If tileMap is null + * @throws DimensionException If gridSizeX or gridSizeY is less than one + * + * @since 0.2.0 + */ + public WaveFunctionCollapseEuclidean2D(TileMap2D tileMap, int gridSizeX, int gridSizeY) throws TileException, DimensionException { + super(tileMap, gridSizeX, gridSizeY); + } + + /** + * Creates a 2-dimensional euclidean grid on which to apply the WFC algorithm with the specified tilemap, + * with the possibility to control the random results providing a seed + * + * @param tileMap The to use for the WFC algorithm + * @param gridSizeX The size of the grid in the X axis (2-dimensional) + * @param gridSizeY The size of the grid in the Y axis (2-dimensional) + * @param seed Seed for random functions + * @throws TileException If tileMap is null + * @throws DimensionException If gridSizeX or gridSizeY is less than one + * + * @since 0.2.0 + */ + public WaveFunctionCollapseEuclidean2D(TileMap2D tileMap, int gridSizeX, int gridSizeY, long seed) throws TileException, DimensionException { + super(tileMap, gridSizeX, gridSizeY, seed); + } + + @Override + protected boolean canUpdateLeftCell(int x, int y) { + return x - 1 >= 1 && this.getLeftCell(x, y).getTile() == null; + } + + @Override + protected Cell2D getLeftCell(int x, int y) { + if(x == 1) { + return null; + } else { + return this.getCell(x - 1, y); + } + } + + @Override + protected boolean canUpdateRightCell(int x, int y) { + return x + 1 <= this.grid[y - 1].length && this.getRightCell(x, y).getTile() == null; + } + + @Override + protected Cell2D getRightCell(int x, int y) { + if(x == this.grid[y - 1].length) { + return null; + } else { + return this.getCell(x + 1, y); + } + } + + @Override + protected boolean canUpdateBottomCell(int x, int y) { + return y + 1 <= this.grid.length && this.getBottomCell(x, y).getTile() == null; + } + + @Override + protected Cell2D getBottomCell(int x, int y) { + if(y == this.grid.length) { + return null; + } else { + return this.getCell(x, y + 1); + } + } + + @Override + protected boolean canUpdateTopCell(int x, int y) { + return y - 1 >= 1 && this.getTopCell(x, y).getTile() == null; + } + + @Override + protected Cell2D getTopCell(int x, int y) { + if(y == 1) { + return null; + } else { + return this.getCell(x, y - 1); + } + } +} \ No newline at end of file diff --git a/src/main/java/eu/irzinfante/wfc4j/api/WaveFunctionCollapseToroidal2D.java b/src/main/java/eu/irzinfante/wfc4j/api/WaveFunctionCollapseToroidal2D.java new file mode 100644 index 0000000..87846cb --- /dev/null +++ b/src/main/java/eu/irzinfante/wfc4j/api/WaveFunctionCollapseToroidal2D.java @@ -0,0 +1,120 @@ +/** + * Library to use the Wave Function Collapse strategy for procedural generation + * Copyright (C) 2023 Iker Ruiz de Infante Gonzalez + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package eu.irzinfante.wfc4j.api; + +import eu.irzinfante.wfc4j.core.AbstractWaveFunctionCollapse2D; +import eu.irzinfante.wfc4j.exceptions.DimensionException; +import eu.irzinfante.wfc4j.exceptions.TileException; +import eu.irzinfante.wfc4j.model.Cell2D; +import eu.irzinfante.wfc4j.model.TileMap2D; + +/** + * @author irzinfante iker@irzinfante.eu + * @since 0.2.0 + */ +public class WaveFunctionCollapseToroidal2D extends AbstractWaveFunctionCollapse2D { + + /** + * Creates a 2-dimensional toroidal grid (borders are stitched) on which to apply the WFC algorithm with the specified tilemap + * + * @param tileMap The to use for the WFC algorithm + * @param gridSizeX The size of the grid in the X axis (2-dimensional) + * @param gridSizeY The size of the grid in the Y axis (2-dimensional) + * @throws TileException If tileMap is null + * @throws DimensionException If gridSizeX or gridSizeY is less than one + * + * @since 0.2.0 + */ + public WaveFunctionCollapseToroidal2D(TileMap2D tileMap, int gridSizeX, int gridSizeY) throws TileException, DimensionException { + super(tileMap, gridSizeX, gridSizeY); + } + + /** + * Creates a 2-dimensional toroidal grid (borders are stitched) on which to apply the WFC algorithm with the specified tilemap, + * with the possibility to control the random results providing a seed + * + * @param tileMap The to use for the WFC algorithm + * @param gridSizeX The size of the grid in the X axis (2-dimensional) + * @param gridSizeY The size of the grid in the Y axis (2-dimensional) + * @param seed Seed for random functions + * @throws TileException If tileMap is null + * @throws DimensionException If gridSizeX or gridSizeY is less than one + * + * @since 0.2.0 + */ + public WaveFunctionCollapseToroidal2D(TileMap2D tileMap, int gridSizeX, int gridSizeY, long seed) throws TileException, DimensionException { + super(tileMap, gridSizeX, gridSizeY, seed); + } + + @Override + protected boolean canUpdateLeftCell(int x, int y) { + return this.getLeftCell(x, y).getTile() == null; + } + + @Override + protected Cell2D getLeftCell(int x, int y) { + if(x == 1) { + return this.getCell(this.grid[y - 1].length, y); + } else { + return this.getCell(x - 1, y); + } + } + + @Override + protected boolean canUpdateRightCell(int x, int y) { + return this.getRightCell(x, y).getTile() == null; + } + + @Override + protected Cell2D getRightCell(int x, int y) { + if(x == this.grid[y - 1].length) { + return this.getCell(1, y); + } else { + return this.getCell(x + 1, y); + } + } + + @Override + protected boolean canUpdateBottomCell(int x, int y) { + return this.getBottomCell(x, y).getTile() == null; + } + + @Override + protected Cell2D getBottomCell(int x, int y) { + if(y == this.grid.length) { + return this.getCell(x, 1); + } else { + return this.getCell(x, y + 1); + } + } + + @Override + protected boolean canUpdateTopCell(int x, int y) { + return this.getTopCell(x, y).getTile() == null; + } + + @Override + protected Cell2D getTopCell(int x, int y) { + if(y == 1) { + return this.getCell(x, this.grid.length); + } else { + return this.getCell(x, y - 1); + } + } +} \ No newline at end of file diff --git a/src/main/java/eu/irzinfante/wfc4j/core/AbstractWaveFunctionCollapse2D.java b/src/main/java/eu/irzinfante/wfc4j/core/AbstractWaveFunctionCollapse2D.java new file mode 100644 index 0000000..3c92b7a --- /dev/null +++ b/src/main/java/eu/irzinfante/wfc4j/core/AbstractWaveFunctionCollapse2D.java @@ -0,0 +1,283 @@ +/** + * Library to use the Wave Function Collapse strategy for procedural generation + * Copyright (C) 2023 Iker Ruiz de Infante Gonzalez + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package eu.irzinfante.wfc4j.core; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Random; +import java.util.Set; + +import eu.irzinfante.wfc4j.enums.Side2D; +import eu.irzinfante.wfc4j.exceptions.DimensionException; +import eu.irzinfante.wfc4j.exceptions.TileException; +import eu.irzinfante.wfc4j.model.Cell2D; +import eu.irzinfante.wfc4j.model.Tile; +import eu.irzinfante.wfc4j.model.TileMap2D; + +/** + * @author irzinfante iker@irzinfante.eu + * @since 0.2.0 + */ +abstract public class AbstractWaveFunctionCollapse2D { + + protected TileMap2D tileMap; + protected Cell2D[][] grid; + protected Set> collapsableCells; + + protected Random random; + protected long deepth; + + protected AbstractWaveFunctionCollapse2D(TileMap2D tileMap, int gridSizeX, int gridSizeY) throws TileException, DimensionException { + + if(tileMap == null) { + throw new TileException("TileMap cannot be null"); + } else if(gridSizeX < 1 || gridSizeY < 1) { + throw new DimensionException("Invalid grid size"); + } + + this.tileMap = tileMap; + this.grid = (Cell2D[][]) new Cell2D[gridSizeY][gridSizeX]; + this.collapsableCells = new HashSet<>(); + + this.random = new Random(); + this.deepth = 0L; + + this.clear(); + } + + protected AbstractWaveFunctionCollapse2D(TileMap2D tileMap, int gridSizeX, int gridSizeY, long seed) throws TileException, DimensionException { + this(tileMap, gridSizeX, gridSizeY); + this.random = new Random(seed); + } + + /** + * Clears the cells of the entire grid + * + * @since 0.2.0 + */ + public void clear() { + for(int y = 1; y <= this.grid.length; y++) { + for(int x = 1; x <= this.grid[y - 1].length; x++) { + this.grid[y - 1][x - 1] = new Cell2D<>(this.tileMap.getTileSet(), x, y); + } + } + } + + /** + * Sets a cell on the grid if: the cell is not null, the cell has no value assigned + * and the entropy of the cell is not empty + * + * @param cell The cell to be set in the grid + * @throws DimensionException If the cell coordinates are out of the range of the grid + * + * @since 0.2.0 + */ + public void setCellConstraint(Cell2D cell) throws DimensionException { + + if(cell != null && cell.getTile() == null && !cell.getEntropy().isEmpty()) { + + var x = cell.getX(); + var y = cell.getY(); + if(y < 1 || y > this.grid.length) { + throw new DimensionException("Invalid cell y coordinate"); + } else if(x < 1 || x > this.grid[y - 1].length) { + throw new DimensionException("Invalid cell x coordinate"); + } + + this.grid[y - 1][x - 1] = cell; + this.collapsableCells.add(cell); + } + } + + /** + * Runs the WFC algorithm to populate the tile values for the cells of the grid + * + * @return A copy of the grid populated with tiles + * @throws TileException If exception occurs at the time of getting the adjacent tiles for some cell's value + * + * @since 0.2.0 + */ + public Cell2D[][] generate() throws TileException { + return this.generate(Long.MAX_VALUE); + } + + /** + * Runs the WFC algorithm to populate the tile values for the cells of the grid until the specified recursion level + * + * @param maxDeepth Maximum level of recursion + * @return A copy of the grid populated with tiles + * @throws TileException If exception occurs at the time of getting the adjacent tiles for some cell's value + * + * @since 0.2.0 + */ + public Cell2D[][] generate(long maxDeepth) throws TileException { + + Cell2D cell; + if(this.collapsableCells.isEmpty()) { + var y = this.random.nextInt(this.grid.length) + 1; + var x = this.random.nextInt(this.grid[y - 1].length) + 1; + cell = this.getCell(x, y); + } else { + cell = this.collapsableCellsToSortedList().get(0); + this.collapsableCells.remove(cell); + } + + if(this.collapseCell(cell, maxDeepth)) { + return Arrays.copyOf(this.grid, this.grid.length); + } else { + return null; + } + } + + protected Cell2D getCell(int x, int y) { + return this.grid[y - 1][x - 1]; + } + + protected List> collapsableCellsToSortedList() { + var collapsableCellsList = new ArrayList<>(this.collapsableCells); + Collections.shuffle(collapsableCellsList, this.random); + Collections.sort(collapsableCellsList); + return collapsableCellsList; + } + + protected boolean collapseCell(Cell2D cell, long maxDeepth) throws TileException { + this.deepth++; + + if(this.deepth <= maxDeepth) { + var entropy = cell.getEntropy(); + if(!entropy.isEmpty()) { + var options = new ArrayList<>(entropy); + Collections.shuffle(options, this.random); + + cell.setEntropy(new HashSet>()); + for(var tile : options) { + cell.setTile(tile); + + if(this.updateAdjacentCellsEntropy(cell)) { + + if(this.collapsableCells.isEmpty()) { + this.deepth--; + return true; + } + + for(var collapsableCell : this.collapsableCellsToSortedList()) { + this.collapsableCells.remove(collapsableCell); + if(this.collapseCell(collapsableCell, maxDeepth)) { + this.deepth--; + return true; + } + this.collapsableCells.add(collapsableCell); + } + } + } + + cell.setEntropy(entropy); + cell.setTile(null); + } + + this.deepth--; + return false; + } else { + this.deepth--; + return true; + } + } + + protected boolean updateAdjacentCellsEntropy(Cell2D currentCell) throws TileException { + var x = currentCell.getX(); + var y = currentCell.getY(); + + var valid = true; + + var newEntropyLeft = new HashSet>(); + if(valid && this.canUpdateLeftCell(x, y)) { + newEntropyLeft.addAll(this.getLeftCell(x, y).getReducedEntropy(this.tileMap.getAdjacents(currentCell.getTile(), Side2D.Left))); + if(newEntropyLeft.isEmpty()) { + valid = false; + } + } + + var newEntropyRight = new HashSet>(); + if(valid && this.canUpdateRightCell(x, y)) { + newEntropyRight.addAll(this.getRightCell(x, y).getReducedEntropy(this.tileMap.getAdjacents(currentCell.getTile(), Side2D.Right))); + if(newEntropyRight.isEmpty()) { + valid = false; + } + } + + var newEntropyBottom = new HashSet>(); + if(valid && this.canUpdateBottomCell(x, y)) { + newEntropyBottom.addAll(this.getBottomCell(x, y).getReducedEntropy(this.tileMap.getAdjacents(currentCell.getTile(), Side2D.Bottom))); + if(newEntropyBottom.isEmpty()) { + valid = false; + } + } + + var newEntropyTop = new HashSet>(); + if(valid && this.canUpdateTopCell(x, y)) { + newEntropyTop.addAll(this.getTopCell(x, y).getReducedEntropy(this.tileMap.getAdjacents(currentCell.getTile(), Side2D.Top))); + if(newEntropyTop.isEmpty()) { + valid = false; + } + } + + if(valid) { + if(this.canUpdateLeftCell(x, y)) { + this.getLeftCell(x, y).setEntropy(newEntropyLeft); + this.collapsableCells.add(this.getLeftCell(x, y)); + } + + if(this.canUpdateRightCell(x, y)) { + this.getRightCell(x, y).setEntropy(newEntropyRight); + this.collapsableCells.add(this.getRightCell(x, y)); + } + + if(this.canUpdateBottomCell(x, y)) { + this.getBottomCell(x, y).setEntropy(newEntropyBottom); + this.collapsableCells.add(this.getBottomCell(x, y)); + } + + if(this.canUpdateTopCell(x, y)) { + this.getTopCell(x, y).setEntropy(newEntropyTop); + this.collapsableCells.add(this.getTopCell(x, y)); + } + } + + return valid; + } + + abstract protected boolean canUpdateLeftCell(int x, int y); + + abstract protected Cell2D getLeftCell(int x, int y); + + abstract protected boolean canUpdateRightCell(int x, int y); + + abstract protected Cell2D getRightCell(int x, int y); + + abstract protected boolean canUpdateBottomCell(int x, int y); + + abstract protected Cell2D getBottomCell(int x, int y); + + abstract protected boolean canUpdateTopCell(int x, int y); + + abstract protected Cell2D getTopCell(int x, int y); +} \ No newline at end of file diff --git a/src/main/java/eu/irzinfante/wfc4j/enums/Side2D.java b/src/main/java/eu/irzinfante/wfc4j/enums/Side2D.java new file mode 100644 index 0000000..b01f43f --- /dev/null +++ b/src/main/java/eu/irzinfante/wfc4j/enums/Side2D.java @@ -0,0 +1,40 @@ +/** + * Library to use the Wave Function Collapse strategy for procedural generation + * Copyright (C) 2023 Iker Ruiz de Infante Gonzalez + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package eu.irzinfante.wfc4j.enums; + +/** + * @author irzinfante iker@irzinfante.eu + * @since 0.2.0 + */ +public enum Side2D { + Left(0), + Right(1), + Bottom(2), + Top(3); + + private final int value; + + private Side2D(int value) { + this.value = value; + } + + public int getValue() { + return value; + } +} \ No newline at end of file diff --git a/src/main/java/eu/irzinfante/wfc4j/model/Cell2D.java b/src/main/java/eu/irzinfante/wfc4j/model/Cell2D.java new file mode 100644 index 0000000..22eb580 --- /dev/null +++ b/src/main/java/eu/irzinfante/wfc4j/model/Cell2D.java @@ -0,0 +1,94 @@ +/** + * Library to use the Wave Function Collapse strategy for procedural generation + * Copyright (C) 2023 Iker Ruiz de Infante Gonzalez + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package eu.irzinfante.wfc4j.model; + +import java.util.Set; + +import java.util.HashSet; + +/** + * @author irzinfante iker@irzinfante.eu + * @since 0.2.0 + */ +public class Cell2D implements Comparable> { + + private Set> entropy; + private Tile tile; + private int x; + private int y; + + /** + * Creates a 2-dimensional cell with the given entropy and coordinates + * + * @param entropy The default entropy (all possible tile values) for the cell + * @param x The X component of the cell's coordinates in a 2-dimensional grid + * @param y The Y component of the cell's coordinates in a 2-dimensional grid + * + * @since 0.2.0 + */ + public Cell2D(Set> entropy, int x, int y) { + this.entropy = entropy; + this.tile = null; + this.x = x; + this.y = y; + } + + /** + * Returns the set intersection between the cell's current entropy and the intersectant set of tiles + * + * @param intersectant The set of tiles to be intersected with the cell's current entropy + * @return The set intersection between the current cell entropy and the intersectant set + * + * @since 0.2.0 + */ + public Set> getReducedEntropy(Set> intersectant) { + var reducedEntropy = new HashSet<>(this.entropy); + reducedEntropy.retainAll(intersectant); + return reducedEntropy; + } + + public Set> getEntropy() { + return this.entropy; + } + + public void setEntropy(Set> entropy) { + this.entropy = entropy; + } + + public Tile getTile() { + return this.tile; + } + + public void setTile(Tile tile) { + this.tile = tile; + } + + public int getX() { + return this.x; + } + + public int getY() { + return this.y; + } + + @Override + public int compareTo(Cell2D other) { + return this.entropy.size() - other.entropy.size(); + } +} \ No newline at end of file diff --git a/src/main/java/eu/irzinfante/wfc4j/model/TileMap2D.java b/src/main/java/eu/irzinfante/wfc4j/model/TileMap2D.java new file mode 100644 index 0000000..96b1fd3 --- /dev/null +++ b/src/main/java/eu/irzinfante/wfc4j/model/TileMap2D.java @@ -0,0 +1,125 @@ +/** + * Library to use the Wave Function Collapse strategy for procedural generation + * Copyright (C) 2023 Iker Ruiz de Infante Gonzalez + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package eu.irzinfante.wfc4j.model; + +import java.util.Set; +import java.util.HashSet; +import java.util.Map; +import java.util.HashMap; + +import eu.irzinfante.wfc4j.enums.Side2D; +import eu.irzinfante.wfc4j.exceptions.TileException; + +/** + * @author irzinfante iker@irzinfante.eu + * @since 0.2.0 + */ +public class TileMap2D { + + private Set> tileSet; + private Map, Set>[]> adjacents; + + /** + * Creates a 2-dimensional tilemap with the given tileset + * + * @param tileSet The set of tiles (i.e. tileset) for the tilemap + * @throws TileException If tileSet is empty + * + * @since 0.2.0 + */ + public TileMap2D(Set> tileSet) throws TileException { + + if(tileSet.isEmpty()) { + throw new TileException("Set of tiles must be non-empty"); + } + + this.tileSet = tileSet; + this.adjacents = new HashMap<>(); + + tileSet.forEach(tile -> { + this.adjacents.put(tile, (Set>[]) new HashSet[4]); + }); + } + + /** + * Get the possible adjacent tiles to a specific side of a given tile + * + * @param tile The given tile for which to get the possible adjacent tiles + * @param side The side of the given tile from which to get the possible adjacent tiles + * @return Set of tiles that can be adjacent to the provided tile from the selected side + * @throws TileException If the given tile is not in present in the tilemap's tileset + * + * @since 0.2.0 + */ + public Set> getAdjacents(Tile tile, Side2D side) throws TileException { + + if(!this.tileSet.contains(tile)) { + throw new TileException("Tile must be present in TileMap"); + } + + return this.adjacents.get(tile)[side.getValue()]; + } + + /** + * Set the possible adjacent tiles to a specific side of a given tile + * + * @param tile The given tile for which to set the possible adjacent tiles + * @param side The side of the given tile for which to set the possible adjacent tiles + * @param adjacents The set of tiles to be set as the possible adjacent tiles for the given tile + * @throws TileException If the given tile or any of the potential adjacent tiles are not in present in the tilemap's tileset + * + * @since 0.2.0 + */ + public void setAdjacents(Tile tile, Side2D side, Set> adjacents) throws TileException { + + if(!this.tileSet.contains(tile)) { + throw new TileException("Tile must be present in TileMap"); + } else if(!this.tileSet.containsAll(adjacents)) { + throw new TileException("All adjacent tiles must be present in TileMap"); + } + + this.adjacents.get(tile)[side.getValue()] = adjacents; + } + + /** + * Add a single tile to the possible adjacent tiles to a specific side of a given tile + * + * @param tile The given tile for which to add the possible adjacent tile + * @param side The side of the given tile for which to add the possible adjacent tile + * @param adjacent A single tile to be added to the possible adjacent tiles for the given tile + * @return true if the adjacent tile to be added was not already contained in the set of adjacent sets + * @throws TileException If the given tile or the potential adjacent tile to be added are not in present in the tilemap's tileset + * + * @since 0.2.0 + */ + public boolean addAdjacent(Tile tile, Side2D side, Tile adjacent) throws TileException { + + if(!this.tileSet.contains(tile)) { + throw new TileException("Tile must be present in TileMap"); + } else if(!this.tileSet.contains(adjacent)) { + throw new TileException("Adjacent tile must be present in TileMap"); + } + + return this.adjacents.get(tile)[side.getValue()].add(adjacent); + } + + public Set> getTileSet() { + return this.tileSet; + } +} \ No newline at end of file diff --git a/src/main/java/eu/irzinfante/wfc4j/util/WFCUtils.java b/src/main/java/eu/irzinfante/wfc4j/util/WFCUtils.java index 298c45c..3312ed2 100644 --- a/src/main/java/eu/irzinfante/wfc4j/util/WFCUtils.java +++ b/src/main/java/eu/irzinfante/wfc4j/util/WFCUtils.java @@ -1,9 +1,11 @@ package eu.irzinfante.wfc4j.util; import eu.irzinfante.wfc4j.model.Cell1D; +import eu.irzinfante.wfc4j.model.Cell2D; /** * @author irzinfante iker@irzinfante.eu + * @version 0.2.0 * @since 0.1.0 */ public final class WFCUtils { @@ -40,4 +42,45 @@ public static String WFC1DToString(Cell1D[] grid) { return topBorder.toString() + "\n" + cellsRepr + "\n" + bottomBorder.toString(); } + + /** + * Gets the String representation of a 2-dimensional grid + * + * @param grid 2-dimensional grid to be represented as a String + * @return String representation of grid + * @since 0.2.0 + */ + public static String WFC2DToString(Cell2D[][] grid) { + var gridBuilder = new StringBuilder(); + + var bottomBorderBuilder = new StringBuilder("└"); + for(int y = 0; y < grid.length; y++) { + + var topBorderBuilder = new StringBuilder(y == 0 ? "┌" : "├"); + var rowBuilder = new StringBuilder("│"); + + for(int x = 0; x < grid[y].length; x++) { + var cellTile = grid[y][x].getTile(); + var value = cellTile == null ? new String(" ") : cellTile.getValue().toString(); + + topBorderBuilder.append("─".repeat(value.length())); + rowBuilder.append(value).append("│"); + + if (y == 0) { + topBorderBuilder.append(x == grid[y].length - 1 ? "┐" : "┬"); + } else { + topBorderBuilder.append(x == grid[y].length - 1 ? "┤" : "┼"); + if (y == grid.length - 1) { + bottomBorderBuilder.append("─".repeat(value.length())).append(x == grid[y].length - 1 ? "┘" : "┴"); + } + } + } + + gridBuilder.append(topBorderBuilder).append("\n"); + gridBuilder.append(rowBuilder).append("\n"); + } + gridBuilder.append(bottomBorderBuilder); + + return gridBuilder.toString(); + } } \ No newline at end of file diff --git a/src/test/java/eu/irzinfante/wfc4j/test/TestWFCEuclidean2D.java b/src/test/java/eu/irzinfante/wfc4j/test/TestWFCEuclidean2D.java new file mode 100644 index 0000000..828fe7f --- /dev/null +++ b/src/test/java/eu/irzinfante/wfc4j/test/TestWFCEuclidean2D.java @@ -0,0 +1,80 @@ +package eu.irzinfante.wfc4j.test; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.HashSet; + +import org.junit.Test; + +import eu.irzinfante.wfc4j.api.WaveFunctionCollapseEuclidean2D; +import eu.irzinfante.wfc4j.enums.Side2D; +import eu.irzinfante.wfc4j.exceptions.DimensionException; +import eu.irzinfante.wfc4j.exceptions.TileException; +import eu.irzinfante.wfc4j.model.Cell2D; +import eu.irzinfante.wfc4j.model.Tile; +import eu.irzinfante.wfc4j.model.TileMap2D; +import eu.irzinfante.wfc4j.util.WFCUtils; + +public class TestWFCEuclidean2D { + + @Test + public void testStringTile() throws TileException, DimensionException { + + /* + * Tile | Left | Right | Bottom | Top | + * NE | NW, SW | NW, SW | SE, SW | SE, SW | + * NW | NE, SE | NE, SE | SE, SW | SE, SW | + * SE | NW, SW | NW, SW | NE, NW | NE, NW | + * SW | NE, SE | NE, SE | NE, NW | NE, NW | + */ + + Tile NE = new Tile<>("NE"), NW = new Tile<>("NW"), SE = new Tile<>("SE"), SW = new Tile<>("SW"); + + var tileSet = new HashSet>(); + tileSet.add(NE); tileSet.add(NW); tileSet.add(SE); tileSet.add(SW); + + var adjacentNWSW = new HashSet>(); + adjacentNWSW.add(NW); adjacentNWSW.add(SW); + + var adjacentSESW = new HashSet>(); + adjacentSESW.add(SE); adjacentSESW.add(SW); + + var adjacentNESE = new HashSet>(); + adjacentNESE.add(NE); adjacentNESE.add(SE); + + var adjacentNENW = new HashSet>(); + adjacentNENW.add(NE); adjacentNENW.add(NW); + + var tileMap = new TileMap2D<>(tileSet); + + tileMap.setAdjacents(NE, Side2D.Left, adjacentNWSW); tileMap.setAdjacents(NE, Side2D.Right, adjacentNWSW); + tileMap.setAdjacents(NE, Side2D.Bottom, adjacentSESW); tileMap.setAdjacents(NE, Side2D.Top, adjacentSESW); + + tileMap.setAdjacents(NW, Side2D.Left, adjacentNESE); tileMap.setAdjacents(NW, Side2D.Right, adjacentNESE); + tileMap.setAdjacents(NW, Side2D.Bottom, adjacentSESW); tileMap.setAdjacents(NW, Side2D.Top, adjacentSESW); + + tileMap.setAdjacents(SE, Side2D.Left, adjacentNWSW); tileMap.setAdjacents(SE, Side2D.Right, adjacentNWSW); + tileMap.setAdjacents(SE, Side2D.Bottom, adjacentNENW); tileMap.setAdjacents(SE, Side2D.Top, adjacentNENW); + + tileMap.setAdjacents(SW, Side2D.Left, adjacentNESE); tileMap.setAdjacents(SW, Side2D.Right, adjacentNESE); + tileMap.setAdjacents(SW, Side2D.Bottom, adjacentNENW); tileMap.setAdjacents(SW, Side2D.Top, adjacentNENW); + + int gridSizeX = 8, gridSizeY = 6; + var WFC = new WaveFunctionCollapseEuclidean2D(tileMap, gridSizeX, gridSizeY); + + WFC.clear(); + var result = WFC.generate(); + + System.out.println(WFCUtils.WFC2DToString(result)); + + WFC.clear(); + WFC.setCellConstraint(new Cell2D<>(new HashSet<>(Arrays.asList(SE)), 4, 3)); + WFC.setCellConstraint(new Cell2D<>(new HashSet<>(Arrays.asList(NW)), 5, 4)); + result = WFC.generate(); + + System.out.println(WFCUtils.WFC2DToString(result)); + assertEquals("Unexpected tile", result[2][4].getTile(), SW); + assertEquals("Unexpected tile", result[3][3].getTile(), NE); + } +} \ No newline at end of file diff --git a/src/test/java/eu/irzinfante/wfc4j/test/TestWFCToroidal2D.java b/src/test/java/eu/irzinfante/wfc4j/test/TestWFCToroidal2D.java new file mode 100644 index 0000000..b388ab8 --- /dev/null +++ b/src/test/java/eu/irzinfante/wfc4j/test/TestWFCToroidal2D.java @@ -0,0 +1,103 @@ +package eu.irzinfante.wfc4j.test; + +import java.util.HashSet; + +import org.junit.Test; + +import eu.irzinfante.wfc4j.api.WaveFunctionCollapseToroidal2D; +import eu.irzinfante.wfc4j.enums.Side2D; +import eu.irzinfante.wfc4j.exceptions.DimensionException; +import eu.irzinfante.wfc4j.exceptions.TileException; +import eu.irzinfante.wfc4j.model.Tile; +import eu.irzinfante.wfc4j.model.TileMap2D; +import eu.irzinfante.wfc4j.util.WFCUtils; + +public class TestWFCToroidal2D { + + @Test + public void testStringTile() throws TileException, DimensionException { + + final String LR = "LR", LB = "LB", LT = "LT", RB = "RB", RT = "RT", BT = "BT"; + final var components = new String[] {LR, LB, LT, RB, RT, BT}; + + var tileSet = new HashSet>(); + for(var first : components) { + for(var second : components) { + tileSet.add(new Tile<>(first + second)); + } + } + + var tileMap = new TileMap2D<>(tileSet); + + for(var tile : tileSet) { + var tileFirstLeft = tile.getValue().substring(0, 2).contains("L"); + var tileSecondLeft = tile.getValue().substring(2, 4).contains("L"); + var leftAdjacents = new HashSet>(); + + var tileFirstRight = tile.getValue().substring(0, 2).contains("R"); + var tileSecondRight = tile.getValue().substring(2, 4).contains("R"); + var rightAdjacents = new HashSet>(); + + var tileFirstBottom = tile.getValue().substring(0, 2).contains("B"); + var tileSecondBottom = tile.getValue().substring(2, 4).contains("B"); + var bottomAdjacents = new HashSet>(); + + var tileFirstTop = tile.getValue().substring(0, 2).contains("T"); + var tileSecondTop = tile.getValue().substring(2, 4).contains("T"); + var topAdjacents = new HashSet>(); + + for(var adjacent : tileSet) { + var adjacentFirstLeft = adjacent.getValue().substring(0, 2).contains("L"); + var adjacentSecondLeft = adjacent.getValue().substring(2, 4).contains("L"); + if( (tileFirstRight && adjacentFirstLeft && tileSecondRight && adjacentSecondLeft) || + (tileFirstRight && adjacentFirstLeft && !tileSecondRight && !adjacentSecondLeft) || + (!tileFirstRight && !adjacentFirstLeft && tileSecondRight && adjacentSecondLeft) || + (!tileFirstRight && !adjacentFirstLeft && !tileSecondRight && !adjacentSecondLeft) + ) { + rightAdjacents.add(adjacent); + } + + var adjacentFirstRight = adjacent.getValue().substring(0, 2).contains("R"); + var adjacentSecondRight = adjacent.getValue().substring(2, 4).contains("R"); + if( (tileFirstLeft && adjacentFirstRight && tileSecondLeft && adjacentSecondRight) || + (tileFirstLeft && adjacentFirstRight && !tileSecondLeft && !adjacentSecondRight) || + (!tileFirstLeft && !adjacentFirstRight && tileSecondLeft && adjacentSecondRight) || + (!tileFirstLeft && !adjacentFirstRight && !tileSecondLeft && !adjacentSecondRight) + ) { + leftAdjacents.add(adjacent); + } + + var adjacentFirstTop = adjacent.getValue().substring(0, 2).contains("T"); + var adjacentSecondTop = adjacent.getValue().substring(2, 4).contains("T"); + if( (tileFirstBottom && adjacentFirstTop && tileSecondBottom && adjacentSecondTop) || + (tileFirstBottom && adjacentFirstTop && !tileSecondBottom && !adjacentSecondTop) || + (!tileFirstBottom && !adjacentFirstTop && tileSecondBottom && adjacentSecondTop) || + (!tileFirstBottom && !adjacentFirstTop && !tileSecondBottom && !adjacentSecondTop) + ) { + bottomAdjacents.add(adjacent); + } + + var adjacentFirstBottom = adjacent.getValue().substring(0, 2).contains("B"); + var adjacentSecondBottom = adjacent.getValue().substring(2, 4).contains("B"); + if( (tileFirstTop && adjacentFirstBottom && tileSecondTop && adjacentSecondBottom) || + (tileFirstTop && adjacentFirstBottom && !tileSecondTop && !adjacentSecondBottom) || + (!tileFirstTop && !adjacentFirstBottom && tileSecondTop && adjacentSecondBottom) || + (!tileFirstTop && !adjacentFirstBottom && !tileSecondTop && !adjacentSecondBottom) + ) { + topAdjacents.add(adjacent); + } + } + + tileMap.setAdjacents(tile, Side2D.Left, leftAdjacents); + tileMap.setAdjacents(tile, Side2D.Right, rightAdjacents); + tileMap.setAdjacents(tile, Side2D.Bottom, bottomAdjacents); + tileMap.setAdjacents(tile, Side2D.Top, topAdjacents); + } + + int gridSizeX = 6, gridSizeY = 6; + var WFC = new WaveFunctionCollapseToroidal2D(tileMap, gridSizeX, gridSizeY); + + var result = WFC.generate(); + System.out.println(WFCUtils.WFC2DToString(result)); + } +} \ No newline at end of file