tikz foreach 迴圈只允許一組變數

tikz foreach 迴圈只允許一組變數

我目前正在嘗試生成以下維恩圖:

\usetikzlibrary{shapes,backgrounds}
\usepackage{tikz}
\usepackage{xcolor}
\begin{tikzpicture}[scale=.8, show background rectangle]
    \def\ellipsea{(0.5cm,0) ellipse [x radius=3cm, y radius=1.5cm, rotate=50]}
    \def\ellipseb{(-0.5cm,0) ellipse [x radius=3cm, y radius=1.5cm, rotate=-50]}
    \def\ellipsec{(1.5cm,-1cm) ellipse [x radius=3cm, y radius=1.5cm, rotate=50]}
    \def\ellipsed{(-1.5cm,-1cm) ellipse [x radius=3cm, y radius=1.5cm, rotate=-50]}
    \def\negating{(-4.5cm,-4.5cm) rectangle (4.5cm,4.5cm)}
    \node (a) at (-2.5cm,2.5cm) {C};
    \node (b) at (2.5cm,2.5cm) {B};
    \node (c) at (-3.5cm,1.5cm) {N};
    \node (d) at (3.5cm,1.5cm) {S};
    %~A~B~C~D
    \scope
        \clip \ellipsea\negating;
        \clip \ellipseb\negating;
        \clip \ellipsec\negating;
        \clip \ellipsed\negating;
        \fill[color=black,opacity=0.2] \negating;
    \endscope
    %ABC~D      
    \scope
        \clip \ellipsea;
        \clip \ellipseb;
        \clip \ellipsec;
        \clip \ellipsed\negating;
        \fill[color=black,opacity=0.2] \negating;
    \endscope
    %AB~CD  
    \scope
        \clip \ellipsea;
        \clip \ellipseb;
        \clip \ellipsec\negating;
        \clip \ellipsed;
        \fill[color=black,opacity=0.2] \negating;
    \endscope
    %A~BCD  
    \scope
        \clip \ellipsea;
        \clip \ellipseb\negating;
        \clip \ellipsec;
        \clip \ellipsed;
        \fill[color=black,opacity=0.2] \negating;
    \endscope
    %~ABCD
    \scope
        \clip \ellipsea\negating;
        \clip \ellipseb;
        \clip \ellipsec;
        \clip \ellipsed;
        \fill[color=blue,opacity=0.2] \negating;
    \endscope
    %ABCD
    \scope
        \clip \ellipsea;
        \clip \ellipseb;
        \clip \ellipsec;
        \clip \ellipsed;
        \fill[color=black,opacity=0.2] \negating;
    \endscope   
    %AB~C~D
    \scope
        \clip \ellipsea;
        \clip \ellipseb;
        \clip \ellipsec\negating;
        \clip \ellipsed\negating;
        \fill[color=green,opacity=0.2] \negating;
    \endscope
    %A~B~CD 
    \scope
        \clip \ellipsea;
        \clip \ellipseb\negating;
        \clip \ellipsec\negating;
        \clip \ellipsed;
        \fill[color=yellow,opacity=0.2] \negating;
    \endscope
    %~AB~CD
    \scope
        \clip \ellipsea\negating;
        \clip \ellipseb;
        \clip \ellipsec\negating;
        \clip \ellipsed;
        \fill[color=black,opacity=0.2] \negating;
    \endscope       
    %~ABC~D
    \scope
        \clip \ellipsea\negating;
        \clip \ellipseb;
        \clip \ellipsec;
        \clip \ellipsed\negating;
        \fill[color=red,opacity=0.2] \negating;
    \endscope       
    %~A~BCD
    \scope
        \clip \ellipsea\negating;
        \clip \ellipseb\negating;
        \clip \ellipsec;
        \clip \ellipsed;
        \fill[color=orange,opacity=0.2] \negating;
    \endscope
    %~AB~C~D
    \scope
        \clip \ellipsea\negating;
        \clip \ellipseb;
        \clip \ellipsec\negating;
        \clip \ellipsed\negating;
        \fill[color=black,opacity=0.2] \negating;
    \endscope
    %~A~B~CD
    \scope
        \clip \ellipsea\negating;
        \clip \ellipseb\negating;
        \clip \ellipsec\negating;
        \clip \ellipsed;
        \fill[color=purple,opacity=0.2] \negating;
    \endscope
    %A~B~D
    \scope
        \clip \ellipsea;
        \clip \ellipseb\negating;
        \clip \ellipsed\negating;
        \fill[color=red,opacity=0.5] \negating;
    \endscope
    %~BC~D
    \scope
        \clip \ellipseb\negating;
        \clip \ellipsec;
        \clip \ellipsed\negating;
        \fill[color=blue,opacity=0.5] \negating;
    \endscope


    \node (ABcd) at (0,1cm) {1};
    \node (aBCD) at (0.5cm,-2.25cm) {1};
    \node (AbcD) at (-1.2cm,-1.9cm) {1};
    \node (aBCd) at (1.2cm,-1.9cm) {2};
    \node (abCD) at (0,-3cm) {4};
    \node (abcD) at (-3cm,0cm) {1}; 
    \node (Abd) at (1.8cm,1.1cm) {3};
    \node (bCd) at (2.5cm,.5cm) {4};

    \draw \ellipsea;
    \draw \ellipseb;
    \draw \ellipsec;
    \draw \ellipsed;    

