我想画出这个问题:给定不同的直线 $OA$ 和 $OB$。从 $OB$ 中的一个点画一条垂直于 $OA$ 的线;从这条垂直线的脚画一条垂直于 $OB$ 的线。从第二条垂直线的脚画一条垂直于 $OA$ 的线;依此类推。我试过
\documentclass[tikz,border=5mm]{standalone}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}[declare function={R=5;r=4.5;},line cap=butt,line join=round]
\path (0,0) coordinate (O)
(0:R) coordinate(A)
(30:R) coordinate(B)
(30:r) coordinate(M)
coordinate (H) at ($(O)!(M)!(A)$)
coordinate (K) at ($(O)!(H)!(B)$)
coordinate (L) at ($(O)!(K)!(A)$)
coordinate (P) at ($(O)!(L)!(B)$)
coordinate (Q) at ($(O)!(P)!(A)$)
coordinate (R) at ($(O)!(Q)!(B)$)
coordinate (S) at ($(O)!(R)!(A)$)
coordinate (T) at ($(O)!(S)!(B)$)
;
\foreach \p/\g in {A/-90,B/90,O/-90,M/90,H/-90,K/90,L/-90,P/90,Q/-90,R/90,S/-90,T/90}
\path (\p)+(\g:3mm) node{$\p$};
\draw (A) -- (O) --(B) (M) -- (H) -- (K) -- (L) -- (P) --(Q) -- (R) --(S)--(T);
\end{tikzpicture}
\end{document}
我怎样才能画出一个循环来绘制它?
答案1
想法是命名每个新的投影点M
,这将覆盖前一个坐标并可在下一次迭代中使用。
交替乙和A标签我正在使用 PGFMath 函数iseven
,它给出0
(true)、0
(false)、1
... 这就是为什么样式place 0
和place 1
存在的原因,它们都对节点的位置及其内容进行排序。
只需删除place …
样式、循环体内的节点和标签即可M
删除标签。
作为建议,对于A点标签从下标 6 开始被抑制,并且对于乙点是 7。这是通过样式\ifnum
内部完成的place …
。
代码
\documentclass[tikz,border=5mm]{standalone}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}[
declare function={R=5; r=4.5;},
line cap=butt,
line join=round]
\draw (0:R) coordinate[label=below right:$A$, alias=A'0] (A) --
(0,0) coordinate[label=below :$O$ ] (O) --
(30:R) coordinate[label=above :$B$, alias=A'1] (B)
(30:r) coordinate[label=above :$B_1$ ] (M);
\draw[
place 0/.style={below, node contents={$A_{#1}$}, \ifnum#1>5 coordinate\fi},
place 1/.style={above, node contents={$B_{#1}$}, \ifnum#1>6 coordinate\fi}]
(M) foreach[
evaluate=\i as \isTop using iseven(\i),
evaluate=\i as \subsc using int(ceil((\i+1)/2))]
\i in {1, ..., 30}{
-- ($(O)!(M)!(A'\isTop)$) coordinate (M) node [place \isTop=\subsc]
};
\end{tikzpicture}
\end{document}
输出
答案2
另一个选项,循环与 Qrrbrbirlbel 几乎相同,但使用三角函数(更准确地说是同位素)。不需要库calc
。
更新:增加了另一个功能,修正了角度(现在它随着a
计划的参数而变化),并延长了线无限地(嗯,实际上只有 20 个步骤)。
\documentclass[tikz,border=5mm]{standalone}
\tikzset
{
every node/.style={execute at end node=\strut},
declare function={a=30;R=5;r=4.5;dist(\x,\y)=r*sin(a)*pow(cos(a),2*\x-2+\y);}
}
\begin{document}
\begin{tikzpicture}[line cap=butt,line join=round]
\path (0,0) coordinate (O)
(0:R) coordinate (A)
(a:R) coordinate (B)
(a:r) coordinate (M);
\draw (A) node[below] {$A$} -- (O) node[left] {$O$} -- (B) node[above] {$B$};
\draw (M) node[above] {$B_1$} foreach[evaluate=\i as \j using int(\i+1)]\i in {1,...,20}
{
--++ ( -90:{dist(\i,0)}) \ifnum\i<6 node[below] {$A_\i$}\fi
--++ (a+90:{dist(\i,1)}) \ifnum\j<6 node[above] {$B_\j$}\fi
};
\node at (O) [below,xshift=5mm] {$\cdots$};
\node at (O) [rotate=a,above,xshift=7mm] {$\cdots$};
\end{tikzpicture}
\end{document}
答案3
值得一提的是:我们既不需要calc
重复的三角计算,也不需要remember
。我们所需要的只是一个非正交坐标系。显然,我并不是说不需要这些东西“更好”。
\documentclass[tikz,border=5mm]{standalone}
\begin{document}
\begin{tikzpicture}[dot/.style={fill,circle,inner sep=1pt},line join=round]
\draw[x={(8cm,0cm)},y={(30:{8cm/cos(30)})}]
(1.1,0) -- (0,0) -- (0,1.2)
foreach \i in {1,...,14}
{\ifodd\i\relax
({pow(0.9,\i)},0) node[dot,label=below:$A_{\the\numexpr\i/2}$](p\i){}
\else
(0,{pow(0.9,\i-iseven(\i))}) node[dot,label=above:$B_{\the\numexpr\i/2}$](p\i){}
\fi
\ifnum\i>1\relax
(p\the\numexpr\i-1\relax.center) edge (p\i.center)
\fi
};
\end{tikzpicture}
\end{document}
答案4
这里(纯粹为了比较/转移注意力)是尝试元帖子,展示了一个内联for
循环和有用的hide()
宏,使您可以随时进行计算。
这已包含在内luamplib
,因此请使用 进行编译lualatex
。
\documentclass[border=5mm]{standalone}
\usepackage{luamplib}
\begin{document}
\mplibtextextlabel{enable}
\begin{mplibcode}
beginfig(1);
pair A, B; % starting points
A = 300 dir 12;
B = 300 dir 40;
pair a, b; % offset vectors for the labels
a = -7 unitvector(A) rotated 90;
b = +9 unitvector(B) rotated 90;
pair A[], B[]; % the projected points
A1 = 0.9 A;
draw A1 for i = 1 upto 16:
hide(
B[i] = whatever[origin, B]; B[i] - A[i] = whatever * B rotated 90;
A[i+1] = whatever[origin, A]; B[i] - A[i+1] = whatever * A rotated 90;
if i < 7:
label("$A_{" & decimal i & "}$", A[i] + a);
label("$B_{" & decimal i & "}$", B[i] + b);
elseif i < 10:
label("$\cdot$", A[i] + a);
label("$\cdot$", B[i] + b);
fi
)
-- B[i] -- A[i+1]
endfor withcolor 2/3 red;
draw A -- origin -- B;
label.llft("$O$", origin);
endfig;
\end{mplibcode}
\end{document}