Graphics, Figures & TablesProblem with recursive figure creation

Information and discussion about graphics, figures & tables in LaTeX documents.
Post Reply
heyitsguay
Posts: 2
Joined: Wed Mar 02, 2011 6:20 am

Problem with recursive figure creation

Post by heyitsguay »

Hello everyone!

I'm trying to create a command to draw the Sierpinski Triangle to arbitrary levels of precision for me (I need it for presentations on my research). After some fiddling, I got the following \SGlevel command to almost work:

Code: Select all

\documentclass{article}
\usepackage{amsmath}
\usepackage{amsthm}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{tikz}
\usepackage{pgf}
\usepackage{graphicx}
\usepackage{fancyhdr}
\usepackage[margin = 1in]{geometry}
\usepackage{parskip}
\usepackage{verbatim}
\usepackage{ifthen}
\usepackage{fp}

\newcommand{\SGlevel}[3]{
	\def \r {0.8660254}
	\ifthenelse{\equal{#1}{0}}{
		\draw (#2,#3) -- (#2+.5,#3+\r) -- (#2+1,#3) -- cycle;
	}{
		\pgfmathparse{int(#1-1)}
		\let\next\pgfmathresult
		\pgfmathparse{#2+2^(#1-2)}
		\let\twox\pgfmathresult
		\pgfmathparse{#3+2^(#1-1)*\r}
		\let\twoy\pgfmathresult
		\pgfmathparse{#2+2^(#1-1)}
		\let\threex\pgfmathresult
		\SGlevel{\next}{#2}{#3}
		\SGlevel{\next}{\twox}{\twoy}
		\SGlevel{\next}{\threex}{#3}
	}
}

\usetikzlibrary{arrows, shapes}

\begin{document}

\begin{figure}[hhhh]
\centering
\begin{tikzpicture}[point/.style={draw,shape=circle,inner sep = 0mm,minimum size = 1mm},scale = 1,>=stealth',auto]

\SGlevel{0}{0}{0}

\end{tikzpicture}
\end{figure}

\end{document}

Basically, the \SGlevel command takes in 3 variables: #1 is the level to which i want the procedure to iterate, while #2 and #3 take in the x and y coordinates of the lower-left hand corner of the triangle. It calls itself recursively, and works fine for #1=0 and #1=1. For some reason though, when I try #1=2 or higher, i get odd results. I haven't been able to find another script online to just steal, and I can't find a previous post that addresses this problem, so apologies if this has been answered already. Anybody have any ideas what is wrong?

Thanks
Last edited by heyitsguay on Thu Mar 03, 2011 4:47 am, edited 2 times in total.

Recommended reading 2024:

LaTeXguide.org • LaTeX-Cookbook.net • TikZ.org

Learn LaTeX easily with newest books:

The LaTeX Beginner's Guide: 2nd edition and perfect for students writing a thesis

The LaTeX Cookbook: 2nd edition full of practical examples for mathematics, physics, chemistry, and more

LaTeX Graphics with TikZ: the first book about TikZ for perfect drawings in your LaTeX thesis

User avatar
localghost
Site Moderator
Posts: 9202
Joined: Fri Feb 02, 2007 12:06 pm

Problem with recursive figure creation

Post by localghost »

I'm not aware of a straightforward solution with pgf/tikZ. But the pst-fractal package does exactly this job.


Best regards and welcome to the board
Thorsten
User avatar
sommerfee
Posts: 503
Joined: Mon Apr 09, 2007 4:20 pm

Problem with recursive figure creation

Post by sommerfee »

It seems you are thinking more in terms of a functional language than in terms of a macro language:

Code: Select all

		\pgfmathparse{int(#1-1)}
		\let\next\pgfmathresult
		\pgfmathparse{#2+2^(#1-2)}
		\let\twox\pgfmathresult
		\pgfmathparse{#3+2^(#1-1)*\r}
		\let\twoy\pgfmathresult
		\pgfmathparse{#2+2^(#1-1)}
		\let\threex\pgfmathresult
		\SGlevel{\next}{#2}{#3}
		\SGlevel{\next}{\twox}{\twoy}
		\SGlevel{\next}{\threex}{#3}
When you use \SGlevel with \next as first argument, \SGlevel will be expanded with \next as #1, and so on. So when using \SGlevel{2}{1}{0} you'll get this on the very first recursive level:

Code: Select all

		\pgfmathparse{int(\next-1)}
		\let\next\pgfmathresult
		\pgfmathparse{1+2^(\next-2)}
		\let\twox\pgfmathresult
		\pgfmathparse{0+2^(\next-1)*\r}
		\let\twoy\pgfmathresult
		\pgfmathparse{1+2^(\next-1)}
		\let\threex\pgfmathresult
		\SGlevel{\next}{1}{0}
		\SGlevel{\next}{\twox}{\twoy}
		\SGlevel{\next}{\threex}{0}
As you see \next will be set to a different value in line 2, and the following lines will use the new value of \next but I assume they should use the "old" value in fact. (Same problem exists with the usage of \twox, \twoy, and \threex as arguments of \SGlevel.)

You can solve this by expanding the arguments first, e.g. by using a helper macro:

Code: Select all

\newcommand\expandthreeargs[4]{%
  \begingroup
    \edef\temp{\endgroup\noexpand #1{#2}{#3}{#4}}%
    \temp}
\newcommand{\SGlevel}[3]{%
  \typeout{\string\SGlevel{#1}{#2}{#3}}% just for debugging
   \def\r{0.8660254}%
   \ifthenelse{\equal{#1}{0}}{%
      \draw (#2,#3) -- (#2+.5,#3+\r) -- (#2+1,#3) -- cycle;
   }{%
      \pgfmathparse{int(#1-1)}%
      \let\next\pgfmathresult
      \pgfmathparse{#2+2^(#1-2)}%
      \let\twox\pgfmathresult
      \pgfmathparse{#3+2^(#1-1)*\r}%
      \let\twoy\pgfmathresult
      \pgfmathparse{#2+2^(#1-1)}%
      \let\threex\pgfmathresult
      \expandthreeargs\SGlevel{\next}{#2}{#3}%
      \expandthreeargs\SGlevel{\next}{\twox}{\twoy}%
      \expandthreeargs\SGlevel{\next}{\threex}{#3}%
   }%
}
I have inserted a \typeout so one will see what values will be used. If you remove the usage of \expandthreeargs they will be different.

If you have questions about this please don't hesitate to ask.
heyitsguay
Posts: 2
Joined: Wed Mar 02, 2011 6:20 am

Re: Problem with recursive figure creation

Post by heyitsguay »

Thanks to both of you! Unfortunately, pst-fractal does not work for me, I need to format this fractal construction in a particular way (i.e. as a graph). Sommerfree - Thank you for the advice. However, it does not solve the problem, I get the same results if I try \SGlevel with #1 > 1 using your script as I did before. I think I understand what you did, I read up on \edef. However, why did you need the \begingroup and \endgroup? It looks like the problem is that \next and \twox etc. are still getting overwritten. I appreciate your efforts though, and look forward to any more help you could give me.

Matt
Post Reply