Использование LaTeX/TikZ для фрактального цветка

Использование LaTeX/TikZ для фрактального цветка

Я пытаюсь создать это конкретное фрактальное изображение цветка, но даже не знаю, с чего и как начать. Можно ли использовать TikZ для создания "Филотаксическая спираль"?

Я видел это здесь:https://www.reddit.com/r/FractalPorn/comments/xr17t1/fractal_rose/

и изображение выглядит так, как показано ниже: Фрактальное изображение

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

РЕДАКТИРОВАТЬ: Как мне поставить зеленую галочку на более чем одном ответе? Результаты, которые вы, ребята, дали, просто поразительны!

решение1

я используюФормула Сэнди Джиздесь, в основном .707^<level>, часть.

Два подхода:

  1. PGF и LuaLaTeX, которые используютОтличный скрипт lua poisson от JLDiaz.
  2. TikZ и PGFmath, которые просто используют эту rndфункцию.

Макрос \pgfpointspiralifdefinedгарантирует, что уже рассчитанные координаты не придется пересчитывать.

Вместо координат a, b, cи d, вы также можете использовать vertexякоряформа воздушного змеякоторый использует ответ Сэнди Г. (конечно, вам нужно назвать узлы, например spiral-\l-\n).

В обоих решениях я возвожу в куб одно из случайных значений так, чтобы точки скапливались по одну сторону от воздушных змеев.

PGF + LuaLaTeX

\documentclass{standalone}
\usepackage{pgf,pgffor}
\usepackage{jldiaz-poisson}% https://tex.stackexchange.com/a/185423/16595
\usepackage{xcolor} % colorwheel
\definecolor{cw0}{HTML}{9AFF00}\definecolor{cw1}{HTML}{FFA500}
\definecolor{cw2}{HTML}{FF001A}\definecolor{cw3}{HTML}{FF00D9}
\definecolor{cw4}{HTML}{6500FF}\definecolor{cw5}{HTML}{005AFF}
\definecolor{cw6}{HTML}{00FFE5}\definecolor{cw7}{HTML}{00FF25}
\pgfset{
  declare function={
    spiralAngle(\level,\spiral) = \directlua{tex.print(
      180/(\pgfkeysvalueof{/pgf/spiral\space N})*\level
     +360/(\pgfkeysvalueof{/pgf/spiral\space N})*\spiral)};
    spiralRadius(\level)        = \directlua{tex.print(
      .707^\level*(\pgfkeysvalueof{/pgf/spiral\space radius}))};
    xSpread(\n)=\n^3*.8+.1; ySpread(\n)=\n*.8+.1;},
  spiral radius/.initial=5, spiral N/.initial=8}
