![如何自动绘制位于两个倾斜镜子之间的一点的图像?](https://linux22.com/image/284122/%E5%A6%82%E4%BD%95%E8%87%AA%E5%8A%A8%E7%BB%98%E5%88%B6%E4%BD%8D%E4%BA%8E%E4%B8%A4%E4%B8%AA%E5%80%BE%E6%96%9C%E9%95%9C%E5%AD%90%E4%B9%8B%E9%97%B4%E7%9A%84%E4%B8%80%E7%82%B9%E7%9A%84%E5%9B%BE%E5%83%8F%EF%BC%9F.png)
考虑位于两个倾斜镜子之间的一点,X
如下所示。
\documentclass[pstricks,border=20pt,12pt]{standalone}
\usepackage{pst-eucl}
\def\Angle{37}% extreme case in which 360/\Angle-1 is not an integer.
\def\R{5}
\begin{document}
\begin{pspicture}[showgrid](-\R,-\R)(\R,\R)
\pstGeonode[PointSymbol=none,PosAngle={45,-90},PointNameSep=24pt](\R;\Angle){B}(0,0){O}(\R;0){A}
\psframe*[linecolor=lightgray](O|0,-12pt)(A|0,0)
\rput{\Angle}(0,0){\psframe*[linecolor=lightgray](O)(B|0,12pt)}
\psline(B)(O)(A)
\pstMarkAngle[MarkAngleRadius=1.6,LabelSep=.8]{A}{O}{B}{$\theta$}
\pstGeonode(3,1){X}
\end{pspicture}
\end{document}
X
我们如何才能自动绘制任意角度的点的图像\Angle
?欢迎使用 PSTricks(首选)、Aysmptote、Metapost、TikZ 甚至原始 PostScript 的解决方案。
编辑
哦,我的鬼,现有的答案没有回答,因为你可能误解了我的问题,但我的问题实际上非常非常清楚。
考虑以下的草图\Angle=60
。
注: 的证明360/angle-1
仍在进行中这里。
答案1
\documentclass[pstricks,border=20pt,12pt]{standalone}
\usepackage{pst-eucl,pst-plot}
\def\Angle{37}
\def\R{5}
\begin{document}
\begin{pspicture}[showgrid](-\R,-\R)(\R,\R)
\pstGeonode[PointSymbol=none,PosAngle={45,-90},PointNameSep=24pt](\R;\Angle){B}(0,0){O}(\R;0){A}
\pcline[linecolor=lightgray,linewidth=12pt,offset=-6pt,strokeopacity=0.6](O)(A)
\pcline[linecolor=lightgray,linewidth=12pt,offset=6pt,strokeopacity=0.6](O)(B)
\psline(B)(O)(A)
\pstMarkAngle[MarkAngleRadius=1.6,LabelSep=.8]{A}{O}{B}{$\theta$}
\pstGeonode(!3 \Angle\space 2 div PtoC){X}
\pstOrtSym{O}{A}{X}[I_1] \psline[linestyle=dotted](X)(I_1)
\newif\ifA \Afalse
\pstFPDiv\No{360}{\Angle}
\multido{\iA=1+1,\iB=2+1}{\numexpr\No-1}{%
\ifA\pstOrtSym{O}{A}{I_\iA}[I_\iB]\else\pstOrtSym{O}{B}{I_\iA}[I_\iB]\fi
\psline[linestyle=dotted](I_\iA)(I_\iB)
\ifA\Afalse\else\Atrue\fi
}%
\pscircle[linestyle=dotted](O){3}
\end{pspicture}
\end{document}
并且两个方向:
\documentclass[pstricks,border=20pt,12pt]{standalone}
\usepackage{pst-eucl,pst-plot}
\def\Angle{37}
\def\R{5}
\begin{document}
\begin{pspicture}[showgrid](-\R,-\R)(\R,\R)
\pstGeonode[PointSymbol=none,PosAngle={45,-90},PointNameSep=24pt](\R;\Angle){B}(0,0){O}(\R;0){A}
\pcline[linecolor=lightgray,linewidth=12pt,offset=-6pt,strokeopacity=0.6](O)(A)
\pcline[linecolor=lightgray,linewidth=12pt,offset=6pt,strokeopacity=0.6](O)(B)
\psline(B)(O)(A)
\pstMarkAngle[MarkAngleRadius=1.6,LabelSep=.8]{A}{O}{B}{$\theta$}
\pstGeonode(!3 \Angle\space 2 div PtoC){X}
\color{blue}\psset{linecolor=blue}%
\pstOrtSym{O}{A}{X}[I_1] \psline[linestyle=dotted](X)(I_1)
\newif\ifA \Afalse
\pstFPDiv\No{360}{\Angle}
\multido{\iA=1+1,\iB=2+1}{\numexpr\No-1}{%
\ifA\pstOrtSym{O}{A}{I_\iA}[I_\iB]\else\pstOrtSym{O}{B}{I_\iA}[I_\iB]\fi
\psline[linestyle=dotted](I_\iA)(I_\iB)
\ifA\Afalse\else\Atrue\fi
}%
\color{red}\psset{linecolor=red}%
\pstOrtSym{O}{B}{X}[I_1] \psline[linestyle=dotted](X)(I_1)
\newif\ifA \Atrue
\pstFPDiv\No{360}{\Angle}
\multido{\iA=1+1,\iB=2+1}{\numexpr\No-1}{%
\ifA\pstOrtSym{O}{A}{I_\iA}[I_\iB]\else\pstOrtSym{O}{B}{I_\iA}[I_\iB]\fi
\psline[linestyle=dotted](I_\iA)(I_\iB)
\ifA\Afalse\else\Atrue\fi
}%
\pscircle[linestyle=dotted](O){3}
\end{pspicture}
\end{document}
答案2
另一次尝试使用 MetaPost,经过了大幅修改。如果 k-1=floor(360/theta),它会检查第“k”幅图像是否等于原始点 X,如果是,则在该点旁边打印“成功!”。否则,它会打印“失败!”。可以进行任意次数的尝试,只需修改“theta”参数即可。因此,很容易检查,如果 360/theta 是整数,则图像数量确实是 360/theta - 1。但我仍然不确定这是否是想要的……
input latexmp;
setupLaTeXMP(options = "12pt",
mode = rerun,
textextlabel = enable,
multicolor=enable,
packages="SIunits");
u:=1.5cm; % for scaling
% Angle
numeric theta; theta = 30;
% Supposed number of images
hypothesis := 360/theta-1;
number_of_images := floor(hypothesis);
% mirrors
numeric eps; eps = 0.4*u; % mirrors thickness
pair A, B, X;
path mirror[];
A := (5u, 0);
mirror1 = origin -- A -- A-(0, eps) -- (0, -eps) -- cycle;
mirror2 = mirror1 reflectedabout(origin, A) rotated theta;
B:= point 1 of mirror2;
beginfig(0);
% Grid and labels
drawoptions(dashed withdots);
for i = -5 upto 5:
draw (-5, i)*u -- (5, i)*u;
draw (i, -5)*u -- (i, 5)*u;
label.bot("$" & decimal(i) & "$", (i*u, -5*u));
label.lft("$" & decimal(i) & "$", (-5u, i*u));
endfor;
% mirrors drawing
drawoptions();
draw mirror1 ; fill mirror1 withcolor 0.8white ; draw origin -- A;
draw mirror2 ; fill mirror2 withcolor 0.8white; draw origin--B;
label.rt("$A$", A); label.rt("$B$", B);
% The angle drawing and its label
draw anglebetween(origin--A, origin--B, "$\theta =" & decimal(theta) & "\degree$");
% X
pair X[]; X0 = (3, 1)*u; freedotlabel("$X$", X0, origin);
draw X0 withpen pencircle scaled 3bp;
% Placement of floor(360/theta-1) images of X
drawoptions(dashed evenly);
k:=1;
forever:
exitunless k <= number_of_images;
X[k] = X[k-1] reflectedabout(origin,
if (k = round(k/2)*2): A else: B fi);
draw X[k-1]--X[k];
draw X[k] withpen pencircle scaled 3bp;
freedotlabel("$X_{" & decimal(k) & "}$", X[k], origin);
k := k+1;
endfor;
% Success or no success?
X[k]= X[k-1] reflectedabout(origin, if (k = round(k/2)*2): A else: B fi);
if (abs(X[k]-X0)< 1e-12):
draw X[k-1] -- X0;
freedotlabel("$X$\ \textcolor{red}{Success!}", X0, origin)
else:
draw X[k-1] -- X[k];
freedotlabel("$X$", X0, origin);
freedotlabel("\textcolor{red}{Failed!}", X[k], origin)
fi;
% The circle
draw fullcircle scaled (2*abs(X1)) dashed withdots;
endfig;
end.
答案3
我尝试使用 MetaPost,但它是值得的:它有点匆忙完成,而且我不确定我是否正确理解了你想要什么。
编辑:正如赫伯特所做的那样,我在图像所在的位置添加了圆圈。
使用MetaFun格式和浮点算法进行处理:
mpost --mem=metafun --numbersystem=double angles.mp
input latexmp;
setupLaTeXMP(options = "12pt", mode = rerun, textextlabel = enable);
u:=1cm; % for scaling
numeric my_angle;
my_angle = 37;
numeric eps; eps = 0.4*u; % mirror thickness
pair A, B, X;
path mirror[];
A := (5u, 0);
mirror1 = origin -- A -- A-(0, eps) -- (0, -eps) -- cycle;
mirror2 = mirror1 reflectedabout(origin, A) rotated my_angle;
B:= point 1 of mirror2;
beginfig(0);
% Grid and labels
drawoptions(dashed withdots);
for i = -5 upto 5:
draw (-5, i)*u -- (5, i)*u;
draw (i, -5)*u -- (i, 5)*u;
label.bot("$" & decimal(i) & "$", (i*u, -5*u));
label.lft("$" & decimal(i) & "$", (-5u, i*u));
endfor;
% mirrors drawing
drawoptions();
draw mirror1 ; fill mirror1 withcolor 0.8white ; draw origin -- A;
draw mirror2 ; fill mirror2 withcolor 0.8white; draw origin--B;
% The angle drawing and its label
draw anglebetween(origin--A, origin--B, textext("$\theta$"));
% The images
pair X[]; X0 = (3, 1)*u; label.rt("$X$", X0);
draw X0 withpen pencircle scaled 3bp;
for k= 0 upto 360/my_angle:
X[k+1] = X[k] reflectedabout(origin,
if (k = round(k/2)*2): A else: B fi);
draw X[k]--X[k+1] dashed evenly;
draw X[k+1] withpen pencircle scaled 3bp;
label.rt("$X_{" & decimal(k+1) & "}$", X[k+1]);
endfor;
% Circle (as Herbert did)
draw fullcircle xyscaled (abs(X0)*2) withpen pencircle scaled 0.7bp dashed withdots;
endfig;
end.