\end{tikzpicture}

為了清楚起見,使用 tikz \foreach 循環,如下所示:

\foreach \abool/\bbool/\cbool/\dbool/\colchoose/\opchoose in {1/1/1/1,black,0.2}
            \scope  
            \ifnum \abool=1
                \clip \ellipsea;
                [\else \clip \ellipsea\negating;]
            \fi
            \ifnum \bbool=1
                \clip \ellipseb;
                [\else \clip \ellipseb\negating;]               
            \fi
            \ifnum \cbool=1
                \clip \ellipsec;
                [\else \clip \ellipsec\negating;]
            \fi
            \ifnum \dbool=1
                \clip \ellipsed;
                [\else \clip \ellipsed\negating;]
            \fi
            \fill[color=\colchoose,opacity=\opchoose] \negating;
            \endscope

替換原始片段中的長行 \scope 。這似乎工作正常,直到我添加多個區域(例如{1/1/1/1/black/0.2,0/1/0/1,black,0.2}),在這種情況下,我收到以下錯誤:

! Missing } inserted.<inserted text>} \end{tikzpicture}
! Missing \endgroup inserted.<inserted text>\endgroup \end{document}

想知道如何解決這個問題,或者我的程式碼是否有問題,因為我對 tikz 還很陌生。

謝謝!

答案1

如果你的程式碼工作正常

  • 您對循環的值要小心\foreach:一次迭代的多個變數的值必須以 分隔/,不同迭代的值必須以分隔,

    \foreach ... in {1/1/1/1/black/0.2,0/1/0/1/black/0.2}
    

    (你嘗試過{1/1/1/1/black/0.2,0/1/0/1,black,0.2}。)

  • 將循環體用大括號括起來。

在此輸入影像描述

\documentclass[border=2mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes,backgrounds}
%\usepackage{xcolor}
\begin{document}
\begin{tikzpicture}[scale=.8, show background rectangle]
    \def\ellipsea{(0.5cm,0) ellipse [x radius=3cm, y radius=1.5cm, rotate=50]}
    \def\ellipseb{(-0.5cm,0) ellipse [x radius=3cm, y radius=1.5cm, rotate=-50]}
    \def\ellipsec{(1.5cm,-1cm) ellipse [x radius=3cm, y radius=1.5cm, rotate=50]}
    \def\ellipsed{(-1.5cm,-1cm) ellipse [x radius=3cm, y radius=1.5cm, rotate=-50]}
    \def\negating{(-4.5cm,-4.5cm) rectangle (4.5cm,4.5cm)}
    \node (a) at (-2.5cm,2.5cm) {C};
    \node (b) at (2.5cm,2.5cm) {B};
    \node (c) at (-3.5cm,1.5cm) {N};
    \node (d) at (3.5cm,1.5cm) {S};



\foreach \abool/\bbool/\cbool/\dbool/\colchoose/\opchoose in {1/1/1/1/black/0.2,0/1/0/1/black/0.2}
{            \scope  
            \ifnum \abool=1
                \clip \ellipsea;
                [\else \clip \ellipsea\negating;]
            \fi
            \ifnum \bbool=1
                \clip \ellipseb;
                [\else \clip \ellipseb\negating;]               
            \fi
            \ifnum \cbool=1
                \clip \ellipsec;
                [\else \clip \ellipsec\negating;]
            \fi
            \ifnum \dbool=1
                \clip \ellipsed;
                [\else \clip \ellipsed\negating;]
            \fi
            \fill[color=\colchoose,opacity=\opchoose] \negating;
            \endscope
}


    \node (ABcd) at (0,1cm) {1};
    \node (aBCD) at (0.5cm,-2.25cm) {1};
    \node (AbcD) at (-1.2cm,-1.9cm) {1};
    \node (aBCd) at (1.2cm,-1.9cm) {2};
    \node (abCD) at (0,-3cm) {4};
    \node (abcD) at (-3cm,0cm) {1}; 
    \node (Abd) at (1.8cm,1.1cm) {3};
    \node (bCd) at (2.5cm,.5cm) {4};

    \draw \ellipsea;
    \draw \ellipseb;
    \draw \ellipsec;
    \draw \ellipsed;    

\end{tikzpicture}
\end{document}

答案2

實際上,我基本上忽略了OP問題並提供了一種更有效的指定圖表的方法:

