Generating Jordan, 6
There is a Jordan curve such that every piecewise-linear path from the inside to the outside intersects the curve infinitely many times. I describe how to draw such a curve here, and do so.
Generating a point sequence
It is easiest to describe wiggling as in the previous post. One could encode courses directly using turtle graphics. However, the number of segments to draw in the final picture is quite large. Suppose we begin with a simplest hex loop, with course Every wiggling multiplies the number of tokens by After just three wigglings the number of segments is We intend to draw the resulting hex curve. To use turtle graphics would mean to use floating point arithmetic to accomplish rotations by 120 degrees port or starboard. After so many rotations and additions, it is reasonable to suspect the resulting “curve” wouldn’t close up. On the other hand, no triple of points in the grid of integers forms an equilateral triangle. So what we do is work over the integer lattice when calculating a point sequence directly from a course. Then after all those points are determined, we apply an affine equivalence from the square grid lattice to the penny-packing lattice. This will give us a closed hex curve, as a sequence of points we may feed to PostScript.
To fix ideas, begin with the lattice generated by and We label these vectors so because if a hex curve comes into a vertex at from along the incoming vector then a starboard turn at would go along whereas a port turn at would go along
In general, at a vertex a hex curve has an incoming vector that is the sum of the outgoing port and starboard vectors More specifically, letting be counterclockwise rotation by we have and
Suppose a hex curve takes a starboard turn at Then: + the next vertex position would be at + the next incoming vector would be the current + the next starboard vector would be and + the next port vector would be
If a hex curve takes a port turn at instead, then: + the next vertex position would be at + the next incoming vector would be the current + the next starboard vector would be and + the next port vector would be
That is, a starboard turn accomplishes the state change
whereas a port turn instead accomplishes
To convert a course of turn-type movement tokens into a sequence of points, then, we begin with an appropriate initial collection of incoming, port, and starboard vectors, and some initial vertex, and we simply apply the appropriate state changes above according to the sequence of tokens, keeping track of the points seen in order. We may encode this in Python as follows:
def add(v,w):
return (v[0]+w[0],v[1]+w[1])
def negate(v):
return (-v[0],-v[1])
def to_points(course, start):
= start
vtx,vs,vp,vi = [vtx]
points = list(course)
toks
toks.reverse()while len(toks) != 0:
= toks.pop()
tok if tok == 'S':
= add(vtx,vs),negate(vp),vi,vs
vtx,vs,vp,vi elif tok == 'P':
= add(vtx,vp),vi,negate(vs),vp
vtx,vs,vp,vi else:
raise Exception("Bad token")
points.append(vtx)return points
N.B. the tokens are reversed in to_points
because Python
pops elements from the end of a list, not the beginning.
Drawing the curve
We could choose a different lattice and still run the above code (starting with say). The resulting points are the vertices of a PL curve affinely equivalent to the desired sequence in via the unique linear map Another way to look at this is that we generate first the (integer) coordinates of the points with respect to the basis then determine their Cartesian coordinates.
Finally, we would like all this to fit on a U.S. letter page. This is not difficult to organize. So, the following code, together with the code above, generates a PostScript file of the third wiggling of the simplest hex loop “PPPPPP,” illustrating what the limit Jordan curve looks like.
def draw(pts):
with open("jordan.ps",'w') as ps:
= pts[0]
(x0,y0) = x0,x0,y0,y0
minx,maxx,miny,maxy for (x,y) in pts[1:]:
= min(minx,x),max(maxx,x)
minx,maxx = min(miny,y),max(maxy,y)
miny,maxy = maxx//2+minx//2+(maxx%2+minx%2)//2
midx = maxy//2+miny//2+(maxy%2+miny%2)//2
midy = maxx-minx
rngx = maxy-miny
rngy
"%!\n")
ps.write(
# Fit US Letter size page to curve
"72 dup scale\n") # Length in inches
ps.write("{0} {1} translate\n".format(8.5/2,11/2))
ps.write(= min(8.5/rngx,11/rngy)
scale "{0} dup scale\n".format(scale)) # Length in coords
ps.write(".95 dup scale\n") # Margin room
ps.write(
# Draw curve
"newpath\n")
ps.write("{0} {1} moveto\n".format(x0-midx,y0-midy))
ps.write(for (x,y) in pts[1:]:
"{0} {1} lineto\n".format(x-midx,y-midy))
ps.write(".111 setlinewidth\nstroke\n")
ps.write("showpage\n")
ps.write(
ps.close()
from math import sqrt
if __name__ == "__main__":
= "PPPPPP"
simple = to_points(wiggle(wiggle(wiggle(simple))))
intpts = sqrt(3)/2
s32 = [(x-0.5*y,s32*y) for (x,y) in intpts]
hexpts draw(hexpts)
The ensuing PostScript file is rather large; I converted it to PDF and thence to a PNG file. Here is what it looks like:

That is the construction. It remains to be shown that it has the two desired properties, namely * that its limit yields a Jordan curve; and * that Jordan curve intersects no PL curve in a positive finite number of points.
Roughly speaking, here are why these properties hold. This yields a Jordan curve because we leave enough space in the triangles so that the curves limit on an continuous injection, and because a point in a triangle of the curve is only wiggled to “nearby” triangles. The Jordan curve is crossed finitely by no PL path because in each triangle, every line segment between the blue and red regions from the first triangle post crosses the curve more than once.

That “explanation” is what G. H. Hardy would call gas. But it’s all I’m putting down for right now!