TikZ를 사용하여 3D로 평면 그리기

TikZ를 사용하여 3D로 평면 그리기

아래 그림과 같은 평면 세트를 그리는 경우

3D에서 교차하는 평면

여기에 포함된 코드처럼 각 평면의 각 시각적 부분을 뒤에서 앞으로 순서대로 그리는 솔루션이 자주 있으며, 또 다른 예는 여기를 참조하세요(교차 평면).

질문: 뷰를 미리 계산할 필요 없이 3D 좌표를 사용하여 평면을 그리고 TikZ 내에서 뷰포인트를 선택할 수 있습니까?

 \documentclass{standalone}
 \usepackage{tikz}
 \usetikzlibrary{positioning,calc}
 \usetikzlibrary{intersections}

 \begin{document}
 \pagecolor{blue!30}
 \pagestyle{empty}

 \begin{tikzpicture}[scale=1.6]

 \definecolor{bg}{RGB}{246,202,203}

 \coordinate (A) at (0.95,3.41);
 \coordinate (B) at (1.95,0.23);
 \coordinate (C) at (3.95,1.23);
 \coordinate (D) at (2.95,4.41);

 \coordinate (E) at (1.90,3.30);
 \coordinate (F) at (0.25,0.45);
 \coordinate (G) at (2.25,1.45);
 \coordinate (H) at (3.90,4.30);

 \coordinate (I) at (-0.2,1.80);
 \coordinate (J) at (2.78,1.00);
 \coordinate (K) at (4.78,2.00);
 \coordinate (L) at (1.80,2.80);

  \path[name path=AB] (A) -- (B);
  \path[name path=CD] (C) -- (D);
  \path[name path=EF] (E) -- (F);
  \path[name path=IJ] (I) -- (J);
  \path[name path=KL] (K) -- (L);
  \path[name path=HG] (H) -- (G);
  \path[name path=IL] (I) -- (L);
    \path [name intersections={of=AB and EF,by=M}];
    \path [name intersections={of=EF and IJ,by=N}];
    \path [name intersections={of=AB and IJ,by=O}];
    \path [name intersections={of=AB and IL,by=P}];
    \path [name intersections={of=CD and KL,by=Q}];
    \path [name intersections={of=CD and HG,by=R}];
    \path [name intersections={of=KL and HG,by=S}];
  \path[name path=NS] (N) -- (S);
  \path[name path=FG] (F) -- (G);
    \path [name intersections={of=NS and AB,by=T}];
    \path [name intersections={of=FG and AB,by=U}];

 \draw[thick, color=white, fill=bg] (A) -- (B) -- (C) -- (D) -- cycle;
 %\draw[thick, color=white, fill=bg] (E) -- (F) -- (G) -- (H) -- cycle;
 %\draw[thick, color=white, fill=bg] (I) -- (J) -- (K) -- (L) -- cycle;

 \draw[thick, color=white, fill=gray!80] (P) -- (O) -- (I) -- cycle;
 \draw[thick, color=white, fill=gray!80] (O) -- (J) -- (K) -- (Q) -- cycle;
 \draw[thick, color=white, fill=gray!40] (H) -- (E) -- (M) -- (R) -- cycle;
 \draw[thick, color=white, fill=gray!40] (M) -- (N) -- (T) -- cycle;
 \draw[thick, color=white, fill=gray!40] (N) -- (F) -- (U) -- (O) -- cycle;

 \end{tikzpicture}
 \end{document}

답변1

이것은 할 수 있지만 약간의 인내심이 필요하다는 메시지를 담은 재미있는 답변입니다. 또한 위도각 세타는 90도 이상의 범위에만 허용됩니다. 이 경우 구별해야 할 경우는 두 가지뿐입니다. 즉, 일반적인 경우는 아닙니다. 두 개의 이진수로 구분되는 네 가지 경우가 있습니다.

  • 화면의 x 방향에 대한 3D x 축 투영의 부호 \xproj.
  • cos(theta)의 부호 \zproj(tikz-3dplot 규칙에서 세타는 0에서 180 사이이고 적도는 세타=90입니다). 이 표시는 자신이 남반구에 있는지 북반구에 있는지 알려줍니다.

