I have decided to do something very stupid…

Trying to create a tiled surface of spectre aperiodic chiral monotiles, in code. Generating svg…

I sure others have, but trying to solve it myself.

I am pondering a coordinate system that is a sum of integer multiples of 0.5 plus integer multiples of sin60.

https://en.wikipedia.org/wiki/Einstein_problem#/media/File%3AMonotilePolygon.svg

Einstein problem - Wikipedia

OK I cannot simply place tiles randomly touching existing tiles as they can leave non tile shaped gaps.

I have to work out allowed ways to place tiles somehow.

Back to drawing board.

@revk I know you're working it out for yourself, but if you get stuck, Simon Tatham (@simontatham) has written in detail about some of the algorithms used for aperiodic tilings on his home page: https://www.chiark.greenend.org.uk/~sgtatham/
Simon Tatham's Home Page

@darkling @simontatham All good, until I get to this - until now all angles multiples of 30 degrees, so easy to make a sort of complex int*sin60+int*cos60 system, but this appears to be 15 degrees. Arrrg!

@revk @darkling only because I rotated the Spectre to that angle for aesthetic purposes, so that it was possible to have a Spectre with its head pointing directly upwards.

All the edges in a Spectre tiling are at angles that are multiples of 30° relative to each other. In that picture I show them at odd multiples of 15°, but you can make them even multiples just as easily.

Sorry – it hadn't occurred to me that that would be confusing!

@simontatham @darkling OK I'll see if this is a simple misunderstanding then, sorry.

Thanks for commenting. That means I may be able to get the hang of it...

Close to having code to make this myself.

Stupid question, how do I work out the actual orientation of these mappings from that, sorry to be thick. I see the origin mapping point.

Oh, and struggling to map the spectre unit length to length between hex meta tiles.

@revk @darkling "how do I work out the actual orientation of these mappings" – you mean the relative orientation of the hexagon and the Spectre? There is no right orientation. It doesn't matter at all. You can choose any relative orientation you like.

The same goes for the mapping between lengths in the hexagon tiling and lengths in the Spectre tiling. Pick whatever you want. It won't matter.

With these combinatorial algorithms, the idea is that once you've finished implementing, the code never has to actually work out any coordinates or lengths in the hexagon tiling. For each Spectre tile, you store a sequence of its parent hexagons with child indices, but you never need to work out where in the plane those hexagons live, unless you actually want to plot them as an extra output diagram.

@simontatham @darkling

I mean "The same goes for the mapping between lengths in the hexagon tiling and lengths in the Spectre tiling. Pick whatever you want. It won't matter."

Ok so I pick 1000 times unit length between hex meta tiles, and now none of my tiles touch each other.

It clearly "matters" and the exact value needs to be known?

I hope I am not being thick here.

@revk @darkling it is counterintuitive! But you don't work out the location of a Spectre tile based on the location of its parent hexagon. You work it out based on the tile you're putting it next to.

In each run of the recursive transition algorithm, you start with a Spectre that has some list of parent hexagons, and you ask what's on the other side of one of its edges. For example:

"I have a Spectre which is child #0 of a G hexagon, which is child #2 of a Y hexagon, which is child #1 of a P hexagon. What's on the other side of edge #7 of that Spectre?"

The algorithm recurses up and down consulting its lookup tables, and answers:

"The tile on the other side of that edge is a Spectre which is the only child of an X hexagon, which is child #7 of an S, which is child #3 of the same second-level P. Edge #7 of your original Spectre meets edge #12 of the new one."

Now you place the new Spectre in your output diagram by lining up its edge #12 with edge #7 of the one you already had. You don't need to calculate it based on the coordinates of the parent tiles. Every tile you place is the neighbour of one you already had, so you place it next to that neighbour.

@simontatham @darkling OK, but I am, doing so. I want to know where to put the tile(s) in the meta hexagon and what size and orientation. That is a simple way to code this.

And ultimately the whole process must have a defined ratio of unit length spectre to until spacing next level meta hex, and then unit length meta hex level above. That is a fixed constant, and must be a known value.

Same with orientation and origin of the tiles.

I'm just trying to code this...

(thanks for help)

@revk @darkling the thing is, as you go up the levels of metatiles, everything gets distorted. The nth-order expansion of a hexagon doesn't look very hexagonal at all. In the limit the tiles end up with some weird fractal shapes.

There _are_ ways that you can calculate exact coordinates for every level of the hierarchy so that everything matches up precisely. But they aren't simple. They involve pretending the tiles are in four dimensions; doing linear algebra on vectors of two complex numbers; and discarding those simple hexagonal metatile shapes in favour of more Spectres and a much more complicated mapping between their edges.

It really is _easier_ to ignore the coordinates of higher-level tiles, and just put each Spectre next to its neighbour. That's why I chose to do it this way in the first place!

@simontatham @darkling Arg, OK, wow.

So not really hexagonal at all.

OK that is going to be a major re-coding to do that.

I may have to leave that until tomorrow...

Thanks for feedback on this.

I may have to code from bottom up - pick a tile type (including G double) and then pick what meta tile it is part of at higher level (at random) and fill out from there.

