用命名坐标反射一条线和/或一个点

用命名坐标反射一条线和/或一个点

此代码不适用于命名坐标(例如以下代码)。如何使用坐标名称将蓝线反映到红线上。如何仅反映命名坐标?

\documentclass[tikz]{standalone}

\begin{document}
\begin{tikzpicture}[scale=0.55]
\coordinate (A) at (0,0);
\coordinate (B) at (1,1);
\coordinate (C) at (1,2);
\coordinate (D) at (2,0);
\coordinate (E) at (2,3);

\draw[blue] (B)--(A)--(C);
\draw[red] (D)--(E);
\end{tikzpicture}
\end{document}

答案1

这是一份提案列表。没有一个是完美的。然而,目标不是逐个转换点,而是整条线。(逐个转换点是可能的,例如使用tkz-euclide或者仅使用calc。)顺序表示这些选项的排名。

第一个选项:(滥用)使用show path construction。(问题:必须用颜色作弊,而且这不是一条路径,而是两条路径。)

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{decorations.pathreplacing,calc}
\makeatletter
\tikzset{reflect at/.style args={#1--#2}{decorate,decoration={
show path construction,
lineto code={\draw[\tikz@textcolor]
($2*($(#1)!(\tikzinputsegmentfirst)!(#2)$)-(\tikzinputsegmentfirst)$)
-- ($2*($(#1)!(\tikzinputsegmentlast)!(#2)$)-(\tikzinputsegmentlast)$);}}}}
\makeatother
\begin{document}
\begin{tikzpicture}[scale=0.55]
\coordinate (A) at (0,0);
\coordinate (B) at (1,1);
\coordinate (C) at (1,2);
\coordinate (D) at (2,0);
\coordinate (E) at (2,3);
\draw[blue] (B)--(A)--(C);
\draw[red] (D)--(E);
\draw[blue,reflect at=D--E] (B)--(A)--(C);
\end{tikzpicture}
\end{document}

在此处输入图片描述

对其稍加修改就能产生指向反射。

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{decorations.pathreplacing,calc}
\makeatletter
\tikzset{point reflect at/.style args={#1}{decorate,decoration={
show path construction,
lineto code={\draw[\tikz@textcolor]
($(\tikzinputsegmentfirst)+2*($(#1)-(\tikzinputsegmentfirst)$)$)
-- ($(\tikzinputsegmentlast)+2*($(#1)-(\tikzinputsegmentlast)$)$);}}}}
\makeatother
\begin{document}
\begin{tikzpicture}[scale=0.55]
\path  (0,0) coordinate (A) (1,1) coordinate (B) (1,2) coordinate (C) 
(2,3) coordinate (D);
\draw[blue] (B)--(A)--(C);
\fill[red] (D) circle(1pt);
\draw[blue,point reflect at=D] (B)--(A)--(C);
\end{tikzpicture}
\end{document}

在此处输入图片描述

第二种选择:改变to路径。(问题:不是一条连续的路径,而是多条独立的路径,需要分段绘制。)

\documentclass[tikz]{standalone}
\usetikzlibrary{calc}
\tikzset{reflect at/.style args={#1--#2}{to path={%
($2*($(#1)!(\tikztostart)!(#2)$)-(\tikztostart)$)
-- ($2*($(#1)!(\tikztotarget)!(#2)$)-(\tikztotarget)$)
}}}
\begin{document}
\begin{tikzpicture}[scale=0.55]
\coordinate (A) at (0,0);
\coordinate (B) at (1,1);
\coordinate (C) at (1,2);
\coordinate (D) at (2,0);
\coordinate (E) at (2,3);

\draw[blue] (B)--(A)--(C);
\draw[red] (D)--(E);
\draw[blue,reflect at=D--E] (B) to (A) (A) to (C);
\end{tikzpicture}
\end{document}

在此处输入图片描述

第三种选择:更多核心层面。(问题:不适用于重新缩放。)

\documentclass[tikz]{standalone}
\makeatletter
\tikzset{get mirror data/.code args={#1--#2}{%\pgftransformreset 
\pgfutil@tempdima=\pgf@x
\pgfutil@tempdimb=\pgf@y
\pgfpointanchor{#1}{center}
\pgf@xa=\pgf@x
\pgf@ya=\pgf@y
\pgfpointanchor{#2}{center}
\pgf@xb=\pgf@x
\pgf@yb=\pgf@y
\pgfmathsetmacro{\tmpt}{2*(-(\pgf@ya*(\pgf@xb-\pgf@xa)) + \pgfutil@tempdimb*(\pgf@xb-\pgf@xa) + (\pgf@xa - \pgfutil@tempdima)*(\pgf@yb-\pgf@ya))/((\pgf@xb-\pgf@xa)^2 + (\pgf@yb-\pgf@ya)^2)}
\advance\pgf@xb by-\pgf@xa
\advance\pgf@yb by-\pgf@ya
\pgfutil@tempdima=\tmpt\pgf@yb
\pgfutil@tempdimb=-\tmpt\pgf@xb
},
mirror at/.style args={#1--#2}{get mirror data=#1--#2,xshift=\pgfutil@tempdima,
yshift=\pgfutil@tempdimb}}
\makeatother
\begin{document}
\begin{tikzpicture}[scale=1]
\coordinate (A) at (0,0);
\coordinate (B) at (1,1);
\coordinate (C) at (1,2);
\path (2,0) coordinate (D) ++ (rnd*120:2) coordinate (E);
\draw[blue] (B)--(A)--(C);
\draw[blue] ([mirror at=D--E]B)--([mirror at=D--E]A)--([mirror at=D--E]C);
\draw[red] (D)--(E);
\end{tikzpicture}
\end{document}

在此处输入图片描述

第四种选择:计算反射坐标的样式。(问题:不幸的是,此版本中的语法需要指定两次坐标,例如B中有两个 s ([reflect=B at D--E]B),并且它不能很好地与 之类的全局转换配合scale=0.55使用。除此之外,它使用这个答案它展示了如何计算直线上一个点的正交投影。)

\documentclass[tikz]{standalone}
\usetikzlibrary{calc}
\tikzset{reflect/.style args={#1 at #2--#3}{shift={%
($2*($(#2)!(#1)!(#3)$)-2*(#1)$)
}}}
\begin{document}
\begin{tikzpicture}
\coordinate (A) at (0,0);
\coordinate (B) at (1,1);
\coordinate (C) at (1,2);
\coordinate (D) at (2,0);
\coordinate (E) at (2,3);

\draw[blue] (B)--(A)--(C);
\draw[red] (D)--(E);

\draw[orange] ([reflect=B at D--E]B) -- ([reflect=A at D--E]A)
-- ([reflect=C at D--E]C);
\end{tikzpicture}
\end{document}

在此处输入图片描述

旁注Paul Gaborit 的解决方案似乎有效。

\documentclass[tikz]{standalone}
\usetikzlibrary{spy,decorations.fractals}
\tikzset{
  mirror scope/.is family,
  mirror scope/angle/.store in=\mirrorangle,
  mirror scope/center/.store in=\mirrorcenter,
  mirror setup/.code={\tikzset{mirror scope/.cd,#1}},
  mirror scope/.style={mirror setup={#1},spy scope={
      rectangle,lens={rotate=\mirrorangle,yscale=-1,rotate=-1*\mirrorangle},size=80cm}},
}
\newcommand\mirror[1][]{\spy[overlay,#1] on (\mirrorcenter) in node at (\mirrorcenter)}

\begin{document}
\begin{tikzpicture}
\coordinate (A) at (0,0);
\coordinate (B) at (1,1);
\coordinate (C) at (1,2);
\coordinate (D) at (2,0);
\coordinate (E) at (2,3);
  \draw [help lines] (0,0) grid (4,3);
  \begin{scope}[mirror scope={center={2,0},angle=90}]
    \draw[blue] (B) -- (A) -- (C);
    \draw[red]  (D) -- (E);
    \mirror;
  \end{scope}
\end{tikzpicture}
\end{document}

在此处输入图片描述

至于您的最新请求:这是一种“保存”坐标的方法。嗯,也许我需要重新考虑一下整体策略……

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{decorations.pathreplacing,calc}
\newcounter{reflected}
\makeatletter
\tikzset{stepref/.code={\stepcounter{reflected}},
point reflect at/.style args={#1}{decorate,decoration={
show path construction,
lineto code={
\draw[\tikz@textcolor]
($(\tikzinputsegmentfirst)+2*($(#1)-(\tikzinputsegmentfirst)$)$) [stepref]
coordinate (reflected coordinate \arabic{reflected})
-- ($(\tikzinputsegmentlast)+2*($(#1)-(\tikzinputsegmentlast)$)$)[stepref]
coordinate (reflected coordinate \arabic{reflected})
;}}}}
\makeatother
\begin{document}
\begin{tikzpicture}[scale=0.55]
\path  (0,0) coordinate (A) (1,1) coordinate (B) (1,2) coordinate (C) 
(2,3) coordinate (D);
\draw[blue] (B)--(A)--(C);
\fill[red] (D) circle(1pt);
\draw[blue,point reflect at=D] (B)--(A)--(C);
\path (reflected coordinate 1) coordinate (B')
(reflected coordinate 2) coordinate (A')
(reflected coordinate 4) coordinate (C');
\draw[red,latex-] (B') -- ++ (-1,1) node[pos=1.2]{B'};
\draw[red,latex-] (A') -- ++ (1,1)  node[pos=1.2]{A'};
\draw[red,latex-] (C') -- ++ (1,-1)  node[pos=1.2]{C'};
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

一种可能性是使用该tkz-euclide包。

要定义 A1,即点 A 相对于直线 DE 的镜像,请使用:\tkzDefPointBy[reflection=over D--E](A) \tkzGetPoint{A1}

\documentclass[border=1cm,tikz]{standalone}
\usepackage{tkz-euclide}
\begin{document}
\begin{tikzpicture}
\draw[help lines,dashed](0,0)grid(4,4);
\coordinate (A) at (0,0);
\coordinate (B) at (1,1);
\coordinate (C) at (1,2);
\coordinate (D) at (2,0);
\coordinate[label=E] (E) at (2,3);

\tkzDefPointBy[reflection=over D--E](A) \tkzGetPoint{A1}
\tkzDefPointBy[reflection=over D--E](B) \tkzGetPoint{B1}
\tkzDefPointBy[reflection=over D--E](C) \tkzGetPoint{C1}

\draw[blue] (B)--(A)--(C);
\draw[red] (D)--(E);

\draw [green] (B1)--(A1)--(C1);
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案3

PSTricks 解决方案仅用于比较目的。

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-eucl}
\begin{document}
\pspicture[PointName=none,PointSymbol=none](8,3)
\pstGeonode(1,3){A}(0,0){B}(2,2){C}(4,3){X}(4,0){Y}
\pstOrtSym{X}{Y}{A,B,C}[A',B',C']
\psline[linecolor=blue](X)(Y)
\psline[linecolor=red](A)(B)(C)
\psline[linecolor=red](A')(B')(C')
\endpspicture
\end{document}

在此处输入图片描述

相关内容