구불구불한 리본을 그리는 TikZ 장식

구불구불한 리본을 그리는 TikZ 장식

저는 TikZ 스타일과 장식을 많이 좋아하지만 여전히 그것들을 만져봅니다. 나는 리본을 비틀지 않으려면 스타일을 사용하여 리본을 그리는 방법을 알고 있습니다. 하지만 저는 길을 따라 리본을 꼬아주는 스타일을 정의하고 싶습니다. 리본은 앞면과 뒷면의 색상이 달라야 합니다. 리본은 곡선 경로를 따라 구부러질 수 있어야 합니다. 이것이 가능한가? 어쩌면 장식을 정의함으로써? 아니면 경로를 따라 베지어 곡선을 삽입하는 것이 가능할까요?

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

\documentclass{article}
\usepackage{tikz}
\begin{document}
    \tikzset{
        ribbon/.style={
            preaction={
                preaction={
                    draw,
                    line width=0.25cm,
                    white
                },
                draw,
                line width=0.2cm,
                black!30!#1
            },
            line width=0.15cm,
            #1
        },
        ribbon/.default=gray
    }
    Ribbons are easy, just with my previously defined style:

    \begin{tikzpicture}
        \draw[ribbon=green] (0,0) to[out=0,in=90] (2,0) to[out=270,in=270] (4,2);
        \draw[ribbon]       (0,1) to[out=30,in=150] (2,1) to[out=-30,in=120] (4,-1);
    \end{tikzpicture}

    How can I make a twisted ribbon a style?

    \newcommand{\myangle}{20}
    \begin{tikzpicture}[looseness=0.5]
        \fill[green] (0,-0.1) to[out=  0,in=180+\myangle] (2,0) to[out=180-\myangle,in=  0] (0,0.1);
        \fill[red]   (4,-0.1) to[out=180,in=   -\myangle] (2,0) to[out=    \myangle,in=180] (4,0.1);
        \draw        (0,-0.1) to[out=  0,in=180+\myangle] (2,0) to[out=    \myangle,in=180] (4,0.1);
        \node[inner sep=1.5pt,fill,white] at (2,0) {};
        \draw        (4,-0.1) to[out=180,in=   -\myangle] (2,0) to[out=180-\myangle,in=  0] (0,0.1);
    \end{tikzpicture}

    Ideally, I'd like to use this like so:
    \begin{verbatim}
        \draw[twistedribbon={red,green}] (0,0) -- (4,0);
    \end{verbatim}

\end{document}

답변1

이 메타 경로를 수정해 보겠습니다.

\documentclass[border=9,tikz]{standalone}
\usetikzlibrary{decorations.pathmorphing}
\begin{document}



\tikzset{
    demo decoration/.style={
        gray,
        postaction={draw=red,decorate,decoration=#1}
    }
}
\begin{tikzpicture}[remember picture]
    \path(0,0)coordinate(A){}(3.7,0)coordinate(B){}(3.8,0)coordinate(C){};
    \draw[demo decoration=snake](A)to[bend left](B);
\end{tikzpicture}

먼저 나는 그림을 그리는 장식을 만들었습니다.평행선메타 경로의 왼쪽에 있습니다.

\pgfdeclaredecoration{stay left}{initial}{
  \state{initial}[width=0,next state=stay above]
  {\pgfpathmoveto{\pgfqpoint{0pt}{\pgfdecorationsegmentamplitude}}}
  \state{stay above}[width=\pgfdecorationsegmentlength,next state=stay above]
  {\pgfpathlineto{\pgfqpoint{0pt}{\pgfdecorationsegmentamplitude}}}
  \state{final}
  {
    \pgfpathlineto{\pgfqpoint{0pt}{\pgfdecorationsegmentamplitude}}
    \pgfpathlineto{\pgfqpoint{\pgfdecoratedremainingdistance}{\pgfdecorationsegmentamplitude}}
    \pgfpathmoveto{\pgfpointdecoratedpathlast}
  }
}
\begin{tikzpicture}
    \draw[demo decoration=stay left](A)to[bend left](B);
\end{tikzpicture}

다음으로 왼쪽에서 오른쪽으로 교차하는 또 다른 하나를 만들었습니다.

\pgfdeclaredecoration{cross from left to right}{initial}{
  \state{initial}[width=0,next state=stay above]
  {\pgfpathmoveto{\pgfqpoint{0pt}{\pgfdecorationsegmentamplitude}}}
  \state{stay above}[width=.5\pgfdecorationsegmentlength,next state=stay above,
                     switch if less than=.5*\pgfdecoratedpathlength+\pgfdecorationsegmentlength to snake down 1]
  {\pgfpathlineto{\pgfqpoint{0pt}{\pgfdecorationsegmentamplitude}}}
  \state{snake down 1}[width=.5\pgfdecorationsegmentlength,next state=snake down 2]
  {\pgfpathlineto{\pgfqpoint{0pt}{\pgfdecorationsegmentamplitude}}}
  \state{snake down 2}[width=.5\pgfdecorationsegmentlength,next state=snake down 3]
  {\pgfpathlineto{\pgfqpoint{0pt}{.7\pgfdecorationsegmentamplitude}}}
  \state{snake down 3}[width=.5\pgfdecorationsegmentlength,next state=snake down 4]
  {\pgfpathlineto{\pgfqpoint{0pt}{0pt}}}
  \state{snake down 4}[width=.5\pgfdecorationsegmentlength,next state=stay below]
  {\pgfpathlineto{\pgfqpoint{0pt}{-.7\pgfdecorationsegmentamplitude}}}
  \state{stay below}[width=.5\pgfdecorationsegmentlength,next state=stay below]
  {\pgfpathlineto{\pgfqpoint{0pt}{-\pgfdecorationsegmentamplitude}}}
  \state{final}
  {
    \pgfpathlineto{\pgfqpoint{0pt}{-\pgfdecorationsegmentamplitude}}
    \pgfpathlineto{\pgfqpoint{\pgfdecoratedremainingdistance}{-\pgfdecorationsegmentamplitude}}
    \pgfpathmoveto{\pgfpointdecoratedpathlast}
  }
}
\begin{tikzpicture}
    \draw[demo decoration=cross from left to right](A)to[bend left](B);
\end{tikzpicture}

따라서 이러한 선을 서로 다른 선으로 여러 번 그리면 리본이 생성됩니다.

\tikzset{
    monochromatic ribbon/.style={
        repeat decoration CFLTR/.list={-5,-4,-3,-2,-1,0,1,2,3,4,5}
    },
    repeat decoration CFLTR/.style={
        preaction={draw,decorate,decoration={cross from left to right,amplitude=#1*.5\pgflinewidth}}
    }
}
\begin{tikzpicture}
    \draw[monochromatic ribbon](A)to[bend left](B);
\end{tikzpicture}

앞면과 뒷면을 다르게 색칠하려면 두 개가 필요합니다.하프 리본서로 만나는 것.

\pgfdeclaredecoration{cross from left to middle}{initial}{
  \state{initial}[width=0,next state=stay above]
  {\pgfpathmoveto{\pgfqpoint{0pt}{\pgfdecorationsegmentamplitude}}}
  \state{stay above}[width=.5\pgfdecorationsegmentlength,
                     switch if less than=.5*\pgfdecoratedpathlength+\pgfdecorationsegmentlength to snake down 1]
  {\pgfpathlineto{\pgfqpoint{0pt}{\pgfdecorationsegmentamplitude}}}
  \state{snake down 1}[width=.5\pgfdecorationsegmentlength,next state=snake down 2]
  {\pgfpathlineto{\pgfqpoint{0pt}{\pgfdecorationsegmentamplitude}}}
  \state{snake down 2}[width=.5\pgfdecorationsegmentlength,next state=snake down 3]
  {\pgfpathlineto{\pgfqpoint{0pt}{.6\pgfdecorationsegmentamplitude}}}
  \state{snake down 3}[width=.5\pgfdecorationsegmentlength,next state=final]
  {\pgfpathlineto{\pgfqpoint{0pt}{0pt}}}
  \state{final}
  {
    \pgfpathmoveto{\pgfpointdecoratedpathlast}
  }
}
\pgfdeclaredecoration{cross from middle to right}{initial}{
  \state{initial}[width=0,next state=stay above]
  {}
  \state{stay above}[width=.5\pgfdecorationsegmentlength,
                     switch if less than=.5*\pgfdecoratedpathlength+\pgfdecorationsegmentlength to snake down 1]
  {}
  \state{snake down 1}[width=.5\pgfdecorationsegmentlength,next state=snake down 2]
  {}
  \state{snake down 2}[width=.5\pgfdecorationsegmentlength,next state=snake down 3]
  {}
  \state{snake down 3}[width=.5\pgfdecorationsegmentlength,next state=snake down 4]
  {\pgfpathmoveto{\pgfqpoint{0pt}{0pt}}}
  \state{snake down 4}[width=.5\pgfdecorationsegmentlength,next state=stay below]
  {\pgfpathlineto{\pgfqpoint{0pt}{-.7\pgfdecorationsegmentamplitude}}}
  \state{stay below}[width=.5\pgfdecorationsegmentlength,next state=stay below]
  {\pgfpathlineto{\pgfqpoint{0pt}{-\pgfdecorationsegmentamplitude}}}
  \state{final}
  {
    \pgfpathlineto{\pgfqpoint{0pt}{-\pgfdecorationsegmentamplitude}}
    \pgfpathlineto{\pgfqpoint{\pgfdecoratedremainingdistance}{-\pgfdecorationsegmentamplitude}}
    \pgfpathmoveto{\pgfpointdecoratedpathlast}
  }
}
    \begin{tikzpicture}
        \draw[demo decoration=cross from left to middle](A)to[bend left](B);
        \draw[brown,decorate,decoration=cross from middle to right](A)to[bend left](B);
    \end{tikzpicture}

다른 색상으로 반복하면 완료됩니다.

\tikzset{
    bichromatic ribbon/.style={
        preaction={draw,decorate,decoration={cross from left to right,amplitude=-6*.5\pgflinewidth}},
        repeat decoration CFLTM/.list={-5,-4,-3,-2,-1,0,1,2,3,4,5},
        repeat decoration CFMTR/.list={-5,-4,-3,-2,-1,0,1,2,3,4,5},
        preaction={draw,decorate,decoration={cross from left to right,amplitude=6*.5\pgflinewidth}},
    },
    repeat decoration CFLTM/.style={
        preaction={draw=blue!50,decorate,decoration={cross from left to middle,amplitude=#1*.5\pgflinewidth}}
    },
    repeat decoration CFMTR/.style={
        preaction={draw=teal!50,decorate,decoration={cross from middle to right,amplitude=#1*.5\pgflinewidth}}
    }
}
    \begin{tikzpicture}
        \path[bichromatic ribbon](A)to[bend left](B);
    \end{tikzpicture}



\end{document}

관련 정보