3D 직사각형 그리기

3D 직사각형 그리기

나는 이것을 몇 시간 동안 검색했지만 이 동작에 대한 이유를 찾지 못했습니다.

내 예는 다음과 같습니다.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{3d}


\begin{document}
    \begin{tikzpicture}[x={(0.866cm,0.5cm)},y={(-0.866cm,0.5cm)},z={(0cm,1cm)}]
        \fill[blue!50,opacity=0.6] (0,0,0) rectangle (2,1,0);
        \fill[green!50,opacity=0.6] (0,0,0) -- (2,0,0) -- (2,1,0) -- (0,1,0) -- (0,0,0);
        \draw[->] (0,0,0) -- (1,0,0);
        \draw[->] (0,0,0) -- (0,1,0);
        \draw[->] (0,0,0) -- (0,0,1);

        \begin{scope}[xshift=3cm]
            \fill[blue!50,opacity=0.6] (0,0,0) circle (1);
            \draw[->] (0,0,0) -- (1,0,0);
            \draw[->] (0,0,0) -- (0,1,0);
            \draw[->] (0,0,0) -- (0,0,1);
        \end{scope}
    \end{tikzpicture}
\end{document}

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

나는 두 직사각형이 모두 동일하게 칠해질 것으로 기대합니다. 더 정확하게 말하면 둘 다 녹색처럼 나타나야 하지만 그렇지 않습니다.

분명히 오른쪽 위 모서리(2,1,0)의 좌표는 두 직사각형 모두에 대해 정확하지만 녹색 좌표만 좌표계의 축과 올바르게 정렬됩니다.

이에 비해 원은 타원으로 그려지기 때문에 수정된 벡터를 올바르게 사용합니다.

파란색 직사각형을 녹색 직사각형처럼 칠하려면 어떻게 해야 합니까?

편집하다: 에서 흥미로운 것을 발견했습니다이것답변. 분명히 다음 코드는 작동하지만 모든 직사각형을 범위에 배치하는 것이 약간 불편하다는 것을 알았습니다.

추가적으로,캔버스는 z의 xy 평면입니다.정말 잘못된 방식으로 구현되었나요? 그렇다면 왜 이것이 해결되지 않습니까?

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{3d}

