如何循环绘制两条线上的一系列投影?

如何循环绘制两条线上的一系列投影?

我想画出这个问题:给定不同的直线 $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 0place 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}

相关内容