texlive[52550] Master/texmf-dist: pst-eucl (28oct19)

commits+karl at tug.org commits+karl at tug.org
Mon Oct 28 21:55:19 CET 2019


Revision: 52550
          http://tug.org/svn/texlive?view=revision&revision=52550
Author:   karl
Date:     2019-10-28 21:55:19 +0100 (Mon, 28 Oct 2019)
Log Message:
-----------
pst-eucl (28oct19)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/generic/pst-eucl/Changes
    trunk/Master/texmf-dist/doc/generic/pst-eucl/pst-eucl-doc.pdf
    trunk/Master/texmf-dist/doc/generic/pst-eucl/pst-eucl-doc.tex
    trunk/Master/texmf-dist/tex/generic/pst-eucl/pst-eucl.tex

Modified: trunk/Master/texmf-dist/doc/generic/pst-eucl/Changes
===================================================================
--- trunk/Master/texmf-dist/doc/generic/pst-eucl/Changes	2019-10-28 20:55:00 UTC (rev 52549)
+++ trunk/Master/texmf-dist/doc/generic/pst-eucl/Changes	2019-10-28 20:55:19 UTC (rev 52550)
@@ -4,6 +4,18 @@
 
 
 pst-eucl.tex --------
+1.67  2019/10/28 - add macros to add/subtract/divide the length of two segment, \pstDistAdd, \pstDistSub, and \pstDistDiv etc.
+                 - add macros to reduce or enlarge the distance, \pstDistMul, \pstDistCoef.
+                 - add macro to get the distance from point C to line AB, \pstDistABC.
+                 - add macro to get the definite proportion node on segment, \pstProportionNode.
+                 - add macro to get the fourth harmonic point, \pstFourthHarmonicNode.
+                 - add macro to put the label for the segment, \pstLabelAB.
+                 - add macro to locate a point on segment with specified length, \pstLocateAB.
+                 - add macro to extend a segment to a new point with specified length, \pstExtendAB.
+                 - add macro to get the inversion mapping of a point to the inversion center, \pstInversion.
+                 - add macro to get the Geometric Mean of two segment, \pstGeometricMean.
+                 - add macro to get the Harmonic Mean of two segment, \pstHarmonicMean.
+                 - add macro to get the radical axis of two circles, \pstCircleRadicalAxis.
 1.66  2019/10/20 - add macros to operate the node coordinates, \pstAbscissa, \pstOrdinate, \pstMoveNode etc.
                  - add optional parameters angleA and angleB for \pstCircleOA and \pstCircleAB.
                  - add optional parameters to output the inner circle center and outer circle center for \pstTriangleIC and \pstTriangleOC.
@@ -10,7 +22,7 @@
                  - add macros to draw the tangent line and tangent node of circle.
                  - add macros to draw the external and internal common tangent lines of two circles.
                  - add macros to draw conics (ellipse, parabola and hyperbola) and their geometrical elements, such as focus, directrix and intersections.
-1.65  2019/08/19 - new type for angle 
+1.65  2019/08/19 - new type for angle
 1.64  2019/01/31 - fix for PointName and pstInterCC
 1.63  2019/01/27 - fix for PointSymbol=none for pstTriangle
 1.62  2019/01/13 - added fillstyle for angles
@@ -23,10 +35,10 @@
 1.58 2018/08/07 - allow PointSymbol?=none
 1.57 2017/11/28 - fix bug with StandardSyml->StandardSymL
 1.56 2017/04/18 - \psGetAngleABC:
-                  - added   dec -1 le { /dec 15 def } if  
+                  - added   dec -1 le { /dec 15 def } if
                   - added \pst at usecolor\pslinecolor in line 1616
-1.55 2016/10/11 - fix for \pstRightAngle 
-1.54 2016/09/01 - added MarkArrow, MarkArroww,MarkArrowww 
+1.55 2016/10/11 - fix for \pstRightAngle
+1.54 2016/09/01 - added MarkArrow, MarkArroww,MarkArrowww
 1.53 2016/05/03 - revert changes of CodeFig(A|B)
 1.52 2015/10/19 - added more optional arguments (ts)
 1.51 2014/05/17 - added two new functions for angles and distances

Modified: trunk/Master/texmf-dist/doc/generic/pst-eucl/pst-eucl-doc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/generic/pst-eucl/pst-eucl-doc.tex
===================================================================
--- trunk/Master/texmf-dist/doc/generic/pst-eucl/pst-eucl-doc.tex	2019-10-28 20:55:00 UTC (rev 52549)
+++ trunk/Master/texmf-dist/doc/generic/pst-eucl/pst-eucl-doc.tex	2019-10-28 20:55:19 UTC (rev 52550)
@@ -216,7 +216,7 @@
 which are not supported good by \PST\space with '! number too big' issue.} to generate the numerical values,
 or the expandable command \Lcs{fpeval}\footnote{Provided by package \texttt{xfp},
 it can truncate the fraction part digits using the \texttt{trunc} function perfectly,
-e.g. \texttt{\textbackslash{}fpeval\{trunc(18/7,3)\}}.} to get a purely numerical result,
+e.g. \texttt{\textbackslash{}fpeval\{trunc(18/7,3)\}}.} to get a purely numerical result.
 
 The macro \Lcs{pstMoveNode} use them to move node $A$ by abscissa increment $dx$
 and ordinate increment $dy$ to get the target node $B$.
@@ -316,27 +316,61 @@
 depends of the width and color of the line when the drawing is done, as shown is the
 next example.
 
-
-
 \begin{LTXexample}[width=5cm,pos=l]
 \begin{pspicture}[showgrid=true](-2,-2)(2,2)
-  \rput{18}{%
-    \pstGeonode[PosAngle={0,90,180,-90}](2,0){A}(2;72){B}
-      (2;144){C}(2;216){D}(2;288){E}}
-  \pstSegmentMark[SegmentSymbol=none]{A}{B}
-  \pstSegmentMark[linecolor=green]{B}{C}
-  \psset{linewidth=2\pslinewidth}
-  \pstSegmentMark[linewidth=2\pslinewidth]{C}{D}
-  \pstSegmentMark[MarkAngle=90]{D}{E}
-  \pstSegmentMark{E}{A}
+\rput{18}{%
+  \pstGeonode[PosAngle={0,90,180,-90}](2,0){A}(2;72){B}
+    (2;144){C}(2;216){D}(2;288){E}}
+\pstSegmentMark[SegmentSymbol=none]{A}{B}
+\pstSegmentMark[linecolor=green]{B}{C}
+\psset{linewidth=2\pslinewidth}
+\pstSegmentMark[linewidth=2\pslinewidth]{C}{D}
+\pstSegmentMark[MarkAngle=90]{D}{E}
+\pstSegmentMark{E}{A}
 \end{pspicture}
 \end{LTXexample}
 
-
 The length and the separation of multiple hases can be set by \Lkeyword{MarkHashLength} and \Lkeyword{MarkHashSep}.
 
+\subsection{Segment labels}
 
+According to the manual of \PST, you can use the macros \Lcs{naput}, \Lcs{ncput} and \Lcs{nbput}
+to put the label \textit{above}, \textit{cover}, \textit{below} the segment. The macro \Lcs{pstLabelAB}
+just use them to draw a ruler bar and put the label on the ruler bar.
 
+\begin{BDef}
+\Lcs{pstLabelAB}\OptArgs\Largb{A}\Largb{B}\Largb{label}
+\end{BDef}
+
+You can use the parameters of \Lcs{ncline} to control the ruler bar,
+such as \Lkeyword{linestyle}, \Lkeyword{linecolor}, \Lkeyword{linewidth},
+\Lkeyword{arrows}, \Lkeyword{nodesep} etc; and use the parameters of \Lcs{ncput}
+to control the label position, such as \Lkeyword{nrot}, \Lkeyword{npos} etc;
+there is another parameter \Lkeyword{offset} to control the separation between
+the rule bar and the segment.
+
+It does not display the ruler bar as default, and you need to setup \Lkeyword{linestyle}
+to display it.
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](-1,-1)(4,4)
+\psset{dotscale=0.5}\psset{PointSymbol=*}\footnotesize
+\pstGeonode[PosAngle=-90](0.5,1.5){A}
+\pstGeonode[PosAngle=-90](2.5,1.5){B}\pstLineAB{A}{B}
+\pstLabelAB{A}{B}{$\sqrt{a^2+b^2}$}
+\pstGeonode[PosAngle=0](0,0.5){C}
+\pstGeonode[PosAngle=0](0,3.5){D}\pstLineAB{C}{D}
+\pstLabelAB[linestyle=dashed]{C}{D}{$\sqrt{a^2+b^2}$}
+\pstGeonode[PosAngle=190](-1,-1){E}
+\pstGeonode[PosAngle=10](3,0){F}\pstLineAB{E}{F}
+\pstLabelAB[linestyle=dashed,arrows=|-|,offset=10pt,linecolor=blue!50]{E}{F}{$\sqrt{a^2+b^2}$}
+\pstLabelAB[linestyle=dashed,arrows=|<->|,offset=10pt,nrot=:D]{F}{E}{$\sqrt{a^2+b^2}$}
+\pstGeonode[PosAngle=100](0,4){G}
+\pstGeonode[PosAngle=-50](4,2){H}\pstLineAB{G}{H}
+\pstLabelAB[linestyle=solid,linecolor=red!50,arrows=|-|,offset=15pt,nrot=:U,npos=0.7]{G}{H}{\textcolor{red!50}{$\dfrac{a}{b}$}}
+\end{pspicture}
+\end{LTXexample}
+
 \subsection{Triangles}
 
 The more classical figure, it has its own macro \Lcs{pstTriangle} for a quick definition:
@@ -536,6 +570,8 @@
 \end{pspicture}
 \end{LTXexample}
 
+\vspace{10pt}
+
 The macro \Lcs{pstLine} draws a new line with two nodes, or two coordinates
 or one node and one coordinate. This macro is similar with \Lcs{pstLineAB},
 but more compatible.
@@ -547,6 +583,8 @@
 \Lcs{pstLine}\OptArgs\cAny\cAny
 \end{BDef}
 
+\vspace{10pt}
+
 The macros \Lcs{pstLineAA} and \Lcs{pstLineAS} draw a new line with one node,
 the slope \texttt{angle} between the line and the horizontal axis, or the
 slope \texttt{gradient} of the line, and create a new node $B$ on the line.
@@ -572,6 +610,8 @@
 \end{pspicture}
 \end{LTXexample}
 
+\vspace{10pt}
+
 The macro \Lcs{pstLineAbsNode} creates a new node $C$ whose abscissa
 is the given value $x_1$ on the line $AB$. The macro \Lcs{pstLineOrdNode} creates a new node $C$ whose ordinate is the given value $y_1$ on the line $AB$.
 You can input $x_1$ or $y_1$ as any number(e.g, 2.0),
@@ -596,65 +636,460 @@
 \end{pspicture}
 \end{LTXexample}
 
+\vspace{10pt}
+
+The macro \Lcs{pstProportionNode} creates the nodes $C$ and $C'$ on segment $AB$ which are satisfied $|AC|:|BC|=\lambda,\;(\lambda>0)$.
+The node $C$ is inside the segment $AB$ and the node $C'$ is outside the segment $AB$, we have
+\begin{equation*}
+\left\{
+\begin{array}{l}
+x_{C}=\dfrac{x_{A}+\lambda{}x_{B}}{1+\lambda}\\
+y_{C}=\dfrac{y_{A}+\lambda{}y_{B}}{1+\lambda}
+\end{array}
+\right.
+\quad\text{and}\quad
+\left\{
+\begin{array}{l}
+x_{C'}=\dfrac{x_{A}-\lambda{}x_{B}}{1-\lambda}\\
+y_{C'}=\dfrac{y_{A}-\lambda{}y_{B}}{1-\lambda}
+\end{array}
+\right.
+\end{equation*}
+
+\begin{BDef}
+\Lcs{pstProportionNode}\OptArgs\Largb{A}\Largb{B}\Largb{$\lambda$}\Largb{C}\Largb{C'}
+\end{BDef}
+
+You can use \Lcs{pstDistDiv} to get the ratio of two segments to $\lambda$,
+we will introduce \Lcs{pstDistDiv} later.
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](-1,-1)(4,4)
+\pstGeonode[PosAngle=-40,PointSymbol=|](0.5,1.5){A}
+\pstGeonode[PosAngle=-40,PointSymbol=|](3.0,3.0){B}
+\pstGeonode[PosAngle=90,linecolor=purple!60,CurveType=polyline](3,0){X}(4,0){Y}
+\pstGeonode[PosAngle=90,linecolor=brown!60,CurveType=polyline](1.5,-1){X'}(4,-1){Y'}
+\pstLineAB[linecolor=red,nodesep=-2.5]{A}{B}
+\psset{PosAngle=-40,PointSymbol=*,dotscale=1.5}
+\pstProportionNode[linecolor=yellow]{A}{B}{3.0}{C}{C'}
+\pstProportionNode[linecolor=blue]{A}{B}{1.0}{D}{D'}
+\pstProportionNode[linecolor=green]{A}{B}{0.2}{E}{E'}
+\pstProportionNode[linecolor=brown]{A}{B}{\pstDistDiv{X}{Y}{X'}{Y'}}{F}{F'}
+\end{pspicture}
+\end{LTXexample}
+
+\vspace{10pt}
+
+The four collinear points $A,B,C,D$ are called \texttt{Harmonic Conjugation Points} if their cross ratio is $-1$,
+that is
+$$(AB,CD)=\dfrac{AC}{BC}:\dfrac{AD}{BD}=-1$$
+If given three collinear points $A,B,C$, how can we get the fourth harmonic point?
+The following macro \Lcs{pstFourthHarmonicNode} is used to get the fourth harmonic point.
+It create a new node $X$ on the same line, but when $A,B,C$ are not collinear, we put it at origin.
+
+\begin{BDef}
+\Lcs{pstFourthHarmonicNode}\OptArgs\Largb{A}\Largb{B}\Largb{C}\Largb{X}
+\end{BDef}
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](-2,-2)(3,3)\footnotesize
+\psset{unit=0.6cm}\psset{dotscale=0.5}\psset{PointSymbol=*}
+\pstGeonode[PosAngle=-90](-2,-2){A}(5,-2){I}(-1,-2){J}
+\pstLineAA[linestyle=none,PointName=none,PointSymbol=none]{A}{38}{A'}
+\pstLineAbsNode[PosAngle=-80]{A}{A'}{0}{B}
+\pstLineAbsNode[PosAngle=20]{A}{A'}{2.5}{C}
+\pstFourthHarmonicNode[PosAngle=180,PointNameSep=0.2]{A}{B}{C}{X}
+% check if A,N,M are also collinear.
+\pstInterLL[PosAngle=90]{J}{X}{I}{C}{P}
+\pstLineAB[linestyle=dashed]{J}{P}
+\pstLineAB[linestyle=dashed]{I}{P}
+\pstInterLL[PosAngle=20]{J}{B}{I}{P}{M}
+\pstInterLL[PosAngle=140]{I}{B}{J}{P}{N}
+\pstLineAB[linestyle=dashed]{J}{M}
+\pstLineAB[linestyle=dashed]{I}{N}
+\pstLineAB[linestyle=dashed]{A}{M}
+\pstLineAB[linestyle=dashed]{A}{I}
+\pstLineAB{A}{C}
+\end{pspicture}
+\end{LTXexample}
+
+\vspace{10pt}
+
+If you want to draw a node like \textsf{'Given $EF$, please find node $C$ on $AB$ such that $AC=EF$'},
+you can use the macro \Lcs{pstLocateAB} to do this, it can seek the node $C$ from $A$ to $B$ with the
+specified length, which can be got from \Lcs{pstDist}, \Lcs{pstDistConst}, \Lcs{pstDistAdd}, \Lcs{pstDistSub},
+etc.
+
+\begin{BDef}
+\Lcs{pstLocateAB}\OptArgs\Largb{A}\Largb{B}\Largb{$L$}\Largb{C}
+\end{BDef}
+
+Note that seek from $B$ will get the node $C$ in the reverse order, for example,
+
+\begin{LTXexample}[width=5cm,pos=l]
+\begin{pspicture}[showgrid=true](-3,-3)(3,3)\footnotesize
+\psset{unit=0.5cm}\psset{dotscale=0.5}\psset{PointSymbol=*}
+\pstGeonode[PosAngle=90,CurveType=polyline](-2,0){A}(-1,0){B}
+\pstGeonode[PosAngle=90,CurveType=polyline](-2,1){A'}(0,1){B'}
+\pstLocateAB[PosAngle=90]{A}{B}{\pstDist{A'}{B'}}{C}
+\pstLocateAB[PosAngle=90]{B}{A}{\pstDist{A'}{B'}}{C'}
+\psset{linestyle=dashed,SegmentSymbol=MarkHashh,MarkAngle=90}
+\pstSegmentMark{A'}{B'}\pstSegmentMark{B}{C'}\pstSegmentMark{A}{C}
+\pstGeonode[PosAngle=90,CurveType=polyline](-3,-2){D}(3,-4){E}
+\pstGeonode[PosAngle=90,CurveType=polyline](-4,2){D'}(-3,4){E'}
+\pstLocateAB[PosAngle=90]{D}{E}{\pstDist{D'}{E'}}{F}
+\pstLocateAB[PosAngle=90]{E}{D}{\pstDist{D'}{E'}}{F'}
+\psset{linestyle=dashed,SegmentSymbol=MarkHashhh,MarkAngle=90}
+\pstSegmentMark{D'}{E'}\pstSegmentMark{E}{F'}\pstSegmentMark{D}{F}
+\pstGeonode[PosAngle=0,CurveType=polyline](2,0){I}(2,1){J}
+\pstGeonode[PosAngle=0,CurveType=polyline](3,2){I'}(3,4){J'}
+\pstLocateAB[PosAngle=0]{I}{J}{\pstDist{I'}{J'}}{K}
+\pstLocateAB[PosAngle=0]{J}{I}{\pstDist{I'}{J'}}{K'}
+\psset{linestyle=dashed,SegmentSymbol=MarkHashhh,MarkAngle=45}
+\pstSegmentMark{I'}{J'}\pstSegmentMark{J}{K'}\pstSegmentMark{I}{K}
+\end{pspicture}
+\end{LTXexample}
+
+\vspace{10pt}
+
+If you want to draw a node like \textsf{'Given $EF$, please extend $AB$ to $C$ such that $BC=EF$'},
+you can use the macro \Lcs{pstExtendAB} to do this, it can extend $AB$ from $B$ to one node with the
+specified length, which can be got from \Lcs{pstDist}, \Lcs{pstDistConst}, \Lcs{pstDistAdd}, \Lcs{pstDistSub},
+etc.
+
+\begin{BDef}
+\Lcs{pstExtendAB}\OptArgs\Largb{A}\Largb{B}\Largb{$L$}\Largb{C}
+\end{BDef}
+
+Note that extend $BA$ to $C$ will get the node $C$ in the reverse order, for example,
+
+\begin{LTXexample}[width=5cm,pos=l]
+\begin{pspicture}[showgrid=true](-3,-3)(3,3)\footnotesize
+\psset{unit=0.5cm}\psset{dotscale=0.5}\psset{PointSymbol=*}
+\pstGeonode[PosAngle=90,CurveType=polyline](-2,0){A}(-1,0){B}
+\pstGeonode[PosAngle=90,CurveType=polyline](-2,1){A'}(0,1){B'}
+\pstExtendAB[PosAngle=90]{A}{B}{\pstDist{A'}{B'}}{C}
+\pstExtendAB[PosAngle=90]{B}{A}{\pstDist{A'}{B'}}{C'}
+\psset{linestyle=dashed,SegmentSymbol=MarkHashh,MarkAngle=90}
+\pstSegmentMark{A'}{B'}\pstSegmentMark{B}{C}\pstSegmentMark{A}{C'}
+\pstGeonode[PosAngle=90,CurveType=polyline](-2,-2){D}(0,-3){E}
+\pstGeonode[PosAngle=90,CurveType=polyline](-4,2){D'}(-3,4){E'}
+\pstExtendAB[PosAngle=90]{D}{E}{\pstDist{D'}{E'}}{F}
+\pstExtendAB[PosAngle=90]{E}{D}{\pstDist{D'}{E'}}{F'}
+\psset{linestyle=dashed,SegmentSymbol=MarkHashhh,MarkAngle=90}
+\pstSegmentMark{D'}{E'}\pstSegmentMark{E}{F}\pstSegmentMark{D}{F'}
+\pstGeonode[PosAngle=0,CurveType=polyline](2,0){I}(2,1){J}
+\pstGeonode[PosAngle=0,CurveType=polyline](3,2){I'}(3,4){J'}
+\pstExtendAB[PosAngle=0]{I}{J}{\pstDist{I'}{J'}}{K}
+\pstExtendAB[PosAngle=0]{J}{I}{\pstDist{I'}{J'}}{K'}
+\psset{linestyle=dashed,SegmentSymbol=MarkHashhh,MarkAngle=45}
+\pstSegmentMark{I'}{J'}\pstSegmentMark{J}{K}\pstSegmentMark{I}{K'}
+\end{pspicture}
+\end{LTXexample}
+
+You can find the node $C$ on segment $AB$ satisfied $|AC|$:$|AB|$=\Lkeyword{DistCoef}
+using \Lcs{pstTranslation}, but it can't do the same thing like \Lcs{pstLocateAB} and \Lcs{pstExtendAB}
+when the given segment $EF$ is not parallel with $AB$, it will be introduced in the later sections.
+
+\vspace{10pt}
+
+If you want to find the inversion point $C'$ of $C$ to the inversion center $O$ with inversion raduis $R$,
+that is, the point $C'$ is satisfied the inversion transform equation
+$$|OC|\times|OC'|=R^2$$
+you can use the macro \Lcs{pstInversion} to do this work.
+In fact, we use the macro \Lcs{pstLocateAB} to implement this macro
+by passing the value $\dfrac{R^2}{|OC|}$ to parameter length.
+
+\begin{BDef}
+\Lcs{pstInversion}\OptArgs\Largb{O}\Largb{A}\Largb{C}\Largb{C'}
+\end{BDef}
+
+It is possible to omit the parameter $A$ and then to specify the inversion radius or
+the inversion diameter using the parameters \Lkeyword{Radius} and \Lkeyword{Diameter},
+which will be introduced in the next section.
+
+It is clear that the inversion mapping of a line is a circle, and the inversion mapping
+of a point on the inversion circle is itself.
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](-1,-2)(4,3)
+\psset{dotscale=0.5}\psset{PointSymbol=*}\footnotesize
+\def\ra{1.5}
+\pstGeonode[PosAngle=180](1,1){O}
+\pstCircleOA[linecolor=red!50,Radius=\pstDistVal{\ra}]{O}{}
+\pstCircleRotNode[PosAngle=180,RotAngle=180,Radius=\pstDistVal{\ra}]{O}{}{A}
+\pstInversion[PosAngle=0,Radius=\pstDistVal{\ra}]{O}{}{A}{A'}
+\pstGeonode[PosAngle=0](3,3){C}
+\pstInversion[PosAngle=100,Radius=\pstDistVal{\ra}]{O}{}{C}{C'}
+\pstLineAB{O}{C}\pstLineAB{O}{C'}
+\pstGeonode[PosAngle=0](3,1.5){D}
+\pstInversion[PosAngle=90,Radius=\pstDistVal{\ra}]{O}{}{D}{D'}
+\pstLineAB{O}{D}\pstLineAB{O}{D'}
+\pstGeonode[PosAngle=0](3,0){E}
+\pstInversion[PosAngle=-90,Radius=\pstDistVal{\ra}]{O}{}{E}{E'}
+\pstLineAB{O}{E}\pstLineAB{O}{E'}
+\pstGeonode[PosAngle=0](3,-2){F}
+\pstInversion[PosAngle=-120]{O}{A}{F}{F'}
+\pstLineAB{O}{F}\pstLineAB{O}{F'}
+\pstLineAB[linecolor=black!50]{C}{F}
+\pstCircleABC[linestyle=dashed,linecolor=blue!40,PosAngle=0]{C'}{D'}{E'}{O'}
+\end{pspicture}
+\end{LTXexample}
+
+\vspace{10pt}
+
+If you want to find the node $C$ from $A$ to $B$, such that $AC$ is the geometric mean of two
+given segments $DE$ of $FG$, that is,
+$$|AC|^2=|DE|\times|FG|$$
+you can use the macro \Lcs{pstGeometricMean} to do this work.
+It also can be used to draw a circle when given two points on the circle, 
+and a line tangents to the circle.
+
+\begin{BDef}
+\Lcs{pstGeometricMean}\OptArgs\Largb{A}\Largb{B}\Largb{$L_1$}\Largb{$L_2$}\Largb{C}
+\end{BDef}
+
+In fact, we use the macro \Lcs{pstLocateAB} to implement this macro
+by passing the value $\sqrt{L_1\times{}L_2}$ to parameter length.
+The length $L_1$ and $L_2$ can be got from \Lcs{pstDist}, \Lcs{pstDistConst},
+\Lcs{pstDistAdd}, \Lcs{pstDistSub}, etc.
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](0,-3)(4,3)
+\psset{dotscale=0.5}\psset{PointSymbol=*}\footnotesize
+\pstGeonode[PosAngle=90](0,1){A}
+\pstGeonode[PosAngle=0](3.2,2){C}(3.2,1){D}(3.2,-2){E}
+\pstGeometricMean[PosAngle=90]{C}{A}{\pstDistAB{C}{D}}{\pstDistAB{D}{E}}{B}
+\pstCircleABC[linecolor=gray!60]{B}{D}{E}{O}
+\pstLineAB[linecolor=red!40]{C}{D}
+\pstLineAB[linecolor=blue!40]{D}{E}
+\psset{linestyle=dashed}
+\pstLineAB[linecolor=purple!80]{C}{A}
+\pstLineAB{D}{B}\pstLineAB{E}{B}
+\end{pspicture}
+\end{LTXexample}
+
+\vspace{10pt}
+
+If you want to find the node $C$ from $A$ to $B$, such that $AC$ is the harmonic mean of two
+given segments $DE$ of $FG$, that is,
+$$\dfrac{1}{|AC|}=\dfrac{1}{2}(\dfrac{1}{|DE|}+\dfrac{1}{|FG|})$$
+you can use the macro \Lcs{pstHarmonicMean} to do this work.
+
+\begin{BDef}
+\Lcs{pstHarmonicMean}\OptArgs\Largb{A}\Largb{B}\Largb{$L_1$}\Largb{$L_2$}\Largb{C}
+\end{BDef}
+
+In fact, we use the macro \Lcs{pstLocateAB} to implement this macro
+by passing the value $\dfrac{2L_1L_2}{L_1+L_2}$ to parameter length.
+The length $L_1$ and $L_2$ can be got from \Lcs{pstDist}, \Lcs{pstDistConst},
+\Lcs{pstDistAdd}, \Lcs{pstDistSub}, etc.
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](0,-3)(4,3)
+\psset{dotscale=0.5}\psset{PointSymbol=*}\footnotesize
+\pstGeonode[PosAngle=90](1,2){A}
+\pstGeonode[PosAngle=-90](0,-2){C}(2.5,-2){D}(4,-2){E}
+\pstHarmonicMean[PosAngle=60]{D}{A}{\pstDistAB{C}{D}}{\pstDistAB{D}{E}}{B}
+\pstLineAB[linecolor=red!40]{C}{D}
+\pstLineAB[linecolor=blue!40]{D}{E}
+\pstLineAB[linecolor=purple!80]{A}{D}
+\pstLineAB[linestyle=dashed]{C}{B}
+\pstLineAB[linestyle=dashed]{E}{B}
+\pstLineAB{C}{A}\pstLineAB{E}{A}
+\end{pspicture}
+\end{LTXexample}
+
+\subsection{Distance}
+Like as coordinates, the distance works at the PostScript level,
+that is, it should be used where the code is interpreted by PostScript engine,
+but not \TeX\ engine. There were three macros to operate the distance before v1.66:
+
+\begin{BDef}
+\Lcs{pstDistAB}\Largb{A}\Largb{B}\\
+\Lcs{pstDistVal}\Largb{l}\\
+\Lcs{pstDistCalc}\Largb{expr}
+\end{BDef}
+
+The first specifies a distance between two points. The second macro can be used to
+specify an explicit numerical value $l$, which is in \texttt{User coordinate}.
+The third one uses the \Lcs{pscalculate} to calculate
+the result of the input expression, which is in \texttt{User coordinate} too.
+The parameter \Lkeyword{DistCoef} can be used to specify
+a coefficient to reduce or enlarge the result distance.
+This parameter will come into effect if it is specified before these macros.
+
+After v1.66, We provide three macros which disable the effect of parameter \Lkeyword{DistCoef}
+one to one as following:
+
+\begin{BDef}
+\Lcs{pstDist}\Largb{A}\Largb{B}\\
+\Lcs{pstDistConst}\Largb{l}\\
+\Lcs{pstDistExpr}\Largb{expr}
+\end{BDef}
+
+We provide the macro \Lcs{pstDistCoef} to reduce or enlarge a given distance explicitly,
+for example: \verb|\pstDistCoef{\pstDist{A}{B}}|, or use macro \Lcs{pstDistMul} to multiply
+the input coefficient.
+
+\vspace{10pt}\noindent{}{\large{\textbf{Note}}}:
+The series of macros \verb|\pstDist*| get the length result in the \texttt{Screen coordinate},
+so you need to convert the length to the \texttt{User coordinate} by macro \Lcs{pstUserDist},
+when use them where need the user coordinate numbers, e.g,
+
+\begin{lstlisting}
+\pnode(! 1 \pstUserDist{\pstDistAdd{A}{B}{C}{D}}){A}
+\pstMoveNode(0,\pstUserDist{\pstDistAdd{A}{B}{C}{D}}){A}{E}
+\end{lstlisting}
+
+You can convert the distance in \texttt{User coordinate} to \texttt{Screen coordinate} by
+macro \Lcs{pstScreenDist}, it is just another name of \Lcs{pstDistConst}. As we said before,
+macros \Lcs{pstAbscissa} and \Lcs{pstOrdinate} give the coordinate of one node in
+\texttt{User coordinate}, so if you want to draw a circle using them, you should type:\\[8pt]
+\verb|\pstCircleOA[Radius=\pstDistConst{\pstAbscissa{A}}]{A}{}|
+
+\vspace{10pt}
+
+It is possible to use the raw PostScript command to make more complex arithmetic operations.
+In order to hide the lower level Postscipt language, we add more macros for distance
+addition and subtraction, such as \Lcs{pstDistAdd}[Val/Coef] and \Lcs{pstDistSub}[Val/Coef], etc.
+These macros can be used to calculate the Radius or Diameter to define a circle.
+
+The macros \Lcs{pstDistAdd} and \Lcs{pstDistSub} are used to get the addition and subtraction
+of the given segments $AB$ and $CD$. The macro \Lcs{pstDistDiv} is used to
+get the length ratio of the given segments $AB$ and $CD$, you can pass the ratio to
+macro \Lcs{pstProportionNode}, or setup the ratio to parameter \Lkeyword{DistCoef} in
+macro \Lcs{pstTranslation}, or pass the ratio to any \verb|\pstDist|* macros which need
+a $\lambda$ parameter.
+
+\begin{BDef}
+\Lcs{pstDistMul}\Largb{A}\Largb{B}\Largb{$\lambda$}\\
+\Lcs{pstDistAdd}\Largb{A}\Largb{B}\Largb{C}\Largb{D}\\
+\Lcs{pstDistAddVal}\Largb{A}\Largb{B}\Largb{$\lambda$}\Largb{$L$}\\
+\Lcs{pstDistAddCoef}\Largb{A}\Largb{B}\Largb{$\lambda_1$}\Largb{C}\Largb{D}\Largb{$\lambda_2$}\\
+\Lcs{pstDistSub}\Largb{A}\Largb{B}\Largb{C}\Largb{D}\\
+\Lcs{pstDistSubVal}\Largb{A}\Largb{B}\Largb{$\lambda$}\Largb{$L$}\\
+\Lcs{pstDistSubCoef}\Largb{A}\Largb{B}\Largb{$\lambda_1$}\Largb{C}\Largb{D}\Largb{$\lambda_2$}\\
+\Lcs{pstDistDiv}\Largb{A}\Largb{B}\Largb{C}\Largb{D}
+\end{BDef}
+
+In these macros, the length $L$ is a numerical value in the \texttt{Screen Coordinate},
+so it is possible to pass the result of any macros like \verb|\pstDist| to it.
+$\lambda$ is a numerical value to multiply, and most important is that the parameter
+\Lkeyword{DistCoef} doesn't take effect any more.
+It is better to describe in formula:
+\\
+- macro \Lcs{pstDistAB} get the screen length of $\text{DistCoef}*|AB|$\\
+- macro \Lcs{pstDistVal} get the screen length of $\text{DistCoef}*l$\\
+- macro \Lcs{pstDistCalc} get the screen length of $\text{DistCoef}*\text{expr}$\\
+- macro \Lcs{pstDistCoef} get the screen length of $\text{DistCoef}*\text{<arg>}$\\
+- macro \Lcs{pstDist} get the screen length of $|AB|$\\
+- macro \Lcs{pstDistConst} get the screen length of $l$\\
+- macro \Lcs{pstDistExpr} get the screen length of $\text{expr}$\\
+- macro \Lcs{pstDistMul} get the screen length of $\lambda{}|AB|$\\
+- macro \Lcs{pstDistAdd} get the screen length of $|AB|+|CD|$\\
+- macro \Lcs{pstDistAddVal} get the screen length of $\lambda{}|AB|+L$\\
+- macro \Lcs{pstDistAddCoef} get the screen length of $\lambda_1{}|AB|+\lambda_2{}|CD|$\\
+- macro \Lcs{pstDistSub} get the screen length of $abs(|AB|-|CD|)$\\
+- macro \Lcs{pstDistSubVal} get the screen length of $abs(\lambda{}|AB|-L)$\\
+- macro \Lcs{pstDistSubCoef} get the screen length of $abs(\lambda_1{}|AB|-\lambda_2{}|CD|)$\\
+- macro \Lcs{pstDistDiv} get the the ratio of length $|AB|:|CD|$
+
+For example, the following one draw a circle with radius length $2|AB|+3|CD|+4|EF|$,
+it shows how to operate more than two distances.
+\begin{lstlisting}
+\pstCircleOA[Radius=\pstDistAddVal{A}{B}{2.0}{\pstDistAddCoef{C}{D}{3.0}{E}{F}{4.0}}]{A}{}
+\end{lstlisting}
+
+Another example is for \Lcs{pstDistMul}, the old code like as
+\begin{lstlisting}
+\pstCircleOA[DistCoef=1 3 div,Radius=\pstDistAB{A}{B}]{O}{}
+\pstCircleOA[DistCoef=1 3 div,Radius=\pstDistAB{A}{B}]{A}{B}{O}{}{I}{J}
+\pstInterCC[DistCoef=1 3 div,RadiusA=\pstDistAB{A}{B},DistCoef=none,RadiusA=\pstDistAB{C}{D}]{O1}{}{O2}{}{I}{J}
+\end{lstlisting}
+could be simplified to
+\begin{lstlisting}
+\pstCircleOA[Radius=\pstDistMul{A}{B}{1 3 div}]{O}{}
+\pstInterLC[Radius=\pstDistMul{A}{B}{1 3 div}]{A}{B}{O}{}{I}{J}
+\pstInterCC[RadiusA=\pstDistMul{A}{B}{1 3 div},RadiusA=\pstDistAB{C}{D}]{O1}{}{O2}{}{I}{J}
+\end{lstlisting}
+
+\vspace{10pt}\noindent{}{\Large{\textbf{Important}}}!
+We recommend that you should use the distance macros which disable the parameter \Lkeyword{DistCoef}
+instead of \verb|\pstDistAB|, \verb|\pstDistVal| or \verb|\pstDistCalc|,
+when you need to pass their result into \Lcs{pstDistAddVal} or \Lcs{pstDistSubVal},
+as it will give you the error result sometimes.
+For example, the following code \\[8pt]
+\verb|\pstDistAddVal{A}{B}{2.0}{\pstDistAB{C}{D}}|\\[8pt]
+is expected to get the length of $2|AB|+|CD|$. If current \Lkeyword{DistCoef} is $\lambda$,
+then it will give the error result as $2|AB|+\lambda|CD|$.
+The right way is \\[8pt]
+\verb|\pstDistAddVal{A}{B}{2.0}{\pstDist{C}{D}}|
+
+\vspace{10pt}
+At last, we provide a macro named \Lcs{pstDistABC} to get the distance from $C$ to line $AB$.
+
+\begin{BDef}
+\Lcs{pstDistABC}\Largb{A}\Largb{B}\Largb{C}
+\end{BDef}
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](-1,-1)(3,3)
+\psset{dotscale=0.5}\psset{PointSymbol=*}\footnotesize
+\pstGeonode[PosAngle=-90](0,0){O}
+\pstGeonode[PosAngle=-90](2,0){A}
+\pstGeonode[PosAngle=90](1,1.5){B}
+\pstCircleOA[linecolor=red,Radius=\pstDistABC{O}{A}{B}]{B}{}
+\pstCircleOA[linecolor=blue,Radius=\pstDistABC{B}{O}{A}]{A}{}
+\pstCircleOA[linecolor=green,Radius=\pstDistABC{A}{B}{O}]{O}{}
+\pstLineAB[linecolor=red]{O}{A}
+\pstLineAB[linecolor=blue]{B}{O}
+\pstLineAB[linecolor=green]{A}{B}
+\end{pspicture}
+\end{LTXexample}
+
 \subsection{Circles}
 
 A circle can be defined either with its center and a point of its
-circumference, or with two diameterly opposed points. There is two
-commands :
+circumference, or with two diameterly opposed points. There are two
+commands:
 
 \begin{BDef}
 \Lcs{pstCircleOA}\OptArgs\Largb{O}\Largb{A}\OptArg{angleA}\OptArg{angleB}\\
-\Lcs{pstCircleAB}\OptArgs\Largb{O}\Largb{A}\OptArg{angleA}\OptArg{angleB}
+\Lcs{pstCircleAB}\OptArgs\Largb{A}\Largb{B}\OptArg{angleA}\OptArg{angleB}
 \end{BDef}
 
-\Lcs{pstCircleOA} draws the circle of center $O$ crossing $A$ from \Lkeyword{angleA} to \Lkeyword{angleB}, going counter clockwise.
-Possible options are \Lkeyword{Radius} and \Lkeyword{Diameter}.
+\Lcs{pstCircleOA} draws the circle of center $O$ crossing $A$ from \Lkeyword{angleA} to \Lkeyword{angleB},
+going counter clockwise. Possible options are \Lkeyword{Radius} and \Lkeyword{Diameter}.
 
 \Lcs{pstCircleAB} draws the circle of diameter $AB$ with the same options.
 
-
 For the first macro, it is possible to omit the second point and then
 to specify a radius or a diameter using the parameters \Lkeyword{Radius}
-and \Lkeyword{Diameter}. The values of these parameters must be specified
-with one of the two following macros :
+\footnote{The package \texttt{pst-fractal} also defines an optional key
+named \texttt{Radius}, if you need to use this package with \texttt{pst-eucl},
+you need to setup the key \texttt{Radius} as following:
+\texttt{\textbackslash{}psset[pst-eucl]\{Radius=\textbackslash{}pstDistVal\{3\}\}}.}
+and \Lkeyword{Diameter}. The values of these parameters can be specified
+with one of the \verb|\pstDist|* series macros.
 
-\begin{BDef}
-\Lcs{pstDistAB}\OptArgs\Largb{A}\Largb{B}\\
-\Lcs{pstDistVal}\OptArgs\Largb{x}
-\end{BDef}
-
-%\Lcs{pstDistAB} Specifies distance $AB$ for the parameters
-%  \Lkeyword{Radius}, \Lkeyword{Diameter} and \Lkeyword{DistCoef}.
-%
-%\Lcs{pstDistVal} Specifies a numerical value for the parameters
-%  \Lkeyword{Radius}, \Lkeyword{Diameter}, and \Lkeyword{DistCoef}.
-
-The first specifies a distance between two points. The parameter
-\Lkeyword{DistCoef} can be used to specify a coefficient to reduce or
-enlarge this distance. To be taken into account this last parameter
-must be specified before the distance. The second macro can be used to
-specify an explicit numeric value.
-%
 We will see later how to draw the circle crossing three points.
-%
-  With this package, it becomes possible to draw:
-  \begin{compactitem}
-  \item {\color{red} the circle of center $A$ crossing $B$;}
-  \item {\color{green} the circle of center $A$ whose radius is $AC$;}
-  \item {\color{blue} the circle of center $A$ whose radius is $BC$;}
-  \item {\color{Sepia} the circle of center $B$ whose radius is $AC$;}
-  \item {\color{Aquamarine} the circle of center $B$ of diameter $AC$;}
-  \item {\color{RoyalBlue} the circle whose diameter is $BC$.}
-  \end{compactitem}
+With this package, it becomes possible to draw:
+\begin{compactitem}
+\item {\color{red} the circle of center $A$ crossing $B$;}
+\item {\color{green} the circle of center $A$ whose radius is $AC$;}
+\item {\color{blue} the circle of center $A$ whose radius is $BC$;}
+\item {\color{Sepia} the circle of center $B$ whose radius is $AC$;}
+\item {\color{Aquamarine} the circle of center $B$ of diameter $AC$;}
+\item {\color{RoyalBlue} the circle whose diameter is $BC$.}
+\end{compactitem}
 
-\clearpage
-
-\begin{LTXexample}[width=\linewidth,pos=t]
-\begin{pspicture}[showgrid](-4,-3.3)(4,3)
-\psset{linewidth=2\pslinewidth}
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid](-3,-3)(3,3)\footnotesize
+\psset{unit=0.65cm}\psset{dotscale=0.5}\psset{PointSymbol=*}
 \pstGeonode[PosAngle={0,-135,90},PointSymbol={*,*,square}](1,0){A}(-2,-1){B}(0,1){C}
 \pstCircleOA[linecolor=red]{A}{B}
-\pstCircleOA[linecolor=green, DistCoef=2 3 div, Radius=\pstDistAB{A}{C}]{A}{}
+\pstCircleOA[linecolor=green, Radius=\pstDistMul{A}{C}{2 3 div}]{A}{}
 \pstCircleOA[linecolor=blue, Radius=\pstDistAB{B}{C}]{A}{}[45][270]
 \pstCircleOA[linecolor=Sepia, Radius=\pstDistAB{A}{C}]{B}{}
 \pstCircleOA[linecolor=Aquamarine, Diameter=\pstDistAB{A}{C}]{B}{}[80][320]
@@ -662,6 +1097,35 @@
 \end{pspicture}
 \end{LTXexample}
 
+\vspace{10pt}
+
+The following example show how to use the more complex distance macros,
+and the parameter to fill the circle.
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](-3,-3)(3,3)\footnotesize
+\psset{unit=0.65cm}\psset{dotscale=0.5}\psset{PointSymbol=*}
+\pstGeonode[PosAngle=90,CurveType=polyline](0,0){A}(1,0){B}
+\pstGeonode[PosAngle=90,CurveType=polyline](0,1){A'}(2,1){B'}
+\pstCircleOA[linecolor=gray,Radius=\pstDistAdd{A}{B}{A'}{B'}]{A}{}
+\pstCircleOA[linecolor=red,Radius=\pstDistAddVal{A}{B}{1.0}{\pstDistConst{0.5}}]{A}{}
+\pstCircleOA[linecolor=blue,Radius=\pstDistAddCoef{A}{B}{0.5}{A'}{B'}{1.5}]{A}{}
+\pstCircleOA[linecolor=green,Radius=\pstDistSub{A}{B}{A'}{B'}]{B'}{}
+\pstCircleOA[linecolor=brown,Radius=\pstDistSubCoef{A}{B}{1.8}{A'}{B'}{0.5}]{A}{}
+\pnode(-1.5,-2){D}
+\pstCircleOA[linecolor=pink,fillstyle=solid,fillcolor=pink!40,Radius=\pstDistMul{A}{B}{0.8}]{D}{}
+\psdot(D)\uput{0.2}[-45](D){$D$}
+\pstCircleOA[linecolor=purple,Radius=\pstDistConst{\pstAbscissa{D}} abs]{D}{}
+\end{pspicture}
+\end{LTXexample}
+
+The last row set the absolute value of the abscissa of node $D$ to \Lkeyword{Radius},
+and then draw a circle at center $D$. Note that it does not work before v1.67,
+as the \Lcs{pstCircleOA} and \Lcs{pstCircleAB} were implemented with a \Lcs{rput} command,
+which will set the center $D$'s coordinate to origin, it causes that the Radius was set to zero
+and none circle will be draw out, so we remove the \Lcs{rput} code in v1.67,
+and everything works well now.
+
 \subsection{Circle arcs}
 
 \begin{BDef}
@@ -669,7 +1133,6 @@
 \Lcs{pstArcnOAB}\OptArgs\Largb{O}\Largb{A}\Largb{B}
 \end{BDef}
 
-
 These two macros draw circle arcs, $O$ is the center, the radius
 defined by $OA$, the beginning angle given by $A$ and the final angle
 by $B$. Finally, the first macro draws the arc in the direct way,
@@ -688,6 +1151,97 @@
 \end{pspicture}
 \end{LTXexample}
 
+\subsection{Circle nodes}
+
+Do you want to draw a point on the circle? A point can be positioned on a circle
+using its rotation angle by macro \Lcs{pstCircleNode} or \Lcs{pstCircleRotNode}.
+The first \Lcs{pstCircleNode} requires an explicit parameter angle $\theta$ to calculate the point;
+but the second \Lcs{pstCircleRotNode} requires an implicit parameter \Lkeyword{RotAngle} to calculate the point,
+If you not set \Lkeyword{RotAngle}, the default value is $60^\circ$.
+
+The circle is defined by center $O$ and point $A$ on the circle or \Lkeyword{Radius} or \Lkeyword{Diameter} in parameter.
+
+\begin{BDef}
+\Lcs{pstCircleNode}\OptArgs\Largb{O}\Largb{A}\Largb{$\theta$}\Largb{X}\\
+\Lcs{pstCircleRotNode}\OptArgs\Largb{O}\Largb{A}\Largb{X}
+\end{BDef}
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](-1,-1)(4,4)
+\psset{dotscale=0.5}\psset{PointSymbol=*}\footnotesize
+\psset{Radius=\pstDistVal{2.0}}
+\pstGeonode[PosAngle=0](1.5,1.5){O}
+\pstCircleOA[linecolor=red]{O}{}
+\pstCircleRotNode[PosAngle=0,RotAngle=0]{O}{}{A}
+\pstCircleRotNode[PosAngle=60]{O}{}{B} % default 60 degree
+\pstCircleRotNode[PosAngle=90,RotAngle=90]{O}{}{C}
+\pstCircleRotNode[PosAngle=150,RotAngle=\pscalculate{3*360/7}]{O}{}{D}
+\pstCircleRotNode[PosAngle=180,RotAngle=180]{O}{}{E}
+\pstCircleRotNode[PosAngle=230,RotAngle=230]{O}{}{F}
+\pstCircleRotNode[PosAngle=270,RotAngle=270]{O}{}{G}
+\pstCircleNode[PosAngle=-45]{O}{}{-45}{H}
+\end{pspicture}
+\end{LTXexample}
+
+\vspace{10pt}
+
+A point can be positioned on a circle using its absolute abscissa or ordinate too.
+You can input $x_1$ or $y_1$ as any number(e.g, 2.0), or use \Lcs{pscalculate} or \Lcs{fpeval} to generate the value,
+or use \Lcs{pstAbscissa} and \Lcs{pstOrdinate} to get the abscissa and ordinate of any other node.
+
+\begin{BDef}
+\Lcs{pstCircleAbsNode}\OptArgs\Largb{O}\Largb{A}\Largb{$x_1$}\Largb{C}\Largb{D}\\
+\Lcs{pstCircleOrdNode}\OptArgs\Largb{O}\Largb{A}\Largb{$y_1$}\Largb{C}\Largb{D}
+\end{BDef}
+
+for example,
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](-1,-1)(4,4)
+\pstGeonode[PosAngle=60](1.5,1.5){O}
+\pstGeonode[PosAngle=-30](2.5,0){A}
+\pstCircleOA[linecolor=red]{O}{A}
+\pstCircleAbsNode[PosAngleA=-60,PosAngleB=60,PointSymbol=*]{O}{A}{1.0}{C}{D}
+\pstCircleOrdNode[PosAngleA=150,PosAngleB=30,PointSymbol=*]{O}{A}{1.0}{E}{F}
+\pstLineAB[linestyle=dashed,linecolor=gray!40,nodesep=-0.5]{C}{D}
+\pstLineAB[linestyle=dashed,linecolor=gray!40,nodesep=-0.5]{E}{F}
+\end{pspicture}
+\end{LTXexample}
+
+\vspace{10pt}
+
+A point can be positioned on a circle using its curved abscissa, that is,
+the arc length from a given node.
+
+\begin{BDef}
+\Lcs{pstCurvAbsNode}\OptArgs\Largb{O}\Largb{A}\Largb{B}\Largb{Abs}
+\end{BDef}
+
+\begin{sloppypar}
+Possible optional arguments are \Lkeyword{PointSymbol}, \Lkeyword{PosAngle},
+  \Lkeyword{PointName}, \Lkeyword{PointNameSep}, \Lkeyword{PtNameMath}, and \Lkeyword{CurvAbsNeg}.
+%
+The point \Argsans{$B$} is positioned on the circle of center
+\Argsans{$O$} crossing \Argsans{$A$}, with the curved abscissa
+\Argsans{Abs}. The origin is \Argsans{$A$} and the direction is
+anti-clockwise by default. The parameter \Lkeyword{CurvAbsNeg}
+\DefaultVal{false} can change this behavior.
+\end{sloppypar}
+
+If the parameter \Lkeyword{PosAngle} is not specified, the point label is put
+automatically in oirder to be alined with the circle center and the point.
+
+\begin{LTXexample}[width=5cm,pos=l]
+\begin{pspicture}[showgrid](-2.5,-2.5)(2.5,2.5)
+\pstGeonode{O}(2,0){A}
+\pstCircleOA{O}{A}
+\pstCurvAbsNode{O}{A}{M_1}{\pstDistVal{5}}
+\pstCurvAbsNode[CurvAbsNeg=true]%
+  {O}{A}{M_2}{\pstDistAB{A}{M_1}}
+\end{pspicture}
+\end{LTXexample}
+
+
+
 \subsection{Circle tangent}
 
 The macro \Lcs{pstCircleTangentLine} is used to draw a tangent line $AT$ from a point $A$ on the circle,
@@ -756,85 +1310,84 @@
 \end{pspicture}
 \end{LTXexample}
 
-\subsection{Curved abscissa}
+\subsection{Circle radical axis}
+If you want to draw the \texttt{Radical Axis} of two given circles, read the following sentenses.
+For given $\odot{O_1}$ with radius $r_1$ and $\odot{O_2}$ with radius $r_2$, and the center
+$O_1(x_1,y_1)$, $O_2(x_2,y_2)$, then any point $P(x,y)$ on the \texttt{Radical Axis} is satisfied:
+$$(x-x_1)^2+(y-y_1)^2-r_1^2=(x-x_2)^2+(y-y_2)^2-r_2^2$$
+It can be simplified to a equation of a line:
+$$2(x_2-x_1)x+2(y_2-y_1)y=(x_2^2+y_2^2-r_2^2)-(x_1^2+y_1^2-r_1^2)$$
+It is clear that the circles with same center have no radical axis,
+and the radical axis is perpendicular to the line of centers.
 
-A point can be positioned on a circle using its curved abscissa.
+We provide the macro \Lcs{pstCircleRadicalAxis} to draw the \texttt{Radical Axis} of two given circles.
+It can handler every position relations of circles such as separation, intersection and inclusion.
 
-
 \begin{BDef}
-\Lcs{pstCurvAbsNode}\OptArgs\Largb{O}\Largb{A}\Largb{B}\Largb{Abs}
+\Lcs{pstCircleRadicalAxis}\OptArgs\Largb{$O_1$}\Largb{A}\Largb{$O_2$}\Largb{B}\Largb{C}\Largb{D}
 \end{BDef}
 
-\begin{sloppypar}
-Possible optional arguments are \Lkeyword{PointSymbol}, \Lkeyword{PosAngle},
-  \Lkeyword{PointName}, \Lkeyword{PointNameSep}, \Lkeyword{PtNameMath}, and \Lkeyword{CurvAbsNeg}.
-%
-The point \Argsans{$B$} is positioned on the circle of center
-\Argsans{$O$} crossing \Argsans{$A$}, with the curved abscissa
-\Argsans{Abs}. The origin is \Argsans{$A$} and the direction is
-anti-clockwise by default. The parameter \Lkeyword{CurvAbsNeg}
-\DefaultVal{false} can change this behavior.
-\end{sloppypar}
+Both parameter $A$ and $B$ can be omitted and then to specify the each radius or
+diameter using the parameters \Lkeyword{RadiusA}, \Lkeyword{DiameterA}, and \Lkeyword{RadiusB}, \Lkeyword{DiameterB}.
+This macro create two new nodes $C$ and $D$ on the radical axis, you can find them in following examples.
 
-If the parameter \Lkeyword{PosAngle} is not specified, the point label is put
-automatically in oirder to be alined with the circle center and the point.
+When they are intersected, we can see the radical axis is the intersected chord line.
 
-\begin{LTXexample}[width=5cm,pos=l]
-\begin{pspicture}[showgrid](-2.5,-2.5)(2.5,2.5)
-\pstGeonode{O}(2,0){A}
-\pstCircleOA{O}{A}
-\pstCurvAbsNode{O}{A}{M_1}{\pstDistVal{5}}
-\pstCurvAbsNode[CurvAbsNeg=true]%
-  {O}{A}{M_2}{\pstDistAB{A}{M_1}}
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](-1,-1)(4,4)
+\psset{dotscale=0.5}\psset{PointSymbol=*}\footnotesize
+\def\ra{1.2}\def\rb{2.0}
+\pstGeonode[PosAngle=0](0,1){O1}(1.5,1.5){O2}
+\pstCircleOA[linecolor=red!50,Radius=\pstDistVal{\ra}]{O1}{}
+\pstCircleOA[linecolor=blue!50,Radius=\pstDistVal{\rb}]{O2}{}
+\pstCircleRadicalAxis[PosAngle={0,0},RadiusA=\pstDistVal{\ra},RadiusB=\pstDistVal{\rb},nodesep=-1,linecolor=brown]{O1}{}{O2}{}{A}{B}
 \end{pspicture}
 \end{LTXexample}
 
+When they are tangent, we can see the radical axis is the common tangent line.
 
-A point can be positioned on a circle using its absolute abscissa or ordinate too.
-You can input $x_1$ or $y_1$ as any number(e.g, 2.0), or use \Lcs{pscalculate} or \Lcs{fpeval} to generate the value,
-or use \Lcs{pstAbscissa} and \Lcs{pstOrdinate} to get the abscissa and ordinate of any other node.
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](-1,-1)(3,4)
+\psset{dotscale=0.5}\psset{PointSymbol=*}\footnotesize
+\def\ra{1.2}\def\rb{2.0}
+\pstGeonode[PosAngle=-90,PointName={O_1,O_2}](1,1){O1}(1,1.8){O2}
+\pstCircleOA[linecolor=red!50,Radius=\pstDistVal{\ra}]{O1}{}
+\pstCircleOA[linecolor=blue!50,Radius=\pstDistVal{\rb}]{O2}{}
+\pstCircleRadicalAxis[nodesep=-2,PosAngle={-90,-90},RadiusA=\pstDistVal{\ra},RadiusB=\pstDistVal{\rb}]{O1}{}{O2}{}{A}{B}
+\pstLineAB[linecolor=red,nodesep=-3]{A}{B}
+\end{pspicture}
+\end{LTXexample}
 
-\begin{BDef}
-\Lcs{pstCircleAbsNode}\OptArgs\Largb{O}\Largb{A}\Largb{$x_1$}\Largb{C}\Largb{C}\\
-\Lcs{pstCircleOrdNode}\OptArgs\Largb{O}\Largb{A}\Largb{$y_1$}\Largb{C}\Largb{C}
-\end{BDef}
+When one of them contains the other, the radical axis is out of the circles.
 
-for example,
 \begin{LTXexample}[width=6cm,pos=l]
-\begin{pspicture}[showgrid=true](-1,-1)(4,4)
-\pstGeonode[PosAngle=60](1.5,1.5){O}
-\pstGeonode[PosAngle=-30](2.5,0){A}
-\pstCircleOA[linecolor=red]{O}{A}
-\pstCircleAbsNode[PosAngleA=-60,PosAngleB=60,PointSymbol=*]{O}{A}{1.0}{C}{D}
-\pstCircleOrdNode[PosAngleA=150,PosAngleB=30,PointSymbol=*]{O}{A}{1.0}{E}{F}
-\pstLineAB[linestyle=dashed,linecolor=gray!40,nodesep=-0.5]{C}{D}
-\pstLineAB[linestyle=dashed,linecolor=gray!40,nodesep=-0.5]{E}{F}
+\begin{pspicture}[showgrid=true](-1,-2)(4,3)
+\psset{dotscale=0.5}\psset{PointSymbol=*}\footnotesize
+\def\ra{1.2}\def\rb{2.0}
+\pstGeonode[PosAngle=0](1.2,1){O1}(1.5,1.5){O2}
+\pstCircleOA[linecolor=red!50,Radius=\pstDistVal{\ra}]{O1}{}
+\pstCircleOA[linecolor=blue!50,Radius=\pstDistVal{\rb}]{O2}{}
+\pstCircleRadicalAxis[PosAngle={-90,90},RadiusA=\pstDistVal{\ra},RadiusB=\pstDistVal{\rb},nodesepA=-1,nodesepB=-3,linecolor=brown]{O1}{}{O2}{}{A}{B}
 \end{pspicture}
 \end{LTXexample}
 
-A point can be positioned on a circle using its rotation angle by macro \Lcs{pstCircleRotNode}.
-The rotation angle should be passed by the \Lkeyword{RotAngle} in the \texttt{Options}.
-The circle is defined by center $O$ and point $A$ on the circle or \Lkeyword{Radius} in parameter.
-If you not set \Lkeyword{RotAngle}, the default value is $60^\circ$.
+When they are separated, the radical axis is between of the circles.
 
-\begin{BDef}
-\Lcs{pstCircleRotNode}\OptArgs\Largb{O}\Largb{A}\Largb{X}
-\end{BDef}
-
 \begin{LTXexample}[width=6cm,pos=l]
-\begin{pspicture}[showgrid=true](-1,-1)(4,4)
+\begin{pspicture}[showgrid=true](-1,-2)(4,3)
 \psset{dotscale=0.5}\psset{PointSymbol=*}\footnotesize
-\psset{Radius=\pstDistVal{2.0}}
-\pstGeonode[PosAngle=0](1.5,1.5){O}
-\pstCircleOA[linecolor=red]{O}{}
-\pstCircleRotNode[PosAngle=0,RotAngle=0]{O}{}{A}
-\pstCircleRotNode[PosAngle=60]{O}{}{B} % default 60 degree
-\pstCircleRotNode[PosAngle=90,RotAngle=90]{O}{}{C}
-\pstCircleRotNode[PosAngle=150,RotAngle=\pscalculate{3*360/7}]{O}{}{D}
-\pstCircleRotNode[PosAngle=180,RotAngle=180]{O}{}{E}
-\pstCircleRotNode[PosAngle=230,RotAngle=230]{O}{}{F}
-\pstCircleRotNode[PosAngle=270,RotAngle=270]{O}{}{G}
-\pstCircleRotNode[PosAngle=-45,RotAngle=-45]{O}{}{H}
+\def\ra{1.2}\def\rb{2.0}
+\pstGeonode[PosAngle=0](-1,0){O1}(2.5,1.5){O2}
+\pstCircleOA[linecolor=red!50,Radius=\pstDistVal{\ra}]{O1}{}
+\pstCircleOA[linecolor=blue!50,Radius=\pstDistVal{\rb}]{O2}{}
+\pstCircleRadicalAxis[PosAngle={-90,90},RadiusA=\pstDistVal{\ra},RadiusB=\pstDistVal{\rb},nodesep=-1,linecolor=brown]{O1}{}{O2}{}{A}{B}
+\psset{linestyle=dashed,linecolor=gray!40}
+\pstCircleTangentNode[Radius=\pstDistVal{\ra},PosAngle={90,200}]{O1}{}{A}{P}{Q}
+\pstCircleTangentNode[Radius=\pstDistVal{\rb},PosAngle={10,100}]{O2}{}{A}{X}{Y}
+\pstCircleOA{A}{P}
+\pstCircleTangentNode[Radius=\pstDistVal{\ra},PosAngle={210,200}]{O1}{}{B}{I}{J}
+\pstCircleTangentNode[Radius=\pstDistVal{\rb},PosAngle={10,-10}]{O2}{}{B}{R}{S}
+\pstCircleOA{B}{I}
 \end{pspicture}
 \end{LTXexample}
 
@@ -873,6 +1426,8 @@
  \end{pspicture}
 \end{LTXexample}
 
+\clearpage
+
 \section{Conics}
 \subsection{Standard Ellipse}
 The Standard Ellipse $E$ with coordinate translation is defined by center $O(x_0,y_0)$,
@@ -902,7 +1457,7 @@
 \begin{LTXexample}[width=6cm,pos=l]
 \begin{pspicture}[showgrid=true](0,0)(4,4)
 \psset{dotscale=0.5}\psset{PointSymbol=*}\footnotesize
-\def\ra{2.4}\def\rb{0.8}\def\rot{56}
+\def\ra{2.4}\def\rb{0.8}
 \pstGeonode[PosAngle=-90,PointNameSep=0.2](2,2){O}
 %\psellipse[linecolor=red!60](O)(\ra,\rb)
 \pstEllipse[linecolor=red!60](O)(\ra,\rb)[0][120]
@@ -1226,8 +1781,8 @@
 \Lcs{pstGeneralEllipseDirectrixLine} to get the two directrix lines.
 
 \begin{BDef}
-\Lcs{pstGeneralEllipseFocusNode}\OptArgs\Largr{O}\Largr{$a,\,b$}\OptArg{$\theta$}\Largb{$t$}\Largb{A}\\
-\Lcs{pstGeneralEllipseDirectrixLine}\OptArgs\Largr{O}\Largr{$a,\,b$}\OptArg{$\theta$}\Largb{A}
+\Lcs{pstGeneralEllipseFocusNode}\OptArgs\Largr{O}\Largr{$a,\,b$}\OptArg{$\theta$}\Largb{$t$}\Largb{$F_1$}\Largb{$F_2$}\\
+\Lcs{pstGeneralEllipseDirectrixLine}\OptArgs\Largr{O}\Largr{$a,\,b$}\OptArg{$\theta$}\Largb{$L_x$}\Largb{$L_y$}\Largb{$R_x$}\Largb{$R_y$}
 \end{BDef}
 
 for example,
@@ -1303,8 +1858,6 @@
 \end{pspicture}
 \end{LTXexample}
 
-\clearpage
-
 \subsection{Standard Parabola}
 The Standard Parabola $P$ with coordinate translation is defined by vertex $O(x_0,y_0)$,
 the half of the focus chord axis $abs(p)$.
@@ -1434,7 +1987,7 @@
 \pstParabolaFocusNode[linecolor=red!40](O){\p}{F}
 \pstLine[linecolor=gray!40,nodesepA=-0.8,nodesepB=-0.8]{0,2}{4,1}
 \pstParabolaLineInter[linecolor=gray!40,PosAngle={120,210}](O){\p}{0,2}{4,1}{P}{Q}
-% if you know focus F, but don't known directrix line
+% if you know focus F, but don't know directrix line
 \pstParabolaPolarNode[linecolor=purple!40,PosAngle=-90](O){\p}(F){P}{Q}{T}
 \end{pspicture}
 \end{LTXexample}
@@ -2204,7 +2757,7 @@
 We use the following theorem to find the tangent points $A$ and $B$ of $T$:
 \begin{theorem}\label{HyperbolaTangentPointTheorem}
 Let $T$ is a point out of the hyperbola, for any two chords $TPQ$ and $TRS$ of the hyperbola, suppose $PR$ and $QS$ intersect at $X$,
-$RQ$ and $PS$ intersect at $Y$, then the intersection point $A$ and $B$ of $XY$ and the hyperbola are the tangent points from $T$.
+$RQ$ and $PS$ intersect at $Y$, then the intersection points $A$ and $B$ of $XY$ and the hyperbola are the tangent points from $T$.
 \end{theorem}
 
 \begin{LTXexample}[width=6cm,pos=l]
@@ -2356,7 +2909,7 @@
 \Lcs{pstIHyperbolaTangentNode}\OptArgs\Largr{O}\Largr{$a,\,b$}\Largb{$T$}\Largb{$A$}\Largb{$B$}
 \end{BDef}
 
-We also use the following theorem \ref{HyperbolaTangentPointTheorem} to find the tangent points $A$ and $B$ of $T$.
+We also use the theorem \ref{HyperbolaTangentPointTheorem} to find the tangent points $A$ and $B$ of $T$.
 
 \begin{LTXexample}[width=6cm,pos=l]
 \begin{pspicture}[showgrid=true](-2,-1)(4,3)
@@ -2539,7 +3092,7 @@
 \Lcs{pstGeneralHyperbolaTangentNode}\OptArgs\Largr{O}\Largr{$a,\,b$}\OptArg{$\theta$}\Largb{$T$}\Largb{$A$}\Largb{$B$}
 \end{BDef}
 
-We also use the following theorem \ref{HyperbolaTangentPointTheorem} to find the tangent points $A$ and $B$ of $T$.
+We also use the theorem \ref{HyperbolaTangentPointTheorem} to find the tangent points $A$ and $B$ of $T$.
 
 \begin{LTXexample}[width=6cm,pos=l]
 \begin{pspicture}[showgrid=true](-2,-1)(4,3)
@@ -2725,7 +3278,7 @@
 \Lcs{pstGeneralIHyperbolaTangentNode}\OptArgs\Largr{O}\Largr{$a,\,b$}\OptArg{$\theta$}\Largb{$T$}\Largb{$A$}\Largb{$B$}
 \end{BDef}
 
-We also use the following theorem \ref{HyperbolaTangentPointTheorem} to find the tangent points $A$ and $B$ of $T$.
+We also use the theorem \ref{HyperbolaTangentPointTheorem} to find the tangent points $A$ and $B$ of $T$.
 
 \begin{LTXexample}[width=6cm,pos=l]
 \begin{pspicture}[showgrid=true](-2,-1)(4,3)
@@ -3204,9 +3757,9 @@
 The circle is specified with its center and either a point of its
 circumference or with a radius specified with parameter \Lkeyword{radius}
 or its diameter specified with parameter \Lkeyword{Diameter}. These two
-parameters can be modify by coefficient \Lkeyword{DistCoef}.
+parameters can be specified by macros \Lcs{pstDist},\Lcs{pstDistMul},\Lcs{pstDistAdd},
+\Lcs{pstDistSub} etc.
 
-
 The position of the wo points is such that the vectors $\vec{AB}$ abd
 $\vec{M_1M_2}$ are in the same direction. Thus, if the points
 definig the line are switch, then the resulting points will be also
@@ -3222,9 +3775,9 @@
 \pstCircleOA[linecolor=red]{O}{A}
 \pstInterLC[PosAngle=-80]{C}{B}{O}{A}{D}{E}
 \pstInterLC[PosAngleB=60, Radius=\pstDistAB{O}{D}]{I}{C}{O}{}{F}{G}
-\pstInterLC[PosAngleB=180,DistCoef=1.3,Diameter=\pstDistAB{O}{D}]
+\pstInterLC[PosAngleB=180,Diameter=\pstDistMul{O}{D}{1.3}]
   {I}{B}{O}{}{H}{J}
-\pstCircleOA[linecolor=red,DistCoef=1.3,Diameter=\pstDistAB{O}{D}]{O}{}
+\pstCircleOA[linecolor=red,Diameter=\pstDistMul{O}{D}{1.3}]{O}{}
 \psset{nodesep=-1}
 \pstLineAB[linecolor=green]{E}{C}
 \pstLineAB[linecolor=cyan]{I}{C}
@@ -3269,21 +3822,27 @@
 exists the parameters \Lkeyword{RadiusA}, \Lkeyword{RadiusB},
 \Lkeyword{DiameterA} and \Lkeyword{DiameterB}.
 
+The macro \Lcs{pstInterCC} will not display the intersections as default, if you want to display
+the label or symbol of the intersections, you must setup the parameters \Lkeyword{PosAngleA}
+and \Lkeyword{PosAngleB} to change the default behavior.
+
 \begin{LTXexample}
 \begin{pspicture}[showgrid](-3,-4)(7,3)
 \pstGeonode[PointName={\Omega,O}](3,-1){Omega}(1,-1){O}
 \pstGeonode[PointSymbol=square, PosAngle={-90,90}](0,3){A}(2,2){B}
 \psset{PointSymbol=o}
-\pstCircleOA[linecolor=red, DistCoef=1 3 10 div add, Radius=\pstDistAB{A}{B}]{O}{}
+\pstCircleOA[linecolor=red, Radius=\pstDistMul{A}{B}{1 3 10 div add}]{O}{}
 \pstCircleOA[linecolor=Orange, Diameter=\pstDistAB{A}{B}]{O}{}
 \pstCircleOA[linecolor=Violet, Radius=\pstDistAB{A}{B}]{Omega}{}
 \pstCircleOA[linecolor=Purple, Diameter=\pstDistAB{A}{B}]{Omega}{}
-\pstInterCC[DistCoef=1 3 10 div add, RadiusA=\pstDistAB{A}{B},
-            DistCoef=none, RadiusB=\pstDistAB{A}{B}]{O}{}{Omega}{}{D}{E}
-\pstInterCC[DiameterA=\pstDistAB{A}{B}, RadiusB=\pstDistAB{A}{B}]{O}{}{Omega}{}{F}{G}
-\pstInterCC[DistCoef=1 3 10 div add, RadiusA=\pstDistAB{A}{B},
-            DistCoef=none, DiameterB=\pstDistAB{A}{B}]{O}{}{Omega}{}{H}{I}
-\pstInterCC[DiameterA=\pstDistAB{A}{B}, DiameterB=\pstDistAB{A}{B}]{O}{}{Omega}{}{J}{K}
+\pstInterCC[RadiusA=\pstDistMul{A}{B}{1 3 10 div add},
+            RadiusB=\pstDistAB{A}{B}]{O}{}{Omega}{}{D}{E}
+\pstInterCC[DiameterA=\pstDistAB{A}{B}, RadiusB=\pstDistAB{A}{B},
+            PosAngleA=90,PosAngleB=-90]{O}{}{Omega}{}{F}{G}
+\pstInterCC[RadiusA=\pstDistMul{A}{B}{1 3 10 div add}, DiameterB=\pstDistAB{A}{B},
+            PosAngleA=90,PosAngleB=-90]{O}{}{Omega}{}{H}{I}
+\pstInterCC[DiameterA=\pstDistAB{A}{B}, DiameterB=\pstDistAB{A}{B},
+            PosAngleA=90,PosAngleB=-90]{O}{}{Omega}{}{J}{K}
 \end{pspicture}
 \end{LTXexample}
 

Modified: trunk/Master/texmf-dist/tex/generic/pst-eucl/pst-eucl.tex
===================================================================
--- trunk/Master/texmf-dist/tex/generic/pst-eucl/pst-eucl.tex	2019-10-28 20:55:00 UTC (rev 52549)
+++ trunk/Master/texmf-dist/tex/generic/pst-eucl/pst-eucl.tex	2019-10-28 20:55:19 UTC (rev 52550)
@@ -20,8 +20,8 @@
 \csname PSTEuclideLoaded\endcsname
 \let\PSTEuclideLoaded\endinput
 %
-\def\fileversion{1.66}
-\def\filedate{2019/10/20}
+\def\fileversion{1.67}
+\def\filedate{2019/10/28}
 %%
 \message{`PST-Euclide v\fileversion, \filedate\space (dr,hv)}%
 %% prologue for postcript
@@ -587,7 +587,6 @@
     \def\pst at circle@node{#3}
     \@ifnextchar[\pstCircleOA at i{\pstCircleOA at i[0][360]}}%
 \def\pstCircleOA at i[#1][#2]{%
-  \rput(\pst at circle@center){%
     \begin at OpenObj
       \def\pst at linetype{4}%
       \addto at pscode{%
@@ -605,7 +604,6 @@
         #1 #2 arc}%
       \showpointsfalse
     \end at OpenObj
-  }%
   \endgroup%
 }%
 %% #2 #3 -> 2 nodes defining a diameter of the circle
@@ -618,19 +616,17 @@
     \@ifnextchar[\pstCircleAB at i{\pstCircleAB at i[0][360]}}%
 \def\pstCircleAB at i[#1][#2]{%
     \Pst at MiddleAB[PointSymbol=none, PointName=none]{\pst at circle@diameter at B}{\pst at circle@diameter at A}{PST at CIRCLE@MAB}
-    \rput(\pst at circle@diameter at A){%
-      \begin at OpenObj
-        \def\pst at linetype{4}%
-        \addto at pscode{%
-          tx at NodeDict begin
-            tx at NodeDict /N at PST@CIRCLE at MAB load GetCenter
-          end
-          2 copy
-          tx at EcldDict begin /N@\pst at circle@diameter at B\space GetNode ABDist end
-          \psk at dimen\space CLW mul sub #1 #2 arc}%
-        \showpointsfalse
-      \end at OpenObj
-    }%
+    \begin at OpenObj
+      \def\pst at linetype{4}%
+      \addto at pscode{%
+        tx at NodeDict begin
+          tx at NodeDict /N at PST@CIRCLE at MAB load GetCenter
+        end
+        2 copy
+        tx at EcldDict begin /N@\pst at circle@diameter at B\space GetNode ABDist end
+        \psk at dimen\space CLW mul sub #1 #2 arc}%
+      \showpointsfalse
+    \end at OpenObj
   \endgroup%
 }%
 %% #2 #3 #4 -> 3 nodes defining the center and two points on the circle
@@ -1673,25 +1669,100 @@
 }%
 %
 %% Distance between two points
-\def\pstDistAB#1#2{%
+\def\pstDist#1#2{%
   tx at EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist end
+}
+\def\pstDistAB#1#2{% Obsoleted
+  tx at EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist end
   \ifx\psk at DistCoef\@none\else
     \psk at DistCoef\space mul
   \fi
 }
+%
+% \pstDistMul{A}{B}{\lambda} -> \lambda * |AB|
+%% Distance |AB| multiply with coefficient \lambda
+\def\pstDistMul#1#2#3{%
+  tx at EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist #3 mul end
+}
+%
+% \pstDistAdd{A}{B}{C}{D} -> |AB| + |CD|
+%% Distance sum of two segments AB and CD
+\def\pstDistAdd#1#2#3#4{%
+  tx at EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist
+  /N@#3 GetNode /N@#4 GetNode ABDist add end
+}
+%
+% \pstDistAddVal{A}{B}{coef1}{val} -> |AB| * coef1 + val
+\def\pstDistAddVal#1#2#3#4{%
+  tx at EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist
+  #3 mul #4 add end
+}
+%
+% \pstDistAddCoef{A}{B}{coef1}{C}{D}{coef2} -> |AB| * coef1 + |CD| * coef2
+\def\pstDistAddCoef#1#2#3#4#5#6{%
+  tx at EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist
+  #3 mul /N@#4 GetNode /N@#5 GetNode ABDist #6 mul add end
+}
+%
+%% Distance difference between two segments AB and CD
+\def\pstDistSub#1#2#3#4{%
+  tx at EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist
+  /N@#3 GetNode /N@#4 GetNode ABDist sub abs end
+}
+%
+% \pstDistSubVal{A}{B}{coef1}{val} -> |AB| * coef1 - val
+\def\pstDistSubVal#1#2#3#4{%
+  tx at EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist
+  #3 mul #4 sub abs end
+}
+%
+% \pstDistSubCoef{A}{B}{coef1}{C}{D}{coef2} -> |AB| * coef1 - |CD| * coef2
+\def\pstDistSubCoef#1#2#3#4#5#6{%
+  tx at EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist
+  #3 mul /N@#4 GetNode /N@#5 GetNode ABDist #6 mul sub abs end
+}
+%
+%% Distance ratio of two segments AB and CD
+\def\pstDistDiv#1#2#3#4{%
+  tx at EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist
+  /N@#3 GetNode /N@#4 GetNode ABDist div end
+}
+%
 %% Distance specified with a number
-\def\pstDistVal#1{%
- #1 \pst at number\psxunit mul
+\def\pstDistConst#1{#1 \pst at number\psxunit mul\space}
+\def\pstDistVal#1{% Obsoleted
+  #1 \pst at number\psxunit mul
   \ifx\psk at DistCoef\@none\else
     \psk at DistCoef\space mul
   \fi
 }
-\def\pstDistCalc#1{%
+\def\pstDistExpr#1{\pscalculate{#1} \pst at number\psxunit mul\space}
+\def\pstDistCalc#1{% Obsoleted
   \pscalculate{#1} \pst at number\psxunit mul
   \ifx\psk at DistCoef\@none\else
     \psk at DistCoef\space mul
   \fi
 }
+%
+\def\pstDistCoef#1{#1 \ifx\psk at DistCoef\@none\else\psk at DistCoef\space mul\space\fi}
+\def\pstUserDist#1{#1 \pst at number\psxunit div\space}
+\def\pstScreenDist#1{#1 \pst at number\psxunit mul\space}
+%
+% \pstDistABC{A}{B}{C} -> return the distance from C to AB.
+\def\pstDistABC#1#2#3{%
+  tx at EcldDict begin /N@#1 GetNode /N@#2 GetNode /N@#3 GetNode
+  % x1 y1 x2 y2 x3 y3
+  5 index 5 index 5 index 5 index ABDist % |AB|
+  6 index 6 index 4 index 4 index ABDist % |AC|
+  5 index 5 index 5 index 5 index ABDist % |BC|
+  2 index 2 index add 1 index add 2 div % p
+  0 index 4 index sub % p-|AB|
+  1 index 4 index sub % p-|AC|
+  2 index 4 index sub % p-|BC|
+  mul mul mul sqrt 3 index div 2 mul
+  10 1 roll pop pop pop pop pop pop pop pop pop end
+}
+%
 %% angle defined by three points
 \def\pstAngleAOB#1#2#3{%
 %  \pstGeonode[PointName=none,PointSymbol=none](#1){temp at 1}(#2){temp at 2}(#3){temp at 3}%
@@ -1837,6 +1908,128 @@
   \endgroup%
 }%
 %
+%% \pstProportionNode[Options]{A}{B}{lambda}{C}{C'}
+%% Create node C and C' which satisified the definite proportion function |AC|:|BC|=lamba,
+%% where lambda is positive, C is inside segment AB, and C' is outside segment AB.
+%% According to the definite proportion equation, we have
+%% $$x_{C}=\dfrac{x_{A}+\lambda{}x_{B}}{1+\lambda},y_{C}=\dfrac{y_{A}+\lambda{}y_{B}}{1+\lambda}$$
+%% and
+%% $$x_{C'}=\dfrac{x_{A}-\lambda{}x_{B}}{1-\lambda},y_{C'}=\dfrac{y_{A}+-lambda{}y_{B}}{1-\lambda}$$
+%% Parameters:
+%% #1 -> options
+%% #2 -> the given segment start node A
+%% #3 -> the given segment end node B
+%% #4 -> the definite proportion $\lambda$
+%% #5 -> the target node C inside segment AB
+%% #6 -> the target node C' outside segment AB
+\def\pstProportionNode{\@ifnextchar[\Pst at ProportionNode{\Pst at ProportionNode[]}}
+\def\Pst at ProportionNode[#1]{%
+  \begingroup
+    \@InitListMng %
+    \psset{#1}%
+    \Pst at ProportionNode@i}
+\def\Pst at ProportionNode@i#1#2#3#4#5{%
+    \pst at getcoor{#1}\pst at tempA%
+    \pst at getcoor{#2}\pst at tempB%
+    \pnode(!
+      \pst at tempA \tx at UserCoor % x1,y1
+      \pst at tempB \tx at UserCoor % x2,y2
+      #3 abs % \lambda
+      4 index 1 index 4 index mul add 1 index 1 add div % (x1+\lambda*x2)/(1+\lambda)
+      4 index 2 index 4 index mul add 2 index 1 add div % (y1+\lambda*y2)/(1+\lambda)
+      7 2 roll pop pop pop pop pop
+    ){#4}%
+    \pnode(!
+      \pst at tempA \tx at UserCoor % x1,y1
+      \pst at tempB \tx at UserCoor % x2,y2
+      #3 abs % \lambda
+      dup 1 sub abs 1E-5 lt {
+        pop pop pop pop pop 0 0
+      } {
+        4 index 1 index 4 index mul sub 1 index 1 exch sub div % (x1-\lambda*x2)/(1-\lambda)
+        4 index 2 index 4 index mul sub 2 index 1 exch sub div % (y1-\lambda*y2)/(1-\lambda)
+        7 2 roll pop pop pop pop pop
+      } ifelse
+    ){#5}%
+    \Pst at ManageParamList{#4}%
+    \Pst at ManageParamList{#5}%
+  \endgroup%
+}%
+%
+%% \pstFourthHarmonicNode[Options]{A}{B}{C}{D}
+%% Create node D such that the four collinear points A,B,C,D form harmonic conjugate points,
+%% that is, $(AB,CD)=\dfrac{AC}{BC}:\dfrac{AD}{BD}=-1$.
+%% Parameters:
+%% #1 -> options
+%% #2 -> the given collinear base node A
+%% #3 -> the given collinear base node B
+%% #4 -> the given collinear proportion node C
+%% #5 -> the output proportion node D
+\def\pstFourthHarmonicNode{\@ifnextchar[\Pst at FourthHarmonicNode{\Pst at FourthHarmonicNode[]}}
+\def\Pst at FourthHarmonicNode[#1]{%
+  \begingroup
+    \@InitListMng %
+    \psset{#1}%
+    \Pst at FourthHarmonicNode@i}
+\def\Pst at FourthHarmonicNode@i#1#2#3#4{%
+    \pst at getcoor{#1}\pst at tempA%
+    \pst at getcoor{#2}\pst at tempB%
+    \pst at getcoor{#3}\pst at tempC%
+    \pnode(!
+      \pst at tempA \tx at UserCoor % x1,y1
+      \pst at tempB \tx at UserCoor % x2,y2
+      \pst at tempC \tx at UserCoor % x3,y3
+      5 index 4 index sub abs 1E-5 lt { % if x1=x2
+        5 index 2 index sub abs 1E-5 lt { % if x1=x3
+          4 index 1 index mul 3 index 2 index mul add 5 index 4 index mul 2 mul sub % y1y3+y2y3-2y1y2
+          1 index 2 mul 6 index sub 4 index sub % 2y3-y1-y2
+          dup abs 1E-5 lt {
+            pop pop pop pop pop pop pop pop
+            0 0
+          } {
+            div % y=\dfrac{y1y3+y2y3-2y1y2}{2y3-y1-y2}
+            2 index exch % x=x3
+            8 2 roll pop pop pop pop pop pop
+          } ifelse
+        } {
+          % C is not collinear with AB.
+          pop pop pop pop pop pop
+          0 0
+        } ifelse
+      } {
+        5 index 2 index sub abs 1E-5 lt { % if x1=x3
+          pop pop pop pop pop pop 0 0
+        } {
+          2 index 5 index sub 4 index 7 index sub div % k(AB)=\dfrac{y2-y1}{x2-x1}
+          4 index 6 index mul 7 index 5 index mul sub 5 index 8 index sub div % d(AB)=\dfrac{x2y1-x1y2}{x2-x1}
+          2 index 7 index sub 4 index 9 index sub div % k(AC)=\dfrac{y3-y1}{x3-x1}
+          4 index 8 index mul 9 index 5 index mul sub 5 index 10 index sub div % d(AC)=\dfrac{x3y1-x1y3}{x3-x1}
+          3 index 2 index sub abs 1E-5 lt 3 index 2 index sub abs 1E-5 lt and { % k(AB)=k(AC) and d(AB)=d(AC)
+            % x=\dfrac{x1x3+x2x3-2x1x2}{2x3-x1-x2}; y=k(AC)x+d(AC)
+            9 index 6 index mul 8 index 7 index mul add 10 index 9 index mul 2 mul sub
+            6 index 2 mul 11 index sub 9 index sub
+            dup abs 1E-5 lt {
+              pop pop pop pop pop pop
+              pop pop pop pop pop pop
+              0 0
+            } {
+              div
+              2 index 1 index mul 2 index add
+              12 2 roll pop pop pop pop pop
+              pop pop pop pop pop
+            } ifelse
+          } {
+            % C is not collinear with AB.
+            pop pop pop pop pop pop pop pop
+            0 0
+          } ifelse
+        } ifelse
+      } ifelse
+    ){#4}%
+    \Pst at ManageParamList{#4}%
+  \endgroup%
+}%
+%
 %% \pstLine[Options]{node}{node}
 %% \pstLine[Options]{node}(coor)
 %% \pstLine[Options](coor){node}
@@ -1960,6 +2153,184 @@
   \endgroup%
 }%
 %
+%% \pstLocateAB[Options]{A}{B}{distance}{C}
+%% Locate node C on segment AB such that |AC|=distance, then create node C.
+%% Note that locate C on BA will get the node C in the reverse order.
+%% Parameters:
+%% #1 -> options
+%% #2 -> the given segment start node A
+%% #3 -> the given segment end node B
+%% #4 -> the specified length in screen coordinate
+%% #5 -> the target node C
+\def\pstLocateAB{\@ifnextchar[\Pst at LocateAB{\Pst at LocateAB[]}}
+\def\Pst at LocateAB[#1]{%
+  \begingroup
+    \psset{#1}%
+    \Pst at LocateAB@i}
+\def\Pst at LocateAB@i#1#2#3#4{%
+    \pst at getcoor{#1}\pst at tempA%
+    \pst at getcoor{#2}\pst at tempB%
+    \pnode(!
+      \pst at tempA \tx at UserCoor % x1,y1
+      \pst at tempB \tx at UserCoor % x2,y2
+      #3 abs \pst at number\psxunit div % User distance
+      4 index 3 index sub abs 1E-5 lt { % if x1=x2
+        3 index 2 index lt { % if y1 < y2
+          3 index 1 index add % y1 + l
+        } {
+          3 index 1 index sub % y1 - l
+        } ifelse
+        3 index exch
+        7 2 roll pop pop pop pop pop
+      } {
+        1 index 4 index sub 3 index 6 index sub div % k = (y2-y1)/(x2-x1)
+        1 index 1 index dup mul 1 add sqrt div % l/sqrt(k^2+1)
+        4 index 7 index lt { % if x2<x1
+          6 index exch sub % x1 - l/sqrt(k^2+1)
+        } {
+          6 index add % x1 + l/sqrt(k^2+1)
+        } ifelse
+        3 index 1 index 6 index sub 3 index mul add % y = y2+(x-x2)k
+        8 2 roll pop pop pop pop pop pop
+      } ifelse
+    ){#4}%
+    \Pst at geonodelabel{#4}%
+  \endgroup%
+}%
+%
+%% \pstLabelAB[Options]{A}{B}{label}
+%% Print the label for segment AB.
+%% Options:
+%% - linestyle: the line style to control the ruler bar
+%% - arrows: the line arrows to control the ruler bar
+%% - offset: the seperation between label and segment
+%% - nrot: the rotation of the label
+%% - npos: the proportion of the label
+\def\pstLabelAB{\@ifnextchar[\Pst at LabelAB{\Pst at LabelAB[]}}
+\def\Pst at LabelAB[#1]#2#3#4{%
+  \begingroup
+    \psset{linestyle=none} % default not show the rule bar.
+    \psset{offset=10pt} % default offset is 10pt
+    \psset{nrot=:U} % default rotation is :U
+    \psset{npos=0.5} % default label proportion from A to B is 0.5
+    \psset{#1}\ncline{#2}{#3}\ncput*{#4}
+  \endgroup%
+}%
+%% \pstExtendAB[Options]{A}{B}{distance}{C}
+%% Extend AB to C such that |BC|=distance, then create node C.
+%% Note that extend BA to C will get the node C in the reverse order.
+%% Parameters:
+%% #1 -> options
+%% #2 -> the given segment start node A
+%% #3 -> the given segment end node B
+%% #4 -> the specified length in screen coordinate
+%% #5 -> the target node C
+\def\pstExtendAB{\@ifnextchar[\Pst at ExtendAB{\Pst at ExtendAB[]}}
+\def\Pst at ExtendAB[#1]{%
+  \begingroup
+    \psset{#1}%
+    \Pst at ExtendAB@i}
+\def\Pst at ExtendAB@i#1#2#3#4{%
+    \pst at getcoor{#1}\pst at tempA%
+    \pst at getcoor{#2}\pst at tempB%
+    \pnode(!
+      \pst at tempA \tx at UserCoor % x1,y1
+      \pst at tempB \tx at UserCoor % x2,y2
+      #3 abs \pst at number\psxunit div % User distance
+      4 index 3 index sub abs 1E-5 lt { % if x1=x2
+        3 index 2 index lt { % if y1 < y2
+          1 index 1 index add % y2 + l
+        } {
+          1 index 1 index sub % y2 - l
+        } ifelse
+        3 index exch
+        7 2 roll pop pop pop pop pop
+      } {
+        1 index 4 index sub 3 index 6 index sub div % k = (y2-y1)/(x2-x1)
+        1 index 1 index dup mul 1 add sqrt div % l/sqrt(k^2+1)
+        4 index 7 index lt { % if x2<x1
+          4 index exch sub % x2 - l/sqrt(k^2+1)
+        } {
+          4 index add % x2 + l/sqrt(k^2+1)
+        } ifelse
+        3 index 1 index 6 index sub 3 index mul add % y = y2+(x-x2)k
+        8 2 roll pop pop pop pop pop pop
+      } ifelse
+    ){#4}%
+    \Pst at geonodelabel{#4}%
+  \endgroup%
+}%
+%
+%% \pstInversion[Options]{O}{A}{C}{C'}
+%% Find the inversion point $C'$ of $C$ such that $|OC|*|OC'|=|OA|^2$, then create node $C'$.
+%% We call $O$ as the inversion center, and |OA| as the inversion radius.
+%% Parameters:
+%% #1 -> options
+%% #2 -> the inversion center O
+%% #3 -> the inversion radius OA, or the specified Radius/Diameter if empty
+%% #4 -> the initial node C
+%% #5 -> the target node C'
+\def\pstInversion{\@ifnextchar[\Pst at Inversion{\Pst at Inversion[]}}
+\def\Pst at Inversion[#1]{%
+  \begingroup
+    \psset{#1}%
+    \Pst at Inversion@i}
+\def\Pst at Inversion@i#1#2#3#4{%
+    \pstLocateAB{#1}{#3}{%
+      tx at EcldDict begin /N@#1 GetNode /N@#3 GetNode ABDist end % |OC|
+      % use Radius or Diameter to get the inversion radius.
+      \ifx\psk at Radius\@none
+        \ifx\psk at Diameter\@none
+          tx at EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist end
+        \else
+          \psk at Diameter\space 2 div
+        \fi
+      \else
+        \psk at Radius\space
+      \fi
+      dup mul exch div % |OA|^2/|OC|
+    }{#4}
+  \endgroup%
+}%
+%
+%% \pstGeometricMean[Options]{A}{B}{l1}{l2}{C}
+%% Find the point $C$ on segment AB such that $|AC|^2=l_1*l_2$, then create node $C$.
+%% Parameters:
+%% #1 -> options
+%% #2 -> the first node A on the given segment
+%% #3 -> the second node B on the given segment
+%% #4 -> the given segment length l1
+%% #5 -> the given segment length l2
+%% #6 -> the target node C
+\def\pstGeometricMean{\@ifnextchar[\Pst at GeometricMean{\Pst at GeometricMean[]}}
+\def\Pst at GeometricMean[#1]{%
+  \begingroup
+    \psset{#1}%
+    \Pst at GeometricMean@i}
+\def\Pst at GeometricMean@i#1#2#3#4#5{%
+    \pstLocateAB{#1}{#2}{#3 #4 mul sqrt}{#5}
+  \endgroup%
+}%
+%
+%% \pstHarmonicMean[Options]{A}{B}{l1}{l2}{C}
+%% Find the point $C$ on segment AB such that $1/|AC|=(1/l_1+1/l_2)/2$, then create node $C$.
+%% Parameters:
+%% #1 -> options
+%% #2 -> the first node A on the given segment
+%% #3 -> the second node B on the given segment
+%% #4 -> the given segment length l1
+%% #5 -> the given segment length l2
+%% #6 -> the target node C
+\def\pstHarmonicMean{\@ifnextchar[\Pst at HarmonicMean{\Pst at HarmonicMean[]}}
+\def\Pst at HarmonicMean[#1]{%
+  \begingroup
+    \psset{#1}%
+    \Pst at HarmonicMean@i}
+\def\Pst at HarmonicMean@i#1#2#3#4#5{%
+    \pstLocateAB{#1}{#2}{#3 #4 2 copy mul 3 1 roll add div 2 mul}{#5}
+  \endgroup%
+}%
+%
 %% \pstCircleAbsNode[Options]{O}{A}{$x_0$}{C}{D}
 %% Create the new nodes C and D on the Circle O whose abscissas are the given value $x_0$.
 %% The circle O is defined by center O and point A on the circle or Radius in parameter.
@@ -2006,6 +2377,40 @@
   \endgroup%
 }%
 %
+%% \pstCircleNode[Options]{O}{A}{anglge}{X}
+%% Create a new node X on the Circle O whose angle is the given value.
+%% The circle O is defined by center O and point A on the circle or Radius in parameter.
+%% Parameters:
+%% #1 -> options
+%% #2 -> [input] the circle center O
+%% #3 -> [input] the circle point A or empty with Radius parameter
+%% #4 -> [input] the input angle value
+%% #4 -> [output] the target node name
+\def\pstCircleNode{\@ifnextchar[\Pst at CircleNode{\Pst at CircleNode[]}}
+\def\Pst at CircleNode[#1]{%
+  \begingroup
+    \psset{#1}%
+    \Pst at CircleNode@i}
+\def\Pst at CircleNode@i#1#2#3#4{%
+  \pnode(!
+    tx at EcldDict begin
+      /N@#1 GetNode
+      \ifx\psk at Radius\@none
+        \ifx\psk at Diameter\@none
+          2 copy /N@#2 GetNode ABDist
+        \else\psk at Diameter 2 div
+        \fi
+      \else\psk at Radius\space
+      \fi
+    end
+    #3 dup sin exch cos
+    2 index mul 4 index add \pst at number\psxunit\space div %
+    5 1 roll mul add \pst at number\psyunit\space div exch pop%
+  ){#4}%
+  \Pst at geonodelabel{#4}%
+  \endgroup%
+}%
+%
 %% \pstCircleRotNode[Options]{O}{A}{X}
 %% Create a new node X on the Circle O whose RotAngle is the given value.
 %% The circle O is defined by center O and point A on the circle or Radius in parameter.
@@ -2032,7 +2437,7 @@
       \else\psk at Radius\space
       \fi
     end
-    \psk at RotAngle\space sin \psk at RotAngle\space cos %
+    \psk at RotAngle\space dup sin exch cos %
     2 index mul 4 index add \pst at number\psxunit\space div %
     5 1 roll mul add \pst at number\psyunit\space div exch pop%
   ){#3}%
@@ -2181,18 +2586,21 @@
 %% The circle B(O1) is defined by center O2 and point B on the circle or RadiusB/DiameterB in parameter.
 %% Parameters:
 %% #1 -> options
-%% #2 -> [input] the circle center O
-%% #3 -> [input] the circle point A or empty with Radius parameter
-%% #4 -> [input] the node name T out of circle
-%% #5 -> [output] the first target name on the circle
-%% #6 -> [output] the second target name on the circle
+%% #2 -> [input] the first circle center O1
+%% #3 -> [input] the first circle point A or empty with RadiusA/DiameterA parameter
+%% #4 -> [input] the second circle center O2
+%% #5 -> [input] the second circle point B or empty with RadiusB/DiameterB parameter
+%% #6 -> [output] the first node name T1 lies on circle A(O1)
+%% #7 -> [output] the second node name T2 lies on circle A(O1)
+%% #8 -> [output] the first node name T3 lies on circle B(O2)
+%% #9 -> [output] the second node name T4 lies on circle B(O2)
 \def\pstCircleExternalCommonTangent{\@ifnextchar[\Pst at CircleExternalCommonTangent{\Pst at CircleExternalCommonTangent[]}}
 \def\Pst at CircleExternalCommonTangent[#1]{%
   \begingroup
     \@InitListMng %
     \psset{#1}%
-    \Pst at CircleExternCommonTangent@i}
-\def\Pst at CircleExternCommonTangent@i#1#2#3#4#5#6#7#8{%
+    \Pst at CircleExternalCommonTangent@i}
+\def\Pst at CircleExternalCommonTangent@i#1#2#3#4#5#6#7#8{%
     % use edef to save the second Radius or Diameter.
     \edef\pst at RadiusB@temp{\psk at RadiusB}
     \edef\pst at DiameterB@temp{\psk at DiameterB}
@@ -2262,11 +2670,14 @@
 %% The circle B(O1) is defined by center O2 and point B on the circle or RadiusB/DiameterB in parameter.
 %% Parameters:
 %% #1 -> options
-%% #2 -> [input] the circle center O
-%% #3 -> [input] the circle point A or empty with Radius parameter
-%% #4 -> [input] the node name T out of circle
-%% #5 -> [output] the first target name on the circle
-%% #6 -> [output] the second target name on the circle
+%% #2 -> [input] the first circle center O1
+%% #3 -> [input] the first circle point A or empty with RadiusA/DiameterA parameter
+%% #4 -> [input] the second circle center O2
+%% #5 -> [input] the second circle point B or empty with RadiusB/DiameterB parameter
+%% #6 -> [output] the first node name T1 lies on circle A(O1)
+%% #7 -> [output] the second node name T2 lies on circle A(O1)
+%% #8 -> [output] the first node name T3 lies on circle B(O2)
+%% #9 -> [output] the second node name T4 lies on circle B(O2)
 \def\pstCircleInternalCommonTangent{\@ifnextchar[\Pst at CircleInternalCommonTangent{\Pst at CircleInternalCommonTangent[]}}
 \def\Pst at CircleInternalCommonTangent[#1]{%
   \begingroup
@@ -2336,6 +2747,212 @@
   \endgroup%
 }%
 %
+%% \pstCircleRadicalAxis[Options]{O1}{A}{O2}{B}{C}{D}
+%% Draw the radical axis of the circle A(O1) and B(O2), and create two nodes $C$ and $D$ on the axis.
+%% The circle A(O1) is defined by center O1 and point A on the circle or RadiusA/DiameterA in parameter.
+%% The circle B(O1) is defined by center O2 and point B on the circle or RadiusB/DiameterB in parameter.
+%% For any point P(x,y) on the radical axis, we have
+%% $$(x-x_1)^2+(y-y_1)^2-r_1^2=(x-x_2)^2+(y-y_2)^2-r_2^2$$
+%% case 1. when $x_1=x_2$, we have
+%% $$2(y_2-y_1)y+y_1^2-r_1^2=y_2^2-r_2^2$$
+%% case 1.1. when $y_1=y_2$, there is none radical axis.
+%% case 1.2. else we have
+%% $$y=\dfrac{(y_2^2-r_2^2)-(y_1^2-r_1^2)}{2(y_2-y_1)}$$
+%% case 1.2.1. when $r_1^2-(y-y_1)^2<0$, there is none intersection of two circle, we select $x=x_1$ and $x=x_1+1$ at this time.
+%% case 1.2.2. else we select $x=x_1\pm\sqrt{r_1^2-(y-y_1)^2}$
+%% case 2. when $x_1\neq{}x_2$, we have
+%% case 2.1. when $y_1=y_2$, we have
+%% $$x=\dfrac{(x_2^2-r_2^2)-(x_1^2-r_1^2)}{2(x_2-x_1)}$$
+%% case 2.1.1. when $r_1^2-(x-x_1)^2<0$, there is none intersection of two circle, we select $y=y_1$ and $y=y_1+1$ at this time.
+%% case 2.1.2. else we select $y=y_1\pm\sqrt{r_1^2-(x-x_1)^2}$
+%% case 2.2. else we have
+%% $$2(x_2-x_1)x+2(y_2-y_1)y=(x_2^2+y_2^2-r_2^2)-(x_1^2+y_1^2-r_1^2)$$
+%% set $a=2(x_2-x_1)$,$b=2(y_2-y_1)$,$m=x_2^2+y_2^2-r_2^2$,$n=x_1^2+y_1^2-r_1^2$, $d=m-n$,we have
+%% $$ax+by=d$$
+%% when $(x-x_1)^2+(y-y_1)^2-r_1^2=0$, let $X=x-x_1$, $Y=y-y_1$, we have
+%% $$X^2+Y^2=r_1^2$$
+%% and
+%% $$aX+bY=d-ax_1-by_1$$
+%% let $e=d-ax_1-by_1$, then
+%% $$(a^2+b^2)X^2-2aeX+e^2-b^2r_1^2=0$$
+%% case 2.2.1 when $(a^2+b^2)r_1^2-e^2>0$, we have
+%% $$x=x_1+\dfrac{ae\pm{}b\sqrt{(a^2+b^2)r_1^2-e^2}}{a^2+b^2}$$
+%% $$y=y_1+\dfrac{be\mp{}a\sqrt{(a^2+b^2)r_1^2-e^2}}{a^2+b^2}$$
+%% case 2.2.2 else we select $x=\dfrac{r_1x_1+r_2x_2}{r_1+r_2}$ and $x=\dfrac{r_2x_1+r_1x_2}{r_1+r_2}$.
+%% Parameters:
+%% #1 -> options
+%% #2 -> [input] the first circle center O1
+%% #3 -> [input] the first circle point A or empty with RadiusA/DiameterA parameter
+%% #4 -> [input] the second circle center O2
+%% #5 -> [input] the second circle point B or empty with RadiusB/DiameterB parameter
+%% #6 -> [output] the first node name C lies on radical axis
+%% #7 -> [output] the second node name D lies on radical axis
+\def\pstCircleRadicalAxis{\@ifnextchar[\Pst at CircleRadicalAxis{\Pst at CircleRadicalAxis[]}}
+\def\Pst at CircleRadicalAxis[#1]{%
+  \begingroup
+    \@InitListMng %
+    \psset{#1}%
+    \Pst at CircleRadicalAxis@i}
+\def\Pst at CircleRadicalAxis@i#1#2#3#4#5#6{%
+    \pst at getcoor{#1}\pst at tempA%
+    \pst at getcoor{#3}\pst at tempB%
+    \pnode(!
+      \pst at tempA \tx at UserCoor % x1,y1
+      \pst at tempB \tx at UserCoor % x2,y2
+      \ifx\psk at RadiusA\@undef
+         \ifx\psk at DiameterA\@undef
+           tx at EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist end
+         \else
+           \psk at DiameterA\space 2 div
+         \fi
+      \else\psk at RadiusA\space\fi
+      \pst at number\psxunit div %r1
+      \ifx\psk at RadiusB\@undef
+         \ifx\psk at DiameterB\@undef
+           tx at EcldDict begin /N@#3 GetNode /N@#4 GetNode ABDist end
+         \else
+           \psk at DiameterB\space 2 div
+         \fi
+      \else\psk at RadiusB\space\fi
+      \pst at number\psxunit div %r2
+      5 index 4 index sub abs 1E-5 lt { % if x1=x2
+        4 index 3 index sub abs 1E-5 lt { % if y1=y2
+          pop pop pop pop pop pop 0 0
+        } {
+          % x1 y1 x2 y2 r1 r2
+          2 index dup mul 1 index dup mul sub % y2^2-r2^2
+          5 index dup mul 3 index dup mul sub % y1^2-r1^2
+          sub 3 index 6 index sub 2 mul div % y=\dfrac{(y2^2-r2^2)-(y1^2-r1^2)}{2(y2-y1)}
+          6 index 3 index dup mul 2 index 8 index sub dup mul sub
+          dup 0 lt {
+            pop % x=x1
+          } {
+            sqrt sub % x=x1\pm\sqrt{r1^2-(y-y1)^2)}
+          } ifelse
+          exch 8 2 roll pop pop pop pop pop pop
+        } ifelse
+      } {
+        4 index 3 index sub abs 1E-5 lt { % if y1=y2
+          % x1 y1 x2 y2 r1 r2
+          3 index dup mul 1 index dup mul sub % x2^2-r2^2
+          6 index dup mul 3 index dup mul sub % x1^2-r1^2
+          sub 4 index 7 index sub 2 mul div % x=\dfrac{(x2^2-r2^2)-(x1^2-r1^2)}{2(x2-x1)}
+          5 index 3 index dup mul 2 index 9 index sub dup mul sub
+          dup 0 lt {
+            pop % y=y1
+          } {
+            sqrt sub % y=y1\pm\sqrt{r1^2-(x-x1)^2)}
+          } ifelse
+          8 2 roll pop pop pop pop pop pop
+        } {
+          % x1 y1 x2 y2 r1 r2
+          3 index dup mul 3 index dup mul add 1 index dup mul sub % m=x2^2+y2^2-r2^2
+          6 index dup mul 6 index dup mul add 3 index dup mul sub % n=x1^2+y1^2-r1^2
+          1 index 1 index sub % d=m-n
+          6 index 9 index sub 2 mul % a=2(x2-x1)
+          6 index 9 index sub 2 mul % b=2(y2-y1)
+          2 index 2 index 12 index mul sub 1 index 11 index mul sub % e=d-ax1-by1
+          2 index dup mul 2 index dup mul add 8 index dup mul mul 1 index dup mul sub % f=(a^2+b^2)r1^2-e^2
+          dup 0 lt {
+            % we select x=\dfrac{r1x1+r2x2}{r1+r2}
+            8 index 13 index mul 8 index 12 index mul add 9 index 9 index add div % x
+            % y=\dfrac{d-ax}{b}
+            5 index 5 index 2 index mul sub 4 index div
+            15 2 roll pop pop pop pop pop pop pop
+            pop pop pop pop pop pop
+          } {
+            sqrt % sqrt(f)
+            % x=x_1+\dfrac{ae\pm{}b\sqrt{(a^2+b^2)r_1^2-e^2}}{a^2+b^2}
+            0 index 3 index mul 4 index 3 index mul exch sub 4 index dup mul 4 index dup mul add div 13 index add
+            % y=y_1+\dfrac{be\mp{}a\sqrt{(a^2+b^2)r_1^2-e^2}}{a^2+b^2}
+            1 index 5 index mul 4 index 4 index mul add 5 index dup mul 5 index dup mul add div 13 index add
+            15 2 roll pop pop pop pop pop pop
+            pop pop pop pop pop pop pop
+          } ifelse
+        } ifelse
+      } ifelse
+    ){#5}
+    \pnode(!
+      \pst at tempA \tx at UserCoor % x1,y1
+      \pst at tempB \tx at UserCoor % x2,y2
+      \ifx\psk at RadiusA\@undef
+         \ifx\psk at DiameterA\@undef
+           tx at EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist end
+         \else
+           \psk at DiameterA\space 2 div
+         \fi
+      \else\psk at RadiusA\space\fi
+      \pst at number\psxunit div %r1
+      \ifx\psk at RadiusB\@undef
+         \ifx\psk at DiameterB\@undef
+           tx at EcldDict begin /N@#3 GetNode /N@#4 GetNode ABDist end
+         \else
+           \psk at DiameterB\space 2 div
+         \fi
+      \else\psk at RadiusB\space\fi
+      \pst at number\psxunit div %r2
+      5 index 4 index sub abs 1E-5 lt { % if x1=x2
+        4 index 3 index sub abs 1E-5 lt { % if y1=y2
+          pop pop pop pop pop pop 0 0
+        } {
+          % x1 y1 x2 y2 r1 r2
+          2 index dup mul 1 index dup mul sub % y2^2-r2^2
+          5 index dup mul 3 index dup mul sub % y1^2-r1^2
+          sub 3 index 6 index sub 2 mul div % y=\dfrac{(y2^2-r2^2)-(y1^2-r1^2)}{2(y2-y1)}
+          6 index 3 index dup mul 2 index 8 index sub dup mul sub
+          dup 0 lt {
+            pop 1 add % x=x1+1
+          } {
+            sqrt add % x=x1\pm\sqrt{r1^2-(y-y1)^2)}
+          } ifelse
+          exch 8 2 roll pop pop pop pop pop pop
+        } ifelse
+      } {
+        4 index 3 index sub abs 1E-5 lt { % if y1=y2
+          3 index dup mul 1 index dup mul sub % x2^2-r2^2
+          6 index dup mul 3 index dup mul sub % x1^2-r1^2
+          sub 4 index 7 index sub 2 mul div % x=\dfrac{(x2^2-r2^2)-(x1^2-r1^2)}{2(x2-x1)}
+          5 index 3 index dup mul 2 index 9 index sub dup mul sub
+          dup 0 lt {
+            pop 1 add % y=y1+1
+          } {
+            sqrt add % y=y1\pm\sqrt{r1^2-(x-x1)^2)}
+          } ifelse
+          8 2 roll pop pop pop pop pop pop
+        } {
+          % x1 y1 x2 y2 r1 r2
+          3 index dup mul 3 index dup mul add 1 index dup mul sub % m=x2^2+y2^2-r2^2
+          6 index dup mul 6 index dup mul add 3 index dup mul sub % n=x1^2+y1^2-r1^2
+          1 index 1 index sub % d=m-n
+          6 index 9 index sub 2 mul % a=2(x2-x1)
+          6 index 9 index sub 2 mul % b=2(y2-y1)
+          2 index 2 index 12 index mul sub 1 index 11 index mul sub % e=d-ax1-by1
+          2 index dup mul 2 index dup mul add 8 index dup mul mul 1 index dup mul sub % f=(a^2+b^2)r1^2-e^2
+          dup 0 lt {
+            % we select x=\dfrac{r2x1+r1x2}{r1+r2}
+            7 index 13 index mul 9 index 12 index mul add 9 index 9 index add div % x
+            % y=\dfrac{d-ax}{b}
+            5 index 5 index 2 index mul sub 4 index div
+            15 2 roll pop pop pop pop pop pop pop
+            pop pop pop pop pop pop
+          } {
+            sqrt % sqrt(f)
+            % x=x_1+\dfrac{ae\pm{}b\sqrt{(a^2+b^2)r_1^2-e^2}}{a^2+b^2}
+            0 index 3 index mul 4 index 3 index mul add 4 index dup mul 4 index dup mul add div 13 index add
+            % y=y_1+\dfrac{be\mp{}a\sqrt{(a^2+b^2)r_1^2-e^2}}{a^2+b^2}
+            1 index 5 index mul 4 index 4 index mul exch sub 5 index dup mul 5 index dup mul add div 13 index add
+            15 2 roll pop pop pop pop pop pop
+            pop pop pop pop pop pop pop
+          } ifelse
+        } ifelse
+      } ifelse
+    ){#6}
+    \Pst at ManageParamList{#5}%
+    \Pst at ManageParamList{#6}%
+    \pstLineAB{#5}{#6}%
+  \endgroup%
+}%
+%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %% Here are some functions to operate the conic curves.
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



More information about the tex-live-commits mailing list