6

I'm trying to make a macro for drawing square puzzle pieces in TikZ. There should be three possibilities for each edge, either jutting in, jutting out, or straight.

Below is what I have so far. As shown, I'm able to decide whether each edge either juts in or out, according whether each argument is 0 or 1. My goal is to make an edge straight when the argument is 2.

The problem is that I can't figure out how to put a conditional within a TikZ path. Namely, I want to skip certain portions of the path if the input is a certain number. I've tried using the ifthen package, but it seems like tikz isn't able to interpret result of \ifthenelse as a valid coordinate. Is there a way to conditionally skip parts of a TikZ path? Or is there a better way to do what I am trying to do?

\documentclass{article}
\usepackage{tikz}
\begin{document}

\def \puzzlepiece(#1,#2,#3,#4)
{
\filldraw[very thick,fill=orange] 
      (0,0) --
      (0,1) arc (270:{90+360*#1}:1) -- %want to skip this line if #1 = 2
      (0,4) --
      (1,4) arc (180:{0+360*#2}:1)  -- %want to skip this line if #2 = 2
      (4,4) --
      (4,3) arc (90:{-90+360*#3}:1) -- %want to skip this line if #3 = 2
      (4,0) --
      (3,0) arc (0:{-180+360*#4}:1) -- %want to skip this line if #4 = 2
      cycle;
}
\tikz{\puzzlepiece(0,1,0,1) }
\tikz{\puzzlepiece(1,0,1,0) }

\end{document}

enter image description here

3 Answers 3

2

A little bit complicated (please observe different behaviour in the last condition), but with conditions that you wanted. Fragments of your code commented and replaced by the following lines.

\documentclass{article}
\usepackage{tikz}
\begin{document}


\def \puzzlepiece(#1,#2,#3,#4)
{
\filldraw[very thick,fill=orange] 
      (0,0) --
     %(0,1) arc (270:{90+360*#1}:1) -- %want to skip this line if #1 = 2
\ifnum#1=2 (0,0)--\else (0,1) arc (270:{90+360*#1}:1)-- \fi
      (0,4) --
%      (1,4) arc (180:{0+360*#2}:1)  -- %want to skip this line if #2 = 2
\ifnum#2=2 (0,4)-- \else(1,4) arc (180:{0+360*#2}:1)  -- \fi
      (4,4) --
%      (4,3) arc (90:{-90+360*#3}:1) -- %want to skip this line if #3 = 2
\ifnum#3=2 (4,4)-- \else (4,3) arc (90:{-90+360*#3}:1) --\fi
     (4,0) --
%      (3,0) arc (0:{-180+360*#4}:1) -- %want to skip this line if #4 = 2
\ifnum#4=2   (4,0)-- cycle;\relax \else (3,0) arc (0:{-180+360*#4}:1) --cycle;\relax\fi
%   cycle;
}
\tikz{\puzzlepiece(0,1,0,1) }
\tikz{\puzzlepiece(1,0,1,0) }
\tikz{\puzzlepiece(2,0,1,0) }
\tikz{\puzzlepiece(2,2,0,1) }
\end{document}

enter image description here

3

Yoiur edge will be straight if arc (0:{0}:1), so the easiest solution would be to write function f(0)=1, f(1)=1, f(2)=0, and arc (f(x)*y:{f(x)*z}:1)

\documentclass{article}
\usepackage{tikz}
\def\myf(#1){(#1+1)*(2-#1)/2}
\def\puzzlepiece(#1,#2,#3,#4)
{
\filldraw[very thick,fill=orange] 
      (0,0) --
      (0,1) arc (\myf(#1)*270:{\myf(#1)*(90+360*#1)}:1)--
      (0,4) --
      (1,4) arc (\myf(#2)*180:{\myf(#2)*(0+360*#2)}:1)--
      (4,4) --
      (4,3) arc (\myf(#3)*90:{\myf(#3)*(-90+360*#3)}:1)--
      (4,0) --
      (3,0) arc (0:{\myf(#4)*(-180+360*#4)}:1)--
      cycle;
}
\begin{document}
\tikz{\puzzlepiece(0,1,0,1) }
\tikz{\puzzlepiece(2,2,2,2) }
\end{document}
3

You can prepare the path using \edef:

\def \puzzlepiece(#1,#2,#3,#4){%
   \edef\onepuzzle{%
      (0,0) --
      \ifnum#1=2 \else (0,1) arc (270:{90+360*#1}:1) -- \fi %skip if #1 = 2
      (0,4) --
      \ifnum#2=2 \else (1,4) arc (180:{0+360*#2}:1)  -- \fi %skip if #2 = 2
      (4,4) --
      \ifnum#3=2 \else (4,3) arc (90:{-90+360*#3}:1) -- \fi %skip if #3 = 2
      (4,0) --
      \ifnum#4=2 \else (3,0) arc (0:{-180+360*#4}:1) -- \fi %skip if #4 = 2
      cycle
   }%
   \filldraw[very thick,fill=orange] \onepuzzle;
}
\tikz{\puzzlepiece(0,1,0,2) }
\tikz{\puzzlepiece(1,0,1,0) }

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .