改进 PSTricks 代码,用于绘制一般正多边形

改进 PSTricks 代码,用于绘制一般正多边形

考虑以下示例。

代码

% pdflatex -shell-escape test.tex

\documentclass{article}

\usepackage{auto-pst-pdf,pst-eucl,pst-poly,pstricks-add}
\usepackage[locale=DE]{siunitx}

\ExplSyntaxOn
  \cs_new_eq:NN
    \calc
  \fp_eval:n
\ExplSyntaxOff

\def\OuterRadius{\calc{\SideLength/(2*sin(pi/\NoSides))}}
\def\RelativeAngle{\calc{360/\NoSides}}
\def\Rotation{\calc{\RelativeAngle/2}}
\def\Area{\calc{1/4*\NoSides*\SideLength^2*cot(pi/\NoSides)}}

\begin{document}

\begin{figure}
% Parameters
\def\NoSides{8}
\def\SideLength{60}
\psset{unit=0.05cm}
\begin{pspicture}(-\OuterRadius,-\OuterRadius)(\OuterRadius,\OuterRadius)
  \pscircle(0,0){\OuterRadius}
  \rput(0,0){%
    \PstPolygon[
      PolyNbSides=\NoSides,
      PolyRotation=\Rotation,
      unit=\OuterRadius,
      linewidth=2\pslinewidth
    ]
  }
  \multido{\rA=0+\RelativeAngle,\iA=1+1}{\NoSides}{%
    \psRelNode[angle=\rA](0,0)%
      (!180 \NoSides\space div cos \OuterRadius\space mul
        180 \NoSides\space div sin \OuterRadius\space mul){1}{P\iA}
  }
 \psset{linewidth=0.5\pslinewidth,RightAngleSize=5}
  \rput(0,0){$A \approx \SI[round-mode=places,round-precision=0]{\Area}{\square\m}$}
  % The (really) bad code starts here.
  \pcline[linestyle=dashed,offset=-8pt]{|-|}(P2)(P1)
  \ncput*[nrot=:U]{\SI{\SideLength}{\m}}
  \psRelLine[linestyle=none](P8)(P1){2}{S'}
  \psRelLine[linestyle=none](P3)(P2){2}{S''}
  \psIntersectionPoint(P1)(S')(P2)(S''){S}
  \pstRightAngle[linestyle=dotted]{P1}{S}{P2}
  \pcline[linestyle=dotted](P1)(S)
  \pcline[linestyle=dashed,offset=-8pt]{|-|}(P1)(S)
  \ncput*{$x$}
  \pcline[linestyle=dotted](P2)(S)
  \pcline[linestyle=dashed,offset=8pt]{|-|}(P2)(S)
  \ncput*{$x$}
  \psRelLine[linestyle=none](P2)(P3){2}{T'}
  \psRelLine[linestyle=none](P5)(P4){2}{T''}
  \psIntersectionPoint(P3)(T')(P4)(T''){T}
  \pstRightAngle[linestyle=dotted]{P3}{T}{P4}
  \psline[linestyle=dotted](P3)(T)(P4)
  \psRelLine[linestyle=none](P4)(P5){2}{U'}
  \psRelLine[linestyle=none](P7)(P6){2}{U''}
  \psIntersectionPoint(P5)(U')(P6)(U''){U}
  \pstRightAngle[linestyle=dotted]{P5}{U}{P6}
  \psline[linestyle=dotted](P5)(U)(P6)
  \psRelLine[linestyle=none](P6)(P7){2}{V'}
  \psRelLine[linestyle=none](P1)(P8){2}{V''}
  \psIntersectionPoint(P7)(V')(P8)(V''){V}
  \pstRightAngle[linestyle=dotted]{P7}{V}{P8}
  \psline[linestyle=dotted](P7)(V)(P8)
\end{pspicture}
\end{figure}

\end{document}

输出

在此处输入图片描述

问题

我得到了想要的输出,但代码不太优雅。问题(尤其是)简化代码,给出八边形周围的虚线和直角标记。

更新

代码:

% pdflatex -shell-escape test.tex

\documentclass{article}

\usepackage{auto-pst-pdf,pst-node,multido}
\usepackage[locale=DE]{siunitx}

\ExplSyntaxOn
  \cs_new_eq:NN \calc \fp_eval:n
\ExplSyntaxOff

\begin{document}

\begin{figure}[htbp]
\centering
% Parameters.
\def\NoSides{5 }
\def\SideLength{60 }
% Help.
\def\OR{\calc{\SideLength/(2*sin(pi/\NoSides))}}
\def\Area{\calc{1/4*\NoSides*\SideLength^2*cot(pi/\NoSides)}}
\edef\dAngle{\the\numexpr360/\NoSides}
\def\IR{\calc{1/2*\SideLength*cot(pi/\NoSides)}}
\def\LabelLine(#1)(#2)#3#4#5{%
  \pcline[linestyle=dashed,offset=#3]{|-|}(#1)(#2)
  \ncput*[nrot=#4]{#5}
}
\psset{unit=0.5mm}
\begin{pspicture}(-\OR,-\OR)(\OR,\OR)
 \pstVerb{/R \SideLength 180 \NoSides div sin 2 mul div def}
  \pscircle(0,0){!R }
  \multido{\iA=\numexpr\dAngle/2+\dAngle,\iB=0+1}{\NoSides}{%
    \pcline[linewidth=2pt](!R \iA\space PtoC)(!R \iA\space \dAngle\space add PtoC)
    \ifnum\iB=0 
      \LabelLine(!R \iA\space \dAngle\space add PtoC)%
                (!R \iA\space PtoC)%
                {-8pt}{:U}{\SI{\SideLength}{\m}}
      \LabelLine(!R \iA\space \dAngle\space add PtoC)%
                (!R \iA\space \dAngle\space add PtoC exch pop \OR\space exch)%
                {8pt}{0}{$x$}
      \LabelLine(!R \iA\space PtoC)%
                (!R \iA\space PtoC pop \OR)%
                {-8pt}{0}{$y$}
    \fi
  }
 \psset{linestyle=dotted}
  \psframe(-\IR,-\IR)(\IR,\IR)
  \rput(-\IR,-\IR){\psframe(5,5)}
  \rput(!-\IR\space \IR\space 5 sub){\psframe(5,5)}
  \rput(!\IR\space 5 sub -\IR){\psframe(5,5)}
  \rput(!\IR\space 5 sub \IR \space 5 sub){\psframe(5,5)}
  \rput(0,0){$A \approx \SI[round-mode=places,round-precision=0]{\Area}{\square\m}$}
\end{pspicture}
\end{figure}

\end{document}

输出:

在此处输入图片描述

问题:

我想

  • 多边形(此处为五边形)完全位于虚线正方形内,
  • x带有和标签的虚线y将像在 Jubobs 的 TikZ 解决方案中一样放置。

更新 2

经过 Herbert 的修改后:

在此处输入图片描述

  • 我希望“上方”虚线是水平的,
  • 多边形仍然没有完全位于正方形内。

如果第二个问题得到解决,第一个问题也会自动得到解决(我认为)。

更新 3

以下是我希望的正方形

在此处输入图片描述

(上图中的正方形是手工绘制的。)

答案1

无需定义节点的解决方案。仅适用于 n=8:

\documentclass{article}
\usepackage[pdf]{pstricks}% for pdflatex --shell-escape
\usepackage{pst-node,multido}
\usepackage[locale=DE]{siunitx}
\ExplSyntaxOn
  \cs_new_eq:NN \calc \fp_eval:n
\ExplSyntaxOff

\def\NoSides{8 }  \def\SideLength{60 }

\def\OR{\calc{\SideLength/(2*sin(pi/\NoSides))}}
\def\Area{\calc{1/4*\NoSides*\SideLength^2*cot(pi/\NoSides)}}
\edef\dAngle{\the\numexpr360/\NoSides}
\makeatletter
\def\LabelLine{\@ifnextchar[\LabelLine@i{\LabelLine@i[0]}}
\def\LabelLine@i[#1](#2)(#3)#4#5{%
  \pcline[linestyle=dashed,offset=#4]{|-|}(#2)(#3)\ncput*[nrot=#1]{#5}}
\makeatother
\begin{document}

\psset{unit=0.5mm}
\begin{pspicture}(-\OR,-\OR)(\OR,\OR)
  \pstVerb{/R \SideLength 180 \NoSides div sin 2 mul div def
           /Q R \dAngle\space 2 div tx@Dict begin PtoC end pop def }
  \pscircle(0,0){!R}
  \multido{\iA=\numexpr\dAngle/2+\dAngle,\iB=0+1}{\NoSides}{%
    \pcline[linewidth=2pt](!R \iA\space PtoC)(!R \iA\space \dAngle\space add PtoC)
    \ifnum\iB=0 
      \LabelLine[:U](!R \iA\space \dAngle\space add PtoC)(!R \iA\space PtoC){-6pt}{\SideLength m}
      \LabelLine(!R \iA\space \dAngle\space add PtoC)(!Q dup){10pt}{$x$}
      \LabelLine(!R \iA\space PtoC)(!Q dup){-10pt}{$x$}
    \fi}
  \psframe[linestyle=dotted](!Q neg dup)(!Q dup)
  \rput(!Q neg dup)    {\psframe[linestyle=dotted](5,5)}
  \rput(!Q neg Q 5 sub){\psframe[linestyle=dotted](5,5)}
  \rput(!Q 5 sub Q neg){\psframe[linestyle=dotted](5,5)}
  \rput(!Q 5 sub dup)  {\psframe[linestyle=dotted](5,5)}
  \rput(0,0){$A \approx \SI[round-mode=places,round-precision=0]{\Area}{\square\m}$}
\end{pspicture}

\end{document}

在此处输入图片描述

答案2

我真的不明白展示外边正方形的目的,尤其是奇数边正多边形。在这个答案中,我省略了外边正方形。

单身的:

在此处输入图片描述

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-plot,pst-node,siunitx}
\usepackage[nomessages]{fp}

% constants declarator
\def\LoadConstants{}
\newcommand\const[3][6]{%
    \edef\temporary{trunc(#3}%
    \expandafter\FPeval\csname#2\expandafter\endcsname
        \expandafter{\temporary:#1)}%
        \edef\LoadConstants{\LoadConstants
            \noexpand\pstVerb{/#2 \csname#2\endcsname\space def}}%
                        \ignorespaces}

\psset{unit=1mm}

\def\polygon#1#2{%
    \def\points{}%
    \const[0]{NoSides}{#1}
    \const{SideLength}{#2}
    \const{OffsetAngle}{pi/NoSides}
    \const{OuterRadius}{SideLength/2/sin(OffsetAngle)}
    \const{Area}{1/4*NoSides*pow(2,SideLength)/tan(OffsetAngle)}
    \begin{pspicture}(-\OuterRadius,-\OuterRadius)(\OuterRadius,\OuterRadius)
        \LoadConstants
        \rput{!OffsetAngle RadtoDeg}(0,0){%
            \curvepnodes[plotpoints=\numexpr\NoSides+1\relax]{0}{360}{OuterRadius t PtoC}{P}
            \multido{\i=0+1}{\Pnodecount}{\xdef\points{\points (P\i)}}
            \expandafter\pspolygon\points}
        \pscircle[dimen=money-oriented-programmer](0,0){!OuterRadius}
        \psset{arrows=|*-|*,nrot=:U,linestyle=dashed,tbarsize=2pt 2}
        \scriptsize
        \pcline[offset=-6pt](P1)(P0)\ncput*{\SI{#2}{\cm}}
        \pcline[offset=5pt](P1)(P0|P1)\ncput*{$x$}
        \pcline[offset=5pt](P0|P1)(P0)\ncput*[nrot=0]{$y$}
        \rput(0,0){$A \approx \SI[round-mode=places,round-precision=0]{\Area}{\square\m}$}
    \end{pspicture}}

\begin{document}
\polygon{8}{60}
\end{document}

多种的:

在此处输入图片描述

\documentclass[border=12pt]{standalone}
\usepackage{pst-plot,pst-node,siunitx}
\usepackage[nomessages]{fp}

% constants declarator
\def\LoadConstants{}
\newcommand\const[3][6]{%
    \edef\temporary{trunc(#3}%
    \expandafter\FPeval\csname#2\expandafter\endcsname
        \expandafter{\temporary:#1)}%
        \edef\LoadConstants{\LoadConstants
            \noexpand\pstVerb{/#2 \csname#2\endcsname\space def}}%
                        \ignorespaces}

\psset{unit=1mm}

\def\polygon#1#2{%
    \def\points{}%
    \const[0]{NoSides}{#1}
    \const{SideLength}{#2}
    \const{OffsetAngle}{pi/NoSides}
    \const{OuterRadius}{SideLength/2/sin(OffsetAngle)}
    \const{Area}{1/4*NoSides*pow(2,SideLength)/tan(OffsetAngle)}
    \begin{pspicture}(-\OuterRadius,-\OuterRadius)(\OuterRadius,\OuterRadius)
        \LoadConstants
        \rput{!OffsetAngle RadtoDeg}(0,0){%
            \curvepnodes[plotpoints=\numexpr\NoSides+1\relax]{0}{360}{OuterRadius t PtoC}{P}
            \multido{\i=0+1}{\Pnodecount}{\xdef\points{\points (P\i)}}
            \expandafter\pspolygon\points}
        \pscircle[dimen=money-oriented-programmer](0,0){!OuterRadius}
        \psset{arrows=|*-|*,nrot=:U,linestyle=dashed,tbarsize=2pt 2}
        \scriptsize
        \pcline[offset=-6pt](P1)(P0)\ncput*{\SI{#2}{\cm}}
        \pcline[offset=5pt](P1)(P0|P1)\ncput*{$x$}
        \pcline[offset=5pt](P0|P1)(P0)\ncput*[nrot=0]{$y$}
        \rput(0,0){$A \approx \SI[round-mode=places,round-precision=0]{\Area}{\square\m}$}
    \end{pspicture}}

\begin{document}
\multido{\i=5+1}{4}{\polygon{\i}{30}}
\end{document}

答案3

不完整的 TikZ 解决方案,但在边数方面具有灵活性:

在此处输入图片描述

\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}

% Disclaimer: I use \pgfmathsetmacro instead of \def
% to avoid conflicts with existing macros

% parameters for the regular polygon
\pgfmathsetmacro{\R}{4}                         % radius of circumcycle
\pgfmathtruncatemacro\N{5}                      % number of sides (best if >= 5)
\pgfmathsetmacro\a{360/\N}                      % twice the interior angle
\pgfmathsetmacro\area{.5*\N*\R*\R*sin(360/\N)}  % area of polygon
\pgfmathsetmacro{\side}{2*\R*sin(180/\N)}       % side length

% quantities relevant for drawing
\pgfmathsetmacro\firstangle{90+.5*\a}           
\pgfmathsetmacro\secondangle{\firstangle-\a}
\pgfmathsetmacro\thirdangle{\secondangle-\a}    
\pgfmathsetmacro\lastangle{-270+.5*\a}
\pgfmathtruncatemacro\myshift{8}

\begin{tikzpicture}[%
    thick,%
    mylinestyle/.style={%
        |-|,%
        black!50,
        dashed,%
    },%
    mynodestyle/.style={%
        fill=white,%
        sloped,%
        pos=.5,
    }
]

    \coordinate (A) at (\secondangle:\R);
    \coordinate (B) at (\thirdangle:\R);

    % draw x line
    \draw[mylinestyle]
        ([yshift=\myshift] A) -- 
        ([yshift=\myshift] A-| B) node[mynodestyle] {$x$};

    % draw y line       
    \draw[mylinestyle]
        ([xshift=\myshift] A-| B) 
        -- ([xshift=\myshift] B) node[mynodestyle,rotate=90] {$y$};

    % draw side line
    \draw[mylinestyle]
        ([xshift={-\myshift*sin(360/\N)},   yshift={-\myshift*cos(360/\N)},] A) --
        ([xshift={-\myshift*sin(360/\N)},   yshift={-\myshift*cos(360/\N)},] B)     
        node[mynodestyle] {$\side \,\text{cm}$};

    % draw the circumcircle   
    \draw[thin,gray] circle (\R)
        node[black] {$A \approx \area \, \text{cm\textsuperscript2}$};

    % Draw the regular polygon
    \draw (\firstangle:\R)
        \foreach \x in {\secondangle,\thirdangle,...,\lastangle} {%
            -- (\x:\R)
        } -- cycle;

\end{tikzpicture}

\end{document}

相关内容