\documentclass[tikz,border=5]{standalone} 
\tikzset{%
    venn/.code 2 args={\scope\def\c{#1}\def\n{}\tikzset{.. venn=#2@;}\endscope},
    .. venn/.code args={#1#2;}{%
        \ifx#1@%
            \path[fill=\c]\negating;
        \else%
            \ifx#1~
                \let\n=\negating
            \else%
                \clip \csname ellipse#1\endcsname\n;
                \def\n{}%
            \fi%
            \tikzset{.. venn=#2;}%
        \fi}}
\def\ellipsea{(0.5cm,0) ellipse [x radius=3cm, y radius=1.5cm, rotate=50]}
\def\ellipseb{(-0.5cm,0) ellipse [x radius=3cm, y radius=1.5cm, rotate=-50]}
\def\ellipsec{(1.5cm,-1cm) ellipse [x radius=3cm, y radius=1.5cm, rotate=50]}
\def\ellipsed{(-1.5cm,-1cm) ellipse [x radius=3cm, y radius=1.5cm, rotate=-50]}
\def\negating{(-4.5cm,-4.5cm) rectangle (4.5cm,4.5cm)}
\newcommand\venn[2][]{\tikzset{venn={#1}{#2}}}
\begin{document}
\begin{tikzpicture}
\venn [red]       {abcd}
\venn [yellow]    {~abcd}
\venn [pink]      {a~bcd}
\venn [green]     {ab~cd}
\venn [orange]    {abc~d}
\venn [purple]    {~a~bcd}
\venn [blue]      {~ab~cd}
\venn [magenta]   {~abc~d}
\venn [olive]     {a~b~cd}
\venn [violet]    {a~bc~d}
\venn [teal]      {ab~c~d}
\venn [brown]     {~a~b~cd}
\venn [teal]      {~a~bc~d}
\venn [lime]      {~ab~c~d}
\venn [darkgray]  {a~b~c~d}
\venn [lightgray] {~a~b~c~d}
\end{tikzpicture}
\end{document}

在此輸入影像描述

這是一個變體,它 (a) 仍然不能回答 OP 問題,但 (b) 可以將規範指定為位元序列,例如1101

\documentclass[tikz,border=5]{standalone} 
\tikzset{%
    venn/.code 2 args={\scope\def\c{#1}\tikzset{.. venn/.expanded=#2@;abcd@;}\endscope},
    .. venn/.code args={#1#2;#3#4;}{%
        \ifx#1@%
            \path[fill=\c]\negating;
        \else%
            \ifcase#1
                \clip \csname ellipse#3\endcsname\negating;
            \or%
                \clip \csname ellipse#3\endcsname;
            \fi%
            \tikzset{.. venn=#2;#4;}%
        \fi%
}}
\def\ellipsea{(0.5cm,0) ellipse [x radius=3cm, y radius=1.5cm, rotate=50]}
\def\ellipseb{(-0.5cm,0) ellipse [x radius=3cm, y radius=1.5cm, rotate=-50]}
\def\ellipsec{(1.5cm,-1cm) ellipse [x radius=3cm, y radius=1.5cm, rotate=50]}
\def\ellipsed{(-1.5cm,-1cm) ellipse [x radius=3cm, y radius=1.5cm, rotate=-50]}
\def\negating{(-4.5cm,-4.5cm) rectangle (4.5cm,4.5cm)}
\newcommand\venn[2][]{\tikzset{venn={#1}{#2}}}
\pgfmathsetbasenumberlength{4}
\begin{document}
\begin{tikzpicture}
\foreach \i [evaluate={\r=rnd;\g=rnd;\b=rnd;}] in {0,...,15}{
  \definecolor{tmp}{rgb}{\r,\g,\b}
  \pgfmathdectobase\n{\i}{2}%
  \venn[tmp]{\n}
}
\end{tikzpicture}
\end{document}

在此輸入影像描述

「解析器」(即vennvenn ..鍵)的操作也許可以用一個例子來最好地解釋。

考慮使用時會發生什麼\venn{1100}

關鍵venn是‘呼叫’ .. venn=1100@;abcd@;。是、、和命令abcd的後綴。這些字符是(任意)哨兵字符,可以檢測何時到達序列末尾。這些字元是標記字串末尾的輪廓符。然後依序考慮每次迭代:\ellipsea\ellipseb\ellipsec\ellipsed@;

  1. 鍵的參數.. venn

    #1 -> 1 #2 -> 100@ 
    #3 -> a #4 -> bcd@
    
  2. 鍵的參數.. venn

    #1 -> 1 #2 -> 00@ 
    #3 -> b #4 -> cd@
    
  3. 鍵的參數.. venn

    #1 -> 0 #2 -> 0@ 
    #3 -> c #4 -> d@
    
  4. 鍵的參數.. venn

    #1 -> 0 #2 -> @ 
    #3 -> d #4 -> @
    
  5. 鍵的參數.. venn

    #1 -> @ #2 ->  
    #3 -> @ #4 -> 
    

到達哨兵字元後,解析器終止。

相關內容