我正在尝试用我在 tikz-3dplot 中制作的东西替换我在 powerpoint 中制作的图表。该图表应该类似于此
我遇到的问题是,这些线完全落在最右边的平面前面或后面
所以我的问题是,实现这一目标的最佳方法是什么?我从不久前的观察中知道,问题在于 tikz-3dplot 实际上将所有内容转换为二维,因此它几乎不可能知道交点发生在哪里。这是 powerpoint 存在的相同问题,我所做的就是创建两个不同的线段并以此方式分层。有没有一种简单的方法可以在 tikz-3dplot 中做到这一点?有没有更好的方法?
我用来生成底部图的代码如下:
\documentclass[10pt,letterpaper]{article}
\usepackage[landscape]{geometry}
\usepackage{tikz}
\usetikzlibrary{calc,arrows}
\usepackage{amsmath}
\usepackage{tikz-3dplot}
\newcommand{\rotateRPY}[3]% roll, pitch, yaw
{ \pgfmathsetmacro{\rollangle}{#1}
\pgfmathsetmacro{\pitchangle}{#2}
\pgfmathsetmacro{\yawangle}{#3}
% to what vector is the x unit vector transformed, and which 2D vector is this?
\pgfmathsetmacro{\newxx}{cos(\yawangle)*cos(\pitchangle)}
\pgfmathsetmacro{\newxy}{sin(\yawangle)*cos(\pitchangle)}
\pgfmathsetmacro{\newxz}{-sin(\pitchangle)}
\path (\newxx,\newxy,\newxz);
\pgfgetlastxy{\nxx}{\nxy};
% to what vector is the y unit vector transformed, and which 2D vector is this?
\pgfmathsetmacro{\newyx}{cos(\yawangle)*sin(\pitchangle)*sin(\rollangle)-sin(\yawangle)*cos(\rollangle)}
\pgfmathsetmacro{\newyy}{sin(\yawangle)*sin(\pitchangle)*sin(\rollangle)+ cos(\yawangle)*cos(\rollangle)}
\pgfmathsetmacro{\newyz}{cos(\pitchangle)*sin(\rollangle)}
\path (\newyx,\newyy,\newyz);
\pgfgetlastxy{\nyx}{\nyy};
% to what vector is the z unit vector transformed, and which 2D vector is this?
\pgfmathsetmacro{\newzx}{cos(\yawangle)*sin(\pitchangle)*cos(\rollangle)+ sin(\yawangle)*sin(\rollangle)}
\pgfmathsetmacro{\newzy}{sin(\yawangle)*sin(\pitchangle)*cos(\rollangle)-cos(\yawangle)*sin(\rollangle)}
\pgfmathsetmacro{\newzz}{cos(\pitchangle)*cos(\rollangle)}
\path (\newzx,\newzy,\newzz);
\pgfgetlastxy{\nzx}{\nzy};
}
\newcommand{\translatepoint}[1]%
{ \coordinate (mytranslation) at (#1);
}
\tikzset{RPY/.style={x={(\nxx,\nxy)},y={(\nyx,\nyy)},z={(\nzx,\nzy)}}}
\tikzset{ultra thick/.style={line width=2.5pt}}
\newcommand\coordLength{0.5}
\newcommand\planeWidth{0.5}
\begin{document}
\tdplotsetmaincoords{60}{120}
\begin{tikzpicture}[tdplot_main_coords,cm={-1,-1,1,0,(0,0)},x=1in,y=0.75in,z=-1in,>=stealth']
%set up the axes so they are correctly oriented
\rotateRPY{0}{0}{90}
\begin{scope}[RPY]
%create coordinates for various points of interest
\coordinate (center) at (0,0,0);
\coordinate (pp) at (0,0,1);
\coordinate (fp) at (0,0,-1);
%\coordinate (point) at (1,-1,3);
\tdplotsetcoord{point}{3.5}{20}{-30};
\coordinate (framew) at (-1,0,2.5);
%Draw the camera coordinate frame
\draw[->,thick] (center) -- ($(\coordLength,0,0)$);
\draw[->,thick] (center) -- ($(0,\coordLength,0)$);
\draw[->,thick] (center) -- ($(0,0,\coordLength)$);
\node[inner sep=2pt] (cx) at ($(\coordLength+0.1,0,0)$) {\large$\textbf{c}_x$};
\node[inner sep=2pt] (cy) at ($(0,\coordLength+0.1,0)$) {\large$\textbf{c}_y$};
\node[inner sep=2pt] (cz) at ($(0,0.05,\coordLength+0.1)$) {\large$\textbf{c}_z$};
%label the camera center
\node[inner sep=2pt] (C) at ($(center)-(0.05,0.05,0.05)$) {\large$C$};
%
%draw the principal axis
\draw[dotted] (fp) -- (0,0,4);
%draw the focal plane
\begin{scope}[canvas is yx plane at z=-1]
\path[fill=lightgray,opacity=0.8,line join=round] (-\planeWidth,-\planeWidth) rectangle (\planeWidth,\planeWidth);
\end{scope}
%draw the world axes
\rotateRPY{0}{10}{75}
\begin{scope}[shift=(framew),RPY]
%Draw the world coordinate frame
\draw[->,thick] (0,0,0) -- ($(\coordLength+0.1,0,0)$);
\draw[->,thick] (0,0,0) -- ($(0,\coordLength+0.1,0)$);
\draw[->,thick,dashed] (0,0,0) -- ($(0,0,\coordLength-0.1)$);
\node[inner sep=2pt] (wz) at ($(\coordLength+0.25,0,0)$) {\large$\textbf{w}_z$};
\node[inner sep=2pt] (wy) at ($(0,\coordLength+0.25,0)$) {\large$\textbf{w}_y$};
\node[inner sep=2pt] (wx) at ($(0,-0.05,\coordLength)$) {\large$\textbf{w}_x$};
\end{scope}
%draw the point and show the vectors to/from it
\draw[ultra thick, ->] (framew) -- (point) node[circle,fill,inner sep=0,minimum size=4pt] {};
\draw[ultra thick, ->] (center) -- (point);
\node[inner sep=2pt] (x) at ($(point)+(0,0.08,0.08)$){\large $x$};
%draw the image plane
\begin{scope}[canvas is yx plane at z=1]
\path[fill=lightgray,opacity=0.8,line join=round] (-\planeWidth,-\planeWidth) rectangle (\planeWidth,\planeWidth);
\end{scope}
\end{scope}
\end{tikzpicture}
\end{document}
请注意,我并没有要求任何人帮我完成绘图(尽管如果你很无聊并且想做点什么,那就请随意吧……)我只是想知道如何在 tikz-3dplot 中复制穿过平面的线条的效果。还请注意,除非它非常简单,否则我宁愿不切换到需要我以 pdflatex 以外的其他方式进行编译的软件包,尽管如果有人给我一个我应该这样做的充分理由,我会考虑的。
谢谢。
安德鲁
答案1
所以我最终在实际处理另一张图表时弄明白了这一点。我所做的是创建两个宏,一个从笛卡尔坐标转换为球坐标,另一个从球坐标转换为笛卡尔坐标。通过这样做,我可以在 3 维空间中定义图像平面上的点,将这些点转换为球坐标,通过延长 rho 来延长这些点,然后转换回笛卡尔点并绘制。然后,这给了我图像平面上的一个点(或此图中的照片平面),我可以在绘制图像平面之前从中心画一条线到该点,然后在绘制图像平面之后画一条线到该点。宏如下:
\newcommand{\xyztortp}[3]
{ \pgfmathsetmacro{\xcoord}{#1}
\pgfmathsetmacro{\ycoord}{#2}
\pgfmathsetmacro{\zcoord}{#3}
\pgfmathsetmacro{\rhoCoord}{((\xcoord)^(2.0)+(\ycoord)^(2.0)+(\zcoord)^(2.0))^(0.5)}
\pgfmathsetmacro{\phiCoord}{ifthenelse((\ycoord)<0,-acos(\zcoord/(\rhoCoord)),acos(\zcoord/(\rhoCoord)))}
\pgfmathsetmacro{\thetaCoord}{acos(\xcoord/(\rhoCoord*sin(\phiCoord))}
}
\newcommand{\rtptoxyz}[3]
{ \pgfmathsetmacro{\rhoCoord}{#1}
\pgfmathsetmacro{\thetaCoord}{#2}
\pgfmathsetmacro{\phiCoord}{#3}
\pgfmathsetmacro{\xCoord}{\rhoCoord*sin(\phiCoord)*cos(\thetaCoord)}
\pgfmathsetmacro{\yCoord}{\rhoCoord*sin(\phiCoord)*sin(\thetaCoord)}
\pgfmathsetmacro{\zCoord}{\rhoCoord*cos(\phiCoord)}
}
对于任何感兴趣的人,生成该图的完整代码如下:
\newcommand{\rotateRPY}[3]% roll, pitch, yaw
{ \pgfmathsetmacro{\rollangle}{#1}
\pgfmathsetmacro{\pitchangle}{#2}
\pgfmathsetmacro{\yawangle}{#3}
% to what vector is the x unit vector transformed, and which 2D vector is this?
\pgfmathsetmacro{\newxx}{cos(\yawangle)*cos(\pitchangle)}
\pgfmathsetmacro{\newxy}{sin(\yawangle)*cos(\pitchangle)}
\pgfmathsetmacro{\newxz}{-sin(\pitchangle)}
\path (\newxx,\newxy,\newxz);
\pgfgetlastxy{\nxx}{\nxy};
% to what vector is the y unit vector transformed, and which 2D vector is this?
\pgfmathsetmacro{\newyx}{cos(\yawangle)*sin(\pitchangle)*sin(\rollangle)-sin(\yawangle)*cos(\rollangle)}
\pgfmathsetmacro{\newyy}{sin(\yawangle)*sin(\pitchangle)*sin(\rollangle)+ cos(\yawangle)*cos(\rollangle)}
\pgfmathsetmacro{\newyz}{cos(\pitchangle)*sin(\rollangle)}
\path (\newyx,\newyy,\newyz);
\pgfgetlastxy{\nyx}{\nyy};
% to what vector is the z unit vector transformed, and which 2D vector is this?
\pgfmathsetmacro{\newzx}{cos(\yawangle)*sin(\pitchangle)*cos(\rollangle)+ sin(\yawangle)*sin(\rollangle)}
\pgfmathsetmacro{\newzy}{sin(\yawangle)*sin(\pitchangle)*cos(\rollangle)-cos(\yawangle)*sin(\rollangle)}
\pgfmathsetmacro{\newzz}{cos(\pitchangle)*cos(\rollangle)}
\path (\newzx,\newzy,\newzz);
\pgfgetlastxy{\nzx}{\nzy};
}
\newcommand{\xyztortp}[3]
{ \pgfmathsetmacro{\xcoord}{#1}
\pgfmathsetmacro{\ycoord}{#2}
\pgfmathsetmacro{\zcoord}{#3}
\pgfmathsetmacro{\rhoCoord}{((\xcoord)^(2.0)+(\ycoord)^(2.0)+(\zcoord)^(2.0))^(0.5)}
\pgfmathsetmacro{\phiCoord}{ifthenelse((\ycoord)<0,-acos(\zcoord/(\rhoCoord)),acos(\zcoord/(\rhoCoord)))}
\pgfmathsetmacro{\thetaCoord}{acos(\xcoord/(\rhoCoord*sin(\phiCoord))}
}
\newcommand{\rtptoxyz}[3]
{ \pgfmathsetmacro{\rhoCoord}{#1}
\pgfmathsetmacro{\thetaCoord}{#2}
\pgfmathsetmacro{\phiCoord}{#3}
\pgfmathsetmacro{\xCoord}{\rhoCoord*sin(\phiCoord)*cos(\thetaCoord)}
\pgfmathsetmacro{\yCoord}{\rhoCoord*sin(\phiCoord)*sin(\thetaCoord)}
\pgfmathsetmacro{\zCoord}{\rhoCoord*cos(\phiCoord)}
}
\newcommand{\translatepoint}[1]%
{ \coordinate (mytranslation) at (#1);
}
\tikzset{RPY/.style={x={(\nxx,\nxy)},y={(\nyx,\nyy)},z={(\nzx,\nzy)}}}
\tikzset{ultra thick/.style={line width=2.5pt}}
\tdplotsetmaincoords{30}{120}
\begin{tikzpicture}[tdplot_main_coords,cm={-1,-1,1,0,(0,0)},x=1in,y=0.75in,z=-1in,>=stealth']
%set up the axes so they are correctly oriented
\rotateRPY{0}{0}{90}
\begin{scope}[RPY]
%create coordinates for various points of interest
\pgfmathsetmacro{\planeDist}{1.5}
\pgfmathsetmacro{\xbp}{-0.25}
\pgfmathsetmacro{\ybp}{-0.15}
\pgfmathsetmacro{\coordLength}{0.35}
\pgfmathsetmacro{\xpp}{0.2}
\pgfmathsetmacro{\ypp}{0.3}
\coordinate (center) at (0,0,0);
\coordinate (cp) at (0,0,\planeDist);
\coordinate (cf) at (0,0,-\planeDist);
\coordinate (bp) at (\xbp,\ybp,\planeDist);
\coordinate (poip) at (\xpp,\ypp,\planeDist);
\coordinate (poif) at (-\xpp,-\ypp,-\planeDist);
\pgfmathsetmacro{\planeWidth}{0.5}
%draw the focal plane and everything that touches it
\begin{scope}[canvas is yx plane at z=-\planeDist]
\path[fill=lightgray,opacity=0.8,line join=round,draw=black] (-\planeWidth,-\planeWidth) rectangle (\planeWidth,\planeWidth);
\pgfmathsetmacro{\fcoordLength}{0.225}
\draw[->,thick] (0,0) -- (\fcoordLength,0) node[anchor=north]{$\textbf{f}_y$};
\draw[->,thick] (0,0) node[anchor=south]{$F$} -- (0,\fcoordLength) node[anchor=north]{$\textbf{f}_x$};
\draw plot[mark=*, mark size=0.5] coordinates{(-\ypp,-\xpp)} node[anchor=north]{$\textbf{x}_F$};
\end{scope}
\draw[decorate,decoration={brace, amplitude=6mm}] (0,0,0)--(0,0,-\planeDist) node[midway,below=6mm]{$f$};
\draw[dashed] (poif) -- (center);
\node[inner sep=2pt,anchor=south east] (fplabel) at (-\coordLength,-\coordLength-0.2,-\planeDist){Focal Plane};
%Draw the camera coordinate frame
\draw[->,thick] (center) -- ($(\coordLength,0,0)$);
\draw[->,thick] (center) -- ($(0,\coordLength,0)$);
\draw[->,thick] (center) -- ($(0,0,\coordLength)$);
\node[inner sep=2pt] (cx) at ($(\coordLength+0.1,0,0)$) {$\textbf{c}_x$};
\node[inner sep=2pt] (cy) at ($(0,\coordLength+0.1,0)$) {$\textbf{c}_y$};
\node[inner sep=2pt] (cz) at ($(0,0.08,\coordLength+0.1)$) {$\textbf{c}_z$};
%draw the vector between the camera center and image plane that connects to the B coordinate system
\draw[<-,thick] (center) node[anchor=south west]{$\textbf{t}_B$} -- (bp);
%draw the vector between the camera center and image plane that connects to the point of interest
\draw[thick] (center) -- (poip);
%label the camera center
\node[inner sep=2pt] (C) at ($(center)-(0.05,0.05,0.1)$) {$C$};
%
%draw the principal axis
\draw[dashed] (cf) -- (cp);
%draw the boresight
\pgfmathsetmacro{\borex}{-0.03}
\pgfmathsetmacro{\borey}{-0.05}
\coordinate (borep) at (\borex,\borey,\planeDist);
\draw[dashed,red,thick] (center) -- (borep); %node[above,text=red]{boresight}
\draw[decorate,decoration={brace, mirror,amplitude=6mm}] (0,0,0)--(0,0,\planeDist) node[midway,below=6mm]{$f$};
%draw the camera field of view
% \coordinate (fov1b) at (\planeWidth,\planeWidth,\planeDist);
% \coordinate (fov2b) at (-\planeWidth,\planeWidth,\planeDist);
% \coordinate (fov3b) at (-\planeWidth,-\planeWidth,\planeDist);
% \coordinate (fov4b) at (\planeWidth,-\planeWidth,\planeDist);
%
% \draw[dotted] (center) -- (fov1b);
% \draw[dotted] (center) -- (fov2b);
% \draw[dotted] (center) -- (fov3b);
% \draw[dotted] (center) -- (fov4b);
%draw the photo plane
\begin{scope}[canvas is yx plane at z=\planeDist]
\path[fill=lightgray,draw=black,opacity=0.8,line join=round] (-\planeWidth,-\planeWidth) rectangle (\planeWidth,\planeWidth);
\draw plot [mark=*, mark size=0.5] coordinates{(0,0)} node[anchor=north west]{$\textbf{c}_P$};
\draw plot [mark=*, mark size=0.5,mark options={color=red}] coordinates{(\borex,\borey)};
\node[anchor=south west,text=red, inner sep=2pt] (boreOnP) at (\borex,\borey){$\textbf{p}_P$};
\pgfmathsetmacro{\icoordLength}{0.225}
\draw[->,thick] (-\planeWidth,-\planeWidth) -- ($(-\planeWidth+\icoordLength,-\planeWidth)$) node[anchor=north]{$\textbf{p}_y$};
\draw[->,thick] (-\planeWidth,-\planeWidth) node[anchor=west]{$P$} -- ($(-\planeWidth,-\planeWidth+\icoordLength)$) node[anchor=north]{$\textbf{p}_x$};
\draw[->,thick] (0,0) -- (\icoordLength,0) node[anchor=north]{$\textbf{i}_y$};
\draw[->,thick] (0,0) node[anchor=south east]{$I$} -- (0,\icoordLength) node[anchor=north]{$\textbf{i}_x$};
\draw plot [mark=*, mark size=0.5] coordinates{(\ypp,\xpp)} node[anchor=north]{$\textbf{x}_I\text{, }\textbf{x}_P$};
\end{scope}
%Extend our field of view lines
% \pgfmathsetmacro{\extend}{1.5}
% \xyztortp{\planeWidth}{\planeWidth}{\planeDist}
% \rtptoxyz{\extend*\rhoCoord}{\thetaCoord}{\phiCoord}
%
% \coordinate (fov1e) at (\xCoord,\yCoord,\zCoord);
%
% \draw[dotted,->] (fov1b) -- (fov1e);
%
% \xyztortp{-\planeWidth}{\planeWidth}{\planeDist}
% \rtptoxyz{\extend*\rhoCoord}{\thetaCoord}{\phiCoord}
%
% \coordinate (fov2e) at (\xCoord,\yCoord,\zCoord);
%
% \draw[dotted,->] (fov2b) -- (fov2e);
%
% \xyztortp{-\planeWidth}{-\planeWidth}{\planeDist}
% \rtptoxyz{\extend*\rhoCoord}{\thetaCoord}{\phiCoord}
%
% \coordinate (fov3e) at (\xCoord,\yCoord,\zCoord);
%
% \draw[dotted,->] (fov3b) -- (fov3e);
%
%
% \xyztortp{\planeWidth}{-\planeWidth}{\planeDist}
% \rtptoxyz{\extend*\rhoCoord}{\thetaCoord}{\phiCoord}
%
% \coordinate (fov4e) at (\xCoord,\yCoord,\zCoord);
%
% \draw[dotted,->] (fov4b) -- (fov4e);
%
%extend the principal axis
\draw[dashed] (cp) -- +(0,0,1.5*\planeDist);
\node[anchor=north] (princlabel) at (0,0,1.7*\planeDist){principal axis};
%extend the boresight
\xyztortp{\borex}{\borey}{\planeDist}
\rtptoxyz{(\planeDist+1.5*\planeDist)/cos(\phiCoord)}{\thetaCoord}{\phiCoord}
\coordinate (boree) at (\xCoord,\yCoord,\zCoord);
\draw[dashed,red,thick] (borep) -- (boree);
\rtptoxyz{\rhoCoord*4/6}{\thetaCoord}{\phiCoord}
\node[anchor=south,text=red] (borelable) at (\xCoord,\yCoord,\zCoord) {boresight};
%extend the line to the body fixed frame
\xyztortp{\xbp}{\ybp}{\planeDist}
\rtptoxyz{2*\rhoCoord}{\thetaCoord}{\phiCoord}
\coordinate (bodyFrame) at (\xCoord,\yCoord,\zCoord);
\draw[thick] (bp) -- (bodyFrame);
%draw the world axes
\rotateRPY{0}{10}{75}
\begin{scope}[shift=(bodyFrame),RPY]
%Draw the world coordinate frame
\draw[->,thick] (0,0,0) -- ($(\coordLength+0.1,0,0)$);
\draw[->,thick] (0,0,0) -- ($(0,\coordLength+0.1,0)$);
\draw[->,thick] (0,0,0) -- ($(0,0,\coordLength-0.1)$);
\node[inner sep=2pt] (wz) at ($(\coordLength+0.25,0,0)$) {$\textbf{b}_z$};
\node[inner sep=2pt] (wy) at ($(0,\coordLength+0.25,0)$) {$\textbf{b}_y$};
\node[inner sep=2pt] (wx) at ($(0,-0.05,\coordLength)$) {$\textbf{b}_x$};
\node[inner sep=2pt] (B) at (-0.03,-0.03,-0.03) {$B$};
\end{scope}
%extend the poi line to the poi
\xyztortp{\xpp}{\ypp}{\planeDist}
\rtptoxyz{1.75*\rhoCoord}{\thetaCoord}{\phiCoord}
\coordinate (poi) at (\xCoord,\yCoord,\zCoord);
\path (poi) node[circle, fill, inner sep=1]{};
\draw[thick,->] (poip) -- (poi) node[anchor=north east]{$\textbf{x}_C$};
\draw[thick,->] (bodyFrame) -- (poi) node[anchor=west]{$\textbf{x}_B$};
\node[inner sep=2pt,anchor=south east] (iplabel) at (-\coordLength,-\coordLength-0.2,\planeDist){Photo Plane};
\end{scope}
\end{tikzpicture}
% \node[inner sep=2pt] (blah) at (2,2,2) {\xcoord|\ycoord|\zcoord|\rhoCoord|\thetaCoord|\phiCoord};
生成结果: