├── README.rst ├── canonical_3.eps ├── clamshell.eps └── rendered ├── canonical3.png ├── clamshell.png ├── clamshell1.png └── closet.jpg /README.rst: -------------------------------------------------------------------------------- 1 | PostScript Fractals 2 | =================== 3 | 4 | There have never been more consumer-accessible CNC-like machines: 5 | 6 | - Laser cutters / engravers 7 | - Vinyl cutters 8 | - 3D printers 9 | - CNC routers 10 | - Plasma cutters (a bit of a stretch, but check your local `makerspace `_) 11 | 12 | Many of these machines work best with vector graphics, and there are plenty of vector graphic programs for drawing things manually. But what if you want to create something intricate and repetitive, like a fractal? 13 | 14 | Enter `PostScript `_, a decades-old stack-based extra-hyphenated programming language that's perfect for defining recursive fractals. 15 | 16 | For example, take clamshell.eps. If you change the last line to be:: 17 | 18 | 500 1 DARK_TRAPAZOID 19 | 20 | ... and rendering it to a PDF (on \*nix anyways):: 21 | 22 | ps2pdf clamshell.eps clamshell1.pdf 23 | 24 | ... you get a small fractal: 25 | 26 | .. image:: http://raw.github.com/steiza/postscript_fractals/master/rendered/clamshell1.png 27 | 28 | But if you crank up the recursion by changing the last line to be:: 29 | 30 | 500 5 DARK_TRAPAZOID 31 | 32 | ... you get something much more complex: 33 | 34 | .. image:: http://raw.github.com/steiza/postscript_fractals/master/rendered/clamshell.png 35 | 36 | More correctly, these are actually `aperiodic tilings `_ there are built using `substitution rules `_, and `there are a lot of them `_. 37 | 38 | .. image:: http://raw.github.com/steiza/postscript_fractals/master/rendered/canonical3.png 39 | 40 | So download this repo, make some fractals, and put them on stuff! 41 | 42 | .. image:: http://raw.github.com/steiza/postscript_fractals/master/rendered/closet.jpg 43 | -------------------------------------------------------------------------------- /canonical_3.eps: -------------------------------------------------------------------------------- 1 | %!PS-Adobe EPSF-3.0 2 | %%BoundingBox: 0 0 850 850 3 | 4 | /angle 1 2 atan def % ~26.5 degrees 5 | /expansion_factor 2 5 sqrt add def 6 | 7 | /SQUARE_1 { 8 | 4 dict begin 9 | /reflect exch def 10 | /level exch def 11 | /len exch def 12 | /short_len len expansion_factor div def 13 | 14 | level 0 gt { 15 | gsave 16 | 17 | % Create center square 18 | gsave 19 | 90 2 angle mul sub reflect mul neg rotate 20 | short_len reflect mul 0 translate 21 | 90 angle sub reflect mul rotate 22 | short_len reflect mul 0 translate 23 | 90 reflect mul neg rotate 24 | short_len reflect mul 0 translate 25 | -180 2 angle mul add reflect mul rotate 26 | short_len level 1 sub reflect neg SQUARE_1 27 | grestore 28 | 29 | 4 { 30 | gsave 31 | short_len level 1 sub reflect DART 32 | -90 2 angle mul add reflect mul rotate 33 | short_len reflect mul 0 translate 34 | 35 | % XXX - this causes problems in SQUARE_2 level 2 36 | %gsave 37 | %-90 angle add reflect mul rotate 38 | %short_len level 1 sub reflect neg DIAMOND_2 39 | %grestore 40 | 41 | 90 angle sub reflect mul rotate 42 | short_len reflect mul 0 translate 43 | -90 angle sub reflect mul rotate 44 | short_len level 1 sub reflect SQUARE_2 45 | angle reflect mul rotate 46 | short_len reflect mul 0 translate 47 | angle neg reflect mul rotate 48 | short_len level 1 sub reflect DIAMOND_1 49 | grestore 50 | 51 | angle reflect mul rotate 52 | len reflect mul 0 translate 53 | angle 90 add neg reflect mul rotate 54 | } repeat 55 | 56 | grestore 57 | } { 58 | newpath 59 | 0 0 moveto 60 | angle reflect mul rotate 61 | len reflect mul 0 rlineto 62 | 0 len neg rlineto 63 | len reflect mul neg 0 rlineto 64 | 0 len rlineto 65 | angle reflect mul neg rotate 66 | closepath 67 | 68 | 0 setgray 69 | 0.5 setlinewidth 70 | stroke 71 | } ifelse 72 | 73 | end 74 | } def 75 | 76 | /SQUARE_2 { 77 | 3 dict begin 78 | /reflect exch def 79 | /level exch def 80 | /len exch def 81 | /short_len len expansion_factor div def 82 | 83 | level 0 gt { 84 | gsave 85 | short_len level 1 sub reflect DART 86 | 2 angle mul reflect mul rotate 87 | short_len reflect mul 0 translate 88 | angle reflect mul rotate 89 | short_len level 1 sub -1 reflect mul SQUARE_3 90 | angle 2 mul reflect mul neg rotate 91 | short_len reflect mul 0 translate 92 | -90 angle sub reflect mul rotate 93 | short_len level 1 sub reflect DIAMOND_1 94 | 2 angle mul reflect mul rotate 95 | short_len reflect mul 0 translate 96 | -90 angle add reflect mul rotate 97 | 98 | gsave 99 | 180 angle sub reflect mul rotate 100 | short_len reflect mul 0 translate 101 | 90 reflect mul rotate 102 | short_len reflect mul 0 translate 103 | angle 90 sub reflect mul rotate 104 | short_len level 1 sub -1 reflect mul SQUARE_2 105 | grestore 106 | 107 | 90 angle 3 mul sub reflect mul rotate 108 | short_len level 1 sub reflect DART 109 | 180 reflect mul rotate 110 | short_len level 1 sub reflect DART 111 | 112 | gsave 113 | -90 angle add reflect mul rotate 114 | short_len reflect mul 0 translate 115 | 90 2 angle mul add reflect mul rotate 116 | short_len level 1 sub reflect neg DIAMOND_2 117 | grestore 118 | 119 | -90 reflect mul rotate 120 | 121 | gsave 122 | angle reflect mul rotate 123 | short_len reflect mul 0 translate 124 | -90 reflect mul rotate 125 | short_len reflect mul 0 translate 126 | -90 angle sub reflect mul rotate 127 | short_len level 1 sub reflect SQUARE_2 128 | grestore 129 | 130 | -90 angle add reflect mul rotate 131 | short_len reflect mul 0 translate 132 | 90 2 angle mul add reflect mul rotate 133 | short_len level 1 sub reflect neg SQUARE_1 134 | 180 3 angle mul sub reflect mul rotate 135 | short_len level 1 sub reflect DIAMOND_1 136 | 2 angle mul reflect mul rotate 137 | short_len reflect mul 0 translate 138 | -2 angle mul reflect mul rotate 139 | short_len level 1 sub reflect SQUARE_3 140 | 90 reflect mul rotate 141 | short_len level 1 sub reflect DIAMOND_2 142 | 143 | gsave 144 | angle 90 sub reflect mul rotate 145 | short_len reflect mul 0 translate 146 | 90 2 angle mul add reflect mul rotate 147 | 148 | gsave 149 | 180 angle sub reflect mul rotate 150 | short_len reflect mul 0 translate 151 | 90 reflect mul rotate 152 | short_len reflect mul 0 translate 153 | angle 90 sub reflect mul rotate 154 | short_len level 1 sub reflect neg SQUARE_2 155 | grestore 156 | 157 | angle reflect mul neg rotate 158 | short_len reflect mul 0 translate 159 | angle reflect mul rotate 160 | short_len level 1 sub reflect neg SQUARE_2 161 | grestore 162 | 163 | 90 2 angle mul reflect mul rotate 164 | short_len reflect mul 0 translate 165 | 90 2 angle mul sub reflect mul rotate 166 | short_len level 1 sub reflect DIAMOND_1 167 | -90 reflect mul rotate 168 | short_len level 1 sub reflect SQUARE_1 169 | 170 | gsave 171 | angle 90 sub reflect mul rotate 172 | short_len reflect mul 0 translate 173 | 174 | gsave 175 | angle reflect mul rotate 176 | short_len reflect mul 0 translate 177 | 180 2 angle mul sub reflect mul rotate 178 | short_len level 1 sub reflect DIAMOND_1 179 | grestore 180 | 181 | 90 reflect mul rotate 182 | short_len reflect mul 0 translate 183 | 90 2 angle mul add reflect mul rotate 184 | short_len level 1 sub reflect neg SQUARE_3 185 | grestore 186 | 187 | gsave 188 | angle reflect mul rotate 189 | short_len reflect mul 0 translate 190 | angle reflect mul neg rotate 191 | short_len level 1 sub reflect DIAMOND_1 192 | 193 | gsave 194 | 90 angle 2 mul add reflect mul rotate 195 | short_len reflect mul 0 translate 196 | angle reflect mul rotate 197 | short_len level 1 sub reflect neg SQUARE_2 198 | grestore 199 | 200 | 2 angle mul reflect mul rotate 201 | short_len reflect mul 0 translate 202 | -90 angle add reflect mul rotate 203 | 204 | 180 angle sub reflect mul rotate 205 | short_len reflect mul 0 translate 206 | 90 2 angle mul sub reflect mul rotate 207 | short_len level 1 sub reflect DIAMOND_2 208 | grestore 209 | 210 | 90 angle 2 mul add reflect mul rotate 211 | short_len reflect mul 0 translate 212 | 90 angle 2 mul sub reflect mul rotate 213 | short_len level 1 sub reflect DIAMOND_1 214 | 215 | -90 angle add reflect mul rotate 216 | short_len reflect mul 0 translate 217 | angle neg reflect mul rotate 218 | short_len level 1 sub reflect DART 219 | -90 reflect mul rotate 220 | 221 | gsave 222 | angle reflect mul rotate 223 | short_len reflect mul 0 translate 224 | -90 reflect mul rotate 225 | short_len reflect mul 0 translate 226 | -90 angle sub reflect mul rotate 227 | short_len level 1 sub reflect SQUARE_2 228 | grestore 229 | 230 | gsave 231 | 180 2 angle mul add reflect mul rotate 232 | short_len reflect mul 0 translate 233 | angle reflect mul rotate 234 | short_len level 1 sub reflect neg SQUARE_2 235 | grestore 236 | 237 | 2 angle mul reflect mul rotate 238 | short_len reflect mul 0 translate 239 | 90 reflect mul rotate 240 | short_len reflect mul 0 translate 241 | -90 angle add reflect mul rotate 242 | short_len level 1 sub reflect neg SQUARE_2 243 | grestore 244 | } { 245 | gsave 246 | 247 | newpath 248 | 0 0 moveto 249 | angle reflect mul rotate 250 | 251 | 0 -1 len mul rlineto 252 | 90 reflect mul rotate 253 | 0 -1 len mul rlineto 254 | 90 reflect mul rotate 255 | 0 -1 len mul rlineto 256 | 90 reflect mul rotate 257 | 0 -1 len mul rlineto 258 | 90 reflect mul rotate 259 | 260 | closepath 261 | 262 | 0 setgray 263 | 0.5 setlinewidth 264 | stroke 265 | 266 | grestore 267 | 268 | % Orientation mark for testing 269 | %gsave 270 | 271 | %angle reflect mul rotate 272 | %reflect 0.8 mul len mul -0.93 len mul translate 273 | %angle reflect mul rotate 274 | 275 | %newpath 276 | %0 0 moveto 277 | %0 0.15 len mul rlineto 278 | %90 rotate 279 | %0 0.15 reflect mul len mul rlineto 280 | %90 rotate 281 | %0 0.15 len mul rlineto 282 | %90 rotate 283 | %0 0.15 reflect mul len mul rlineto 284 | %90 rotate 285 | 286 | %closepath 287 | %0 setgray 288 | %fill 289 | 290 | %grestore 291 | } ifelse 292 | 293 | end 294 | } def 295 | 296 | /SQUARE_3 { 297 | 3 dict begin 298 | /reflect exch def 299 | /level exch def 300 | /len exch def 301 | /short_len len expansion_factor div def 302 | 303 | level 0 gt { 304 | gsave 305 | short_len level 1 sub reflect DART 306 | 2 angle mul reflect mul rotate 307 | short_len reflect mul 0 translate 308 | angle reflect mul rotate 309 | short_len level 1 sub reflect neg SQUARE_3 310 | -2 angle mul reflect mul rotate 311 | short_len reflect mul 0 translate 312 | -90 angle sub reflect mul rotate 313 | short_len level 1 sub reflect DIAMOND_1 314 | 315 | gsave 316 | 90 2 angle mul add reflect mul rotate 317 | short_len reflect mul 0 translate 318 | angle reflect mul rotate 319 | short_len level 1 sub reflect neg SQUARE_2 320 | grestore 321 | 322 | 2 angle mul reflect mul rotate 323 | short_len reflect mul 0 translate 324 | -2 angle mul reflect mul rotate 325 | short_len level 1 sub reflect DART 326 | 180 reflect mul rotate 327 | short_len level 1 sub reflect DART 328 | -90 angle add reflect mul rotate 329 | short_len reflect mul 0 translate 330 | 90 2 angle mul add reflect mul rotate 331 | short_len level 1 sub reflect neg DIAMOND_2 332 | 180 2 angle mul sub reflect mul rotate 333 | short_len reflect mul 0 translate 334 | -180 angle 2 mul add reflect mul rotate 335 | short_len level 1 sub reflect neg SQUARE_2 336 | 90 3 angle mul sub reflect mul rotate 337 | short_len level 1 sub reflect SQUARE_2 338 | 90 2 angle mul add reflect mul rotate 339 | short_len reflect mul 0 translate 340 | 90 2 angle mul sub reflect mul rotate 341 | short_len level 1 sub reflect DIAMOND_1 342 | -90 reflect mul rotate 343 | short_len level 1 sub reflect SQUARE_1 344 | angle reflect mul rotate 345 | short_len reflect mul 0 translate 346 | -180 2 angle mul add reflect mul rotate 347 | short_len level 1 sub reflect neg SQUARE_3 348 | -90 reflect mul rotate 349 | short_len level 1 sub reflect neg DIAMOND_2 350 | 180 2 angle mul sub reflect mul rotate 351 | short_len reflect mul 0 translate 352 | 90 2 angle mul add reflect mul rotate 353 | short_len level 1 sub reflect neg DIAMOND_2 354 | 90 reflect mul rotate 355 | short_len level 1 sub reflect neg SQUARE_2 356 | 180 angle sub reflect mul rotate 357 | short_len reflect mul 0 translate 358 | 90 2 angle mul sub reflect mul rotate 359 | short_len level 1 sub reflect DIAMOND_1 360 | -90 angle add reflect mul rotate 361 | 362 | gsave 363 | short_len reflect mul 0 translate 364 | -180 2 angle mul add reflect mul rotate 365 | short_len level 1 sub reflect neg SQUARE_3 366 | grestore 367 | 368 | -90 reflect mul rotate 369 | short_len reflect mul 0 translate 370 | 90 2 angle mul add reflect mul rotate 371 | short_len level 1 sub reflect neg SQUARE_1 372 | 90 3 angle mul sub reflect mul rotate 373 | short_len level 1 sub reflect SQUARE_2 374 | -180 2 angle mul add reflect mul rotate 375 | short_len reflect mul 0 translate 376 | 90 2 angle mul sub reflect mul rotate 377 | short_len level 1 sub reflect SQUARE_3 378 | 379 | gsave 380 | -180 2 angle mul add reflect mul rotate 381 | short_len reflect mul 0 translate 382 | 180 2 angle mul sub reflect mul rotate 383 | short_len level 1 sub reflect DIAMOND_1 384 | 90 2 angle mul add reflect mul rotate 385 | short_len reflect mul 0 translate 386 | 180 2 angle mul sub reflect mul rotate 387 | short_len level 1 sub reflect DIAMOND_1 388 | grestore 389 | 390 | 90 reflect mul rotate 391 | short_len level 1 sub reflect DIAMOND_2 392 | -90 angle add reflect mul rotate 393 | short_len reflect mul 0 translate 394 | 180 angle sub reflect mul rotate 395 | short_len level 1 sub reflect DART 396 | -180 2 angle mul add reflect mul rotate 397 | short_len reflect mul 0 translate 398 | 180 2 angle mul sub reflect mul rotate 399 | short_len level 1 sub reflect DIAMOND_1 400 | 401 | gsave 402 | 90 2 angle mul add reflect mul rotate 403 | short_len reflect mul 0 translate 404 | angle reflect mul rotate 405 | short_len level 1 sub reflect neg SQUARE_2 406 | grestore 407 | 408 | -90 angle add reflect mul rotate 409 | short_len reflect mul 0 translate 410 | -180 2 angle mul add reflect mul rotate 411 | short_len level 1 sub reflect neg SQUARE_3 412 | 413 | grestore 414 | } { 415 | gsave 416 | 417 | newpath 418 | 0 0 moveto 419 | angle reflect mul rotate 420 | 421 | 0 -1 len mul rlineto 422 | 90 reflect mul rotate 423 | 0 -1 len mul rlineto 424 | 90 reflect mul rotate 425 | 0 -1 len mul rlineto 426 | 90 reflect mul rotate 427 | 0 -1 len mul rlineto 428 | 90 reflect mul rotate 429 | 430 | closepath 431 | 432 | 0 setgray 433 | 0.5 setlinewidth 434 | stroke 435 | 436 | grestore 437 | 438 | % Orientation mark for testing 439 | %gsave 440 | 441 | %angle reflect mul rotate 442 | %0.65 len mul reflect mul 0.5 len mul neg translate 443 | 444 | %newpath 445 | %0 0 moveto 446 | %2 angle mul reflect mul neg rotate 447 | %0.15 len mul reflect mul 0 rlineto 448 | %90 rotate 449 | %0.30 len mul 0 rlineto 450 | %90 rotate 451 | %0.15 len mul reflect mul 0 rlineto 452 | %90 rotate 453 | %0.30 len mul 0 rlineto 454 | %90 rotate 455 | %closepath 456 | %0 setgray 457 | %fill 458 | 459 | %grestore 460 | } ifelse 461 | 462 | end 463 | } def 464 | 465 | /DIAMOND_1 { 466 | 4 dict begin 467 | /reflect exch def 468 | /level exch def 469 | /len exch def 470 | /short_len len expansion_factor div def 471 | 472 | level 0 gt { 473 | gsave 474 | 475 | short_len level 1 sub reflect DART 476 | -90 2 angle mul add reflect mul rotate 477 | short_len reflect mul 0 translate 478 | -90 angle add reflect mul rotate 479 | short_len level 1 sub reflect neg DIAMOND_2 480 | 180 2 angle mul sub reflect mul rotate 481 | short_len reflect mul 0 translate 482 | -90 angle sub reflect mul rotate 483 | short_len level 1 sub reflect SQUARE_2 484 | -90 3 angle mul add reflect mul rotate 485 | short_len level 1 sub reflect neg SQUARE_2 486 | angle reflect mul rotate 487 | 90 3 angle mul sub reflect mul rotate 488 | short_len reflect mul 0 translate 489 | 90 2 angle mul add reflect mul rotate 490 | short_len level 1 sub reflect neg DIAMOND_2 491 | 90 reflect mul rotate 492 | short_len level 1 sub reflect neg SQUARE_1 493 | -90 angle sub reflect mul rotate 494 | short_len reflect mul 0 translate 495 | -90 angle add reflect mul rotate 496 | short_len level 1 sub reflect neg DIAMOND_1 497 | 180 3 angle mul sub reflect mul rotate 498 | short_len level 1 sub reflect SQUARE_1 499 | -90 angle add reflect mul rotate 500 | short_len reflect mul 0 translate 501 | 2 angle mul reflect mul rotate 502 | short_len level 1 sub reflect neg DIAMOND_2 503 | 90 reflect mul rotate 504 | short_len level 1 sub reflect neg SQUARE_3 505 | -2 angle mul reflect mul rotate 506 | short_len reflect mul 0 translate 507 | 2 angle mul reflect mul rotate 508 | short_len level 1 sub reflect neg DIAMOND_1 509 | 510 | gsave 511 | -90 angle sub reflect mul rotate 512 | short_len reflect mul 0 translate 513 | -2 angle mul reflect mul rotate 514 | short_len level 1 sub reflect DART 515 | grestore 516 | 517 | angle neg reflect mul rotate 518 | short_len reflect mul 0 translate 519 | angle reflect mul rotate 520 | short_len level 1 sub reflect neg SQUARE_2 521 | 90 3 angle mul sub reflect mul rotate 522 | short_len level 1 sub reflect SQUARE_2 523 | -180 3 angle mul add reflect mul rotate 524 | short_len level 1 sub reflect neg DIAMOND_2 525 | angle neg reflect mul rotate 526 | short_len reflect mul 0 translate 527 | 180 2 angle mul sub reflect mul rotate 528 | short_len level 1 sub reflect DIAMOND_2 529 | grestore 530 | 531 | gsave 532 | 90 reflect mul rotate 533 | short_len level 1 sub reflect DART 534 | -90 2 angle mul add reflect mul rotate 535 | short_len reflect mul 0 translate 536 | 90 angle sub reflect mul rotate 537 | short_len reflect mul 0 translate 538 | -90 angle sub reflect mul rotate 539 | short_len level 1 sub reflect SQUARE_2 540 | grestore 541 | 542 | gsave 543 | -90 angle add reflect mul rotate 544 | short_len reflect mul 0 translate 545 | -90 angle add reflect mul rotate 546 | short_len reflect mul 0 translate 547 | -90 angle add reflect mul rotate 548 | short_len level 1 sub reflect neg SQUARE_2 549 | 180 angle sub reflect mul rotate 550 | short_len reflect mul 0 translate 551 | short_len reflect mul 0 translate 552 | 90 2 angle mul sub reflect mul rotate 553 | short_len level 1 sub reflect DIAMOND_2 554 | 2 angle mul reflect mul rotate 555 | short_len reflect mul 0 translate 556 | -90 angle add reflect mul rotate 557 | short_len level 1 sub reflect neg SQUARE_2 558 | 90 3 angle mul sub reflect mul rotate 559 | short_len level 1 sub reflect SQUARE_2 560 | angle reflect mul rotate 561 | short_len reflect mul 0 translate 562 | angle neg reflect mul rotate 563 | short_len level 1 sub reflect DIAMOND_1 564 | 2 angle mul reflect mul rotate 565 | short_len reflect mul 0 translate 566 | -2 angle mul reflect mul rotate 567 | short_len level 1 sub reflect SQUARE_3 568 | grestore 569 | } { 570 | gsave 571 | newpath 572 | 0 0 moveto 573 | angle 2 mul reflect mul rotate 574 | len reflect mul 0 rlineto 575 | 90 angle add reflect mul neg rotate 576 | len reflect mul 0 rlineto 577 | angle 90 sub reflect mul rotate 578 | len reflect mul 0 rlineto 579 | 90 angle add reflect mul neg rotate 580 | len reflect mul 0 rlineto 581 | closepath 582 | 583 | 0 setgray 584 | 0.5 setlinewidth 585 | stroke 586 | grestore 587 | 588 | % Orientation mark for testing 589 | %gsave 590 | %newpath 591 | %0 0 moveto 592 | %angle 2 mul reflect mul rotate 593 | %0.15 len mul reflect mul 0 rlineto 594 | %90 angle add reflect mul neg rotate 595 | %0.15 len mul reflect mul 0 rlineto 596 | %angle 90 sub reflect mul rotate 597 | %0.15 len mul reflect mul 0 rlineto 598 | %90 angle add reflect mul neg rotate 599 | %0.15 len mul 0 rlineto 600 | %closepath 601 | %0 setgray 602 | %fill 603 | %grestore 604 | } ifelse 605 | 606 | end 607 | } def 608 | 609 | /DIAMOND_2 { 610 | 4 dict begin 611 | /reflect exch def 612 | /level exch def 613 | /len exch def 614 | /short_len len expansion_factor div def 615 | 616 | level 0 gt { 617 | gsave 618 | 619 | 90 reflect mul rotate 620 | short_len level 1 sub reflect DART 621 | -180 2 angle mul add reflect mul rotate 622 | short_len reflect mul 0 translate 623 | angle reflect mul rotate 624 | short_len level 1 sub reflect neg SQUARE_3 625 | -90 reflect mul rotate 626 | short_len level 1 sub reflect neg DIAMOND_2 627 | 90 2 angle mul sub reflect mul rotate 628 | short_len reflect mul 0 translate 629 | 2 angle mul reflect mul rotate 630 | short_len level 1 sub reflect neg DIAMOND_1 631 | angle neg reflect mul rotate 632 | short_len reflect mul 0 translate 633 | angle reflect mul rotate 634 | short_len level 1 sub reflect neg SQUARE_2 635 | 90 3 angle mul sub reflect mul rotate 636 | short_len level 1 sub reflect SQUARE_2 637 | 638 | gsave 639 | -90 angle add reflect mul rotate 640 | short_len reflect mul 0 translate 641 | 2 angle mul reflect mul rotate 642 | short_len level 1 sub reflect neg DIAMOND_2 643 | grestore 644 | 645 | angle reflect mul rotate 646 | short_len reflect mul 0 translate 647 | angle neg reflect mul rotate 648 | short_len level 1 sub reflect DIAMOND_1 649 | 2 angle mul reflect mul rotate 650 | short_len reflect mul 0 translate 651 | -2 angle mul reflect mul rotate 652 | short_len level 1 sub reflect SQUARE_3 653 | 90 reflect mul rotate 654 | short_len level 1 sub reflect DIAMOND_2 655 | 656 | gsave 657 | -90 angle add reflect mul rotate 658 | short_len reflect mul 0 translate 659 | 180 angle sub reflect mul rotate 660 | short_len level 1 sub reflect DART 661 | -90 angle add reflect mul rotate 662 | short_len reflect mul 0 translate 663 | -90 angle add reflect mul rotate 664 | short_len reflect mul 0 translate 665 | -90 angle add reflect mul rotate 666 | short_len level 1 sub reflect neg SQUARE_2 667 | grestore 668 | 669 | 2 angle mul reflect mul rotate 670 | short_len reflect mul 0 translate 671 | -2 angle mul reflect mul rotate 672 | short_len level 1 sub reflect SQUARE_2 673 | 90 reflect mul rotate 674 | short_len level 1 sub reflect DIAMOND_2 675 | 2 angle mul reflect mul rotate 676 | short_len reflect mul 0 translate 677 | 90 2 angle mul sub reflect mul rotate 678 | short_len level 1 sub reflect DIAMOND_1 679 | 680 | -90 reflect mul rotate 681 | short_len level 1 sub reflect SQUARE_1 682 | -90 3 angle mul add reflect mul rotate 683 | short_len level 1 sub reflect neg SQUARE_1 684 | 685 | -2 angle mul reflect mul rotate 686 | short_len reflect mul 0 translate 687 | 90 2 angle mul add reflect mul rotate 688 | short_len level 1 sub reflect neg SQUARE_2 689 | 690 | 180 angle sub reflect mul rotate 691 | short_len reflect mul 0 translate 692 | -180 angle add reflect mul rotate 693 | short_len level 1 sub reflect neg DIAMOND_1 694 | -90 angle sub reflect mul rotate 695 | short_len reflect mul 0 translate 696 | -90 angle sub reflect mul rotate 697 | short_len reflect mul 0 translate 698 | 90 2 angle mul add reflect mul rotate 699 | short_len level 1 sub reflect neg SQUARE_2 700 | 90 3 angle mul sub reflect mul rotate 701 | short_len level 1 sub reflect SQUARE_2 702 | -90 angle add reflect mul rotate 703 | short_len reflect mul 0 translate 704 | 2 angle mul reflect mul rotate 705 | short_len level 1 sub reflect neg DIAMOND_2 706 | 90 2 angle mul sub reflect mul rotate 707 | short_len reflect mul 0 translate 708 | short_len reflect mul 0 translate 709 | 180 1 angle mul sub reflect mul rotate 710 | short_len level 1 sub reflect SQUARE_2 711 | 712 | grestore 713 | } { 714 | gsave 715 | newpath 716 | 0 0 moveto 717 | angle 2 mul reflect mul rotate 718 | len reflect mul 0 rlineto 719 | 90 angle add reflect mul neg rotate 720 | len reflect mul 0 rlineto 721 | angle 90 sub reflect mul rotate 722 | len reflect mul 0 rlineto 723 | 90 angle add reflect mul neg rotate 724 | len reflect mul 0 rlineto 725 | closepath 726 | 727 | 0 setgray 728 | 0.5 setlinewidth 729 | stroke 730 | grestore 731 | 732 | % Orientation mark for testing 733 | %gsave 734 | %angle 2 mul reflect mul rotate 735 | %0.85 len mul reflect mul 0 translate 736 | %newpath 737 | %0 0 moveto 738 | %0.15 len mul reflect mul 0 rlineto 739 | %90 angle add reflect mul neg rotate 740 | %0.15 len mul reflect mul 0 rlineto 741 | %angle 90 sub reflect mul rotate 742 | %0.15 len mul reflect mul 0 rlineto 743 | %90 angle add reflect mul neg rotate 744 | %0.15 len mul reflect mul 0 rlineto 745 | %closepath 746 | %fill 747 | %grestore 748 | } ifelse 749 | 750 | end 751 | } def 752 | 753 | /DART { 754 | 4 dict begin 755 | /reflect exch def 756 | /level exch def 757 | /len exch def 758 | /short_len len expansion_factor div def 759 | 760 | level 0 gt { 761 | gsave 762 | 763 | 2 { 764 | short_len level 1 sub reflect DART 765 | 766 | gsave 767 | -90 angle add reflect mul rotate 768 | short_len reflect mul 0 translate 769 | -90 angle add reflect mul rotate 770 | short_len reflect mul 0 translate 771 | -90 angle add reflect mul rotate 772 | short_len level 1 sub reflect neg SQUARE_2 773 | 180 angle sub reflect mul rotate 774 | short_len reflect mul 0 translate 775 | 90 2 angle mul sub reflect mul rotate 776 | short_len level 1 sub reflect DIAMOND_1 777 | -90 angle add reflect mul rotate 778 | short_len reflect mul 0 translate 779 | -180 2 angle mul add reflect mul rotate 780 | short_len level 1 sub reflect neg SQUARE_3 781 | grestore 782 | 783 | gsave 784 | -90 2 angle mul add reflect mul rotate 785 | short_len reflect mul 0 translate 786 | 90 angle sub reflect mul rotate 787 | short_len reflect mul 0 translate 788 | -90 angle sub reflect mul rotate 789 | short_len level 1 sub reflect SQUARE_2 790 | angle reflect mul rotate 791 | short_len reflect mul 0 translate 792 | angle neg reflect mul rotate 793 | short_len level 1 sub reflect DIAMOND_1 794 | 795 | gsave 796 | -90 angle add reflect mul rotate 797 | short_len reflect mul 0 translate 798 | 180 angle sub reflect mul rotate 799 | short_len level 1 sub reflect DART 800 | grestore 801 | 802 | 2 angle mul reflect mul rotate 803 | short_len reflect mul 0 translate 804 | -2 angle mul reflect mul rotate 805 | short_len level 1 sub reflect SQUARE_3 806 | angle reflect mul rotate 807 | short_len reflect mul 0 translate 808 | angle neg reflect mul rotate 809 | short_len level 1 sub reflect DART 810 | grestore 811 | 812 | -90 angle add reflect mul rotate 813 | len reflect mul 0 translate 814 | angle reflect mul rotate 815 | len reflect mul 0 translate 816 | -90 2 angle mul sub reflect mul rotate 817 | } repeat 818 | 819 | grestore 820 | } { 821 | gsave 822 | newpath 823 | 0 0 moveto 824 | 90 2 angle mul sub reflect mul neg rotate 825 | len reflect mul 0 rlineto 826 | angle reflect mul neg rotate 827 | len reflect mul 0 rlineto 828 | angle 180 add reflect mul rotate 829 | len reflect mul 0 rlineto 830 | angle reflect mul neg rotate 831 | len reflect mul 0 rlineto 832 | closepath 833 | 834 | 0 setgray 835 | 0.5 setlinewidth 836 | stroke 837 | grestore 838 | } ifelse 839 | 840 | end 841 | } def 842 | 843 | 1 setlinejoin 844 | 50 350 translate 845 | 350 2 1 SQUARE_2 846 | %350 1 1 SQUARE_1 847 | -------------------------------------------------------------------------------- /clamshell.eps: -------------------------------------------------------------------------------- 1 | %!PS-Adobe EPSF-3.0 2 | %%BoundingBox: 0 0 850 850 3 | 4 | /LIGHT_TRAPAZOID { 5 | 4 dict begin % 4 variable in local scope 6 | /level exch def % grab level off the stack 7 | /len exch def % grab len off the stack 8 | /angle 18 def 9 | /short_len len 1 2 angle sin mul sub mul def 10 | 11 | level 0 gt { 12 | gsave 13 | 54 rotate 14 | short_len 0 translate 15 | 54 neg rotate 16 | short_len level 1 sub LIGHT_TRAPAZOID 17 | grestore 18 | 19 | gsave 20 | 108 neg rotate 21 | 0 short_len translate 22 | 180 rotate 23 | short_len level 1 sub LIGHT_TRAPAZOID 24 | 144 neg rotate 25 | 0 short_len translate 26 | 180 rotate 27 | short_len level 1 sub LIGHT_TRAPAZOID 28 | 144 neg rotate 29 | 0 short_len translate 30 | 180 rotate 31 | short_len level 1 sub DARK_TRAPAZOID 32 | 144 neg rotate 33 | 0 short_len translate 34 | 180 rotate 35 | short_len level 1 sub DARK_TRAPAZOID 36 | grestore 37 | 38 | gsave 39 | 36 rotate 40 | short_len level 1 sub DARK_TRAPAZOID 41 | 0 short_len translate 42 | 36 neg rotate 43 | short_len level 1 sub LIGHT_TRAPAZOID 44 | 0 short_len translate 45 | 36 neg rotate 46 | short_len level 1 sub LIGHT_TRAPAZOID 47 | 48 | grestore 49 | } { 50 | newpath 51 | 0 0 moveto 52 | 0 len rlineto 53 | len angle cos mul len angle sin mul neg rlineto 54 | 0 len 2 len angle sin mul mul sub neg rlineto 55 | closepath 56 | 57 | 0 setgray 58 | 0.5 setlinewidth 59 | stroke 60 | } ifelse 61 | end 62 | 63 | } def 64 | 65 | /DARK_TRAPAZOID { 66 | 4 dict begin % 4 variable in local scope 67 | /level exch def % grab level off the stack 68 | /len exch def % grab len off the stack 69 | /angle 18 def 70 | /short_len len 1 2 angle sin mul sub mul def 71 | 72 | level 0 gt { 73 | gsave 74 | 54 rotate 75 | short_len 0 translate 76 | 54 neg rotate 77 | short_len level 1 sub DARK_TRAPAZOID 78 | grestore 79 | 80 | gsave 81 | 108 neg rotate 82 | 0 short_len translate 83 | 180 rotate 84 | short_len level 1 sub LIGHT_TRAPAZOID 85 | 144 neg rotate 86 | 0 short_len translate 87 | 180 rotate 88 | short_len level 1 sub LIGHT_TRAPAZOID 89 | 144 neg rotate 90 | 0 short_len translate 91 | 180 rotate 92 | short_len level 1 sub DARK_TRAPAZOID 93 | 144 neg rotate 94 | 0 short_len translate 95 | 180 rotate 96 | short_len level 1 sub LIGHT_TRAPAZOID 97 | grestore 98 | } { 99 | newpath 100 | 0 0 moveto 101 | 0 len rlineto 102 | len angle cos mul len angle sin mul neg rlineto 103 | 0 len 2 len angle sin mul mul sub neg rlineto 104 | closepath 105 | 106 | gsave 107 | 0.5 setgray 108 | fill 109 | grestore 110 | 111 | 0 setgray 112 | 0.5 setlinewidth 113 | stroke 114 | } ifelse 115 | end 116 | } def 117 | 118 | 1 setlinejoin 119 | 50 100 translate 120 | 500 5 DARK_TRAPAZOID 121 | -------------------------------------------------------------------------------- /rendered/canonical3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steiza/postscript_fractals/3ecf677767e9c0db315f6714e28a744f256cb169/rendered/canonical3.png -------------------------------------------------------------------------------- /rendered/clamshell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steiza/postscript_fractals/3ecf677767e9c0db315f6714e28a744f256cb169/rendered/clamshell.png -------------------------------------------------------------------------------- /rendered/clamshell1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steiza/postscript_fractals/3ecf677767e9c0db315f6714e28a744f256cb169/rendered/clamshell1.png -------------------------------------------------------------------------------- /rendered/closet.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steiza/postscript_fractals/3ecf677767e9c0db315f6714e28a744f256cb169/rendered/closet.jpg --------------------------------------------------------------------------------