I was doing top down. Sounds like bottom up is needed.

@revk yes, "bottom up" is exactly right. You invent each higher-order tile at random as you find you need it, going upwards from the lowest layer rather than down from the top. Literally, make it up as you go along. :-)

(PS @darkling do you still want to be on CC for all this? I'm sure we can drop you if you're not interested)

@simontatham @darkling OK I am starting by trying to make the overall hex grid before substituting the tiles in to it.

But I am struggling to understand "Transitions between hexagons". You show, say G, maps to 7 sub meta tiles. But you show a dot at top of G and side of P in that set. So I am unsure or orientation.

e.g. G left of S, so the 7 tiles in G, are they orientated as shown? And the S is 60 degrees left rotated from show, and they slot together. Like this?

...

@simontatham @darkling Or have I got the orientation totally wrong?

I am not understanding the Large blob by P, or the X.X numbering, sorry.

Can you provide say an example of a whole G meta tile expanded to meta tiles, in the same orientation, and then expanded again to meta tiles showing how these component meta tiles of a G are themselves arranged and orientated?

@simontatham @darkling I may help if I explain what I think is the scheme to spot if I have misunderstood.

There are 9 hexagonal meta tiles, and being hexagonal each can be in one of 6 orientations.

Each can be substituted for a specific pattern of hexagonal meta tiles, each with a type and orientation. And even though the pattern of these 7 or 8 sub tiles is not itself a hexagonal unit, they do fit together. This can be done recursively.

@simontatham @darkling Finally these each can be substituted for a spectre (or two). And again, they fit together.

Is that right.

My issue is the orientation and relative position of these sub meta tiles is not entirely obvious.

When writing code I should be able to know that each block of 7 or 8 sub tiles has a specific position and orientation so that it does fit and cover a hex grid of sub tiles.

Same when it get to the spectre pieces.

Then I can code it!

Is that right?

@simontatham @darkling what I would love to see is a single meta tile, expanded to a set of 7 or 8 meta tiles, expanded to a grid of meta tiles perhaps with heavy line around the groups. And then finally that expanded to spectre tiles.

@revk @darkling yes, everything you say there is right as far as I can see.

The way to match up the patches of hexagons is using the X.Y numbers on the external edges. In each of the expansion diagrams from one parent hexagon to 7 or 8 child hexagons, each X.Y label on an edge of the expansion means that that edge corresponds to part of edge Y of the parent hexagon.

As an example, you asked about how the G and S patches fit together. You can see in the expansion diagrams that edge 4 of a G hexagon always meets edge 0 of an S. Therefore, when you put the G and S patches together, the edges labelled 0.4, 1.4, 2.4, 3.4 and 4.4 in the G expansion must meet the edges labelled 4.0, 3.0, 2.0, 1.0 and 0.0 in the S expansion. So you should rotate the S right by 60°, and put it below the G.

But if you were putting a _D_ next to a G, then that's different, because edge 3 of the G meets edge 1 of the D, so you want to arrange that edges 0.3,…,4.3 of the G patch meet edges 4.1,…,0.1 of the D patch. And for that, you would rotate the D patch 60° left and put it on the right side of the G patch. (In fact that looks like what you did in your diagram, because that looks more like a G+D to me than a G+S.)

@simontatham @darkling OK I'll look again.

If doing by hand, one could place a tile and say, oh that matches there. Like the interventions you added on sides of hex tiles for example.

From a programatic point of view, I simply need to know "When expanding a G, where does each of the sub tiles go exactly relative the the reference point (centre) of the original G hex tile" and so on.

It is that lack of precise offset and rotation that is, in my view, very unclear in your paper.

...

@simontatham @darkling But I appreciate your time, and will persevere.

If I work out the answers I may do a new paper/blog showing how one does this programatically.

Thanks again for your time.

Actually, assuming I do crack this, I'll publish C code anyway, but maybe do a paper on programmatically spectre tiling referencing yours. Would be delighted for you to review if I do.

My plan is code making SVG covering a defined area with specified unit size, colours, overall angle, and much more.

@revk @darkling the reason I didn't give that information is that it in the algorithm I _intended_ to describe – and certainly in the one I implemented – it isn't needed at all. You say you _need_ to know how to place the subtiles of a G relative to a reference point in the original G: I say, no, you don't _need_ to know it. It isn't even necessary to remember which orientation supertiles are in.

I'm not sure whether you haven't yet _understood_ how it's possible to compute the required answers without knowing those positions and orientations, or whether you do understand it but are choosing to do something a bit different from what I did.

@simontatham @darkling Well, I am choosing the way that seems simplest too me that is that I have a meta tile and want to make 7 or 8 new smaller meta tiles from that, where exactly do I put them, x/y offset from the original and new orientation. Simple as that.

There are other ways to try and do this, I am sure. I have already moved from simple Cartesian to co-ordinates that are integer multiples of sin60 and cos60 to make it all line up nicely when finally output as SVG.

@simontatham @darkling I understand not needing to remember supertitle orientation as the new subtitles have their new absolute orientation from that, I agree on that one.

