Working with Saddle Connections

from flatsurf import translation_surfaces

s = translation_surfaces.veech_double_n_gon(5)
s.plot()
../_images/cbd1ccf86cceae119014cb5b385e37fea9d49663a746407f41f2582095904734.png

We get a list of all saddle connections of length less than \(\sqrt{10}\).

sc_list = s.saddle_connections(10)
len(sc_list)
60

The following removes duplicate saddle connections which appear with opposite orientations.

sc_set = set()
for sc in sc_list:
    if sc.invert() not in sc_set:
        sc_set.add(sc)
sc_list2 = list(sc_set)
len(sc_list2)
30

We pick two saddle connections:

sc1 = sc_list2[-15]
sc2 = sc_list2[-12]

We can find their holonomies and other information about them using methods.

print("Holonomy of sc1 is" + str(sc1.holonomy()) + " = " + str(sc1.holonomy().n()))
print("Holonomy of sc2 is" + str(sc2.holonomy()) + " = " + str(sc2.holonomy().n()))
Holonomy of sc1 is(3/2*a^2 - 5/2, -1/2*a) = (2.92705098312484, -0.951056516295154)
Holonomy of sc2 is(-1/2*a^2 + 1/2, -a^3 + 5/2*a) = (-1.30901699437495, -2.12662702088010)
s.plot() + sc1.plot(color="orange") + sc2.plot(color="green")
../_images/66f29a9cdc4dc9e78a8edc6924be46b052c9a8517407ff5daefc4b31a8d4699e.png

We can test that they intersect. By default the singularity does not count.

sc1.intersects(sc2)
True

We can get an iterator over the set of intersection points:

for p in sc1.intersections(sc2):
    print(p)
Point (-1/6*a^2 + 2/3, 1/6*a^3 - 1/6*a) of polygon 0
Point (1/6*a^2 - 2/3, -1/6*a^3 + 1/6*a) of polygon 1

It is a good idea to store the intersections in a list if you want to reuse them:

intersections = list(sc1.intersections(sc2))

We can plot the intersection points:

plot = s.plot() + sc1.plot(color="orange") + sc2.plot(color="green")
for p in intersections:
    plot += p.plot(color="red", zorder=3)
plot
../_images/23b18f8c14bdd95f71b754783a235fd938261128af24e34944fc84b8359914d9.png

We can plot all the saddle connections:

plot = s.plot(edge_labels=False, polygon_labels=False)
for sc in sc_list:
    plot += sc.plot(thickness=0.05)
plot
../_images/ade02fe1b11aeb81b7c40304268b3e8bd724ef97f1969b0001f27e5be51eb8ae.png

We will build a subset of the saddle connection graph where vertices are saddle connections and two vertices are joined by an edge if and only if the saddle connections do not intersect (on their interiors).

d = {}

for i in range(len(sc_list2)):
    for j in range(i + 1, len(sc_list2)):
        if not sc_list2[i].intersects(sc_list2[j]):
            if i not in d:
                d[i] = [j]
            else:
                d[i].append(j)
            if j not in d:
                d[j] = [i]
            else:
                d[j].append(i)

g = Graph(d)

We place the vertex of a saddle connection with holonomy \(z \in {\mathbb C}\) at the point \(z^2\).

pos = {}
for i in range(len(sc_list2)):
    sc = sc_list2[i]
    val = sc.holonomy().n()
    z = val[0] + I * val[1]
    w = z**2 / z.abs()
    pos[i] = (w.real(), w.imag())
g.plot(pos=pos, vertex_labels=False, vertex_size=0)
../_images/112140d489cf90050f81d968e6a3ff50aa5f1f06b5fd8885775699c8e761f955.png