\newcommand*\pgfpointspiral[2]{% #1 = level, #2 = spiral
  \pgfpointpolarxy{spiralAngle(#1,#2)}{spiralRadius(#1)}}
\makeatletter
\newcommand*\pgfpointspiralifdefined[3]{%
  % if spiral-#2-#3 doesn't exist, define it
  % if it does do nothing
  \pgfutil@ifundefined{pgf@sh@ns@spiral-#2-#3}{%
    \pgfcoordinate{spiral-#2-#3}{\pgfpointspiral{#2}{#3}}%
  }{}% and make it an alias for #1
  \pgfnodealias{#1}{spiral-#2-#3}}
\makeatother
\begin{document}
\begin{pgfpicture}
\pgfsetxvec{\pgfqpoint{5mm}{0mm}}
\pgfsetyvec{\pgfqpoint{0mm}{5mm}}
\foreach \l in {0,...,6}{
  \foreach \n in {0,...,7}{
    \pgfpointspiralifdefined{a}{\l}            {\n}
    \pgfpointspiralifdefined{b}{\inteval{\l+1}}{\n}
    \pgfpointspiralifdefined{c}{\l}            {\inteval{\n+1}}
    \pgfpointspiralifdefined{d}{\inteval{\l-1}}{\inteval{\n+1}}
    \pgfsetfillcolor{cw\n}
    \foreach[expand list, evaluate={\xSpread=xSpread(\x);}]
      \x/\y in {\poissonpointslist{1}{1}{.02+.0\l}{10}} {
      \pgfpathcircle{
        \pgfpointlineattime{ySpread(\y)}
          {\pgfpointlineattime{\xSpread}
            {\pgfpointanchor{a}{center}}{\pgfpointanchor{b}{center}}}
          {\pgfpointlineattime{\xSpread}
            {\pgfpointanchor{d}{center}}{\pgfpointanchor{c}{center}}}
      }{+.25pt}
      \pgfusepath{fill}
    }
  }
}
\end{pgfpicture}
\end{document}

TikZ + PGFmath

Это \pgfpointspiralifdefinedтакже можно было бы реализовать с помощью пользовательской системы координат TikZ, но зачем беспокоиться…

\documentclass[tikz]{standalone}
\usetikzlibrary{calc}
\pgfset{
  declare function={
    xSpread(\n)=\n^3*.8+.1; ySpread(\n)=\n*.8+.1;},
  spiral radius/.initial=5,
  spiral N/.initial=8}
\newcommand*\pgfpointspiral[2]{% #1 = level, #2 = spiral
  \pgfpointpolarxy{180/(\pgfkeysvalueof{/pgf/spiral N})*(#1)
                  +360/(\pgfkeysvalueof{/pgf/spiral N})*(#2)}
                  {.707^(#1)*(\pgfkeysvalueof{/pgf/spiral radius})}}
\makeatletter
\newcommand*\pgfpointspiralifdefined[3]{%
  \pgfutil@ifundefined{pgf@sh@ns@spiral-#2-#3}{%
    \pgfcoordinate{spiral-#2-#3}{\pgfpointspiral{#2}{#3}}%
  }{}%
  \pgfnodealias{#1}{spiral-#2-#3}}
\makeatother
\begin{document}
\begin{tikzpicture}[x=+5mm, y=+5mm]
\foreach \l[evaluate={\Dots=250*.7^\l}] in {0,...,6} {
  \foreach \n in {0,...,7} {
    \pgfpointspiralifdefined{a}{\l}            {\n}
    \pgfpointspiralifdefined{b}{\inteval{\l+1}}{\n}
    \pgfpointspiralifdefined{c}{\l}            {\inteval{\n+1}}
    \pgfpointspiralifdefined{d}{\inteval{\l-1}}{\inteval{\n+1}}
    \fill[radius=+.4pt] foreach[
      evaluate={\xSpread=xSpread rnd; \ySpread=ySpread rnd;}]
      \dot in {0,...,\Dots} {
        ($($(a)!\ySpread!(d)$)!\xSpread!($(b)!\ySpread!(c)$)$)
        circle[radius=+.4pt]};
  }
}
\end{tikzpicture}
\end{document}

Выход

введите описание изображения здесь введите описание изображения здесь

решение2

Вот роза, которая использует kiteформу узла из библиотеки tikz shapes.geometric. Я оставляю другим возможность заполнить узлы точками.

введите описание изображения здесь

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{shapes.geometric}

\tikzset{mykite/.style={inner sep=.1pt, kite, fill=red!30, kite vertex angles=120 and 75}}

\begin{document}

\begin{tikzpicture}
\foreach \l in {1,...,12}{
\foreach \n[evaluate=\n as \t using \l*22.5+\n*45, % \t is the angle for node placement
    evaluate=\n as \s using .703^(\l-1), % \s is the scaling factor for the distance from 0 for each level
    evaluate=\n as \c using \s-.01] in {1,...,8} % \c is used to shrink each node just a bit.
    {\node[mykite, rotate=\t, minimum size=\c cm] at (\t-90:{\s*1.38}){};}
}
\end{tikzpicture}

\end{document}

Чтобы получить 8-вершинную розу, углы вершин змея должны отличаться на 45 (120 и 75 в коде выше). Вы можете изменить .703на (sin((\aaa-45)/2)/sin(\aaa/2)), где \aaa— больший угол, чтобы получить вариации формы. Фактор 1.38также нуждается в корректировке.

введите описание изображения здесь

решение3

введите описание изображения здесьТест

Я попытался сделать конструкцию с использованием picи спиральной кривой. Все вычисления скрыты в определении petalPiece( picэлемента), который создает четырехугольник; каждый лепесток будет состоять из \nbQuadчастей.

Есть две глобальные переменные: количество лепестков и количество деталей для каждого лепестка. Например, при 9 лепестках мы получим рисунок ниже. введите описание изображения здесь

Код

\documentclass[11pt, margin=1cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{math, calc}
\begin{document}

\tikzmath{
  integer \nbPetals, \nbQuad;
  \nbPetals = 8;
  \nbQuad = 7;
  real \a, \base, \r;
  \a = 360/\nbPetals;  % petal's angle
  \base = 2;  % base of the exponential definig the helix
  \r = .35;  % scaling constant
  function tmpR(\i) {% integer giving a point along the helix
    return {\r*pow(\base, 3.145*\i/\nbQuad)};
  };
}
\tikzset{%
  pics/petalPiece/.style 2 args={% branch number, base point number
    code={%
      \tikzmath{integer \b, \p; \b = #1; \p = #2;}
      \path
      (\p/\nbQuad*180 +\b*\a: {tmpR(\p)}) coordinate (NW)
      ({(\p +1)/\nbQuad*180 +\b*\a}: {tmpR(\p +1)}) coordinate (NE)
      ({(\p +2)/\nbQuad*180 +(\b -1)*\a}: {tmpR(\p +2)}) coordinate (SE)
      ({(\p +1)/\nbQuad*180 +(\b -1)*\a}: {tmpR(\p +1)}) coordinate (SW);
      \foreach \i in {0, .05, ..., .9}{%
        \draw[white, thick, fill=magenta!90, opacity=.05]
        ($(NW)!\i!(SW)$) -- ($(NE)!\i/2!(SE)$) -- (SE) -- (SW) -- cycle;
      }
    }
  }
}
\begin{tikzpicture}
  \foreach \l in {1, 2, ..., \nbPetals}{
    \foreach \i in {-1, 0, 1, 2, ..., \nbQuad}{%
      \path (0, 0) pic {petalPiece={\l}{\i}};
    }
  }
\end{tikzpicture}

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