\makeatletter
\tikzoption{canvas is xy plane at z}[]{%
  \def\tikz@plane@origin{\pgfpointxyz{0}{0}{#1}}%
  \def\tikz@plane@x{\pgfpointxyz{1}{0}{#1}}%
  \def\tikz@plane@y{\pgfpointxyz{0}{1}{#1}}%
  \tikz@canvas@is@plane
}
\makeatother

\begin{document}
\begin{tikzpicture}[x={(0.866cm,0.5cm)},y={(-0.866cm,0.5cm)},z={(0cm,1cm)}]
        \begin{scope}[canvas is xy plane at z=0,transform shape]
            \fill[blue!50,opacity=0.6] (0,0,0) rectangle (2,1,0);
        \end{scope}

        \fill[green!50,opacity=0.6] (0,0,0) -- (2,0,0) -- (2,1,0) -- (0,1,0) -- (0,0,0);

        \draw[->] (0,0,0) -- (1,0,0);
        \draw[->] (0,0,0) -- (0,1,0);
        \draw[->] (0,0,0) -- (0,0,1);

        \begin{scope}[xshift=3cm]
            \fill[blue!50,opacity=0.6] (0,0,0) circle (1);
            \draw[->] (0,0,0) -- (1,0,0);
            \draw[->] (0,0,0) -- (0,1,0);
            \draw[->] (0,0,0) -- (0,0,1);
        \end{scope}
\end{tikzpicture}
\end{document}

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

답변1

명령을 범위에 넣을 필요는 없으며 옵션을 명령에 직접 전달할 수 있습니다.

\draw[canvas is xy plane at z=0] ...;,

그러나 이렇게 하면 줄 길이가 크게 늘어납니다. 대신 매개변수로 스타일을 정의하여 다음을 사용할 수 있습니다.

\tikzset{my style name/.style={canvas is xy plane at z=#1}}

그리고 작은 설명으로: 단위 벡터를 데카르트 형식으로 제공하는 대신(변경하려는 경우 매우 불편함) 극 표기법을 사용할 수 있습니다.

[x={(0.866cm,0.5cm)}] [x={(-30:1cm)}

암호

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{3d}

\makeatletter
\tikzoption{canvas is xy plane at z}[]{%
  \def\tikz@plane@origin{\pgfpointxyz{0}{0}{#1}}%
  \def\tikz@plane@x{\pgfpointxyz{1}{0}{#1}}%
  \def\tikz@plane@y{\pgfpointxyz{0}{1}{#1}}%
  \tikz@canvas@is@plane
}
\makeatother

\tikzset{xyp/.style={canvas is xy plane at z=#1}}
\tikzset{xzp/.style={canvas is xz plane at y=#1}}
\tikzset{yzp/.style={canvas is yz plane at x=#1}}

\begin{document}
\begin{tikzpicture}[x={(-30:1cm)},y={(210:1cm)},z={(90:1cm)}]
    \draw[->] (0,0,0) -- node[pos=1.2] {x} (1,0,0);
    \draw[->] (0,0,0) -- node[pos=1.2] {y} (0,1,0);
    \draw[->] (0,0,0) -- node[pos=1.2] {z} (0,0,1);
    \foreach \n in {-0.1,-0.2,...,-2}
    {   \fill[opacity=0.3,yellow,draw=black,xyp=\n] (0-\n/5,0-\n/5) rectangle (2+\n/5,2+\n/5);
        \fill[opacity=0.3,red,draw=black,xzp=\n] (0,0) (0-\n/5,0-\n/5) rectangle (2+\n/5,2+\n/5);
        \fill[opacity=0.3,blue,draw=black,yzp=\n] (0,0) (0-\n/5,0-\n/5) rectangle (2+\n/5,2+\n/5);
    }  
\end{tikzpicture}
\end{document}

산출

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

답변2

소스를 읽어보니 그냥 교체하면 된다는 걸 알았습니다.

canvas is xy plane at z

~에 의해

canvas is yx plane at z

그들의 정의는 다음과 tikzlibrary3d.code.tex같습니다

\tikzoption{canvas is xy plane at z}{%
  \tikz@addtransform{\pgftransformshift{\pgfpointxyz{0}{0}{#1}}}%
}
\tikzoption{canvas is yx plane at z}[]{%
  \def\tikz@plane@origin{\pgfpointxyz{0}{0}{#1}}%
  \def\tikz@plane@x{\pgfpointxyz{0}{1}{#1}}%
  \def\tikz@plane@y{\pgfpointxyz{1}{0}{#1}}%
  \tikz@canvas@is@plane
}

예를 들어 @Tom Bombadil의 답변은 다음과 같이 수정될 수 있습니다.

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{3d}

\tikzset{xyp/.style={canvas is yx plane at z=#1}}
\tikzset{xzp/.style={canvas is xz plane at y=#1}}
\tikzset{yzp/.style={canvas is yz plane at x=#1}}

\begin{document}
\begin{tikzpicture}[x={(-30:1cm)},y={(210:1cm)},z={(90:1cm)}]
    \draw[->] (0,0,0) -- node[pos=1.2] {x} (1,0,0);
    \draw[->] (0,0,0) -- node[pos=1.2] {y} (0,1,0);
    \draw[->] (0,0,0) -- node[pos=1.2] {z} (0,0,1);
    \foreach \n in {-0.1,-0.2,...,-2}
    {   \fill[opacity=0.3,yellow,draw=black,xyp=\n] (0-\n/5,0-\n/5) rectangle (2+\n/5,2+\n/5);
        \fill[opacity=0.3,red,draw=black,xzp=\n] (0,0) (0-\n/5,0-\n/5) rectangle (2+\n/5,2+\n/5);
        \fill[opacity=0.3,blue,draw=black,yzp=\n] (0,0) (0-\n/5,0-\n/5) rectangle (2+\n/5,2+\n/5);
    }  
\end{tikzpicture}
\end{document}

그리고 출력은 정확히 동일합니다.


분명히 연결된 질문의 @Alain Matthes도 이것을 발견했습니다.

관련 정보