Рисование зон Бриллюэна в TikZ

Рисование зон Бриллюэна в TikZ

Я пытаюсь заставить TikZ рисовать зоны Бриллюэна для двумерных решеток, но пока что мне не очень повезло ни с чем из того, что я пробовал. Зоны Бриллюэна — это, по сути, область пространства вокруг точки решетки, которая находится ближе всего к этой точке, и поэтому они похожи наДиаграммы Вороного. Вы можете увидеть, как они выглядят, на этом изображении, на котором нарисованы первая, вторая и третья зоны Бриллюэна: первые три зоны Бриллюэна
(источник:eelvex.net)

Если бы я рисовал это вручную, я бы построил первую зону Бриллюэна, проведя линию от центральной точки решетки до каждой из точек на расстоянии 1 (принимая, что точки решетки разделены единичным расстоянием) от центральной точки, так что это были бы те, что к северу, востоку, югу и западу от нее. Затем я бы взял перпендикулярные серединные сектора (на языке физики это плоскости Брэгга) каждой из этих линий. Тогда первая зона Бриллюэна была бы областью, которая ограничена перпендикулярными серединными секторами (и является серой областью, заштрихованной на изображении выше). Более высокие зоны строятся таким же образом; дается немного другое объяснениена этом сайте. У него также есть код в Asymptote, но он, похоже, просто жестко закодирован.

Есть ли способ сделать это в TikZ, и есть ли способ сделать это как для любой заданной решетки, так и для любого количества зон Бриллюэна? Я пробовал несколько подходов, но безуспешно, включая различные попытки сделать это с помощью Lua (в котором я очень неопытен), но единственное, что у меня действительно работает, — это способ рисования точек решетки, который я включил здесь для квадратной решетки, но не так уж сложно модифицировать его, чтобы получить шестиугольную решетку.

\documentclass{standalone}
\usepackage{tikz}
\begin{document}
%%% For a square lattice
\begin{tikzpicture}
\foreach \x in {-2, ..., 2}{
    \foreach \y in {-2, ..., 2}{
        \fill [black] (\x, \y) circle (0.1);
    }   
}
\end{tikzpicture}
\end{document}

решение1

Есть ли способ сделать это в TikZ, и есть ли способ сделать это как для любой заданной решетки, так и для любого количества зон Бриллюэна?

Короткий ответ:Да!

Более развернутый ответ:Нет!Эта задача может быть вычислительно очень затратной для больших значений. Вам следует отделить расчет от отображения, потому что (я полагаю) вы не хотите начинать с нуля каждый раз при компиляции. И если вы делаете это отдельно, почему бы вам не использовать более подходящий инструмент для этого, который может легко хранить и использовать ранее вычисленные вещи для любой заданной решетки?!


Более длинный ответ наЧасть "Да". Вот алгоритм, который может работать и может быть реализован в LaTeX (но на самом деле не должен). Он немного «хакерский», потому что это описание на самом деле не подразумевает «закрытую формулу» для раскрашивания (и, возможно, ее нет).

Я думаю, что следующее должно работать. И это утверждение основано на индуктивной природе алгоритма.

  1. Вычислите серединные перпендикуляры.
  2. Вычислите пересечение (если оно есть) для каждой пары биссектрис.
  3. Создатьструктура данныхкоторый индексируется по пересечениям и имеет список для каждого из них с проходящими через него линиями.
  4. Создайте список рёбер из внутреннего квадрата ( k=0квадрат). Пусть k=1.
  5. На основе списка ребер и пересечений (здесь идетбесконечное веселье с векторами и их перекрестными произведениями) начать с каждого ребра на оболочке по часовой стрелке (по часовой стрелке) (по часовой стрелке, если kчетно) и идти в самое левое (самое правое, если kчетно) каждый раз, пока не вернетесь. Теперь у вас есть область для k. Сделайте это для каждого ребра. Сохраните новый список ребер (оболочки) и используйте его в следующей итерации. Вы можете решить, куда вы можете пойти от пересечения и какое из них является самым левым (самым правым), используя индекс, созданный на шаге 3.
  6. Увеличивайте kна один и повторяйте 5–6 столько, сколько захотите.

Это можно улучшить алгоритмически несколькими способами, но для начала этого будет достаточно.

После успешного расчета точек данных вы можете просто нарисовать фигуры, используя команды tikz, например:\fill[red] (0,-1) -- (1,0) -- (0,1) -- (-1,0) -- cycle;

Другая возможность — иметь линии и вычислять цвет попиксельно для (битового) изображения. Это может быть намного лучше, если у вас большая, kно маленькая картинка.


Я предложил вознаграждение за ваш вопрос, надеясь на лучший подход, чем вышеизложенный. Безуспешно.

Связанный контент