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 s의 긴 줄을 바꾸려면. 여러 영역(예: {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}

여기에 이미지 설명을 입력하세요

venn'파서'(즉, 및 키) 의 동작은 venn ..예를 들어 가장 잘 설명될 수 있습니다.

을 사용할 때 어떤 일이 발생하는지 고려하십시오 \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 -> 
    

센티널 문자에 도달하면 파서가 종료됩니다.

관련 정보