Рождественские дни — время отложить привычные дела и вспомнить забавы — калейдоскопы, мозаики, снежинки… Кто нарисует самую красивую звезду?
![](https://habrastorage.org/r/w1560/files/c20/ecf/fa1/c20ecffa12c74c49b3ede917eff785b0.png)
Симметрия радует глаз. Создать красоту помогает математика, язык Питон и его библиотеки — математический numpy и графический matplotlib.
КДПВ получена визуализацией значений собственных векторов некой симметричной матрицы.
В основе — спектры регулярных решеток. Некоторые их свойства уже рассматривались ранее. Здесь формулы поработают на эстетику.
Итак, допустим, есть некий базовый набор точек, расположенных на плоскости. Требований немного — конфигурация должна быть центрально симметричной. Например, хорошим выбором будет шестиугольная сетка:
![](https://habrastorage.org/r/w1560/files/391/d87/d5d/391d87d5d2ed4606825c93912b04aea7.png)
Уже красиво, только несколько однообразно.
Кружки — это точки. Каждая характеризуется двумя координатами. Для заданного набора точек можно вычислить их собственные координаты на основе матрицы квадратов расстояний между точками. Об этом рассказано в упомянутой выше статье. Для расчета спектра надо матрицу квадратов расстояний преобразовать в лапласиан (которым в данном случае является матрица корреляции) и вычислить спектр данного лапласиана, то есть найти его собственные числа и соответствующие им векторы.
Если рассчитать спектр для набора точек, расположенных на плоскости, то в спектре будет всего лишь две компоненты — одна соответствует координате x, а другая — y.
А надо сделать так, чтобы спектр «зазвенел», но при этом сохранил симметрию. Добиться этого несложно. Достаточно изменить (или возмутить) функцию расстояния между точками. Например, можно положить, что расстояние между точками равно не квадрату расстояния, а его кубу, или обратному расстоянию — можно использовать любую функцию, зависящую от расстояния.
Для такой «матрицы расстояний» спектр уже не может быть двумерным. Алгоритм разложения матрицы расстояний в спектр должен каким-то образом подобрать каждой точке такой набор координат, чтобы удовлетворить нестандартному расстоянию. Такой спектр начинает звенеть, — количество его компонент в общем случае равно общему количеству точек (правда, нулевой можно исключить).
Если набор точек обладает симметрией, то часть компонент будет вырождена. Это означает, что одному и тому же значению собственного числа будут соответствовать разные собственные векторы. В нашем случае исходная конфигурация точек двумерна,- соответственно и степень вырождения будет кратна двум (наверное, для этого утверждения существует какая-то теорема). А это значит, что такие двукратно вырожденные уровни — проекции — можно нарисовать на плоскости. В самом простом варианте — также точками.
Допустим, что функция расстояния имеет следующий вид:
f(R2) = w*Rd + 1/Rd, где w = dist/n^2, Rd = R2^degree.
Здесь dist и degree — два варьируемых параметра возмущения. Тогда первые 9 вырожденных уровней для представленной выше базовой конфигурации (гексагональной решетки размера 7) при параметрах возмущения dist = -2, degree = 1 имеют вид:
![](https://habrastorage.org/r/w1560/files/ab4/cde/5f4/ab4cde5f422d490487e8ad72c4412baf.png)
В левом верхнем углу — исходная конфигурация. Значения параметров подобраны таким образом, чтобы она была почти не искаженной.
Все узоры гарантированно разные, — это следует из свойств собственных векторов (хотя иногда на глаз не отличимы). Некоторые кажутся более необычными чем другими. Вот, например, одна из причудливых конфигураций:
![](https://habrastorage.org/r/w1560/files/38f/4d8/af2/38f4d8af232d4ddcbb4ef1aff3dd1e4f.png)
Можно взять в качестве исходного набора квадратную решетку. Тогда симметрия будет квадратной:
![](https://habrastorage.org/r/w1560/files/896/270/a3b/896270a3b745465a9f412c28d0cca750.png)
Поскольку симметрия понижена, то количество невырожденных спектров тут в два раза больше, чем вырожденных.
Если придать точкам цвет и размер, то снежинки (узоры) станут веселее и разнообразнее. Фишка в том, что цвет и размер точек можно также формировать на основе собственных векторов данного набора.
Алгоритм формирования цвета простой. Используем некую цветовую карту (из доступных наборов в matplotlib), которая преобразует значение точки в цвет, а само значение точки берем из какого-нибудь невырожденного собственного вектора. То же самое и для размера точки. Тогда можно получить примерно такое веселое кружево:
![](https://habrastorage.org/r/w1560/files/b27/8b2/3ba/b278b23bacf14cb5b880cfb9f7a0a3b5.png)
Если варьировать только цвет, то можно поиграть в детскую мозаику:
![](https://habrastorage.org/r/w1560/files/8c1/20a/53c/8c120a53c4bc4746aa9e735251c2254d.png)
Это математика разукрасила базовую конфигурацию точек в разные цвета.
Если близкие точки соединить линиями, то получим нечто вроде паутины. По научному такая операция называется триангуляцией. Достоинство пакета matplotlib в том, что там такая операция доступна «из коробки». Паутинки красивы:
![](https://habrastorage.org/r/w1560/files/c9e/e17/50a/c9ee1750aa624806af8696761c8315d5.png)
Можно удалить часть треугольников на основе масок:
![](https://habrastorage.org/r/w1560/files/3fc/fdb/316/3fcfdb316dec476eacf214bf08223260.png)
Триангуляция становится цветной, если треугольники залить разными цветами:
![](https://habrastorage.org/r/w1560/files/f0b/b81/8b1/f0bb818b1681478683cf1bddd0378f28.png)
Выбор цветовой карты и цветового вектора сильно влияет на восприятие одной и той же конфигурации:
![](https://habrastorage.org/r/w1560/files/481/e59/8e1/481e598e1fa34c8583b208b7a30318ab.png)
Использование масок обостряет контуры узоров:
![](https://habrastorage.org/r/w1560/files/b81/e5c/82a/b81e5c82a100495aba3bd882d99cedd0.png)
Количество комбинаций и вариаций практически бесконечно, игра узоров очень причудлива.
Возможно, что самыми изысканными являются узоры, полученные с помощью рисования контуров на основе триангуляции. Данные узоры получаются с помощью метода tricontour() библиотеки matplotlib. Даже самые невзрачные и скучные наборы точек приобретают совершенно неожиданные вариации.
![](https://habrastorage.org/r/w1560/files/a17/388/607/a17388607d8048c997709f026bb885cc.png)
Симметрия может быть любой, например, 5-го порядка:
![](https://habrastorage.org/r/w1560/files/e28/d0e/a17/e28d0ea17de94ad0b1deeda882390880.png)
Магия какая-то.
Все приведенные узоры создавались с помощью программы "Spectroscope" написанной на Питоне. Код программы не идеален, но доступен.
![](https://habrastorage.org/r/w1560/files/278/2e1/32d/2782e132d23d4739a0572cff0a584f0c.png)
С ее помощью каждый может создавать узоры, варьируя параметры через несложный интерфейс.
Вверху панели управления можно выбрать один из базовых наборов распределений точек (Base). Базовое распределение всегда имеет индекс один, если параметры возмущения равны соответственно -2 (Disturb) и 1 (Degree), поэтому на него можно всегда посмотреть.
Наиболее мощными являются базовые наборы Hex (гекс) и Square (квадрат), так как в них больше всего точек. Поэтому и разнообразных узоров они дают больше. А вот наборы x-border (границы многоугольников) и особенно Circle (окружность) наоборот — выхолощены и интересны больше для исследовательских целей.
Для базового набора можно указать его размер (Order) с помощью слайдера (ползунка). Следующее поле (Index) задает номера отображаемых спектров (уровней) из доступных для данного набора. В данной версии можно выводить 1, 4 или 9 узоров одновременно.
Важный параметр — тип узора (Plot type). Именно он задает способ (режим) отображения наших собственных векторов. Доступные перечислены выше (Points, Web, Mosaic, Contour).
Флажок "Titles" выводит над каждым спектром его числовые параметры, порядковый номер в общем составе уровней и значение собственного числа данного уровня. Это для тех, кому интересна не только графика.
Ниже расположены два слайдера для параметров варьирования. При их изменении спектры оживают. Напомним, что правая кнопка мыши на слайдере — сдвигает его к текущему положению, левая — инкрементирует.
Далее следуют параметры, влияющие на вид спектров — цвет, маркеры и маска. Не во всех режимах отображения они задействованы. Маркеры, например, имеют значение только для «точечного» режима, а маски — наоборот,- для всех, кроме точечного.
Наиболее важен, пожалуй, цвет (Color). Для его задания необходимо указать цветовую карту (Map). Но играют цветом с помощью вектора (слайдер с флажком Use). Вектор цвета (и размера маркеров тоже) выбирается, как уже отмечалось, из невырожденных уровней.
В меню программы доступны стандартные функции для сохранения спектров в файлы и экспорта как изображений.
Есть много направлений, куда можно развивать спектроскоп. Помимо очевидных улучшений интерфейса, развития возможностей (анимация, например, или веб-доступ) нужно попробовать построить трехмерные узоры. Их можно не только смотреть, но и лепить ).
Во время игр со спектрами возникает несколько интересных вопросов разной степени важности.
Может, это и не самый важный вопрос, но возможно, самый простой. Очевидно, что доля вырожденных спектров зависит от базового распределения точек. Для основных решеток (гексагональной и квадратной) есть явные формулы.
Для гексагональной решетки количество «снежинок» Ns связано с общим количеством точек (узлов) N как:
Ns = (N-1)/3
В свою очередь количество точек квадратично зависит от размера решетки a:
N(a) = 3a(a-1) + 1. Отсюда Ns(a) = a(a-1).
В квадратной решетке количество вырожденных спектров связано с количеством точек аналогичным образом:
Ns = N/4 = a^2/4
Как получать такие формулы для произвольных конфигураций — не очень понятно. Возможно, что общего алгоритма и не существует.
Пожалуй, наиболее интересный вопрос. Основным способом идентификации уровней спектра является величина собственного числа. Если отсортировать данные числа в порядке возрастания, то можно каждому уровню (значению собственного числа) присвоить индекс. Данный индекс как будто бы и идентифицирует спектр.
На самом деле это не очень надежный способ. При варьировании параметров возмущения спектры оживают — узоры начинают дышать (можно видеть, например, как «плющит» базовое распределение при изменении параметра Disturb), и их собственные числа тоже меняются. При этом возникают ситуации, когда собственные числа разных уровней приближаются к друг другу и проходят далее. То есть спектры меняются местами. При этом по характеру рисунка спектра можно видеть, где какой спектр. Этот «характер» и надо каким-то образом хэшировать в идентификатор спектра.
Явление бурного изменения узоров происходит в узкой полосе параметра возмущения. Похоже чем-то на фазовый переход. Возможно, что это известное явление. При фазовом переходе меняется как вид спектров, так и их относительное расположение. В программе выбран вид возмущаемой функции таким, чтобы при изменении параметра возмущения Disturb функция меняла знак. Можно видеть, что базовое распределение при изменении параметра с минимального на максимальный переходит с первого индекса на последний. Этот переход осуществляется вроде бы перемещением базового узора по индексам от меньшего к большему. Через какое-то время измененный базовый узор возникает на последнем индексе. Который затем эволюционирует к исходной базовой конфигурации.
Однако в больших конфигурациях, похоже, никто никуда не перемещается (ну или это невозможно отследить). Просто в определенный момент возникает зачаток новой базовой конфигурации в нужном месте (на максимальном индексе). Короче, кому интересно — посмотрите ).
Если бы был какой-то параметр идентификации собственных уровней — можно было бы более точно отслеживать перемещение (или смерть и рождение?) спектров. И показывать на картинке всегда заданные спектры независимо от значений их собственных чисел.
тоже пока не особо удалась. Узоры периодически вращаются вправо/влево. Непонятно, каким образом проще всего сориентировать их всегда в одном направлении.
Когда базовой конфигурацией является простая окружность (точки в вершинах правильных многоугольников), то возникает феномен делителей целых чисел. В такой конфигурации все точки равноправны. Соответственно все вырожденные уровни (а других тут и нет) также являются координатами вершин многоугольников (лежат на окружности). Но при этом спектры простых многоугольников (число вершин простое число) отличаются от составных. В спектрах простых все уровни — это тоже простые многоугольники с таким же числом вершин. А в спектрах составных уровни состоят из делителей вершин базового многоугольника.
Например, спектр 30-угольника состоит из 14 вырожденных уровней (проекций). Из них четыре 30-угольника, четыре 15-угольника, два 10-угольника, один 6-угольник, два 5-угольника и один 3-угольник. Почему именно такое распределение уровней по делителям — не ясно (но сильно и не вникали). Возможно, это уже объяснено где-то в теории групп.
На этом пока все. Удачи в творческом поиске и с Рождеством!
![](https://habrastorage.org/files/c20/ecf/fa1/c20ecffa12c74c49b3ede917eff785b0.png)
Симметрия радует глаз. Создать красоту помогает математика, язык Питон и его библиотеки — математический numpy и графический matplotlib.
Спектры невозможных решеток
КДПВ получена визуализацией значений собственных векторов некой симметричной матрицы.
В основе — спектры регулярных решеток. Некоторые их свойства уже рассматривались ранее. Здесь формулы поработают на эстетику.
Итак, допустим, есть некий базовый набор точек, расположенных на плоскости. Требований немного — конфигурация должна быть центрально симметричной. Например, хорошим выбором будет шестиугольная сетка:
![](https://habrastorage.org/files/391/d87/d5d/391d87d5d2ed4606825c93912b04aea7.png)
Уже красиво, только несколько однообразно.
Кружки — это точки. Каждая характеризуется двумя координатами. Для заданного набора точек можно вычислить их собственные координаты на основе матрицы квадратов расстояний между точками. Об этом рассказано в упомянутой выше статье. Для расчета спектра надо матрицу квадратов расстояний преобразовать в лапласиан (которым в данном случае является матрица корреляции) и вычислить спектр данного лапласиана, то есть найти его собственные числа и соответствующие им векторы.
Если рассчитать спектр для набора точек, расположенных на плоскости, то в спектре будет всего лишь две компоненты — одна соответствует координате x, а другая — y.
А надо сделать так, чтобы спектр «зазвенел», но при этом сохранил симметрию. Добиться этого несложно. Достаточно изменить (или возмутить) функцию расстояния между точками. Например, можно положить, что расстояние между точками равно не квадрату расстояния, а его кубу, или обратному расстоянию — можно использовать любую функцию, зависящую от расстояния.
Для такой «матрицы расстояний» спектр уже не может быть двумерным. Алгоритм разложения матрицы расстояний в спектр должен каким-то образом подобрать каждой точке такой набор координат, чтобы удовлетворить нестандартному расстоянию. Такой спектр начинает звенеть, — количество его компонент в общем случае равно общему количеству точек (правда, нулевой можно исключить).
Если набор точек обладает симметрией, то часть компонент будет вырождена. Это означает, что одному и тому же значению собственного числа будут соответствовать разные собственные векторы. В нашем случае исходная конфигурация точек двумерна,- соответственно и степень вырождения будет кратна двум (наверное, для этого утверждения существует какая-то теорема). А это значит, что такие двукратно вырожденные уровни — проекции — можно нарисовать на плоскости. В самом простом варианте — также точками.
Допустим, что функция расстояния имеет следующий вид:
f(R2) = w*Rd + 1/Rd, где w = dist/n^2, Rd = R2^degree.
Здесь dist и degree — два варьируемых параметра возмущения. Тогда первые 9 вырожденных уровней для представленной выше базовой конфигурации (гексагональной решетки размера 7) при параметрах возмущения dist = -2, degree = 1 имеют вид:
![](https://habrastorage.org/files/ab4/cde/5f4/ab4cde5f422d490487e8ad72c4412baf.png)
В левом верхнем углу — исходная конфигурация. Значения параметров подобраны таким образом, чтобы она была почти не искаженной.
Все узоры гарантированно разные, — это следует из свойств собственных векторов (хотя иногда на глаз не отличимы). Некоторые кажутся более необычными чем другими. Вот, например, одна из причудливых конфигураций:
![](https://habrastorage.org/files/38f/4d8/af2/38f4d8af232d4ddcbb4ef1aff3dd1e4f.png)
Можно взять в качестве исходного набора квадратную решетку. Тогда симметрия будет квадратной:
![](https://habrastorage.org/files/896/270/a3b/896270a3b745465a9f412c28d0cca750.png)
Поскольку симметрия понижена, то количество невырожденных спектров тут в два раза больше, чем вырожденных.
Добавляем цвет и размер
Если придать точкам цвет и размер, то снежинки (узоры) станут веселее и разнообразнее. Фишка в том, что цвет и размер точек можно также формировать на основе собственных векторов данного набора.
Алгоритм формирования цвета простой. Используем некую цветовую карту (из доступных наборов в matplotlib), которая преобразует значение точки в цвет, а само значение точки берем из какого-нибудь невырожденного собственного вектора. То же самое и для размера точки. Тогда можно получить примерно такое веселое кружево:
![](https://habrastorage.org/files/b27/8b2/3ba/b278b23bacf14cb5b880cfb9f7a0a3b5.png)
Если варьировать только цвет, то можно поиграть в детскую мозаику:
![](https://habrastorage.org/files/8c1/20a/53c/8c120a53c4bc4746aa9e735251c2254d.png)
Это математика разукрасила базовую конфигурацию точек в разные цвета.
Паутинки
Если близкие точки соединить линиями, то получим нечто вроде паутины. По научному такая операция называется триангуляцией. Достоинство пакета matplotlib в том, что там такая операция доступна «из коробки». Паутинки красивы:
![](https://habrastorage.org/files/c9e/e17/50a/c9ee1750aa624806af8696761c8315d5.png)
Можно удалить часть треугольников на основе масок:
![](https://habrastorage.org/files/3fc/fdb/316/3fcfdb316dec476eacf214bf08223260.png)
Мозаики
Триангуляция становится цветной, если треугольники залить разными цветами:
![](https://habrastorage.org/files/f0b/b81/8b1/f0bb818b1681478683cf1bddd0378f28.png)
Выбор цветовой карты и цветового вектора сильно влияет на восприятие одной и той же конфигурации:
![](https://habrastorage.org/files/481/e59/8e1/481e598e1fa34c8583b208b7a30318ab.png)
Использование масок обостряет контуры узоров:
![](https://habrastorage.org/files/b81/e5c/82a/b81e5c82a100495aba3bd882d99cedd0.png)
Количество комбинаций и вариаций практически бесконечно, игра узоров очень причудлива.
Контуры
Возможно, что самыми изысканными являются узоры, полученные с помощью рисования контуров на основе триангуляции. Данные узоры получаются с помощью метода tricontour() библиотеки matplotlib. Даже самые невзрачные и скучные наборы точек приобретают совершенно неожиданные вариации.
![](https://habrastorage.org/files/a17/388/607/a17388607d8048c997709f026bb885cc.png)
Симметрия может быть любой, например, 5-го порядка:
![](https://habrastorage.org/files/e28/d0e/a17/e28d0ea17de94ad0b1deeda882390880.png)
Магия какая-то.
Спектроскоп
Все приведенные узоры создавались с помощью программы "Spectroscope" написанной на Питоне. Код программы не идеален, но доступен.
![](https://habrastorage.org/files/278/2e1/32d/2782e132d23d4739a0572cff0a584f0c.png)
С ее помощью каждый может создавать узоры, варьируя параметры через несложный интерфейс.
Вверху панели управления можно выбрать один из базовых наборов распределений точек (Base). Базовое распределение всегда имеет индекс один, если параметры возмущения равны соответственно -2 (Disturb) и 1 (Degree), поэтому на него можно всегда посмотреть.
Наиболее мощными являются базовые наборы Hex (гекс) и Square (квадрат), так как в них больше всего точек. Поэтому и разнообразных узоров они дают больше. А вот наборы x-border (границы многоугольников) и особенно Circle (окружность) наоборот — выхолощены и интересны больше для исследовательских целей.
Для базового набора можно указать его размер (Order) с помощью слайдера (ползунка). Следующее поле (Index) задает номера отображаемых спектров (уровней) из доступных для данного набора. В данной версии можно выводить 1, 4 или 9 узоров одновременно.
Важный параметр — тип узора (Plot type). Именно он задает способ (режим) отображения наших собственных векторов. Доступные перечислены выше (Points, Web, Mosaic, Contour).
Флажок "Titles" выводит над каждым спектром его числовые параметры, порядковый номер в общем составе уровней и значение собственного числа данного уровня. Это для тех, кому интересна не только графика.
Ниже расположены два слайдера для параметров варьирования. При их изменении спектры оживают. Напомним, что правая кнопка мыши на слайдере — сдвигает его к текущему положению, левая — инкрементирует.
Далее следуют параметры, влияющие на вид спектров — цвет, маркеры и маска. Не во всех режимах отображения они задействованы. Маркеры, например, имеют значение только для «точечного» режима, а маски — наоборот,- для всех, кроме точечного.
Наиболее важен, пожалуй, цвет (Color). Для его задания необходимо указать цветовую карту (Map). Но играют цветом с помощью вектора (слайдер с флажком Use). Вектор цвета (и размера маркеров тоже) выбирается, как уже отмечалось, из невырожденных уровней.
В меню программы доступны стандартные функции для сохранения спектров в файлы и экспорта как изображений.
Есть много направлений, куда можно развивать спектроскоп. Помимо очевидных улучшений интерфейса, развития возможностей (анимация, например, или веб-доступ) нужно попробовать построить трехмерные узоры. Их можно не только смотреть, но и лепить ).
Математические аспекты
Во время игр со спектрами возникает несколько интересных вопросов разной степени важности.
Расчет количества вырожденных спектров
Может, это и не самый важный вопрос, но возможно, самый простой. Очевидно, что доля вырожденных спектров зависит от базового распределения точек. Для основных решеток (гексагональной и квадратной) есть явные формулы.
Для гексагональной решетки количество «снежинок» Ns связано с общим количеством точек (узлов) N как:
Ns = (N-1)/3
В свою очередь количество точек квадратично зависит от размера решетки a:
N(a) = 3a(a-1) + 1. Отсюда Ns(a) = a(a-1).
В квадратной решетке количество вырожденных спектров связано с количеством точек аналогичным образом:
Ns = N/4 = a^2/4
Как получать такие формулы для произвольных конфигураций — не очень понятно. Возможно, что общего алгоритма и не существует.
Идентификация уровней спектра
Пожалуй, наиболее интересный вопрос. Основным способом идентификации уровней спектра является величина собственного числа. Если отсортировать данные числа в порядке возрастания, то можно каждому уровню (значению собственного числа) присвоить индекс. Данный индекс как будто бы и идентифицирует спектр.
На самом деле это не очень надежный способ. При варьировании параметров возмущения спектры оживают — узоры начинают дышать (можно видеть, например, как «плющит» базовое распределение при изменении параметра Disturb), и их собственные числа тоже меняются. При этом возникают ситуации, когда собственные числа разных уровней приближаются к друг другу и проходят далее. То есть спектры меняются местами. При этом по характеру рисунка спектра можно видеть, где какой спектр. Этот «характер» и надо каким-то образом хэшировать в идентификатор спектра.
Фазовые переходы
Явление бурного изменения узоров происходит в узкой полосе параметра возмущения. Похоже чем-то на фазовый переход. Возможно, что это известное явление. При фазовом переходе меняется как вид спектров, так и их относительное расположение. В программе выбран вид возмущаемой функции таким, чтобы при изменении параметра возмущения Disturb функция меняла знак. Можно видеть, что базовое распределение при изменении параметра с минимального на максимальный переходит с первого индекса на последний. Этот переход осуществляется вроде бы перемещением базового узора по индексам от меньшего к большему. Через какое-то время измененный базовый узор возникает на последнем индексе. Который затем эволюционирует к исходной базовой конфигурации.
Однако в больших конфигурациях, похоже, никто никуда не перемещается (ну или это невозможно отследить). Просто в определенный момент возникает зачаток новой базовой конфигурации в нужном месте (на максимальном индексе). Короче, кому интересно — посмотрите ).
Если бы был какой-то параметр идентификации собственных уровней — можно было бы более точно отслеживать перемещение (или смерть и рождение?) спектров. И показывать на картинке всегда заданные спектры независимо от значений их собственных чисел.
Стабилизация картинки
тоже пока не особо удалась. Узоры периодически вращаются вправо/влево. Непонятно, каким образом проще всего сориентировать их всегда в одном направлении.
Делители
Когда базовой конфигурацией является простая окружность (точки в вершинах правильных многоугольников), то возникает феномен делителей целых чисел. В такой конфигурации все точки равноправны. Соответственно все вырожденные уровни (а других тут и нет) также являются координатами вершин многоугольников (лежат на окружности). Но при этом спектры простых многоугольников (число вершин простое число) отличаются от составных. В спектрах простых все уровни — это тоже простые многоугольники с таким же числом вершин. А в спектрах составных уровни состоят из делителей вершин базового многоугольника.
Например, спектр 30-угольника состоит из 14 вырожденных уровней (проекций). Из них четыре 30-угольника, четыре 15-угольника, два 10-угольника, один 6-угольник, два 5-угольника и один 3-угольник. Почему именно такое распределение уровней по делителям — не ясно (но сильно и не вникали). Возможно, это уже объяснено где-то в теории групп.
На этом пока все. Удачи в творческом поиске и с Рождеством!