Kleinian reflections¶
This notebook illustrates repeated reflections in a system of circular mirrors (called here cycles in line with the general framework).
First, we define a procedure which will make iterative reflections of a figure in the initial cycles.
def make_reflections(F, n : int):
"""The routine produces sequential reflection of the figure F
in its all generation-0 cycles in a turn.
n -- the number of reflections to perform.
Since there is no predefined ordering for GiNaC object,
every run of this routine can produce a different output."""
# We are copying the figure to do not spoil the original with reflections.
F0= figure(F)
# All cycles at generation 0 a treated as mirrors
mirrors = F0.get_all_keys(0, 0)
Nm = len(mirrors)
for i in range(n):
# print(f"Make reflection in {mirrors[i % Nm]}")
# supscript_regex(f"{i}") is used to produce unique supscripts for cycles under each refelection
F0.reflection(mirrors[i % Nm], True, supscript_regex(f"{i}"), False)
return figure(F0)
The simplicity of the above routine is possible due to advanced algorithms implemented in the library figure
, which we are loading here.
from figure import *
from IPython.display import Image
show_asy_off()
%load_ext figure.figure_ipython
Now we define a simple figure with only two cycles. We are adding a bit of colours to make illustration more vivid.
# We define a new figure with the following point and cycle metrics:
mir = figure()
mir.set_asy_style(mir.get_real_line(), "invisible")
# ## Cycles in generation 0
# The following cycles are defined by their coefficients
A = mir.add_cycle(cycle_data(1, matrix([[1.0, 0]]), -1), "A")
mir.set_asy_style(A, "rgb(0,0.333333,0)+solid+1pt")
B = mir.add_cycle(cycle_data(1, matrix([[-2.25, 0]]), 2), "B")
mir.set_asy_style(B, "rgb(0.666667,0,1)+solid+1pt")
%asy_write mir, 300, -3, 2, -3, 3, "mirrors"
For visualisation we have used the IPython magic here defined by the figure
package. Otherwise a pair of commands
#mir.asy_write(300, -3, 2, -3, 3, "mirrors", "png", True, True, 0, "", True, False)
#Image("mirrors.png")
will produce the same effect.
Let us see what are the repeated reflections in these two cycles.
Technical: We supplied the parameter with_labels=False
to the method asy_write()
because we do not want the appearance of cycles' labels: there will be too many cycles after reflections, their labels will make the picture messy.
mir1 = make_reflections(mir, 6)
%asy_write mir1, 300, -3, 2, -3, 3, "mirrors2", with_labels=False
We got nested cycles from the pencil spanned by the initial two cycles. This can be verified as follows:
reflections = mir1.get_all_keys(1, 6)
AreInPencil = True
for R in reflections:
AreInPencil = AreInPencil and mir1.check_rel(R, [A,B], 'pencil')[0].op(0).is_zero_matrix()
f"The reflection belongs to the pencil of mirrors: {AreInPencil}"
Let us add the third cycle to the figure...
C = mir.add_cycle(cycle_data(1, matrix([[-0.35, 2.1]]), 3.45), "C")
mir.set_asy_style(C, "rgb(0,0,1)+solid+1pt")
%asy_write mir, 300, -3, 2, -3, 3, "mirrors"
...and produce reflections for them:
mir1 = make_reflections(mir, 6)
%asy_write mir1, 300, -3, 2, -3, 3, "mirrors3", with_labels=False
This time all images are located around the cycle orthogonal to three initial cycles. Let us add this cycle explicitly to visualise the relation:
mir1.add_cycle_rel([is_orthogonal(A), is_orthogonal(B), is_orthogonal(C)], "E")
%asy_write mir1, 500, -3, 2, -3, 3, "mirrors3a", with_labels=False
Finally, let us add the fourth cycle,
D = mir.add_cycle(cycle_data(1, matrix([[-0.24, -3.11]]), 6), "D")
mir.set_asy_style(D, "rgb(0.67,0.33,0)+solid+1pt")
%asy_write mir, 300, -3, 2, -3, 3, "mirrors", "png"
%asy_write make_reflections(mir, 12), 500,-3,2,-3,3,"mirrors4","png", with_labels=False
References¶
- Mumford, David; Series, Caroline; Wright, David (2002), Indra's pearls, Cambridge University Press, ISBN 978-0-521-35253-6, MR 1913879