在下面的代码中,我尝试在三个正交平面上绘制三个剪裁圆。我使用这方法来裁剪圆的适当部分。这在 xy 和 yz 平面上效果很好,但在 xz 平面上效果不佳,如输出所示。
根据输出,我似乎犯了一个简单的错误,但我就是找不到它。我尝试检查示波器中 xz 平面(红色圆圈)的坐标,它们似乎是正确的。我附上了三张图,显示了每个示波器的剪切路径。(绘制的剪切路径显示了一些小错误,但这些与问题无关。)任何帮助查找错误的帮助都将不胜感激。
一些可能使代码更清晰的数学属性:
- 盒子的中心是点 (1,1,1)
- 绘制的轴交于 (1,1,1),而不是原点,因此图形本质上移动了 [1,1,1]
- 所有圆都以中心点 (1,1,1) 为同心圆
- 圆的半径是 2
\documentclass[11pt]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{tikz,tikz-3dplot}
\usetikzlibrary{arrows}
\begin{document}
\definecolor{darkgreen}{rgb}{0.1,0.7,0.1}
\tdplotsetmaincoords{60}{125}
\begin{tikzpicture}[tdplot_main_coords,>=latex]
\pgfsetlinewidth{0.8}
\tdplotsetcoord{P}{3.4641}{54.74}{45}
% box
\draw[fill=black!10] (Px) -- (Pxy) -- (Py) -- (Pyz) -- (Pz) -- (Pxz) -- cycle;
\draw (Pxy) -- (P);
\draw (Pxz) -- (P);
\draw (Pyz) -- (P);
\pgfsetlinewidth{1.4}
\begin{scope} % blue circle, xy plane
\color{blue}
\tikzstyle{reverseclip}=[insert path={(3.1,3.1,1) -- (-1.1,3.1,1) -- (-1,-1.1,1) -- (3.1,-1.1,1) -- (3.1,3.1,1)}]
\begin{pgfinterruptboundingbox}
\path[clip] (1,1,1) -- (1.3,-1.1,1) -- (-1.1,-1.1,1) -- (-1.1,2,1) -- cycle [reverseclip];
\end{pgfinterruptboundingbox}
\pgfpathellipse{\pgfpointxyz{1}{1}{1}}{\pgfpointxyz{2}{0}{0}}{\pgfpointxyz{0}{2}{0}}
\pgfusepath{draw}
\end{scope}
\begin{scope} % green circle, yz plane
\color{darkgreen}
\tikzstyle{reverseclip}=[insert path={(1,3.1,3.1) -- (1,3.1,-1.1) -- (1,-1.1,-1.1) -- (1,-1.1,3.1) -- (1,3.1,3.1)}]
\begin{pgfinterruptboundingbox}
\path[clip] (1,1,1) -- (1,-1.1,1.8) -- (1,-1.1,-1.1) -- (1,1.7,-1.1) -- cycle [reverseclip];
\end{pgfinterruptboundingbox}
\pgfpathellipse{\pgfpointxyz{1}{1}{1}}{\pgfpointxyz{0}{2}{0}}{\pgfpointxyz{0}{0}{2}}
\pgfusepath{draw}
\end{scope}
\begin{scope} % red circle, xz plane
\color{red}
\tikzstyle{reverseclip}=[insert path={(3.1,1,3.1) -- (-1.1,1,3.1) -- (-1.1,1,-1.1) -- (3.1,1,-1.1) -- (3.1,1,3.1)}]
\begin{pgfinterruptboundingbox}
\path[clip] (1,1,1) -- (-1.1,1,2) -- (-1.1,1,-1.1) -- (1.5,1,-1.1) -- cycle [reverseclip];
\end{pgfinterruptboundingbox}
\pgfpathellipse{\pgfpointxyz{1}{1}{1}}{\pgfpointxyz{2}{0}{0}}{\pgfpointxyz{0}{0}{2}}
\pgfusepath{draw}
\end{scope}
% axes
\draw[line width=0.8pt,->] (2,1,1) -- (4,1,1) node[anchor=north east]{\textbf{x}};
\draw[line width=0.8pt,->] (1,2,1) -- (1,4,1) node[anchor=north west]{\textbf{y}};
\draw[line width=0.8pt,->] (1,1,2) -- (1,1,4) node[anchor=south]{\textbf{z}};
\end{tikzpicture}
\end{document}
答案1
使用
\path[clip] (1.5,1,-1.1) -- (-1.1,1,-1.1) -- (-1.1,1,2) -- (1,1,1) -- cycle [reverseclip];
在最后一种情况下,反转剪切路径的方向。
\documentclass[11pt]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{tikz,tikz-3dplot}
\usetikzlibrary{arrows}
\begin{document}
\definecolor{darkgreen}{rgb}{0.1,0.7,0.1}
\tdplotsetmaincoords{60}{125}
\begin{tikzpicture}[tdplot_main_coords,>=latex]
\pgfsetlinewidth{0.8}
\tdplotsetcoord{P}{3.4641}{54.74}{45}
% box
\draw[fill=black!10] (Px) -- (Pxy) -- (Py) -- (Pyz) -- (Pz) -- (Pxz) -- cycle;
\draw (Pxy) -- (P);
\draw (Pxz) -- (P);
\draw (Pyz) -- (P);
\pgfsetlinewidth{1.4}
\begin{scope} % blue circle, xy plane
\color{blue}
\tikzstyle{reverseclip}=[insert path={(3.1,3.1,1) -- (-1.1,3.1,1) -- (-1,-1.1,1) -- (3.1,-1.1,1) -- (3.1,3.1,1)}]
\begin{pgfinterruptboundingbox}
\path[clip] (1,1,1) -- (1.3,-1.1,1) -- (-1.1,-1.1,1) -- (-1.1,2,1) -- cycle [reverseclip];
\end{pgfinterruptboundingbox}
\pgfpathellipse{\pgfpointxyz{1}{1}{1}}{\pgfpointxyz{2}{0}{0}}{\pgfpointxyz{0}{2}{0}}
\pgfusepath{draw}
\end{scope}
\begin{scope} % green circle, yz plane
\color{darkgreen}
\tikzstyle{reverseclip}=[insert path={(1,3.1,3.1) -- (1,3.1,-1.1) -- (1,-1.1,-1.1) -- (1,-1.1,3.1) -- (1,3.1,3.1)}]
\begin{pgfinterruptboundingbox}
\path[clip] (1,1,1) -- (1,-1.1,1.8) -- (1,-1.1,-1.1) -- (1,1.7,-1.1) -- cycle [reverseclip];
\end{pgfinterruptboundingbox}
\pgfpathellipse{\pgfpointxyz{1}{1}{1}}{\pgfpointxyz{0}{2}{0}}{\pgfpointxyz{0}{0}{2}}
\pgfusepath{draw}
\end{scope}
\begin{scope} % red circle, xz plane
\color{red}
\tikzstyle{reverseclip}=[insert path={(3.1,1,3.1) -- (-1.1,1,3.1) -- (-1.1,1,-1.1) -- (3.1,1,-1.1) -- (3.1,1,3.1)}]
\begin{pgfinterruptboundingbox}
\path[clip] (1.5,1,-1.1) -- (-1.1,1,-1.1) -- (-1.1,1,2) -- (1,1,1) -- cycle [reverseclip];
\end{pgfinterruptboundingbox}
\pgfpathellipse{\pgfpointxyz{1}{1}{1}}{\pgfpointxyz{2}{0}{0}}{\pgfpointxyz{0}{0}{2}}
\pgfusepath{draw}
\end{scope}
% axes
\draw[line width=0.8pt,->] (2,1,1) -- (4,1,1) node[anchor=north east]{\textbf{x}};
\draw[line width=0.8pt,->] (1,2,1) -- (1,4,1) node[anchor=north west]{\textbf{y}};
\draw[line width=0.8pt,->] (1,1,2) -- (1,1,4) node[anchor=south]{\textbf{z}};
\end{tikzpicture}
\end{document}
这给了我一个想法:
\documentclass[11pt,crop=false,preview=false]{standalone}
\usepackage[utf8]{inputenc}
\usepackage{tikz,tikz-3dplot}
\usetikzlibrary{arrows}
\begin{document}
\definecolor{darkgreen}{rgb}{0.1,0.7,0.1}
\tdplotsetmaincoords{60}{125}
\begin{tikzpicture}[tdplot_main_coords,>=latex]
\pgfsetlinewidth{0.8}
\tdplotsetcoord{P}{3.4641}{54.74}{45}
% box
\draw[fill=black!10] (Px) -- (Pxy) -- (Py) -- (Pyz) -- (Pz) -- (Pxz) -- cycle;
\draw (Pxy) -- (P);
\draw (Pxz) -- (P);
\draw (Pyz) -- (P);
\pgfsetlinewidth{1.4}
\begin{scope} % blue circle, xy plane
\color{blue}
\tikzstyle{reverseclip}=[insert path={(3.1,3.1,1) -- (-1.1,3.1,1) -- (-1,-1.1,1) -- (3.1,-1.1,1) -- (3.1,3.1,1)}]
\begin{pgfinterruptboundingbox}
\path[clip] (1,1,1) -- (1.3,-1.1,1) -- (-1.1,-1.1,1) -- (-1.1,2,1) -- cycle [reverseclip];
\end{pgfinterruptboundingbox}
\pgfpathellipse{\pgfpointxyz{1}{1}{1}}{\pgfpointxyz{2}{0}{0}}{\pgfpointxyz{0}{2}{0}}
\pgfusepath{draw}
\end{scope}
\begin{scope} % green circle, yz plane
\color{darkgreen}
\tikzstyle{reverseclip}=[insert path={(1,3.1,3.1) -- (1,3.1,-1.1) -- (1,-1.1,-1.1) -- (1,-1.1,3.1) -- (1,3.1,3.1)}]
\begin{pgfinterruptboundingbox}
\draw[purple,->] (1,1,1) -- (1,-1.1,1.8) -- (1,-1.1,-1.1) -- (1,1.7,-1.1);
\path[clip] (1,1,1) -- (1,-1.1,1.8) -- (1,-1.1,-1.1) -- (1,1.7,-1.1) -- cycle [reverseclip];
\end{pgfinterruptboundingbox}
\pgfpathellipse{\pgfpointxyz{1}{1}{1}}{\pgfpointxyz{0}{2}{0}}{\pgfpointxyz{0}{0}{2}}
\pgfusepath{draw}
\end{scope}
\begin{scope} % red circle, xz plane
\color{red}
\tikzstyle{reverseclip}=[insert path={(3.1,1,3.1) -- (-1.1,1,3.1) -- (-1.1,1,-1.1) -- (3.1,1,-1.1) -- (3.1,1,3.1)}]
\begin{pgfinterruptboundingbox}
\draw[orange,->] (1,1,1) -- (-1.1,1,2) -- (-1.1,1,-1.1) -- (1.5,1,-1.1);
\path[clip] (1,1,1) -- (-1.1,1,2) -- (-1.1,1,-1.1) -- (1.5,1,-1.1) -- cycle [reverseclip];
\end{pgfinterruptboundingbox}
\pgfpathellipse{\pgfpointxyz{1}{1}{1}}{\pgfpointxyz{2}{0}{0}}{\pgfpointxyz{0}{0}{2}}
\pgfusepath{draw}
\end{scope}
% axes
\draw[line width=0.8pt,->] (2,1,1) -- (4,1,1) node[anchor=north east]{\textbf{x}};
\draw[line width=0.8pt,->] (1,2,1) -- (1,4,1) node[anchor=north west]{\textbf{y}};
\draw[line width=0.8pt,->] (1,1,2) -- (1,1,4) node[anchor=south]{\textbf{z}};
\end{tikzpicture}
\end{document}
答案2
在这种情况下,也许您可以使用弧线和rotate around
围绕指定轴向量旋转坐标系的键,如下所示(注意,shift
要使此功能正常工作,需要将 a 置于框的中心)。但是,它确实需要最新版本的PGF
。我对原始代码进行了一些改动。
\documentclass[tikz,border=5]{standalone}
\usepackage{tikz-3dplot}
\begin{document}
\definecolor{dark green}{rgb}{0.1,0.7,0.1}
\tdplotsetmaincoords{60}{125}
\begin{tikzpicture}[tdplot_main_coords,>=latex, thick, line cap=round, line join=round]
\tdplotsetcoord{P}{3.4641}{54.74}{45}
\coordinate (O) at (1,1,1);
% box
\draw[fill=black!10] (Px) -- (Pxy) -- (Py) -- (Pyz) -- (Pz) -- (Pxz) -- cycle;
\draw (Pxy) -- (P) (Pxz) -- (P) (Pyz) -- (P);
\tikzset{shift={(O)}, ultra thick}
\draw [blue, rotate around z=-90]
(15:2) arc (15:245:2);
\draw [dark green, rotate around z=-90, rotate around x=90]
(15:2) arc (15:245:2);
\draw [red, rotate around z=-90, rotate around y=90]
(15:2) arc (15:245:2);
\tikzset{thick}
% axes
\draw [->] (1,0,0) -- (3,0,0) node[below left] {\textbf{x}};
\draw [->] (0,1,0) -- (0,3,0) node[below right] {\textbf{y}};
\draw [->] (0,0,1) -- (0,0,3) node[above] {\textbf{z}};
\end{tikzpicture}
\end{document}