Last active
November 17, 2022 20:15
-
-
Save hivehand/e6ecad689c321a896e3cc6e8efd82628 to your computer and use it in GitHub Desktop.
Teeny tiny hexagon tiling
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% Draw, in white on black, the set of Pointer Pattern Pad hexagons described | |
% here: | |
% | |
% http://bitsavers.trailing-edge.com/pdf/xerox/mouse/lyon_optical/018P87005_D_Pointer_Pattern_Pad_Oct84.pdf | |
/inch { 72 mul } def | |
% Alter the following for different page sizes. | |
/pagewidth 8.5 inch def | |
/pageheight 11 inch def | |
<< /PageSize [pagewidth pageheight] >> setpagedevice | |
% Alter the following to change the hexagon width (that is, the distance | |
% between two opposing edges of the same hexagon) and the distance between | |
% lines of hex edges. | |
/hexwidth 0.008 inch def | |
/edgesep 0.007 inch def | |
% Set this to true if you want a peek at what's actually going on. When | |
% enabled, the actual page is outlined in red, and zoomed out by a factor of | |
% two, allowing you to see the linesets used to generate the pattern. | |
/demo false def | |
/offset hexwidth edgesep add def | |
% Given two values, return the one with the greater absolute value. | |
/abs_max { | |
2 dict begin | |
/num1 exch abs def | |
/num2 exch abs def | |
num1 num2 gt | |
{ num1 } | |
{ num2 } | |
ifelse | |
end | |
} def | |
% Given an angle, return the width and height of the bounding box encompassing | |
% the page twisted at that angle. | |
/get_bounds { | |
4 dict begin | |
/twist_angle exch def | |
/hypotenuse | |
pagewidth 2 exp | |
pageheight 2 exp | |
add sqrt | |
def | |
pagewidth pageheight atan dup | |
/a1 exch twist_angle add def | |
/a2 exch twist_angle sub def | |
a1 sin hypotenuse mul | |
a2 sin hypotenuse mul | |
abs_max | |
a1 cos hypotenuse mul | |
a2 cos hypotenuse mul | |
abs_max | |
end | |
} def | |
% Given an angle, first compute the bounding box for the page at that angle, | |
% then rotate to said angle and cover the bounding box with a set of stripes whose | |
% width is the distance between hexagons, separated by the width of the | |
% hexagons themselves. | |
/weave { | |
6 dict begin | |
/twist_angle exch def | |
twist_angle get_bounds | |
/spanheight exch def | |
/spanwidth exch def | |
/stripecount spanwidth offset div round def | |
/leftedge stripecount -2 div ceiling offset mul | |
offset 2 div sub def | |
/bottom spanheight -2 div def | |
gsave | |
twist_angle rotate | |
0 1 stripecount { | |
offset mul | |
leftedge add bottom moveto | |
0 spanheight rlineto | |
stroke | |
} for | |
grestore | |
end | |
} def | |
% Showtime. | |
% Set the linewidth to match the separation distance between hexagon edges. | |
edgesep setlinewidth | |
% Center the page around a hexagon, so that it will be symmetric. | |
pagewidth 2 div | |
pageheight 2 div | |
translate | |
% Scale the page down if we're in demo mode. | |
demo { 0.5 0.5 scale } if | |
% Move to what is now page center. | |
0 0 moveto | |
% Draw three sets of lines, twisted 60 degrees relative to one another, to | |
% create a set of hexagons. | |
0 60 120 { | |
weave | |
} for | |
% If we're in demo mode, draw the border of the page itself, to verify that | |
% the bounding boxes are exactly as large as they need to be, and no larger. | |
demo { | |
1 0 0 setrgbcolor | |
0 setlinewidth | |
pagewidth -2 div pageheight -2 div moveto | |
0 pageheight rlineto | |
pagewidth 0 rlineto | |
0 pageheight neg rlineto | |
closepath | |
stroke | |
} if | |
showpage |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% DON'T USE THIS. Use ppmesh.ps instead. | |
% | |
% This was a first attempt, and while it technically works, it turns out to | |
% be a stupefyingly greedy resource hog that chokes printers and generates a | |
% 50-megabyte PDF. It's drawing several thousand tiny hexagons. This could | |
% no doubt be optimized down to reasonable resource consumption, but in this | |
% particular instance, the spacing of the hexagons means that you can generate | |
% them via negative space: just draw three sets of parallel lines at 120° to | |
% one another. | |
% Draw, in white on black, the set of Pointer Pattern Pad hexagons described | |
% here: | |
% | |
% http://bitsavers.trailing-edge.com/pdf/xerox/mouse/lyon_optical/018P87005_D_Pointer_Pattern_Pad_Oct84.pdf | |
/inch { 72 mul } def | |
% Alter the following for different page sizes. | |
/pagewidth 8.5 inch def | |
/pageheight 11 inch def | |
<< /PageSize [pagewidth pageheight] >> setpagedevice | |
% Alter the following to change the hexagon width (that is, the distance | |
% between two opposing edges of the same hexagon) and the distance between | |
% lines of hex edges. | |
/hexwidth 0.008 inch def | |
/edgesep 0.007 inch def | |
% Fill a white hexagon. We cheat and use global variables here because when | |
% you're drawing a million or so of these, every little performance optimization | |
% helps. | |
/hex { | |
gsave | |
0 edgelength 2 div rmoveto | |
120 neg rotate | |
1 1 5 { | |
pop | |
0 edgelength rlineto | |
60 rotate | |
} for | |
closepath | |
fill | |
grestore | |
} def | |
% Blacken the page. | |
0 0 0 setrgbcolor | |
0 0 moveto | |
0 pageheight lineto | |
pagewidth pageheight lineto | |
pagewidth 0 lineto | |
closepath | |
fill | |
% Now set up the hex show. | |
1 1 1 setrgbcolor | |
/edgelength | |
hexwidth 2 div | |
30 cos div | |
def | |
% The distance between any point on a given hex and the corresponding point on | |
% a neighbor. | |
/distance edgesep 30 cos div edgelength 2 mul add def | |
% The number of vertical hex tiles per page. | |
/tilecount pageheight distance div ceiling def | |
% The distance between a vertical strip of hexes and its neighbor. | |
/stripsep hexwidth edgesep add def | |
% The number of vertical strips spanning the width of the page. | |
/stripcount pagewidth stripsep div ceiling def | |
0 0 moveto | |
% Draw a succession of strips, each consisting of a succession of tiles. | |
0 1 stripcount 1 sub { | |
/i exch def | |
/offset i 2 mod def | |
i stripsep mul 0 moveto | |
% To stagger alternating strips, add a downward offset and an extra tile, | |
% but only if we're on an odd-numbered strip. | |
0 distance -2 div | |
offset mul | |
rmoveto | |
1 1 tilecount offset add { | |
pop | |
hex | |
0 distance rmoveto | |
} for | |
} for | |
showpage |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment