Как создать двумерную ленту Мёбиуса, бутылку Клейна и массивы проективной плоскости? - PullRequest
0 голосов
/ 31 октября 2018

Я читал следующую статью о & ldquo; Играх на странных досках & rdquo ;. Он описывает различные локально топологии двумерного массива, такие как:

  1. цилиндр

    Cylinder

  2. Torus

    Torus

  3. полоса Мёбиуса

    Möbius strip

  4. бутылка Кляйна

    Klein bottle

  5. Проективная плоскость

    Projective plane

На вышеприведенных диаграммах стороны с одинаковыми стрелками склеены таким образом, что они совпадают. Следовательно, если стрелки указывают в одном и том же направлении, они приклеиваются нормально. Однако, если они указывают в разные стороны, они склеиваются после скручивания.

Например, перемещение от верхнего правого края цилиндра вернет вас к верхнему левому краю. Однако перемещение с верхнего правого края ленты Мебиуса вернет вас к нижнему левому краю.

Теперь создавать цилиндрические и тороидальные массивы очень просто. Вы используете операцию по модулю, чтобы обернуть строки и столбцы. Рассмотрим код для вычисления координат тороидального массива с m строками и n столбцами:

const mod = (x, y) => (x % y + y) % y; // floored division modulo operation

const coords = (m, n) => (i, j) => [mod(i, m), mod(j, n)]; // toroidal array

Как бы вы рассчитали координаты ленты Мебиуса, бутылки Клейна или проективной плоскости? Существуют ли какие-либо особые случаи для рассмотрения, учитывая, что это неориентируемые поверхности ?

1 Ответ

0 голосов
/ 31 октября 2018

Рассмотрим цилиндр из прямоугольного листа бумаги. Лист имеет две стороны, переднюю и заднюю. Когда мы склеиваем лист в цилиндр, мы не можем достичь задней стороны (внутри цилиндра) с передней стороны (снаружи цилиндра). Однако, если мы склеим лист бумаги в полосу Мёбиуса, то сможем. Вот как будет выглядеть сетка на полосе Мёбиуса, если мы разделим две стороны и сгладим ее:

 ┌────┬────┬────┬────┰────┬────┬────┬────┐
 │ a4 │ b4 │ c4 │ d4 ┃ A1 │ B1 │ C1 │ D1 │
 ├────┼────┼────┼────╂────┼────┼────┼────┤
 │ a3 │ b3 │ c3 │ d3 ┃ A2 │ B2 │ C2 │ D2 │
 ├────┼────┼────┼────╂────┼────┼────┼────┤
 │ a2 │ b2 │ c2 │ d2 ┃ A3 │ B3 │ C3 │ D3 │
 ├────┼────┼────┼────╂────┼────┼────┼────┤
 │ a1 │ b1 │ c1 │ d1 ┃ A4 │ B4 │ C4 │ D4 │
 └────┴────┴────┴────┸────┴────┴────┴────┘

Обратите внимание, что квадраты слева (т. Е. В нижнем регистре) находятся спереди, а квадраты справа (т. Е. В верхнем регистре) находятся сзади. Квадраты с разницей в регистре - это один и тот же квадрат, только на противоположных сторонах полосы Мебиуса. Следует отметить, что эта сплющенная полоса Мёбиуса очень похожа на цилиндр, за исключением того, что левая и правая стороны совпадают.

Вот как будет выглядеть код для ленты Мебиуса:

const mod = (x, y) => (x % y + y) % y;

const coords = (m, n) => (i, j) => {
    j = mod(j, 2 * n);         // wrapping around like a cylinder
    if (j < n) return [i, j];  // front side
    return [m - i - 1, j - n]; // back side, translated to front side
};

Бутылка Кляйна, точно такая же, как полоса Мёбиуса, за исключением того, что она ведет себя как тор, а не как цилиндр. Вот как будет выглядеть код бутылки Кляйна:

const mod = (x, y) => (x % y + y) % y;

const coords = (m, n) => (i, j) => {
    i = mod(i, m);             // wrapping around
    j = mod(j, 2 * n);         // like a torus
    if (j < n) return [i, j];  // front side
    return [m - i - 1, j - n]; // back side, translated to front side
};

Проективная плоскость также ведет себя как тор. Однако каждая из его сторон может иметь две ориентации, правильную и повернутую на 180 °. Вот как будет выглядеть сплющенная проективная плоскость:

 ┌────┬────┬────┬────┰────┬────┬────┬────┐
 │ a4 │ b4 │ c4 │ d4 ┃ A1 │ B1 │ C1 │ D1 │
 ├────┼────┼────┼────╂────┼────┼────┼────┤
 │ a3 │ b3 │ c3 │ d3 ┃ A2 │ B2 │ C2 │ D2 │
 ├────┼────┼────┼────╂────┼────┼────┼────┤
 │ a2 │ b2 │ c2 │ d2 ┃ A3 │ B3 │ C3 │ D3 │
 ├────┼────┼────┼────╂────┼────┼────┼────┤
 │ a1 │ b1 │ c1 │ d1 ┃ A4 │ B4 │ C4 │ D4 │
 ┝━━━━┿━━━━┿━━━━┿━━━━╋━━━━┿━━━━┿━━━━┿━━━━┥
 │ D4 │ C4 │ B4 │ A4 ┃ d1 │ c1 │ b1 │ a1 │
 ├────┼────┼────┼────╂────┼────┼────┼────┤
 │ D3 │ C3 │ B3 │ A3 ┃ d2 │ c2 │ b2 │ a2 │
 ├────┼────┼────┼────╂────┼────┼────┼────┤
 │ D2 │ C2 │ B2 │ A2 ┃ d3 │ c3 │ b3 │ a3 │
 ├────┼────┼────┼────╂────┼────┼────┼────┤
 │ D1 │ C1 │ B1 │ A1 ┃ d4 │ c4 │ b4 │ a4 │
 └────┴────┴────┴────┸────┴────┴────┴────┘

Итак, вот как будет выглядеть код для проективной плоскости:

const mod = (x, y) => (x % y + y) % y;

const coords = (m, n) => (i, j) => {
    i = mod(i, 2 * m);         // wrapping around
    j = mod(j, 2 * n);         // like a torus

    if (i >= m) {              // collapse to Klein bottle topology
        i -= m;
        j  = mod(n - j - 1, 2 * n);
    }

    if (j < n) return [i, j];  // front side
    return [m - i - 1, j - n]; // back side, translated to front side
};

Надеюсь, это поможет.

...