But I sort of need to know where to put them, especially relative to the other adjacent supertitles. I have to set an x/y co-ordinate for each such that they will align with the sub tiles of the adjacent supertitle.

Well, I think so!

@simontatham @darkling Ultimately I am plonking tiles on a plane in an SVG.

Those tiles need an actual position and orientation! So at some point I have to resolve to that to make the output.

FYI my maths only really go to an A at (UK) A-level, so I may be missing some logic here, sorry.

@revk @darkling but the only tiles you're plonking in the SVG are the Spectres. So those are the only ones you need to know the coordinates of.

You don't need to draw the hexagons at all. They're purely imaginary – an aid to understanding and bookkeeping. It isn't necessary to know where they are, only how they connect to each other. Like edges and vertices in a graph, you can treat them as completely abstract.

And you can place each Spectre by putting it next to the previous Spectre, since my algorithm discovers each one by starting from its neighbour. And that also doesn't need to know anything about where the hexagons are.

Unless you're _also_ intending to draw a separate SVG full of the corresponding hexagons? In that case of course you _would_ need to decide where to put the hexagons. (But if it were me, I'd do that independently.)

@simontatham @darkling OK

Yes, I do sort of appreciate that.

However, I decided a good start to make sure I have my understanding of the super tiles and so on, was to actually plot the hex grid as a starting point. That should remain possible, yes, even if that is logically only an aid for placing the spectre tiles eventually.

Even if I only logically link the hex tiles, i.e. an array of each of the 6 adjacent tiles, I could then plot it.

@simontatham @darkling

So even if not exact x/y co-ordinates I have to understand the logical placement of the sub tiles, and that is where I got stuck. I'll try and understand the X.X numbers you have published to crack this.

And yes, so far I have one tile. Plan is to move up from that to supertitles and neighbours to cover an area.

Maybe tomorrow.

https://excalibur.belmont.cymru/spectre.cgi

@revk @darkling if you do want to decide on plane coordinates for each layer of hexagons as well, then I think the process I'd recommend is to generate them the same way I describe for the Spectres: at every layer, a newly discovered tile is given coordinates by placing it next to the one you discovered it from.

The first tile you invent in any layer is assigned some arbitrary starting coordinate, like (0,0) and a default orientation, or whatever you prefer. This applies to the initial Spectre, and also, every time you invent a new random supertile in a layer you hadn't needed to use before, you assign that initial supertile an arbitrary starting position too.

And then, every tile you discover in _every_ layer comes with information about what other tile it's next to, and which pair of edges of those tiles meet. So you can calculate the coordinates of the new tile by placing it next to the old one.

If you do that, you get an augmented version of my own algorithm, which also returns coordinates for all the supertiles, so that you could plot a whole sheaf of SVGs corresponding to the layers of hierarchy you've explored.

@simontatham @darkling Indeed. I am trying first with the hex meta tiles as a plot, as that seems an easier starting point than the spectres to be honest, and from which I should be able to place spectres.

I appreciate your time. I'll see if I can make sense of the X.X coding and work it out.

There is a danger this goes in to our R&D tax claim at this point 🙂

All this is to make a "nice" and "mathematical" pattern on a product front panel, maybe unique per product instance even.

@simontatham @darkling one of my main issues here is…

It must be possible to define the exact offsets and orientations at each stage for meta to meta and meta to spectre.

So why not just do that?

Why leave it to “work out which edges had to match up”.

Why not say this tile to the tile is exactly this x/y offset?

That is kind of my problem.

If that was done, coding would have been a doddle…

@revk @darkling my only answer is that from my point of view the 'just' goes in the other direction.

At any given layer of hexagons, the offsets between adjacent hexagons are nice and regular. But if you look at the corresponding offsets between the sub-hexagons at the next layer down, they're not all the same as each other, _because_ the expanded patch from each hexagon is a weird irregular shape, and it depends which way round they all are.

So from my point of view, the question goes the other way. Why do all the complicated calculations to get the x/y coordinates, when you don't need them? Why not _just_ remember which edges connect to which other edges?

@simontatham @darkling OK…

Spending another night going through this in my head, again…

I do see what you are getting at, and the approach. Finally. And so I think I can work out the coding I need.

Essentially it is saying tile 1 side X touches tile 2 side Y. From that, knowing where tile 1 is I can place exactly tile 2. This works for the spectres at lowest level and the hex tiles at level above:

@simontatham @darkling The fun then is the level above that where side X of a super tile is actually a set of sub hex tile edges.

But even there I only actually need to join one tile for each edge of the cluster of tiles to one tile on the edge of the next cluster. I don’t need to knit them all together and have every tile linked to every neighbour to be able to follow the links and place the final tiles.

So I only need to essentially keep track of the 6 “edge” tiles in the cluster of any size

@simontatham @darkling and even that can be kept track of as part of recursive calls. Only when finally applying the spectres as part of this at the lowest level do I need to look at the actual location and rotation of the spectre to which I am attaching the new one so as to know the new spectres actual location and rotation.

Apologies if I was being thick.

OK need to have 12 edges one for in and one for out for each 6 sides, in effect. But doable.