즉, 경우를 구별하여 긍정적인 경우와 부정적인 경우를 구분 \xproj합니다 \zproj. 이러한 기호에 따라 평면이 그려지는 순서가 변경됩니다. 약간의 명확성을 유지하기 위해 이 답변은 매크로와 함께 제공되므로 \DrawSinglePlane{<plane number>그리기 순서의 변경은 목록의 순열에 해당합니다 plane number.

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usetikzlibrary{calc}
\newcommand{\DrawPlane}[3][]{\draw[#1] 
(-1*\PlaneScale,{\PlaneScale*cos(#2)},{\PlaneScale*sin(#2)})
 -- ++  (2*\PlaneScale,0,0)
 -- ++ (0,{sqrt(3)*\PlaneScale*cos(#3)},{sqrt(3)*\PlaneScale*sin(#3)})
 -- ++  (-2*\PlaneScale,0,0) -- cycle;}
\newcommand{\DrawSinglePlane}[2][]{\ifcase#2
\or
\DrawPlane[fill=blue,#1]{210}{240} %left bottom 
\or
\DrawPlane[fill=red,#1]{-30}{-60} % right bottom
\or
\DrawPlane[fill=purple,#1]{210}{180} % bottom left
\or
\DrawPlane[fill=purple,#1]{210}{0} % bottom middle
\or
\DrawPlane[fill=purple,#1]{-30}{0} % bottom right
\or
\DrawPlane[fill=blue,#1]{90}{240} % left top
\or
\DrawPlane[fill=red,#1]{90}{-60} % right middle
\or
\DrawPlane[fill=red,#1]{90}{120} % right top
\or
\DrawPlane[fill=blue,#1]{90}{60} % left top
\fi
} 
\begin{document}
\foreach \X in {0,5,...,355}
{\tdplotsetmaincoords{90+40*sin(\X)}{\X} % the first argument cannot be larger than 90
\pgfmathsetmacro{\PlaneScale}{1}
\begin{tikzpicture}
\path[use as bounding box] (-4*\PlaneScale,-4*\PlaneScale) rectangle (4*\PlaneScale,4*\PlaneScale);
\begin{scope}[tdplot_main_coords]
% \draw[thick,->] (0,0,0) -- (2,0,0) node[anchor=north east]{$x$};
% \draw[thick,->] (0,0,0) -- (0,2,0) node[anchor=north west]{$y$};
% \draw[thick,->] (0,0,0) -- (0,0,1.5) node[anchor=south]{$z$};
\path let \p1=(1,0,0)  in 
\pgfextra{\pgfmathtruncatemacro{\xproj}{sign(\x1)}\xdef\xproj{\xproj}};
\pgfmathtruncatemacro{\zproj}{sign(cos(\tdplotmaintheta))}
\xdef\zproj{\zproj}
% \node[anchor=north west] at (current bounding box.north west)
% {\tdplotmaintheta,\tdplotmainphi,\xproj,\zproj};
\ifnum\zproj=1
  \ifnum\xproj=1
   \foreach \X in {2,1,5,4,3,7,6,9,8}
    {\DrawSinglePlane{\X}}
  \else
   \foreach \X in {1,...,9}
    {\DrawSinglePlane{\X}}
  \fi  
\else
  \ifnum\xproj=1
   \foreach \X in {9,8,7,6,3,4,5,2,1}
    {\DrawSinglePlane{\X}}
  \else
   \foreach \X in {8,9,6,7,3,5,4,1,2}
    {\DrawSinglePlane{\X}}
  \fi  
\fi  
\end{scope}
\end{tikzpicture}}
\end{document}

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

그리고\tdplotsetmaincoords{90+40*cos(\X)}{\X}

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

잠재적으로 중요한 의견은 pgfplots에 관한 것입니다. 원칙적으로 패치플롯을 사용하여 동일한 작업을 수행할 수 있습니다. pfplots는 주석에서 설명한 대로 주문을 수행하는 몇 가지 수단과 함께 제공됩니다.

UDPATE: 이제 전체 범위를 포괄합니다.

중요 사항: 이 애니메이션에서는 오리나 마못이 피해를 입지 않았습니다. ;-)

답변2

Tikz는 강력한 요구 사항인가요? 나는 Asymptote(TeXLive에 포함되어 있음)가 그러한 작업을 위한 훌륭한 도구라는 것을 알았습니다. 아래는 매우 가볍게 편집된 예입니다.점근선 갤러리.

로 시작하는 선을 변경하는 것만으로 시점을 변경할 수 있습니다 currentprojection.

size(6cm,0);
import bsp;
real u=2.5;
real v=1;
currentprojection = oblique;
path3 y=plane((2u,0,0),(0,2v,0),(-u,-v,0));
path3 a=rotate(45,X)*y;
path3 l=rotate(-45,Z)*rotate(45,Y)*rotate(45,Z)*y;
path3 g=rotate(45,X)*rotate(45,Y)*rotate(45,Z)*y;
face[] faces;
filldraw(faces.push(a),project(a),gray);
filldraw(faces.push(l),project(l),blue);
filldraw(faces.push(g),project(g),pink);
add(faces);

그러면 다음 그림이 생성됩니다.

점근선에 의해 생성된 교차 평면.

이 그림을 생성하기 위해 한 줄이 변경되는 동안 currentprojection = perspective(5,2,3);:

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

우수한점근선 튜토리얼 시카고 대학의 박사과정 학생인 Charles Staats가 썼습니다.

관련 정보