summaryrefslogtreecommitdiff
path: root/graphics
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-11-22 03:00:38 +0000
committerNorbert Preining <norbert@preining.info>2019-11-22 03:00:38 +0000
commit28453b76f5307a4e4f018d469cdd8eb18e7d048b (patch)
treeef08916d859a7174cb62de39176ad83a030563fb /graphics
parent6332f770ef657658c6e3068266d960d18d185036 (diff)
CTAN sync 201911220300
Diffstat (limited to 'graphics')
-rw-r--r--graphics/pstricks/contrib/pst-eucl/Changes14
-rw-r--r--graphics/pstricks/contrib/pst-eucl/doc/pst-eucl-doc.pdfbin1341324 -> 1688997 bytes
-rw-r--r--graphics/pstricks/contrib/pst-eucl/doc/pst-eucl-doc.tex473
-rw-r--r--graphics/pstricks/contrib/pst-eucl/dvips/pst-eucl-alt.pro132
-rw-r--r--graphics/pstricks/contrib/pst-eucl/dvips/pst-eucl.pro139
-rw-r--r--graphics/pstricks/contrib/pst-eucl/latex/pst-eucl.sty2
-rw-r--r--graphics/pstricks/contrib/pst-eucl/tex/pst-eucl.tex1690
7 files changed, 2425 insertions, 25 deletions
diff --git a/graphics/pstricks/contrib/pst-eucl/Changes b/graphics/pstricks/contrib/pst-eucl/Changes
index 585f6936d3..eb8fab448e 100644
--- a/graphics/pstricks/contrib/pst-eucl/Changes
+++ b/graphics/pstricks/contrib/pst-eucl/Changes
@@ -1,9 +1,23 @@
pst-eucl.pro --------
+1.02 2019/11/21 - add DeterminantTwo,DeterminantThree,DeterminantFour,DeterminantFive.
1.01 2012/09/21 - fix for introduced bug
1.00 2011/08/05 - fix bug in /InterLines
pst-eucl.tex --------
+1.68 2019/11/21 - add macros to construct a triangle by SSS, SAS, ASA, AAS, \pstTriangleSSS, \pstTriangleSAS, etc.
+ - add macro to get the bisector node of angle AOB, \pstBisectorAOB, refer to pstBissectBAC, pstOutBissectBAC.
+ - add macro to get the Golden Mean node of a given segment, \pstGoldenMean.
+ - add macro to define an ellipse by its focus(F) and directrix line(l) and eccentricity(e), \pstGeneralEllipseFle.
+ - add macro to define an ellipse by quadratic curve equation $ax^2+bxy+cy^2+dx+ey+f=0$, \pstGeneralEllipseCoef.
+ - add macro to define an ellipse by given five points, \pstGeneralEllipseABCDE.
+ - add macro to define an parabola by its focus(F) and directrix line(l), \pstGeneralParabolaFl.
+ - add macro to define an parabola by quadratic curve equation $ax^2+bxy+cy^2+dx+ey+f=0$, \pstGeneralParabolaCoef.
+ - add macro to define an parabola by given five points, \pstGeneralParabolaABCDE.
+ - add macro to define an hyperbola by its focus(F) and directrix line(l) and eccentricity(e), \pstGeneralHyperbolaFle.
+ - add macro to define an hyperbola by quadratic curve equation $ax^2+bxy+cy^2+dx+ey+f=0$, \pstGeneralHyperbolaCoef.
+ - add macro to define an hyperbola by given five points, \pstGeneralHyperbolaABCDE.
+ - add macro to draw the line Ax+By+C=0, \pstLineCoef.
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.
diff --git a/graphics/pstricks/contrib/pst-eucl/doc/pst-eucl-doc.pdf b/graphics/pstricks/contrib/pst-eucl/doc/pst-eucl-doc.pdf
index 1766af0c73..703c91b79e 100644
--- a/graphics/pstricks/contrib/pst-eucl/doc/pst-eucl-doc.pdf
+++ b/graphics/pstricks/contrib/pst-eucl/doc/pst-eucl-doc.pdf
Binary files differ
diff --git a/graphics/pstricks/contrib/pst-eucl/doc/pst-eucl-doc.tex b/graphics/pstricks/contrib/pst-eucl/doc/pst-eucl-doc.tex
index dc97768b52..b9000b9750 100644
--- a/graphics/pstricks/contrib/pst-eucl/doc/pst-eucl-doc.tex
+++ b/graphics/pstricks/contrib/pst-eucl/doc/pst-eucl-doc.tex
@@ -6,7 +6,7 @@
\usepackage{multicol}
\usepackage{ntheorem}
\newtheorem{theorem}{Theorem}
-\usepackage{pst-plot,paralist}
+\usepackage{pst-func,pst-plot,paralist}
\usepackage[mathscr]{eucal}
\lstset{pos=l,wide=false,language=PSTricks,
morekeywords={multidipole,parallel},basicstyle=\footnotesize\ttfamily}
@@ -403,6 +403,53 @@ for each points: \Lkeyword{PointSymbolA}, \Lkeyword{PointSymbolB} and
\Lkeyword{PointSymbol}. The management of the default value followed the
same rule.
+The macros \Lcs{pstTriangleSSS}, \Lcs{pstTriangleSAS}, \Lcs{pstTriangleAAS} and
+\Lcs{pstTriangleASA} are used to draw the triangle according the specified sides
+or angles.
+
+\begin{BDef}
+\Lcs{pstTriangleSSS}\OptArgs\Largr{pos}\Largb{A}\Largr{a,b,c}\Largb{B}\Largb{C}\\
+\Lcs{pstTriangleSAS}\OptArgs\Largr{pos}\Largb{A}\Largr{b,$\angle{A}$,c}\Largb{B}\Largb{C}\\
+\Lcs{pstTriangleAAS}\OptArgs\Largr{pos}\Largb{A}\Largr{$\angle{C}$,$\angle{A}$,c}\Largb{B}\Largb{C}\\
+\Lcs{pstTriangleASA}\OptArgs\Largr{pos}\Largb{A}\Largr{$\angle{A}$,c,$\angle{B}$}\Largb{B}\Largb{C}
+\end{BDef}
+
+- Macro \Lcs{pstTriangleSSS} create a triangle $ABC$ with given $A(x_1,y_1)$, and the three sides $a,b,c$,
+it output $B(x_2,y_2)$ and $C(x_3,y_3)$.\\
+- Macro \Lcs{pstTriangleSAS} create a triangle $ABC$ with given $A(x_1,y_1)$, the angle of $\angle{A}$, and the other two sides $b,c$,
+it output $B(x_2,y_2)$ and $C(x_3,y_3)$.\\
+- Macro \Lcs{pstTriangleAAS} create a triangle $ABC$ with given $A(x_1,y_1)$, the angle of $\angle{C}$, the angle of $\angle{A}$, and the side of $AB=c$,
+it output $B(x_2,y_2)$ and $C(x_3,y_3)$.\\
+- Macro \Lcs{pstTriangleASA} create a triangle $ABC$ with given $A(x_1,y_1)$, the angle of $\angle{A}$, the angle of $\angle{B}$, and the side of $AB=c$,
+it output $B(x_2,y_2)$ and $C(x_3,y_3)$.
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](0,0)(4,4)
+\psset{dotscale=0.5}\psset{PointSymbol=*}\footnotesize
+\pstGeonode[PosAngle=-90](0,1){A}
+\pstTriangleSSS[linecolor=red!60,PosAngle={-90,90}]{A}(3,4,5){B}{C}
+\pstTriangleSSS[linecolor=blue!60,PosAngle={-90,90}]{A}(2,4.5,3.8){D}{E}
+\pstTriangleSAS[linecolor=green!60,PosAngle={-90,90}]{A}(3,40,2.8){F}{G}
+\pstTriangleAAS[linecolor=black!60,PosAngle={-90,90}]{A}(40,50,1.8){H}{I}
+\pstTriangleASA[linecolor=purple!60,PosAngle={-90,90}]{A}(70,1.0,60){J}{K}
+\end{pspicture}
+\end{LTXexample}
+
+The optional parameter \texttt{pos} setup the position of the first node $A$, it should be 'L' for left, 'R' for right, 'U' for up and 'D' for down.
+If you don't input this parameter, the default value is 'L'. The following example explains how to draw an isoceles triangle with the given isoceles sides
+and the vertex angle.
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](0,0)(4,4)
+\psset{dotscale=0.5}\psset{PointSymbol=*}\footnotesize
+\pstGeonode[PosAngle=205](2,2){A}
+\pstTriangleSAS[linecolor=red!60,PosAngle={-90,90}]{A}(2,40,2){B}{C}
+\pstTriangleSAS[linecolor=blue!60,PosAngle={-90,-90}](U){A}(2,40,2){B}{C}
+\pstTriangleSAS[linecolor=purple!60,PosAngle={90,90}](D){A}(2,40,2){B}{C}
+\pstTriangleSAS[linecolor=green!60,PosAngle={90,-90}](R){A}(2,40,2){B}{C}
+\end{pspicture}
+\end{LTXexample}
+
The macros \Lcs{pstTriangleIC} and \Lcs{pstTriangleOC} are used to draw the inner circle
and outer circle of triangle $ABC$.
@@ -612,6 +659,26 @@ Here are some examples:
\vspace{10pt}
+The macros \Lcs{pstLineCoef} is used to draw a line $ax+by+c=0$ with the given coefficents $a,b,c$,
+and create two new node $A,B$ on the line.
+
+\begin{BDef}
+\Lcs{pstLineCoef}\OptArgs\Largb{a,b,c}\Largb{A}\Largb{B}
+\end{BDef}
+
+Here are some examples:
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](-2,-2)(2,2)
+\pstLineCoef[linecolor=red!60, PosAngle={210,0}]{3,-2,1}{A}{B}
+\pstLineCoef[linecolor=blue!60, PosAngle={180,0}]{4,3,2}{C}{D}
+\pstLineCoef[linecolor=green!60, PosAngle={90,90}]{0,3,-3}{E}{F}
+\pstLineCoef[linecolor=purple!60, PosAngle={180,180}]{4,0,4}{G}{H}
+\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),
@@ -678,6 +745,30 @@ we will introduce \Lcs{pstDistDiv} later.
\end{pspicture}
\end{LTXexample}
+One application of \Lcs{pstProportionNode} is used to find the bisector and out bisector of a given angle.
+So we define the macro \Lcs{pstBisectorAOB} to do this work, it is more friendly than the macros
+\Lcs{pstBissectBAC} and \Lcs{pstOutBissectBAC}, as it put the new node $T_1$ and $T_2$ on line $AB$, not arc $AB$.
+
+\begin{BDef}
+\Lcs{pstBisectorAOB}\OptArgs\Largb{A}\Largb{O}\Largb{B}\Largb{$T_1$}\Largb{$T_2$}
+\end{BDef}
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](0,-1)(5,3)
+\psset{unit=0.6cm}\footnotesize\psset{PointSymbol=*}
+\pstGeonode[PosAngle=-90](0,0){A}
+\pstGeonode[PosAngle=90](3,3){C}
+\pstGeonode[PosAngle=-90](2,0){B}
+\pstBisectorAOB[PosAngle={-90,-90}]{A}{C}{B}{T_1}{T_2}
+\pstLineAB[linecolor=black!50]{A}{C}
+\pstLineAB[linecolor=black!50]{B}{C}
+\pstLineAB[linecolor=black!50]{A}{B}
+\pstLineAB[linestyle=dashed,linecolor=gray]{C}{T_1}
+\pstLineAB[linestyle=dashed,linecolor=gray]{C}{T_2}
+\pstLineAB[linestyle=dashed,linecolor=gray]{B}{T_2}
+\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$,
@@ -838,11 +929,34 @@ of a point on the inversion circle is itself.
\vspace{10pt}
+If you want to find the node $C$ from $A$ to $B$, such that $C$ is the golden section of the
+given segments $AB$, that is,
+$$|AC|^2=|AB|\times|BC|\quad\text{or}\quad{}AC:AB=BC:AC\quad\text{or}\quad{}AC=\dfrac{\sqrt{5}-1}{2}AB$$
+you can use the macro \Lcs{pstGoldenMean} to do this work.
+
+\begin{BDef}
+\Lcs{pstGoldenMean}\OptArgs\Largb{A}\Largb{B}\Largb{C}
+\end{BDef}
+
+In fact, we use the macro \Lcs{pstLocateAB} to implement this macro
+by passing the value $\dfrac{\sqrt{5}-1}{2}|AB|$ to parameter length.
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](0,0)(4,3)
+\psset{dotscale=0.5}\psset{PointSymbol=*}\footnotesize
+\pstGeonode[PosAngle=90](0,1){A}(4,2){B}
+\pstGoldenMean[PosAngle=90,PointSymbol=o]{A}{B}{C}
+\pstLineAB{A}{B}
+\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,
+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}
@@ -1107,15 +1221,15 @@ and the parameter to fill the circle.
\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}{}
+\pstCircleOA[linecolor=gray,Radius=\pstDistAdd{A}{B}{A'}{B'}]{A}{} % R=|AB|+|A'B'|
+\pstCircleOA[linecolor=red,Radius=\pstDistAddVal{A}{B}{1.0}{\pstDistConst{0.5}}]{A}{} % R=|AB|+0.5
+\pstCircleOA[linecolor=blue,Radius=\pstDistAddCoef{A}{B}{0.5}{A'}{B'}{1.5}]{A}{} % R=0.5|AB|+1.5|A'B'|
+\pstCircleOA[linecolor=green,Radius=\pstDistSub{A}{B}{A'}{B'}]{B'}{} % R=|AB|-|A'B'|
+\pstCircleOA[linecolor=brown,Radius=\pstDistSubCoef{A}{B}{1.8}{A'}{B'}{0.5}]{A}{} R=1.8|AB|-0.5|A'B'|
\pnode(-1.5,-2){D}
-\pstCircleOA[linecolor=pink,fillstyle=solid,fillcolor=pink!40,Radius=\pstDistMul{A}{B}{0.8}]{D}{}
+\pstCircleOA[linecolor=pink,fillstyle=solid,fillcolor=pink!40,Radius=\pstDistMul{A}{B}{0.8}]{D}{} % R=0.8|AB|
\psdot(D)\uput{0.2}[-45](D){$D$}
-\pstCircleOA[linecolor=purple,Radius=\pstDistConst{\pstAbscissa{D}} abs]{D}{}
+\pstCircleOA[linecolor=purple,Radius=\pstDistConst{\pstAbscissa{D}} abs]{D}{} % R=|D.x|
\end{pspicture}
\end{LTXexample}
@@ -1200,8 +1314,8 @@ for example,
\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}
+\pstCircleAbsNode[PosAngle={-60,60},PointSymbol=*]{O}{A}{1.0}{C}{D}
+\pstCircleOrdNode[PosAngle={150,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}
@@ -1468,6 +1582,25 @@ the macro will draw the whole ellipse.
\end{pspicture}
\end{LTXexample}
+Like as the coordinates, the parameters $a,b$ can be got by the raw PostScript commands too,
+where you can use the macros \Lcs{pstDist}*, for example,
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](-3,-3)(3,3)
+\psset{dotscale=0.5}\psset{PointSymbol=*}\footnotesize
+\pstGeonode[PosAngle=-90,PointSymbol=*](0,0){O}(0,-2.5){R}
+\pstCircleOA[linecolor=blue!60]{O}{R}
+\pstGeonode[PosAngle=0,PointName=O_1,PointSymbol=*](0,0.8){O1}
+\pstGeonode[PosAngle=0,PointName=O_2,PointSymbol=*](0,1.6){O2}
+\pstCircleOrdNode[PointName={P,Q},PosAngle={180,0}]{O}{R}{\pstOrdinate{O1}}{P}{Q}
+\pstCircleOrdNode[PointName={P',Q'},PosAngle={180,0}]{O}{R}{\pstOrdinate{O2}}{P'}{Q'}
+\pstEllipse[linecolor=green!60,linestyle=dashed](O1)(! \pstUserDist{\pstDist{O1}{P}} 0.7)[0][180]
+\pstEllipse[linecolor=green!60](O1)(! \pstUserDist{\pstDist{O1}{P}} 0.7)[180][360]
+\pstEllipse[linecolor=red!60,linestyle=dashed](O2)(! \pstUserDist{\pstDist{O2}{P'}} 0.5)[0][180]
+\pstEllipse[linecolor=red!60](O2)(! \pstUserDist{\pstDist{O2}{P'}} 0.5)[180][360]
+\end{pspicture}
+\end{LTXexample}
+
Now you can draw some points on this Ellipse using macro \Lcs{pstEllipseNode} or \Lcs{pstEllipseRotNode}.
The macro \Lcs{pstEllipseNode} requires an explicit parameter $t$ as $\alpha$ in equation (\ref{ParametricFunctionOfEllipse})
to calculate the point; but the macro \Lcs{pstEllipseRotNode} requires an implicit parameter \Lkeyword{RotAngle}
@@ -1746,7 +1879,120 @@ That is, \Lcs{pstGeneralEllipse} is more complex than \Lcs{pstEllipse}!
\end{pspicture}
\end{LTXexample}
-Similarly, we can location the points on the General Ellipse using the macros
+\vspace{10pt}
+
+The Macro \Lcs{pstGeneralEllipseFle} is used to define a General Ellipse with Focus $F$, directrix line $l$,
+and the eccentricity $e$, where $0\le{}e<1$. It just calculate the center $O$, major radius $a$, minor radius $b$ and the rotation
+angle $\theta$ of the major axis, then you can pass them into macro \Lcs{pstGeneralEllipse} to draw this ellipse.
+
+\begin{BDef}
+\Lcs{pstGeneralEllipseFle}\OptArgs\Largb{F}\Largb{A}\Largb{B}\Largb{$e$}\Largb{O}\Largb{Rab}\Largb{$\theta$}
+\end{BDef}
+
+The output parameter \texttt{O} is a node name to store the center point, its label and symbol can
+be controlled by the options for \PST\ node, such as \Lkeyword{PosAngle}.
+The output parameter \texttt{Rab} is a PostScript key to store the pair of major radius and minor radius,
+it just use \PST\ node coordinate to store a pair of value, but not a geometrical point.
+The output parameter \texttt{$\theta$} is also a PostScript key to store the rotation angle of major axis,
+when you pass it to \Lcs{pstGeneralEllipse}, PostScript will lookup the value of this key in current dictionary.
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](-2,-2)(2,2)
+\psset{unit=1.0cm}\psset{dotscale=0.5}\footnotesize
+\psset{CodeFig=true,CodeFigColor=gray!50}\psset{PointSymbol=*}
+\pstGeonode[PosAngle=30](1,-1){F_1}
+\pstGeonode[PosAngle=30](-1,1){F_2}
+\pstGeonode[PosAngle=-60](-2,-1){A}
+\pstGeonode[PosAngle=-60](2,1){B}
+\pstGeneralEllipseFle[PosAngle=30]{F_1}{A}{B}{0.5}{O_1}{R_1}{MajorRotAngle1}
+\pstGeneralEllipse[linecolor=red!60](O_1)(R_1)[MajorRotAngle1]
+\pstGeneralEllipseFle[PosAngle=30]{F_2}{A}{B}{0.5}{O_2}{R_2}{MajorRotAngle2}
+\pstGeneralEllipse[linecolor=blue!60](O_2)(R_2)[MajorRotAngle2]
+\pstGeneralEllipseFle[PosAngle=20]{F_1}{A}{B}{0.6}{O_3}{R_3}{MajorRotAngle3}
+\pstGeneralEllipse[linecolor=green!60](O_3)(R_3)[MajorRotAngle3]
+\end{pspicture}
+\end{LTXexample}
+
+\vspace{10pt}
+
+The Macro \Lcs{pstGeneralEllipseCoef} is used to define a General Ellipse by the quadratic curve equation $ax^2+bxy+cy^2+dx+ey+f=0$,
+it just calculate the center $O$, major radius $a$, minor radius $b$ and the rotation angle $\theta$ of the major axis,
+then you can pass them into macro \Lcs{pstGeneralEllipse} to draw this ellipse.
+The package \texttt{pst-func} provides macro \Lcs{psplotImp} to draw an implicit defined functions too,
+but it can't tell you the geometrical elements like as center or radii, and it will take more time to
+calculate the function value point by point.
+
+\begin{BDef}
+\Lcs{pstGeneralEllipseCoef}\OptArgs\Largb{a,b,c,d,e,f}\Largb{O}\Largb{Rab}\Largb{$\theta$}
+\end{BDef}
+
+The output parameter \texttt{O}, the output parameter \texttt{Rab} and the output parameter \texttt{$\theta$}
+are same with \Lcs{pstGeneralEllipseFle}. They are set to zero if the coeffients are invalid to construct an ellipse.
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](-4,-3)(2,3)
+\psset{unit=1.0cm}\footnotesize\psset{dotscale=0.5}
+\psset{CodeFig=true}\psset{PointSymbol=*}
+%2x^2-2xy+3y^2+6x+5y+8=0
+\pstGeneralEllipseCoef[PosAngle=-100,CodeFigColor=red!50]{2,-2,3,6,5,8}{O_1}{R_1}{MajorRotAngle1}
+\pstGeneralEllipse[linecolor=red!60](O_1)(R_1)[MajorRotAngle1]
+%3x^2-2xy+2y^2-3x+6y+3=0
+\pstGeneralEllipseCoef[PosAngle=-80,CodeFigColor=purple!50]{3,-2,2,-3,5,2}{O_2}{R_2}{MajorRotAngle2}
+\pstGeneralEllipse[linecolor=purple!60](O_2)(R_2)[MajorRotAngle2]
+%x^2-xy+y^2+x-3y+1=0
+\pstGeneralEllipseCoef[PosAngle=-90,CodeFigColor=green!50]{1,-1,1,1,-3,1}{O_3}{R_3}{MajorRotAngle3}
+\pstGeneralEllipse[linecolor=green!60](O_3)(R_3)[MajorRotAngle3]
+%2x^2+4xy+3y^2+8x+6y+8=0
+\pstGeneralEllipseCoef[PosAngle=-80,CodeFigColor=blue!50]{2,4,3,8,6,8}{O_4}{R_4}{MajorRotAngle4}
+\pstGeneralEllipse[linecolor=blue!60](O_4)(R_4)[MajorRotAngle4]
+\end{pspicture}
+\end{LTXexample}
+
+You can verify the output figures with \Lcs{psplotImp} as following:
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](-4,-3)(2,3)
+\psset{unit=1.0cm}\footnotesize\psset{dotscale=0.5}
+%2x^2-2xy+3y^2+6x+5y+8=0
+\psplotImp[linecolor=red!60](-4,-3)(2,3){ 2 x dup mul mul -2 x mul y mul add 3 y dup mul mul add 6 x mul add 5 y mul add 8 add }
+%3x^2-2xy+2y^2-3x+6y+3=0
+\psplotImp[linecolor=purple!60](-4,-3)(2,3){ 3 x dup mul mul -2 x mul y mul add 2 y dup mul mul add -3 x mul add 6 y mul add 3 add }
+%x^2-xy+y^2+x-3y+1=0
+\psplotImp[linecolor=green!60](-4,-3)(2,3){ 1 x dup mul mul -1 x mul y mul add 1 y dup mul mul add 1 x mul add -3 y mul add 1 add }
+%2x^2+4xy+3y^2+8x+6y+8=0
+\psplotImp[linecolor=blue!60](-5,-3)(2,3){ 2 x dup mul mul 4 x mul y mul add 3 y dup mul mul add 8 x mul add 6 y mul add 8 add }
+\end{pspicture}
+\end{LTXexample}
+
+\vspace{10pt}
+
+The Macro \Lcs{pstGeneralEllipseABCDE} is used to define a General Ellipse by the given five points $A,B,C,D,E$,
+it just calculate the center $O$, major radius $a$, minor radius $b$ and the rotation angle $\theta$ of the major axis,
+then you can pass them into macro \Lcs{pstGeneralEllipse} to draw this ellipse.
+
+\begin{BDef}
+\Lcs{pstGeneralEllipseABCDE}\OptArgs\Largb{A}\Largb{B}\Largb{C}\Largb{D}\Largb{E}\Largb{O}\Largb{Rab}\Largb{$\theta$}
+\end{BDef}
+
+The output parameter \texttt{O}, the output parameter \texttt{Rab} and the output parameter \texttt{$\theta$}
+are same with \Lcs{pstGeneralEllipseFle}. They are set to zero if the points are invalid to construct an ellipse.
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](-1,-2)(5,4)
+\psset{unit=1.0cm}\footnotesize\psset{PointSymbol=*}
+\psset{CodeFig=true,CodeFigColor=gray!50}
+\pstGeonode[PosAngle=180](0,0){A}
+\pstGeonode[PosAngle=-90](2,-1){B}
+\pstGeonode[PosAngle=90](3,3){C}
+\pstGeonode[PosAngle=-90](4,0){D}
+\pstGeonode[PosAngle=0](5,2){E}
+\pstGeneralEllipseABCDE[PosAngle=0]{A}{B}{C}{D}{E}{O}{R}{MajorRotAngle}
+\pstGeneralEllipse[linecolor=red!60](O)(R)[MajorRotAngle]
+\end{pspicture}
+\end{LTXexample}
+
+\vspace{10pt}
+
+We can location the points on the General Ellipse using the macros
\Lcs{pstGeneralEllipseNode}, \Lcs{pstGeneralEllipseRotNode}, \Lcs{pstGeneralEllipseAbsNode}
and \Lcs{pstGeneralEllipseOrdNode} as following.
@@ -2212,6 +2458,7 @@ We also use the theorem \ref{ParabolaTangentPointTheorem} to find the tangent no
The General Parabola $P$ with coordinate translation and rotation is defined by vertex $O(x_0,y_0)$,
the half of the focus chord axis $abs(p)$, the sign of $p$ indicates the direction of the parabola,
and the rotation angle $\theta$ of the symmetrical axis.
+The symmetrical axis is perpendicular to x-axis when $\theta=0^\circ$, and perpendicular to y-axis when $\theta=90^\circ$.
The equation can be got from the parametric function of the parabola equation (\ref{ParametricFunctionOfStandardParabola}),
using the rotation transform formula (\ref{RotationTransformFormula}), then we have
@@ -2271,6 +2518,111 @@ at most time.
\end{pspicture}
\end{LTXexample}
+\vspace{10pt}
+
+The Macro \Lcs{pstGeneralParabolaFl} is used to define a General Parabola with Focus $F$, and the directrix line $l$. It just calculate the vertex $O$, half focal chord $p$, and the rotation
+angle $\theta$ of the symmetrical axis, then you can pass them into macro \Lcs{pstGeneralParabola} to draw this parabola.
+
+\begin{BDef}
+\Lcs{pstGeneralParabolaFl}\OptArgs\Largb{F}\Largb{A}\Largb{B}\Largb{O}\Largb{p}\Largb{$\theta$}
+\end{BDef}
+
+The output parameter \texttt{O} is a node name to store the vertex point, its label and symbol can
+be controlled by the options for \PST\ node, such as \Lkeyword{PosAngle}.
+The output parameter \texttt{p} is a PostScript key to store the value of half focal chord.
+The output parameter \texttt{$\theta$} is also a PostScript key to store the rotation angle of symmetrical axis,
+when you pass it to \Lcs{pstGeneralParabola}, PostScript will lookup the value of this key in current dictionary.
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](-2,-2)(2,2)
+\psset{unit=1.0cm}\psset{dotscale=0.5}\footnotesize
+\psset{CodeFig=true,CodeFigColor=gray!50}\psset{PointSymbol=*}
+\pstGeonode[PosAngle=-60](1,1){F_1}
+\pstGeonode[PosAngle=-60](-1,-1){F_2}
+\pstGeonode[PosAngle=60](1,-1){B}
+\pstGeonode[PosAngle=60](-1,1){A}
+\pstGeneralParabolaFl[PosAngle=60]{F_1}{A}{B}{O_1}{semifocalchordp1}{SymAxisRotAngle1}
+\pstGeneralParabola[linecolor=red!60](O_1){semifocalchordp1}[SymAxisRotAngle1]{-2}{2}
+\pstGeneralParabolaFl[PosAngle=60]{F_2}{A}{B}{O_2}{semifocalchordp2}{SymAxisRotAngle2}
+\pstGeneralParabola[linecolor=blue!60](O_2){semifocalchordp2}[SymAxisRotAngle2]{-2}{2}
+\pstGeneralParabolaFl[PosAngle=60]{B}{F_1}{F2}{O_3}{semifocalchordp3}{SymAxisRotAngle3}
+\pstGeneralParabola[linecolor=green!60](O_3){semifocalchordp3}[SymAxisRotAngle3]{-2}{2}
+\pstGeneralParabolaFl[PosAngle=60]{A}{F_1}{F2}{O_4}{semifocalchordp4}{SymAxisRotAngle4}
+\pstGeneralParabola[linecolor=green!60](O_4){semifocalchordp4}[SymAxisRotAngle4]{-2}{2}
+\end{pspicture}
+\end{LTXexample}
+
+\vspace{10pt}
+
+The Macro \Lcs{pstGeneralParabolaCoef} is used to define a General Parabola by the quadratic curve equation $ax^2+bxy+cy^2+dx+ey+f=0$,
+it just calculate the vertex $O$, half focal chord $p$ and the rotation angle $\theta$ of the symmetrical axis,
+then you can pass them into macro \Lcs{pstGeneralParabola} to draw this parabola.
+The package \texttt{pst-func} provides macro \Lcs{psplotImp} to draw an implicit defined functions too,
+but it can't tell you the geometrical elements like as center or radii, and it will take more time to
+calculate the function value point by point.
+
+\begin{BDef}
+\Lcs{pstGeneralParabolaCoef}\OptArgs\Largb{a,b,c,d,e,f}\Largb{O}\Largb{p}\Largb{$\theta$}
+\end{BDef}
+
+The output parameter \texttt{O}, \texttt{p} and \texttt{$\theta$}are same with \Lcs{pstGeneralParabolaFl}.
+They are set to zero if the coeffients are invalid to construct a parabola.
+If you pass the zero $p$ into macro \Lcs{pstGeneralParabola}, it will abort with the exception of dividing by zero.
+
+In the following example, we use \Lcs{psplotImp} to draw the same parabolas, just to check the results
+given by macros \Lcs{pstGeneralParabolaCoef} are correct.
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](-1,-1)(4,4)
+\psset{unit=0.40cm}\footnotesize\psset{dotscale=0.5}
+\psset{CodeFig=true}\psset{PointSymbol=*}
+%x^2-2xy+y^2-8x+16=0
+\psplotImp[linecolor=green!30](-10,-10)(10,10){ 1 x dup mul mul -2 x mul y mul add 1 y dup mul mul add -8 x mul add 0 y mul add 16 add }
+\pstGeneralParabolaCoef[PosAngle=0,CodeFigColor=red!50]{1,-2,1,-8,0,16}{O_1}{P1}{SymAxisRotAngle1}
+\pstGeneralParabola[linecolor=red!60](O_1){P1}[SymAxisRotAngle1]{-3}{3}
+%x^2+2xy+y^2+2x-2y-5=0
+\psplotImp[linecolor=green!30](-10,-10)(10,10){ 1 x dup mul mul 2 x mul y mul add 1 y dup mul mul add 2 x mul add -2 y mul add -5 add }
+\pstGeneralParabolaCoef[PosAngle=-90,CodeFigColor=black!60]{1,2,1,2,-2,-5}{O_2}{P2}{SymAxisRotAngle2}
+\pstGeneralParabola[linecolor=black!60](O_2){P2}[SymAxisRotAngle2]{-3}{3}
+\end{pspicture}
+\end{LTXexample}
+
+\vspace{10pt}
+
+The Macro \Lcs{pstGeneralParabolaABCDE} is used to define a General Parabola by the given five points $A,B,C,D,E$,
+it just calculate the vertex $O$, half focal chord $p$ and the rotation angle $\theta$ of the symmetrical axis,
+then you can pass them into macro \Lcs{pstGeneralParabola} to draw this parabola.
+
+\begin{BDef}
+\Lcs{pstGeneralParabolaABCDE}\OptArgs\Largb{A}\Largb{B}\Largb{C}\Largb{D}\Largb{E}\Largb{O}\Largb{p}\Largb{$\theta$}
+\end{BDef}
+
+The output parameter \texttt{O}, \texttt{p} and \texttt{$\theta$} are same with \Lcs{pstGeneralParabolaFl}.
+They are set to zero if the points are invalid to construct a parabola.
+If you pass the zero $p$ into macro \Lcs{pstGeneralParabola}, it will abort with the exception of dividing by zero.
+
+Note the algorithm may fit a hyperbola quadratic curve from the given five points,
+in order to get the right parabola curve, you must input the point coordinates very precisely.
+In the following example, if you input point $A$ as $(3,1.732)$, it will fail as no such parabola
+can fit these five points.
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](0,-2)(4,2)
+\psset{unit=0.5cm}\footnotesize\psset{PointSymbol=*}
+\psset{CodeFig=true,CodeFigColor=gray!50}
+% five points from y^2-2x+3=0
+\pstGeonode[PosAngle=90](3,1.73205){A}
+\pstGeonode[PosAngle=90](2,1){B}
+\pstGeonode[PosAngle=-90](2,-1){C}
+\pstGeonode[PosAngle=90](6,3){D}
+\pstGeonode[PosAngle=-90](6,-3){E}
+\pstGeneralParabolaABCDE[PosAngle=235]{A}{B}{C}{D}{E}{O}{P}{SymAxisRotAngle}
+\pstGeneralParabola[linecolor=red!60](O){P}[SymAxisRotAngle]{-3}{3}
+\end{pspicture}
+\end{LTXexample}
+
+\vspace{10pt}
+
The macro \Lcs{pstGeneralParabolaFocusNode} is used to find the focus of the parabola,
and the macro \Lcs{pstGeneralParabolaDirectrixLine} is used to find the directrix line of the parabola.
@@ -2969,6 +3321,101 @@ it should be setup from 0 to 90.
\end{pspicture}
\end{LTXexample}
+\vspace{10pt}
+
+The Macro \Lcs{pstGeneralHyperbolaFle} is used to define a General Hyperbola with Focus $F$, directrix line $l$,
+and the eccentricity $e$, where $e>1$. It just calculate the center $O$, real radius $a$, imaginary radius $b$ and the rotation
+angle $\theta$ of the real axis, then you can pass them into macro \Lcs{pstGeneralHyperbola} to draw this hyperbola.
+
+\begin{BDef}
+\Lcs{pstGeneralHyperbolaFle}\OptArgs\Largb{F}\Largb{A}\Largb{B}\Largb{$e$}\Largb{O}\Largb{Rab}\Largb{$\theta$}
+\end{BDef}
+
+The output parameter \texttt{O} is a node name to store the center point, its label and symbol can
+be controlled by the options for \PST\ node, such as \Lkeyword{PosAngle}.
+The output parameter \texttt{Rab} is a PostScript key to store the pair of real radius and imaginary radius,
+it just use \PST\ node coordinate to store a pair of value, but not a geometrical point.
+The output parameter \texttt{$\theta$} is also a PostScript key to store the rotation angle of real axis,
+when you pass it to \Lcs{pstGeneralHyperbola}, PostScript will lookup the value of this key in current dictionary.
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](-2,-2)(2,2)
+\psset{unit=1.0cm}\psset{dotscale=0.5}\footnotesize
+\psset{CodeFig=true,CodeFigColor=gray!50}\psset{PointSymbol=*}
+\pstGeonode[PosAngle=-60](1,1){F_1}
+\pstGeonode[PosAngle=-60](-1,-1){F_2}
+\pstGeonode[PosAngle=-60](1,-1){B}
+\pstGeonode[PosAngle=-60](-1,1){A}
+\pstGeneralHyperbolaFle[PosAngle=-60]{F_1}{A}{B}{2.4}{O_1}{R_1}{RealAxisRotAngle1}
+\pstGeneralHyperbola[linecolor=red!60](O_1)(R_1)[RealAxisRotAngle1][65]
+\pstGeneralHyperbolaFle[PosAngle=-60]{F_2}{A}{B}{2.4}{O_2}{R_2}{RealAxisRotAngle2}
+\pstGeneralHyperbola[linecolor=blue!60](O_2)(R_2)[RealAxisRotAngle2][65]
+\end{pspicture}
+\end{LTXexample}
+
+\vspace{10pt}
+
+The Macro \Lcs{pstGeneralHyperbolaCoef} is used to define a General Hyperbola by the quadratic curve equation $ax^2+bxy+cy^2+dx+ey+f=0$,
+it just calculate the center $O$, real radius $a$ and imaginary radius $b$ and the rotation angle $\theta$ of the real axis,
+then you can pass them into macro \Lcs{pstGeneralHyperbola} to draw this hyperbola.
+The package \texttt{pst-func} provides macro \Lcs{psplotImp} to draw an implicit defined functions too,
+but it can't tell you the geometrical elements like as center or radii, and it will take more time to
+calculate the function value point by point.
+
+\begin{BDef}
+\Lcs{pstGeneralHyperbolaCoef}\OptArgs\Largb{a,b,c,d,e,f}\Largb{O}\Largb{Rab}\Largb{$\theta$}
+\end{BDef}
+
+The output parameter \texttt{O}, the output parameter \texttt{Rab} and the output parameter \texttt{$\theta$}~
+are same with \Lcs{pstGeneralHyperbolaFle}. They are set to zero if the coeffients are invalid to construct a hyperbola.
+
+In the following example, we use \Lcs{psplotImp} to draw the same hyperbolas, just to check the results
+given by macros \Lcs{pstGeneralHyperbolaCoef} are correct.
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](-4,-4)(4,4)
+\psset{unit=0.40cm}\footnotesize\psset{dotscale=0.5}
+\psset{CodeFig=true}\psset{PointSymbol=*}
+%x^2+3xy-2y^2+10x-5y+6=0
+\psplotImp[linecolor=green!30](-10,-10)(10,10){ 1 x dup mul mul 3 x mul y mul add -2 y dup mul mul add 10 x mul add -5 y mul add 6 add }
+\pstGeneralHyperbolaCoef[PosAngle=-30,CodeFigColor=red]{1,3,-2,10,-5,6}{O_1}{R_1}{RealAxisRotAngle1}
+\pstGeneralHyperbola[linecolor=red](O_1)(R_1)[RealAxisRotAngle1][60]
+%x^2-3xy+y^2+10x-10y+21=0
+\psplotImp[linecolor=blue!30](-10,-10)(10,10){ 1 x dup mul mul -3 x mul y mul add 1 y dup mul mul add 10 x mul add -10 y mul add 21 add }
+\pstGeneralHyperbolaCoef[PosAngle=-10,CodeFigColor=black]{1,-3,1,10,-10,21}{O_2}{R_2}{RealAxisRotAngle2}
+\pstGeneralHyperbola[linecolor=black](O_2)(R_2)[RealAxisRotAngle2][60]
+\end{pspicture}
+\end{LTXexample}
+
+\vspace{10pt}
+
+The Macro \Lcs{pstGeneralHyperbolaABCDE} is used to define a General Hyperbola by the given five points $A,B,C,D,E$,
+it just calculate the center $O$, real radius $a$ and imaginary radius $b$ and the rotation angle $\theta$ of the real axis,
+then you can pass them into macro \Lcs{pstGeneralHyperbola} to draw this hyperbola.
+
+\begin{BDef}
+\Lcs{pstGeneralHyperbolaABCDE}\OptArgs\Largb{A}\Largb{B}\Largb{C}\Largb{D}\Largb{E}\Largb{O}\Largb{Rab}\Largb{$\theta$}
+\end{BDef}
+
+The output parameter \texttt{O}, the output parameter \texttt{Rab} and the output parameter \texttt{$\theta$}~
+are same with \Lcs{pstGeneralHyperbolaFle}. They are set to zero if the points are invalid to construct a hyperbola.
+
+\begin{LTXexample}[width=6cm,pos=l]
+\begin{pspicture}[showgrid=true](-1,-3)(4,2)
+\psset{unit=0.5cm}\footnotesize\psset{PointSymbol=*}
+\psset{CodeFig=true,CodeFigColor=gray!50}
+\pstGeonode[PosAngle=180](0,0){A}
+\pstGeonode[PosAngle=-90](2,-1){B}
+\pstGeonode[PosAngle=-90](3,-3){C}
+\pstGeonode[PosAngle=-90](4,0){D}
+\pstGeonode[PosAngle=0](5,2){E}
+\pstGeneralHyperbolaABCDE[PosAngle=0]{A}{B}{C}{D}{E}{O}{R}{RealAxisRotAngle}
+\pstGeneralHyperbola[linecolor=red!60](O)(R)[RealAxisRotAngle][80]
+\end{pspicture}
+\end{LTXexample}
+
+\vspace{10pt}
+
The macro \Lcs{pstGeneralHyperbolaNode} is used to draw a node whose parameter is the given value $t$ on General Hyperbola,
please refer to equation (\ref{ParametricFunctionOfGeneralHyperbola}).
The macro \Lcs{pstGeneralHyperbolaAbsNode} is used to draw the nodes whose abscissa are the given value $x_1$ on General Hyperbola.
@@ -4613,7 +5060,7 @@ set of all the mediator lines of segments defined by $A$ and the
circle points, create two conics depending of the position of $A$:
\begin{compactitem}
-\item inside the circle: an hyperbola;
+\item inside the circle: a hyperbola;
\item outside the circle: an ellipse.
\end{compactitem}
diff --git a/graphics/pstricks/contrib/pst-eucl/dvips/pst-eucl-alt.pro b/graphics/pstricks/contrib/pst-eucl/dvips/pst-eucl-alt.pro
new file mode 100644
index 0000000000..64f0164114
--- /dev/null
+++ b/graphics/pstricks/contrib/pst-eucl/dvips/pst-eucl-alt.pro
@@ -0,0 +1,132 @@
+%!
+% PostScript prologue for pst-eucl.tex.
+% Version 1.00 2011/08/04
+% For distribution, see pstricks.tex.
+%
+/tx@EcldDict 40 dict def tx@EcldDict begin
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Pi
+/Pi 3.14159265359 def
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% e
+/E 2.718281828459045 def
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% x -> true (if |x| < 1E-6)
+/ZeroEq { abs 1E-6 lt } bind def
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% x1 y1 x2 y2 -> a b c (ax-by+c=0 with a^2+b^2=1)
+/EqDr {
+ 4 copy 3 -1 roll sub 7 1 roll exch sub 5 1 roll 4 -1 roll
+ mul 3 1 roll mul exch sub
+ 2 index dup mul 2 index dup mul add sqrt
+ 4 -1 roll 1 index div exch
+ 4 -1 roll 1 index div exch
+ 4 -1 roll 1 index div exch pop
+} bind def
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% orthogonal projection of M1 onto (OM2)
+%% x1 y1 x2 y2 -> x3 y3
+/Project {
+ 2 copy dup mul exch dup mul add 5 1 roll 2 copy 5 -1 roll mul exch
+ 5 -1 roll mul add 4 -1 roll div dup 4 -1 roll mul exch 3 -1 roll mul
+} bind def
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% a b c (ax2+bx+c=0) -> x1 y1
+/SolvTrin {
+ /c exch def /b exch def /a exch def
+ b dup mul a c mul 4 mul sub dup 0 lt
+ { pop 0 0 } %% no solutions
+ {sqrt dup b neg add a 2 mul div exch b add neg 2 a mul div }
+ ifelse } bind def
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% x1 y1 x2 y2 -> Dist
+/ABDist { 3 -1 roll sub dup mul 3 1 roll sub dup mul add sqrt } bind def
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% x1 y1 x2 y2 -> x1-x2 y1-y2
+/ABVect { 3 -1 roll exch sub 3 1 roll sub exch } bind def
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% x1 y1 x2 y2 x3 y3 x4 y4 -> x y
+/InterLines {
+ EqDr /D1c exch def /D1b exch def /D1a exch def
+ EqDr /D2c exch def /D2b exch def /D2a exch def
+ D1a D2b mul D1b D2a mul sub dup ZeroEq
+% { pop pop pop 0 0 } %% parallel lines % --- hv 20110714
+ { pop 0 0 } %% parallel lines --- hv 20110714
+ {
+ /Det exch def
+ D1b D2c mul D1c D2b mul sub Det div
+ D1a D2c mul D2a D1c mul sub Det div
+ } ifelse } bind def
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% a b c R -> x1 y1 x2 y2
+/InterLineCircle {
+ /CR exch def /Dc exch def neg /Db exch def /Da exch def
+ ABVect /Vy exch def /Vx exch def
+ %% Dc==0 then O belong to the line
+ %% First project O on the line -> M (-ca;-cb)
+ %% l'abscisse de M sur (OM) divisée par R donne le cosinus
+ %Dc neg dup Db mul exch Da mul 2 copy 0 0
+ %ABDist dup CR gt { pop pop pop 0 0 0 0 }
+ %{ ZeroEq { pop pop Db Da } if Atan /alpha exch def
+ Dc abs CR gt { 0 0 0 0 }
+ { Db neg Da neg Atan /alpha exch def
+ Dc CR div dup dup mul 1 exch sub sqrt exch Atan /beta exch def
+ alpha beta add dup cos CR mul exch sin CR mul
+ alpha beta sub dup cos CR mul exch sin CR mul
+ 4 copy ABVect Vy mul 0 le exch Vx mul 0 le and
+ { 4 2 roll } if } ifelse
+ } def
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% R R' OO' -> x1 y1 x2 y2
+/InterCircles {
+ /OOP exch def /CRP exch def /CR exch def
+ OOP dup mul CRP dup mul sub CR dup mul add OOP div 2 div
+ dup dup mul CR dup mul exch sub dup
+ 0 lt { pop pop 0 0 0 0 } { sqrt 2 copy neg } ifelse
+} bind def
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% x y theta -> x' y' (rotation of theta)
+/Rotate {
+ dup sin /sintheta exch def cos /costheta exch def /y exch def /x exch def
+ x costheta mul y sintheta mul sub
+ y costheta mul x sintheta mul add
+} def
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% N -> x y
+/GetNode {
+ tx@NodeDict begin
+ tx@NodeDict 1 index known { load GetCenter } { pop 0 0 } ifelse
+ end
+} bind def
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% x -> ch(x)
+/ch { dup Ex exch neg Ex add 2 div } bind def
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% x -> sh(x)
+/sh { dup Ex exch neg Ex sub 2 div } bind def
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% x -> e^(x)
+/Ex { E exch exp } bind def
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% x f g -> x y n
+/NewtonSolving {
+ /g exch def /f exch def 0
+ { %%% STACK: x0 n
+ 1 add exch %% one more loop
+ dup ZeroEq
+ { dup 0.0005 add fgeval
+ 1 index 0.0005 sub fgeval sub .001 div }
+ { dup 1.0005 mul fgeval
+ 1 index 0.9995 mul fgeval sub .001 2 index mul div } ifelse %%% STACK: n x0 fg'(x0)
+ %%% compute x1=x0-fg(x0)/fg'(x0)
+ 1 index fgeval exch div dup 4 1 roll sub exch %% stack: dx x0 n
+ 3 -1 roll ZeroEq %% exit if root found
+ 1 index 100 eq or { exit } if %% or looping for more than 100 times
+ } loop
+ dup 100 lt { exch dup /x exch def f } { pop 0 0 } ifelse
+ 3 -1 roll
+} def
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+/fgeval { /x exch def f g sub } bind def
+end
+% END ps-euclide.pro
diff --git a/graphics/pstricks/contrib/pst-eucl/dvips/pst-eucl.pro b/graphics/pstricks/contrib/pst-eucl/dvips/pst-eucl.pro
index d45dfca68a..3d2fe93c80 100644
--- a/graphics/pstricks/contrib/pst-eucl/dvips/pst-eucl.pro
+++ b/graphics/pstricks/contrib/pst-eucl/dvips/pst-eucl.pro
@@ -1,6 +1,6 @@
%!
% PostScript prologue for pst-eucl.tex.
-% Version 1.01 2012/09/21
+% Version 1.02 2012/11/21
% For distribution, see pstricks.tex.
%
/tx@EcldDict 40 dict def tx@EcldDict begin
@@ -69,7 +69,7 @@
%Dc neg dup Db mul exch Da mul 2 copy 0 0
%ABDist dup CR gt { pop pop pop 0 0 0 0 }
%{ ZeroEq { pop pop Db Da } if Atan /alpha exch def
- Dc abs CR gt { 0 0 0 0 }
+ Dc abs CR gt { 0 0 0 0 }
{ Db neg Da neg Atan /alpha exch def
Dc CR div dup dup mul 1 exch sub sqrt exch Atan /beta exch def
alpha beta add dup cos CR mul exch sin CR mul
@@ -129,5 +129,140 @@
} def
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/fgeval { /x exch def f g sub } bind def
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% calculate the line coefficents Ax+By+C=0
+%% x1 y1 x2 y2 -> A B C
+/LineCoefABC {
+ 0 index 3 index sub % A=y2-y1
+ 4 index 3 index sub % B=x1-x2
+ 3 index 5 index mul 6 index 4 index mul sub % C=x2y1-x1y2
+ 7 3 roll pop pop pop pop
+} def
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% calculate the 2-order determinant
+%% |a11 a12|
+%% |a21 a22|
+%% a11 a12, a21 a22 -> X
+/DeterminantTwo {
+ 4 1 roll mul 3 1 roll mul exch sub
+} def
+%% calculate the 3-order determinant
+%% |a11 a12 a13|
+%% |a21 a22 a23|
+%% |a31 a32 a33|
+%% 8 7 6 5 4 3 2 1 0
+%% a11 a12 a13, a21 a22 a23, a31 a32 a33 -> X
+/DeterminantThree {
+ % |a22 a23, a32 a33| * (-1)^(1+1)a11
+ 8 index abs 1E-5 lt { %a11=0
+ 0
+ } {
+ 4 index 4 index 3 index 3 index DeterminantTwo
+ 9 index mul
+ } ifelse
+ % |a12 a13, a32 a33| * (-1)^(1+2)a21
+ 6 index abs 1E-5 lt { %a12=0
+ 0 sub
+ } {
+ 8 index 8 index 4 index 4 index DeterminantTwo
+ 7 index mul sub
+ } ifelse
+ % |a12 a13, a22 a23| * (-1)^(1+3)a31
+ 3 index abs 1E-5 lt { %a13=0
+ 0 add
+ } {
+ 8 index 8 index 7 index 7 index DeterminantTwo
+ 4 index mul add
+ } ifelse
+ 10 1 roll pop pop pop pop pop pop pop pop pop
+} def
+%% calculate the 4-order determinant
+%% |a11 a12 a13 a14|
+%% |a21 a22 a23 a24|
+%% |a31 a32 a33 a34|
+%% |a41 a42 a43 a44|
+%% 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+%% a11 a12 a13 a14, a21 a22 a23 a24, a31 a32 a33 a34, a41 a42 a43 a44 -> X
+/DeterminantFour {
+ % |a22 a23 a24, a32 a33 a34, a42 a43 a44| * (-1)^(1+1)a11
+ 15 index abs 1E-5 lt { %a11=0
+ 0
+ } {
+ 10 index 10 index 10 index 9 index 9 index 9 index 8 index 8 index 8 index DeterminantThree
+ 16 index mul
+ } ifelse
+ % |a12 a13 a14, a32 a33 a34, a42 a43 a44| * (-1)^(1+2)a21
+ 12 index abs 1E-5 lt { %a21=0
+ 0 sub
+ } {
+ 15 index 15 index 15 index 10 index 10 index 10 index 9 index 9 index 9 index DeterminantThree
+ 13 index mul sub
+ } ifelse
+ % |a12 a13 a14, a22 a23 a24, a42 a43 a44| * (-1)^(1+3)a31
+ 8 index abs 1E-5 lt { %a31=0
+ 0 add
+ } {
+ 15 index 15 index 15 index 14 index 14 index 14 index 9 index 9 index 9 index DeterminantThree
+ 9 index mul add
+ } ifelse
+ % |a12 a13 a14, a22 a23 a24, a32 a33 a34| * (-1)^(1+4)a41
+ 4 index abs 1E-5 lt { %a41=0
+ 0 sub
+ } {
+ 15 index 15 index 15 index 14 index 14 index 14 index 13 index 13 index 13 index DeterminantThree
+ 5 index mul sub
+ } ifelse
+ 17 1 roll pop pop pop pop pop pop pop pop
+ pop pop pop pop pop pop pop pop
+} def
+%% calculate the 5-order determinant
+%% |a11 a12 a13 a14 a15|
+%% |a21 a22 a23 a24 a25|
+%% |a31 a32 a33 a34 a35|
+%% |a41 a42 a43 a44 a45|
+%% |a51 a52 a53 a54 a55|
+%% 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+%% a11 a12 a13 a14 a15, a21 a22 a23 a24 a25, a31 a32 a33 a34 a35, a41 a42 a43 a44 a45, a51 a52 a53 a54 a55-> X
+/DeterminantFive {
+ % |a22 a23 a24 a25, a32 a33 a34 a35, a42 a43 a44 a45, a52 a53 a54 a55| * (-1)^(1+1)a11
+ 24 index abs 1E-5 lt { %a11=0
+ 0
+ } {
+ 18 index 18 index 18 index 18 index 17 index 17 index 17 index 17 index 16 index 16 index 16 index 16 index 15 index 15 index 15 index 15 index DeterminantFour
+ 25 index mul
+ } ifelse
+ % |a12 a13 a14 a15, a32 a33 a34 a35, a42 a43 a44 a45, a52 a53 a54 a55| * (-1)^(1+2)a21
+ 20 index abs 1E-5 lt { %a21=0
+ 0 sub
+ } {
+ 24 index 24 index 24 index 24 index 18 index 18 index 18 index 18 index 17 index 17 index 17 index 17 index 16 index 16 index 16 index 16 index DeterminantFour
+ 21 index mul sub
+ } ifelse
+ % |a12 a13 a14 a15, a22 a23 a24 a25, a42 a43 a44 a45, a52 a53 a54 a55| * (-1)^(1+3)a31
+ 15 index abs 1E-5 lt { %a31=0
+ 0 add
+ } {
+ 24 index 24 index 24 index 24 index 23 index 23 index 23 index 23 index 17 index 17 index 17 index 17 index 16 index 16 index 16 index 16 index DeterminantFour
+ 16 index mul add
+ } ifelse
+ % |a12 a13 a14 a15, a22 a23 a24 a25, a32 a33 a34 a35, a52 a53 a54 a55| * (-1)^(1+4)a41
+ 10 index abs 1E-5 lt { %a41=0
+ 0 sub
+ } {
+ 24 index 24 index 24 index 24 index 23 index 23 index 23 index 23 index 22 index 22 index 22 index 22 index 16 index 16 index 16 index 16 index DeterminantFour
+ 11 index mul sub
+ } ifelse
+ % |a12 a13 a14 a15, a22 a23 a24 a25, a32 a33 a34 a35, a42 a43 a44 a45| * (-1)^(1+5)a51
+ 5 index abs 1E-5 lt { %a51=0
+ 0 add
+ } {
+ 24 index 24 index 24 index 24 index 23 index 23 index 23 index 23 index 22 index 22 index 22 index 22 index 21 index 21 index 21 index 21 index DeterminantFour
+ 6 index mul add
+ } ifelse
+ 26 1 roll pop pop pop pop pop pop pop pop pop pop
+ pop pop pop pop pop pop pop pop pop pop
+ pop pop pop pop pop
+} def
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
end
% END ps-euclide.pro
diff --git a/graphics/pstricks/contrib/pst-eucl/latex/pst-eucl.sty b/graphics/pstricks/contrib/pst-eucl/latex/pst-eucl.sty
index 8b4a2c0e3c..7a0c4e993d 100644
--- a/graphics/pstricks/contrib/pst-eucl/latex/pst-eucl.sty
+++ b/graphics/pstricks/contrib/pst-eucl/latex/pst-eucl.sty
@@ -10,6 +10,6 @@
[\filedate\space v\fileversion\space `PST-eucl' (dr,hv)]
\IfFileExists{pst-eucl.pro}{%
\ProvidesFile{pst-eucl.pro}
- [2012/09/21 v. 1.01, PostScript prologue file (hv)]
+ [2019/11/21 v. 1.02, PostScript prologue file (hv)]
\@addtofilelist{pst-eucl.pro}}{}%
\endinput
diff --git a/graphics/pstricks/contrib/pst-eucl/tex/pst-eucl.tex b/graphics/pstricks/contrib/pst-eucl/tex/pst-eucl.tex
index 690515707d..c4b7b53296 100644
--- a/graphics/pstricks/contrib/pst-eucl/tex/pst-eucl.tex
+++ b/graphics/pstricks/contrib/pst-eucl/tex/pst-eucl.tex
@@ -20,8 +20,8 @@
\csname PSTEuclideLoaded\endcsname
\let\PSTEuclideLoaded\endinput
%
-\def\fileversion{1.67}
-\def\filedate{2019/10/28}
+\def\fileversion{1.68}
+\def\filedate{2019/11/21}
%%
\message{`PST-Euclide v\fileversion, \filedate\space (dr,hv)}%
%% prologue for postcript
@@ -229,6 +229,43 @@
\edef\psk@PosAngle{\expandafter\PstParamListLasts\OldPosAngle,undef/}%
\edef\psk@PointSymbol{\expandafter\PstParamListLasts\OldPointSymbol,undef/}}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% \pstParseArg{ArgPrefix}{ElementiList}{ValueList}
+%% parse the ValueList into element named in ElementList with prefix ArgPrefix.
+%% ArgPrefix - the prefix of the element name
+%% ElementList - the element list joined with comma
+%% ValueList - the value list joined with comma
+%
+%% For example, the following command
+%% \pstParseArg{EqnCoef}{a,b,c,d,e,f}{1,2,3,4,5,6}
+%% will create six variable elements:
+%% \EqnCoefa,\EqnCoefb,\EqnCoefc,...,\EqnCoeff
+%% with value 1,2,3,...,6 respectively.
+%
+\def\pstParseArg#1#2#3{%
+\def\@ArgPrefix{#1}%
+\Pst@ParseArg{#2}{#3}%
+}%
+\def\Pst@ParseArg#1#2{%
+\@List{#1}\edef\@ElementList{\@NewList}%
+\edef\@ArgElement{\expandafter\PstParamListFirst\@ElementList,undef/}%
+\@List{#2}\edef\@ValueList{\@NewList}%
+\edef\@ArgValue{\expandafter\PstParamListFirst\@ValueList,undef/}%
+\Pst@ParseArg@i%
+}%
+\def\pst@BuildArg#1#2#3{%
+\expandafter\edef\csname #1#2\endcsname{#3}%
+}%
+\def\Pst@ParseArg@i{%
+\ifx\@ArgValue\@undef\def\@ArgValue{0.00}\fi
+%\typeout{\@ArgPrefix\@ArgElement:\@ArgValue}
+\pst@BuildArg{\@ArgPrefix}{\@ArgElement}{\@ArgValue}%
+\edef\@ValueList{\expandafter\PstParamListLasts\@ValueList,undef/}%
+\edef\@ArgValue{\expandafter\PstParamListFirst\@ValueList,undef/}%
+\edef\@ElementList{\expandafter\PstParamListLasts\@ElementList,undef/}%
+\edef\@ArgElement{\expandafter\PstParamListFirst\@ElementList,undef/}%
+\ifx\@ArgElement\@undef\else\Pst@ParseArg@i\fi%
+}%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Create a point with an associated node,
%% #1 -> options
%% #2 -> coordinates
@@ -563,6 +600,458 @@
}%
%
\def\pst@TraceTriangle#1#2#3{\pspolygon(#1)(#2)(#3)}%
+%
+%% \pstTriangleSSS[Options](pos){A}(a,b,c){B}{C}
+%% Create a triangle ABC whose three sides are a,b,c.
+%% Given $A(x_1,y_1)$, and the three sides $a,b,c$,
+%% when pos=L, we output $B(x_2,y_2)$ and $C(x_3,y_3)$ as following
+%% $$x_2=x_1+c,y_2=y_1$$
+%% since
+%% $$\cos{A}=\dfrac{c^2+b^2-a^2}{2bc}$$
+%% so
+%% $$x_3=x_1+b\cos{A},y_3=y_1+b\sin{A}$$
+%% we have
+%% $$x_3=x_1+\dfrac{c^2+b^2-a^2}{2c}$$
+%% and
+%% $$y_3=y_1+\sqrt{b^2-(x_3-x_1)^2}$$
+%%
+%% Parameters:
+%% #1 -> options
+%% #2 -> optional, the pos of given input node A, L/R/U/D
+%% #3 -> the given input node A
+%% #4 -> the given side BC=a
+%% #5 -> the given side CA=b
+%% #6 -> the given side AB=c
+%% #7 -> the output node B
+%% #8 -> the output node C
+\def\pstTriangleSSS{\@ifnextchar[\Pst@TriangleSSS{\Pst@TriangleSSS[]}}
+\def\Pst@TriangleSSS[#1]{%
+ \begingroup
+ \@InitListMng%
+ \psset{#1}%
+ \@ifnextchar(\Pst@TriangleSSS@i{\Pst@TriangleSSS@i(L)}}
+\def\Pst@TriangleSSS@i(#1)#2(#3,#4,#5)#6#7{%
+ \def\Pst@TriangleSSS@left{L}
+ \def\Pst@TriangleSSS@right{R}
+ \def\Pst@TriangleSSS@up{U}
+ \def\Pst@TriangleSSS@down{D}
+ \def\Pst@TriangleSSS@pos{#1}
+ \pst@getcoor{#2}\pst@tempA%
+ \ifx\Pst@TriangleSSS@pos\Pst@TriangleSSS@right%
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % a,b,c
+ %% x_2=x_1-\dfrac{c^2+b^2-a^2}{2b}
+ 1 index dup mul 1 index dup mul add 3 index dup mul sub 2 index 2 mul div 5 index exch sub
+ %% y_2=y_1+\sqrt{c^2-(x_2-x_1)^2}
+ 1 index dup mul 1 index 7 index sub dup mul sub sqrt 5 index add
+ 7 2 roll pop pop pop pop pop
+ ){#6}%B
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % a,b,c
+ 4 index 2 index sub 4 index % x1-b,y1
+ 7 2 roll pop pop pop pop pop
+ ){#7}%C
+ \else\ifx\Pst@TriangleSSS@pos\Pst@TriangleSSS@up
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % a,b,c
+ %% x_2=x_1-\dfrac{c^2+a^2-b^2}{2a}
+ 2 index dup mul 1 index dup mul add 2 index dup mul sub 3 index 2 mul div 5 index exch sub
+ %% y_2=y_1-\sqrt{c^2-(x_2-x_1)^2}
+ 1 index dup mul 1 index 7 index sub dup mul sub sqrt 5 index exch sub
+ 7 2 roll pop pop pop pop pop
+ ){#6}%B
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % a,b,c
+ %% x_3=x_1+\dfrac{a^2+b^2-c^2}{2a}
+ 2 index dup mul 2 index dup mul add 1 index dup mul sub 3 index 2 mul div 5 index add
+ %% y_3=y_1-\sqrt{b^2-(x_3-x_1)^2}
+ 2 index dup mul 1 index 7 index sub dup mul sub sqrt 5 index exch sub
+ 7 2 roll pop pop pop pop pop
+ ){#7}%C
+ \else\ifx\Pst@TriangleSSS@pos\Pst@TriangleSSS@down
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % a,b,c
+ %% x_2=x_1+\dfrac{a^2+c^2-b^2}{2a}
+ 2 index dup mul 1 index dup mul add 2 index dup mul sub 3 index 2 mul div 5 index add
+ %% y_2=y_1+\sqrt{c^2-(x_2-x_1)^2}
+ 1 index dup mul 1 index 7 index sub dup mul sub sqrt 5 index add
+ 7 2 roll pop pop pop pop pop
+ ){#6}%B
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % a,b,c
+ %% x_3=x_1-\dfrac{a^2+b^2-c^2}{2a}
+ 2 index dup mul 2 index dup mul add 1 index dup mul sub 3 index 2 mul div 5 index exch sub
+ %% y_3=y_1+\sqrt{b^2-(x_3-x_1)^2}
+ 2 index dup mul 1 index 7 index sub dup mul sub sqrt 5 index add
+ 7 2 roll pop pop pop pop pop
+ ){#7}%C
+ \else% default position is at left vertex
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % a,b,c
+ 4 index 1 index add 4 index % x1+c,y1
+ 7 2 roll pop pop pop pop pop
+ ){#6}%B
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % a,b,c
+ %% x_3=x_1+\dfrac{c^2+b^2-a^2}{2c}
+ 1 index dup mul 1 index dup mul add 3 index dup mul sub 1 index 2 mul div 5 index add
+ %% y_3=y_1+\sqrt{b^2-(x_3-x_1)^2}
+ 2 index dup mul 1 index 7 index sub dup mul sub sqrt 5 index add
+ 7 2 roll pop pop pop pop pop
+ ){#7}%C
+ \fi\fi\fi%
+ \Pst@ManageParamList{#6}%
+ \Pst@ManageParamList{#7}%
+ \pstLineAB{#2}{#6}%
+ \pstLineAB{#2}{#7}%
+ \pstLineAB{#6}{#7}%
+ \endgroup%
+}%
+%
+%% \pstTriangleSAS[Options](pos){A}(b,A,c){B}{C}
+%% Create a triangle ABC whth sides b,c and angle A.
+%% Given $A(x_1,y_1)$, and the angle of A, the other two sides $b,c$,
+%% when pos=L, we output $B(x_2,y_2)$ and $C(x_3,y_3)$ as following
+%% $$x_2=x_1+c,y_2=y_1$$
+%% and
+%% $$x_3=x_1+b\cos{A},y_3=y_1+b\sin{A}$$
+%%
+%% Parameters:
+%% #1 -> options
+%% #2 -> optional, the pos of given input node A, L/R/U/D
+%% #3 -> the given input node A
+%% #4 -> the given side AC=b
+%% #5 -> the given angle A
+%% #6 -> the given side AB=c
+%% #7 -> the output node B
+%% #8 -> the output node C
+\def\pstTriangleSAS{\@ifnextchar[\Pst@TriangleSAS{\Pst@TriangleSAS[]}}
+\def\Pst@TriangleSAS[#1]{%
+ \begingroup
+ \@InitListMng%
+ \psset{#1}%
+ \@ifnextchar(\Pst@TriangleSAS@i{\Pst@TriangleSAS@i(L)}}
+\def\Pst@TriangleSAS@i(#1)#2(#3,#4,#5)#6#7{%
+ \def\Pst@TriangleSAS@left{L}
+ \def\Pst@TriangleSAS@right{R}
+ \def\Pst@TriangleSAS@up{U}
+ \def\Pst@TriangleSAS@down{D}
+ \def\Pst@TriangleSAS@pos{#1}
+ \pst@getcoor{#2}\pst@tempA%
+ \ifx\Pst@TriangleSAS@pos\Pst@TriangleSAS@right%
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % b,A,c
+ % x2=x1-c\cos{A},y2=y1+c\sin{A}
+ 4 index 1 index 3 index cos mul sub
+ 4 index 2 index 4 index sin mul add
+ 7 2 roll pop pop pop pop pop
+ ){#6}%
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % b,A,c
+ % x_3=x_1-b,y_3=y_1
+ 4 index 3 index sub 4 index % x1-b,y1
+ 7 2 roll pop pop pop pop pop
+ ){#7}%
+ \else\ifx\Pst@TriangleSAS@pos\Pst@TriangleSAS@up
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % b,A,c
+ % a^2=b^2+c^2-2bc\cos{A}
+ 2 index dup mul 1 index dup mul add 3 index 2 index mul 2 mul 3 index cos mul sub sqrt % a
+ % y2=y1-c\sin{B}=y1-bc\sin{A}/a
+ 4 index 4 index 3 index mul 4 index sin mul 2 index div sub % y2
+ % x2=x1-c\cos{B}=x1-\dfrac{a^2+c^2-b^2}{2a}
+ 6 index 3 index dup mul 3 index dup mul add 6 index dup mul sub 3 index 2 mul div sub exch % x2
+ 8 2 roll pop pop pop pop pop pop
+ ){#6}%
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % b,A,c
+ % a^2=b^2+c^2-2bc\cos{A}
+ 2 index dup mul 1 index dup mul add 3 index 2 index mul 2 mul 3 index cos mul sub sqrt % a
+ % y3=y1-b\sin{C}=y1-bc\sin{A}/a
+ 4 index 4 index 3 index mul 4 index sin mul 2 index div sub % y3
+ % x3=x1+b\cos{C}=x1+\dfrac{a^2+b^2-c^2}{2a}
+ 6 index 5 index dup mul 3 index dup mul add 4 index dup mul sub 3 index 2 mul div add exch % x3
+ 8 2 roll pop pop pop pop pop pop
+ ){#7}%
+ \else\ifx\Pst@TriangleSAS@pos\Pst@TriangleSAS@down
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % b,A,c
+ % a^2=b^2+c^2-2bc\cos{A}
+ 2 index dup mul 1 index dup mul add 3 index 2 index mul 2 mul 3 index cos mul sub sqrt % a
+ % y2=y1+c\sin{B}=y1+bc\sin{A}/a
+ 4 index 4 index 3 index mul 4 index sin mul 2 index div add % y2
+ % x2=x1+c\cos{B}=x1+\dfrac{a^2+c^2-b^2}{2a}
+ 6 index 3 index dup mul 3 index dup mul add 6 index dup mul sub 3 index 2 mul div add exch % x2
+ 8 2 roll pop pop pop pop pop pop
+ ){#6}%
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % b,A,c
+ % a^2=b^2+c^2-2bc\cos{A}
+ 2 index dup mul 1 index dup mul add 3 index 2 index mul 2 mul 3 index cos mul sub sqrt % a
+ % y3=y1+b\sin{C}=y1+bc\sin{A}/a
+ 4 index 4 index 3 index mul 4 index sin mul 2 index div add % y3
+ % x3=x1-b\cos{C}=x1-\dfrac{a^2+b^2-c^2}{2a}
+ 6 index 5 index dup mul 3 index dup mul add 4 index dup mul sub 3 index 2 mul div sub exch % x3
+ 8 2 roll pop pop pop pop pop pop
+ ){#7}%
+ \else% default position is at left vertex
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % b,A,c
+ 4 index 1 index add 4 index % x1+c,y1
+ 7 2 roll pop pop pop pop pop
+ ){#6}%
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % b,A,c
+ %% x_3=x_1+b\cos{A},y_3=y_1+b\sin{A}
+ 4 index 3 index 3 index cos mul add
+ 4 index 4 index 4 index sin mul add
+ 7 2 roll pop pop pop pop pop
+ ){#7}%
+ \fi\fi\fi%
+ \Pst@ManageParamList{#6}%
+ \Pst@ManageParamList{#7}%
+ \pstLineAB{#2}{#6}%
+ \pstLineAB{#2}{#7}%
+ \pstLineAB{#6}{#7}%
+ \endgroup%
+}%
+%
+%% \pstTriangleAAS[Options](pos){A}(C,A,c){B}{C}
+%% Create a triangle ABC with angle A,C and side AB=c.
+%%
+%% Given $A(x_1,y_1)$, and the angle of A, the angle of C, the side of AB $c$,
+%% when pos=L, we output $B(x_2,y_2)$ and $C(x_3,y_3)$ as following
+%% $$x_2=x_1+c,y_2=y_1$$
+%% and
+%% $$x_3=x_1+b\cos{A}=x_1+\dfrac{c\sin{B}}{\sin{C}}\cos{A},y_3=y_1+b\sin{A}=y_1+\dfrac{c\sin{B}}{\sin{C}}\sin{A}$$
+%% where $B=180-A-C$.
+%%
+%% Parameters:
+%% #1 -> options
+%% #2 -> optional, the pos of given input node A, L/R/U/D
+%% #3 -> the given input node A
+%% #4 -> the given angle C
+%% #5 -> the given angle A
+%% #6 -> the given side AB=c
+%% #7 -> the output node B
+%% #8 -> the output node C
+\def\pstTriangleAAS{\@ifnextchar[\Pst@TriangleAAS{\Pst@TriangleAAS[]}}
+\def\Pst@TriangleAAS[#1]{%
+ \begingroup
+ \@InitListMng%
+ \psset{#1}%
+ \@ifnextchar(\Pst@TriangleAAS@i{\Pst@TriangleAAS@i(L)}}
+\def\Pst@TriangleAAS@i(#1)#2(#3,#4,#5)#6#7{%
+ \def\Pst@TriangleAAS@left{L}
+ \def\Pst@TriangleAAS@right{R}
+ \def\Pst@TriangleAAS@up{U}
+ \def\Pst@TriangleAAS@down{D}
+ \def\Pst@TriangleAAS@pos{#1}
+ \pst@getcoor{#2}\pst@tempA%
+ \ifx\Pst@TriangleAAS@pos\Pst@TriangleAAS@right%
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % C,A,c
+ % x2=x1-c\cos{A},y2=y1+c\sin{A}
+ 4 index 1 index 3 index cos mul sub % x2
+ 4 index 2 index 4 index sin mul add % y2
+ 7 2 roll pop pop pop pop pop
+ ){#6}%
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % C,A,c
+ % x3=x1-b=x1-c\sin(A+C)/\sin{C},y3=y1
+ 4 index 1 index 4 index 4 index add sin mul 4 index sin div sub % x3
+ 4 index % y3
+ 7 2 roll pop pop pop pop pop
+ ){#7}%
+ \else\ifx\Pst@TriangleAAS@pos\Pst@TriangleAAS@up
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % C,A,c
+ % x2=x1-c\cos{B},y2=y1-c\sin{B}
+ 4 index 1 index 4 index 4 index add 180 exch sub cos mul sub % x2
+ 4 index 2 index 5 index 5 index add 180 exch sub sin mul sub % y2
+ 7 2 roll pop pop pop pop pop
+ ){#6}%
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % C,A,c
+ % b=c\sin{B}/\sin{C}
+ % x3=x1+b\cos{C}=x1+c\sin(A+C)\cos{C}/\sin{C}
+ % y3=y1-b\sin{C}=y1-c\sin(A+C)
+ 4 index 1 index 4 index 4 index add sin mul 4 index cos mul 4 index sin div add % x3
+ 4 index 2 index 5 index 5 index add sin mul sub % y3
+ 7 2 roll pop pop pop pop pop
+ ){#7}%
+ \else\ifx\Pst@TriangleAAS@pos\Pst@TriangleAAS@down
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % C,A,c
+ % x2=x1+c\cos{B},y2=y1+c\sin{B}
+ 4 index 1 index 4 index 4 index add 180 exch sub cos mul add % x2
+ 4 index 2 index 5 index 5 index add sin mul add % y2
+ 7 2 roll pop pop pop pop pop
+ ){#6}%
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % C,A,c
+ % x3=x1-b\cos{C}=x1-c\sin(A+C)\cos{C}/\sin{C},y3=y1+c\sin{B}
+ 4 index 1 index 4 index 4 index add sin mul 4 index cos mul 4 index sin div sub % x3
+ 4 index 2 index 5 index 5 index add sin mul add % y3
+ 7 2 roll pop pop pop pop pop
+ ){#7}%
+ \else% default position is at left vertex
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % C,A,c
+ 4 index 1 index add 4 index % x1+c,y1
+ 7 2 roll pop pop pop pop pop
+ ){#6}%
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % C,A,c
+ 0 index 3 index 3 index add sin mul 3 index sin div % b=\dfrac{c\sin{B}}{\sin{C}}
+ %% x_3=x_1+b\cos{A}
+ 2 index cos 1 index mul 6 index add
+ %% y_3=y_1+b\sin{A}
+ 3 index sin 2 index mul 6 index add
+ 8 2 roll pop pop pop pop pop pop
+ ){#7}%
+ \fi\fi\fi%
+ \Pst@ManageParamList{#6}%
+ \Pst@ManageParamList{#7}%
+ \pstLineAB{#2}{#6}%
+ \pstLineAB{#2}{#7}%
+ \pstLineAB{#6}{#7}%
+ \endgroup%
+}%
+%
+%% \pstTriangleASA[Options](pos){A}(A,c,B){B}{C}
+%% Create a triangle ABC with angle A,B and side AB=c.
+%%
+%% Given $A(x_1,y_1)$, and the angle of A, the angle of B, the side of AB $c$,
+%% when pos=L, we output $B(x_2,y_2)$ and $C(x_3,y_3)$ as following
+%% $$x_2=x_1+c,y_2=y_1$$
+%% and
+%% $$x_3=x_1+b\cos{A}=x_1+\dfrac{c\sin{B}}{\sin{C}}\cos{A},y_3=y_1+b\sin{A}=y_1+\dfrac{c\sin{B}}{\sin{C}}\sin{A}$$
+%% where $C=180-A-B$.
+%%
+%% Parameters:
+%% #1 -> options
+%% #2 -> optional, the pos of given input node A, L/R/U/D
+%% #3 -> the given input node A
+%% #4 -> the given angle A
+%% #5 -> the given side AB=c
+%% #6 -> the given angle B
+%% #7 -> the output node B
+%% #8 -> the output node C
+\def\pstTriangleASA{\@ifnextchar[\Pst@TriangleASA{\Pst@TriangleASA[]}}
+\def\Pst@TriangleASA[#1]{%
+ \begingroup
+ \@InitListMng%
+ \psset{#1}%
+ \@ifnextchar(\Pst@TriangleASA@i{\Pst@TriangleASA@i(L)}}
+\def\Pst@TriangleASA@i(#1)#2(#3,#4,#5)#6#7{%
+ \def\Pst@TriangleASA@left{L}
+ \def\Pst@TriangleASA@right{R}
+ \def\Pst@TriangleASA@up{U}
+ \def\Pst@TriangleASA@down{D}
+ \def\Pst@TriangleASA@pos{#1}
+ \pst@getcoor{#2}\pst@tempA%
+ \ifx\Pst@TriangleASA@pos\Pst@TriangleASA@right%
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % A,c,B
+ % x2=x1-c\cos{A},y2=y1+c\sin{A}
+ 4 index 2 index 4 index cos mul sub % x2
+ 4 index 3 index 5 index sin mul add % y2
+ 7 2 roll pop pop pop pop pop
+ ){#6}%
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % A,c,B
+ % x3=x1-b=x1-c\sin{B}/\sin(A+B),y2=y1
+ 4 index 2 index 2 index sin mul 4 index 3 index add sin div sub % x3
+ 4 index % y2
+ 7 2 roll pop pop pop pop pop
+ ){#7}%
+ \else\ifx\Pst@TriangleASA@pos\Pst@TriangleASA@up
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % A,c,B
+ % x2=x1-c\cos{B},y2=y1-c\sin{B}
+ 4 index 2 index 2 index cos mul sub % x2
+ 4 index 3 index 3 index sin mul sub % y2
+ 7 2 roll pop pop pop pop pop
+ ){#6}%
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % A,c,B
+ % x3=x1+b\cos{C}=x1+c\sin{B}\cos{C}/\sin{C},y3=y1-c\sin{B}
+ 4 index 2 index 2 index sin mul 4 index 3 index add 180 exch sub dup cos exch sin div mul add % x3
+ 4 index 3 index 3 index sin mul sub % y3
+ 7 2 roll pop pop pop pop pop
+ ){#7}%
+ \else\ifx\Pst@TriangleASA@pos\Pst@TriangleASA@down
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % A,c,B
+ % x2=x1+c\cos{B},y2=y1+c\sin{B}
+ 4 index 2 index 2 index cos mul add % x2
+ 4 index 3 index 3 index sin mul add % y2
+ 7 2 roll pop pop pop pop pop
+ ){#6}%
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % A,c,B
+ % x3=x1-b\cos{C}=x1-c\sin{B}\cos{C}/\sin{C},y3=y1+c\sin{B}
+ 4 index 2 index 2 index sin mul 4 index 3 index add 180 exch sub dup cos exch sin div mul sub % x3
+ 4 index 3 index 3 index sin mul add % y3
+ 7 2 roll pop pop pop pop pop
+ ){#7}%
+ \else% default position is at left vertex
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % A,c,B
+ 4 index 2 index add 4 index % x1+c,y1
+ 7 2 roll pop pop pop pop pop
+ ){#6}%
+ \pnode(!
+ \pst@tempA \tx@UserCoor % x1,y1
+ #3 abs #4 abs #5 abs % A,c,B
+ 1 index 1 index sin mul 3 index 2 index add sin div % b=\dfrac{c\sin{B}}{\sin{C}}
+ %% x_3=x_1+b\cos{A}
+ 3 index cos 1 index mul 6 index add
+ %% y_3=y_1+b\sin{A}
+ 4 index sin 2 index mul 6 index add
+ 8 2 roll pop pop pop pop pop pop
+ ){#7}%
+ \fi\fi\fi%
+ \Pst@ManageParamList{#6}%
+ \Pst@ManageParamList{#7}%
+ \pstLineAB{#2}{#6}%
+ \pstLineAB{#2}{#7}%
+ \pstLineAB{#6}{#7}%
+ \endgroup%
+}%
+%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Line, circle, Arc
%% #2 #3 -> 2 nodes defining the line
@@ -585,7 +1074,7 @@
\psset{#1}%
\def\pst@circle@center{#2}
\def\pst@circle@node{#3}
- \@ifnextchar[\pstCircleOA@i{\pstCircleOA@i[0][360]}}%
+ \@ifnextchar[\pstCircleOA@i{\pstCircleOA@j}}%
\def\pstCircleOA@i[#1][#2]{%
\begin@OpenObj
\def\pst@linetype{4}%
@@ -606,6 +1095,26 @@
\end@OpenObj
\endgroup%
}%
+\def\pstCircleOA@j{%
+ \begin@ClosedObj
+ \def\pst@linetype{4}%
+ \addto@pscode{%
+ tx@EcldDict begin
+ /N@\pst@circle@center\space GetNode
+ \ifx\psk@Radius\@none
+ \ifx\psk@Diameter\@none
+ 2 copy /N@\pst@circle@node\space GetNode ABDist
+ \else\psk@Diameter\space 2 div
+ \fi
+ \else\psk@Radius\space
+ \fi
+ end
+ %\psk@dimen CLW mul sub 0 360 arc closepath}%
+ 0 360 arc closepath}%
+ \showpointsfalse
+ \end@ClosedObj
+ \endgroup%
+}%
%% #2 #3 -> 2 nodes defining a diameter of the circle
\def\pstCircleAB{\@ifnextchar[\Pst@CircleAB{\Pst@CircleAB[]}}
\def\Pst@CircleAB[#1]#2#3{%
@@ -613,7 +1122,7 @@
\psset{#1}%
\def\pst@circle@diameter@A{#2}
\def\pst@circle@diameter@B{#3}
- \@ifnextchar[\pstCircleAB@i{\pstCircleAB@i[0][360]}}%
+ \@ifnextchar[\pstCircleAB@i{\pstCircleAB@j}}%
\def\pstCircleAB@i[#1][#2]{%
\Pst@MiddleAB[PointSymbol=none, PointName=none]{\pst@circle@diameter@B}{\pst@circle@diameter@A}{PST@CIRCLE@MAB}
\begin@OpenObj
@@ -629,6 +1138,21 @@
\end@OpenObj
\endgroup%
}%
+\def\pstCircleAB@j{%
+ \Pst@MiddleAB[PointSymbol=none, PointName=none]{\pst@circle@diameter@B}{\pst@circle@diameter@A}{PST@CIRCLE@MAB}
+ \begin@ClosedObj
+ \def\pst@linetype{4}%
+ \addto@pscode{%
+ tx@NodeDict begin
+ tx@NodeDict /N@PST@CIRCLE@MAB load GetCenter
+ end
+ 2 copy
+ tx@EcldDict begin /N@\pst@circle@diameter@B\space GetNode ABDist end
+ \psk@dimen\space CLW mul sub 0 360 arc closepath}%
+ \showpointsfalse
+ \end@ClosedObj
+ \endgroup%
+}%
%% #2 #3 #4 -> 3 nodes defining the center and two points on the circle
\def\pstArcOAB{\pst@object{pstArcOAB}}%
\def\pstArcnOAB{\pst@object{pstArcnOAB}}%
@@ -1888,6 +2412,13 @@
tx@EcldDict begin /N@#1 GetNode exch pop \pst@number\psyunit div end
}%
%
+\def\pstShowCoor#1{
+\begin@ClosedObj
+ \addto@pscode{%
+ tx@EcldDict begin /N@#1 GetNode exch \pst@number\psyunit div = \pst@number\psyunit div = end%
+ }
+\end@ClosedObj
+}%
%% \pstMoveNode[Options](dx,dy){A}{B}
%% move node A by abscissa increment dx and ordinate increment dy to the target node B.
%% This Macro will create the new node B.
@@ -1956,6 +2487,22 @@
\endgroup%
}%
%
+%% \pstBisectorAOB[Options]{A}{O}{B}{T_1}{T_2}
+%% redefine the bisector and outbisector of AOB, and create a new node on line AB!
+%% Parameters:
+%% #1 -> options
+%% #2 -> the given node A
+%% #3 -> the given node O
+%% #4 -> the given node B
+%% #5 -> the output bisector AT_1
+%% #6 -> the output out-bisector AT_2
+\def\pstBisectorAOB{\@ifnextchar[\Pst@BisectorAOB{\Pst@BisectorAOB[]}}%
+\def\Pst@BisectorAOB[#1]#2#3#4#5#6{%
+ \bgroup\psset{#1}%
+ \pstProportionNode{#2}{#4}{\pstDistDiv{#2}{#3}{#4}{#3}}{#5}{#6}
+ \egroup%
+}%
+%
%% \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$.
@@ -2109,6 +2656,50 @@
\endgroup%
}%
%
+%% \pstLineCoef[Options]{Coefficients}{A}{B}
+%% Create a new line with equation ax+by+c=0 and create the new nodes A, B on the line.
+%% Parameters:
+%% #1 -> options
+%% #2 -> [input] the coefficients a,b,c list
+%% #3 -> [output] the new node A on the line
+%% #4 -> [output] the new node B on the line
+\def\pstLineCoef{\@ifnextchar[\Pst@LineCoef{\Pst@LineCoef[]}}
+\def\Pst@LineCoef[#1]#2#3#4{%
+ \begingroup
+ \@InitListMng %
+ \psset{#1}%
+ \pstParseArg{LineCoef}{a,b,c}{#2}
+ \pnode(!
+ \LineCoefa /LineCoefa ED
+ \LineCoefb /LineCoefb ED
+ \LineCoefc /LineCoefc ED
+ LineCoefa abs 1E-5 lt { % a = 0
+ LineCoefb abs 1E-5 lt { % b = 0
+ 0 0
+ } {
+ 0 /LineAX ED
+ LineCoefc LineCoefb neg div /LineAY ED
+ 1 LineAY
+ } ifelse
+ } {
+ LineCoefb abs 1E-5 lt { % b = 0
+ LineCoefc LineCoefa neg div /LineAX ED
+ 0 /LineAY ED
+ LineAX 1
+ } {
+ 0 /LineAX ED
+ LineCoefc LineCoefb neg div /LineAY ED
+ 1 LineCoefa LineCoefc add LineCoefb neg div
+ } ifelse
+ } ifelse
+ ){#4}
+ \pnode(! LineAX LineAY){#3}
+ \Pst@ManageParamList{#3}%
+ \Pst@ManageParamList{#4}%
+ \pstLine{#3}{#4}
+ \endgroup%
+}%
+%
%% \pstLineAbsNode[Options]{A}{B}{$x_0$}{C}
%% Create a new node C on the line AB whose abscissa is the given value $x_0$.
%% You can input $x_0$ as any number(e.g, 2.0), and use \pscalculate{} to generate the value,
@@ -2312,6 +2903,24 @@
\endgroup%
}%
%
+%% \pstGoldenMean[Options]{A}{B}{C}
+%% Find the point $C$ on segment AB such that $|AC|^2=|AB|*|BC|$.
+%% We have $|AC|=\dfrac{\sqrt{5}-1}{2}|AB|$.
+%% Parameters:
+%% #1 -> options
+%% #2 -> the first node A on the given segment
+%% #3 -> the second node B on the given segment
+%% #4 -> the output node C
+\def\pstGoldenMean{\@ifnextchar[\Pst@GoldenMean{\Pst@GoldenMean[]}}
+\def\Pst@GoldenMean[#1]{%
+ \begingroup
+ \psset{#1}%
+ \Pst@GoldenMean@i}
+\def\Pst@GoldenMean@i#1#2#3{%
+ \pstLocateAB{#1}{#2}{5 sqrt 1 sub 2 div \pstDist{#1}{#2} mul}{#3}
+ \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:
@@ -2346,11 +2955,35 @@
\def\pstCircleAbsNode{\@ifnextchar[\Pst@CircleAbsNode{\Pst@CircleAbsNode[]}}
\def\Pst@CircleAbsNode[#1]{%
\begingroup
+ \@InitListMng %
\psset{#1}%
\Pst@CircleAbsNode@i}
\def\Pst@CircleAbsNode@i#1#2#3#4#5{%
- \pnode(! #3 0){@LINEABSAUXA#1#2}\pnode(! #3 1){@LINEABSAUXB#1#2}%
- \pstInterLC{@LINEABSAUXA#1#2}{@LINEABSAUXB#1#2}{#1}{#2}{#4}{#5}%
+ \pnode(!
+ tx@EcldDict begin
+ /N@#1 GetNode \tx@UserCoor
+ \ifx\psk@Radius\@none
+ \ifx\psk@Diameter\@none
+ 2 copy /N@#2 GetNode \tx@UserCoor ABDist
+ \else\psk@Diameter 2 div \pst@number\psxunit\space div
+ \fi
+ \else\psk@Radius\space \pst@number\psxunit\space div
+ \fi
+ end
+ #3 % Ox Oy R x_0
+ 1 index dup mul 1 index 5 index sub dup mul sub % R^2-(x_0-Ox)^2
+ dup 0 lt {
+ pop pop pop pop pop 0 0
+ 0 /#5.X ED 0 /#5.Y ED
+ } {
+ sqrt dup 4 index add /#5.Y ED
+ 3 index exch sub 1 index exch 2 index /#5.X ED
+ 6 2 roll pop pop pop pop
+ } ifelse
+ ){#4}%
+ \pnode(! #5.X #5.Y){#5}
+ \Pst@ManageParamList{#4}%
+ \Pst@ManageParamList{#5}%
\endgroup%
}%
%
@@ -2369,11 +3002,35 @@
\def\pstCircleOrdNode{\@ifnextchar[\Pst@CircleOrdNode{\Pst@CircleOrdNode[]}}
\def\Pst@CircleOrdNode[#1]{%
\begingroup
+ \@InitListMng %
\psset{#1}%
\Pst@CircleOrdNode@i}
\def\Pst@CircleOrdNode@i#1#2#3#4#5{%
- \pnode(! 0 #3){@LINEORDAUXA#1#2}\pnode(! 1 #3){@LINEORDAUXB#1#2}%
- \pstInterLC{@LINEORDAUXA#1#2}{@LINEORDAUXB#1#2}{#1}{#2}{#4}{#5}%
+ \pnode(!
+ tx@EcldDict begin
+ /N@#1 GetNode \tx@UserCoor
+ \ifx\psk@Radius\@none
+ \ifx\psk@Diameter\@none
+ 2 copy /N@#2 GetNode \tx@UserCoor ABDist
+ \else\psk@Diameter 2 div \pst@number\psxunit\space div
+ \fi
+ \else\psk@Radius\space \pst@number\psxunit\space div
+ \fi
+ end
+ #3 % Ox Oy R y_0
+ 1 index dup mul 1 index 4 index sub dup mul sub % R^2-(y_0-Oy)^2
+ dup 0 lt {
+ pop pop pop pop pop 0 0
+ 0 /#5.X ED 0 /#5.Y ED
+ } {
+ sqrt dup 5 index add /#5.X ED
+ 4 index exch sub 1 index 2 index /#5.Y ED
+ 6 2 roll pop pop pop pop
+ } ifelse
+ ){#4}%
+ \pnode(! #5.X #5.Y){#5}
+ \Pst@ManageParamList{#4}%
+ \Pst@ManageParamList{#5}%
\endgroup%
}%
%
@@ -3528,6 +4185,318 @@
\endgroup%
}%
%
+%% \pstGeneralEllipseFle[Options]{F}{l_A}{l_B}{e}{O}{R}{\theta}
+%% Calculate the center and the radii of a General Ellipse with directrix line $l$, focus $F$ and eccentricity $e$,
+%% then you can access the ellipse with them.
+%% Parameters:
+%% #1 -> options
+%% #2 -> [input] the given focus F
+%% #3 -> [input] the given node A on directrix line
+%% #4 -> [input] the given node B on directrix line
+%% #5 -> [input] the given eccentricity e
+%% #6 -> [output] the center of the ellipse.
+%% #7 -> [output] the pair of major and minor radius of the ellipse.
+%% #8 -> [output] the rotation of the ellipse major axis.
+\def\pstGeneralEllipseFle{\@ifnextchar[\Pst@GeneralEllipseFle{\Pst@GeneralEllipseFle[]}}
+\def\Pst@GeneralEllipseFle[#1]#2#3#4#5#6#7#8{
+ \begingroup
+ \psset{#1}%
+ \pst@getcoor{#2}\pst@tempF%
+ \pst@getcoor{#3}\pst@tempA%
+ \pst@getcoor{#4}\pst@tempB%
+ \pnode(!
+ #5 abs /MyEccentricity ED
+ MyEccentricity 1.0 ge { % if e\ge1
+ 0 0
+ }{
+ \pst@tempA \tx@UserCoor /Ay ED /Ax ED
+ \pst@tempB \tx@UserCoor /By ED /Bx ED
+ \pst@tempF \tx@UserCoor /Fy ED /Fx ED
+ % get coefficients of equation Ax+By+C=0 for line AB
+ By Ay sub /CoefA ED
+ Ax Bx sub /CoefB ED
+ Bx Ay mul By Ax mul sub /CoefC ED
+ % get projection point Hx=Fx-A(AFx+BFy+C)/(A^2+B^2), Hy=Fy-B(AFx+BFy+C)/(A^2+B^2)
+ Fx CoefA Fx mul CoefB Fy mul add CoefC add CoefA mul CoefA dup mul CoefB dup mul add div sub /Hx ED
+ Fy CoefA Fx mul CoefB Fy mul add CoefC add CoefB mul CoefA dup mul CoefB dup mul add div sub /Hy ED
+ % get distance F to AB
+ Fx Hx sub dup mul Fy Hy sub dup mul add sqrt /DistFAB ED % |FH|
+ DistFAB abs 1E-5 lt { % if F on AB
+ 0 0
+ }{
+ % e=c/a, g=Dist(F,AB)=a^2/c-c => a=ge/(1-e^2), c=ge^2/(1-e^2), b=ge/sqrt(1-e^2) theta={x2-x1 y1-y2 atan}
+ Ax Bx lt {
+ Bx Ax sub Ay By sub atan /#8 ED
+ }{
+ Ax Bx sub By Ay sub atan /#8 ED
+ } ifelse
+ DistFAB MyEccentricity mul 1.0 MyEccentricity dup mul sub div /MyEllipseA ED
+ DistFAB MyEccentricity mul 1.0 MyEccentricity dup mul sub sqrt div /MyEllipseB ED
+ DistFAB MyEccentricity dup mul mul 1.0 MyEccentricity dup mul sub div /MyEllipseC ED
+ % CoefA = CoefB = CoefC = Hx = Hy = DistFAB = MyEllipseC = #8 = (--------) =
+ Fx Hx sub abs 1E-5 lt {
+ Fy Hy lt {
+ Fx Fy MyEllipseC sub
+ }{
+ Fx Fy MyEllipseC add
+ } ifelse
+ } {
+ Fy Hy sub Fx Hx sub div /KFH ED
+ MyEllipseC KFH dup mul 1.0 add sqrt div /XDistFO ED
+ Fx Hx lt {
+ Fx XDistFO sub
+ }{
+ Fx XDistFO add
+ } ifelse
+ dup Fx sub KFH mul Fy add
+ } ifelse
+ } ifelse
+ } ifelse
+ ){#6}
+ \Pst@geonodelabel{#6}%
+ \pnode(! MyEllipseA MyEllipseB){#7}
+ \ifPst@CodeFig
+ \begingroup\psset{PointName=none,linecolor=\psk@CodeFigColor}
+ \pnode(! Hx Hy){PST@ELLIPSE@FLE@H}
+ \Pst@geonodelabel{PST@ELLIPSE@FLE@H}%
+ \pstLineAB[nodesep=-0.6]{#3}{#4}
+ \pstLineAB[nodesepA=-2.5,nodesepB=-0.5]{#2}{PST@ELLIPSE@FLE@H}
+ \endgroup
+ \fi
+ \endgroup%
+}%
+%
+%% \pstGeneralEllipseCoef[Options]{Coefficients}{O}{R}{\theta}
+%% Calculate the center and the radii of the ellipse defined by the quadratic curve equation $ax^2+bxy+cy^2+dx+ey+f=0$,
+%% then you can access the ellipse with them, the package pst-func provides macro \psplotImp to draw an implicit defined functions,
+%% but it don't tell you the geometrical elements like as center or radii.
+%% Parameters:
+%% #1 -> options
+%% #2 -> [input] the coefficents of the quadratic curve equation, with six numbers $a,b,c,d,e,f$ joined with comma.
+%% #3 -> [output] the center of the ellipse.
+%% #4 -> [output] the pair of major and minor radius of the ellipse.
+%% #5 -> [output] the rotation of the ellipse major axis.
+\def\pstGeneralEllipseCoef{\@ifnextchar[\Pst@GeneralEllipseCoef{\Pst@GeneralEllipseCoef[]}}
+\def\Pst@GeneralEllipseCoef[#1]#2#3#4#5{
+ \begingroup
+ \psset{#1}%
+ \pstParseArg{CurveCoef}{a,b,c,d,e,f}{#2}
+ \pnode(!
+ \CurveCoefa /CurveCoefa ED
+ \CurveCoefb\space 2 div /CurveCoefb ED
+ \CurveCoefc /CurveCoefc ED
+ \CurveCoefd\space 2 div /CurveCoefd ED
+ \CurveCoefe\space 2 div /CurveCoefe ED
+ \CurveCoeff /CurveCoeff ED
+ % I1=a+c
+ CurveCoefa CurveCoefc add /DiscriminantI ED
+ % I2=ac-b^2
+ CurveCoefa CurveCoefc mul CurveCoefb dup mul sub /DiscriminantII ED
+ DiscriminantII 0 le { % if I2\le0
+ 0 0
+ 0 /MyEllipseA ED
+ 0 /MyEllipseB ED
+ 0 /#5 ED
+ }{
+ CurveCoefa CurveCoefc sub dup mul 4 CurveCoefb dup mul mul add sqrt /CurveCoefTempA ED
+ CurveCoefa CurveCoefe dup mul mul CurveCoefc CurveCoefd dup mul mul add
+ CurveCoeff CurveCoefb dup mul mul add 2 CurveCoefb mul CurveCoefd mul
+ CurveCoefe mul sub CurveCoefa CurveCoefc mul CurveCoeff mul sub 2 mul /CurveCoefTempB ED
+ % Ra = sqrt((2(ae^2+cd^2+fb^2-2bde-acf))/((ac-b^2)[(a+c)-sqrt((a-c)^2+4b^2)]))
+ CurveCoefTempB DiscriminantII DiscriminantI CurveCoefTempA sub mul div /MyEllipseSquareA ED
+ % Rb = sqrt((2(ae^2+cd^2+fb^2-2bde-acf))/((ac-b^2)[(a+c)+sqrt((a-c)^2+4b^2)]))
+ CurveCoefTempB DiscriminantII DiscriminantI CurveCoefTempA add mul div /MyEllipseSquareB ED
+ MyEllipseSquareA 0 lt MyEllipseSquareB 0 lt or {
+ 0 0
+ 0 /MyEllipseA ED
+ 0 /MyEllipseB ED
+ 0 /#5 ED
+ } {
+ MyEllipseSquareA sqrt /MyEllipseA ED
+ MyEllipseSquareB sqrt /MyEllipseB ED
+ CurveCoefb abs 1E-5 lt { % b == 0
+ CurveCoefa CurveCoefc lt { % a < c
+ 0 /#5 ED
+ } {
+ 90 /#5 ED
+ } ifelse
+ } {
+ CurveCoefa CurveCoefc sub abs 1E-5 lt { % a = c
+ 45 /#5 ED
+ } {
+ CurveCoefb 0 lt {
+ 2 CurveCoefb mul neg CurveCoefc CurveCoefa sub atan /MyEllipseAngDbl ED
+ MyEllipseAngDbl 2 div /#5 ED
+ } {
+ 2 CurveCoefb mul CurveCoefa CurveCoefc sub atan /MyEllipseAngDbl ED
+ MyEllipseAngDbl 180 add 2 div /#5 ED
+ } ifelse
+ } ifelse
+ } ifelse
+ CurveCoefb CurveCoefe mul CurveCoefd CurveCoefc mul sub DiscriminantII div % x0
+ CurveCoefb CurveCoefd mul CurveCoefa CurveCoefe mul sub DiscriminantII div % y0
+ } ifelse
+ } ifelse
+ ){#3}
+ \Pst@geonodelabel{#3}%
+ \pnode(! MyEllipseA MyEllipseB){#4}
+ \ifPst@CodeFig
+ \begingroup\psset{PointName=none,linecolor=\psk@CodeFigColor}
+ \pstLineAA[nodesepA=-1.8,nodesepB=-0.8]{#3}{#5}{PST@ELLIPSE@COEF@A}
+ \pstLineAA[nodesepA=-1.8,nodesepB=-0.8]{#3}{#5 90 add}{PST@ELLIPSE@COEF@B}
+ \endgroup
+ \fi
+ \endgroup%
+}%
+%
+%% \pstGeneralEllipseABCDE[Options]{A}{B}{C}{D}{E}{O}{R}{\theta}
+%% Calculate the center and the radii of the ellipse defined by the five different points A,B,C,D,E,
+%% then you can access the ellipse with them.
+%% Parameters:
+%% #1 -> options
+%% #2 -> [input] the given point A.
+%% #3 -> [input] the given point B.
+%% #4 -> [input] the given point C.
+%% #5 -> [input] the given point D.
+%% #6 -> [input] the given point E.
+%% #7 -> [output] the center of the ellipse.
+%% #8 -> [output] the pair of major and minor radius of the ellipse.
+%% #9 -> [output] the rotation of the ellipse major axis.
+\def\pstGeneralEllipseABCDE{\@ifnextchar[\Pst@GeneralEllipseABCDE{\Pst@GeneralEllipseABCDE[]}}
+\def\Pst@GeneralEllipseABCDE[#1]#2#3#4#5#6#7#8#9{
+ \begingroup
+ \psset{#1}%
+ \pst@getcoor{#2}\pst@CurveNodeA%
+ \pst@getcoor{#3}\pst@CurveNodeB%
+ \pst@getcoor{#4}\pst@CurveNodeC%
+ \pst@getcoor{#5}\pst@CurveNodeD%
+ \pst@getcoor{#6}\pst@CurveNodeE%
+ \pnode(!
+ \pst@CurveNodeA \tx@UserCoor /CurveNodeAY ED /CurveNodeAX ED
+ \pst@CurveNodeB \tx@UserCoor /CurveNodeBY ED /CurveNodeBX ED
+ \pst@CurveNodeC \tx@UserCoor /CurveNodeCY ED /CurveNodeCX ED
+ \pst@CurveNodeD \tx@UserCoor /CurveNodeDY ED /CurveNodeDX ED
+ \pst@CurveNodeE \tx@UserCoor /CurveNodeEY ED /CurveNodeEX ED
+ %%
+ % ax^2+bxy+cy^2+dx+ey+f=0, let a=1, we can use A,B,C,D,E to solve b,c,d,e,f, we have
+ % AxAy b + Ay^2 c + Ax d + Ay e + 1 f = -Ax^2
+ % BxBy b + By^2 c + Bx d + By e + 1 f = -Bx^2
+ % CxCy b + Cy^2 c + Cx d + Cy e + 1 f = -Cx^2
+ % DxDy b + Dy^2 c + Dx d + Dy e + 1 f = -Dx^2
+ % ExEy b + Ey^2 c + Ex d + Ey e + 1 f = -Ex^2
+ % by Cramer's Rule, we have
+ % |Ax^2 Ay^2 Ax Ay 1| |AxAy Ay^2 Ax Ay 1|
+ % |Bx^2 By^2 Bx By 1| |BxBy By^2 Bx By 1|
+ % b=-|Cx^2 Cy^2 Cx Cy 1|/|CxCy Cy^2 Cx Cy 1| etc.
+ % |Dx^2 Dy^2 Dx Dy 1| |DxDy Dy^2 Dx Dy 1|
+ % |Ex^2 Ey^2 Ex Ey 1| |ExEy Ey^2 Ex Ey 1|
+ %%
+ CurveNodeAX CurveNodeAY mul CurveNodeAY dup mul CurveNodeAX CurveNodeAY 1
+ CurveNodeBX CurveNodeBY mul CurveNodeBY dup mul CurveNodeBX CurveNodeBY 1
+ CurveNodeCX CurveNodeCY mul CurveNodeCY dup mul CurveNodeCX CurveNodeCY 1
+ CurveNodeDX CurveNodeDY mul CurveNodeDY dup mul CurveNodeDX CurveNodeDY 1
+ CurveNodeEX CurveNodeEY mul CurveNodeEY dup mul CurveNodeEX CurveNodeEY 1
+ tx@EcldDict begin DeterminantFive end /LinearDiscriminant ED
+ LinearDiscriminant abs 1E-5 lt { % D=0
+ 0 0
+ 0 /MyEllipseA ED
+ 0 /MyEllipseB ED
+ 0 /#9 ED
+ } {
+ 1 /CurveCoefa ED
+ CurveNodeAX dup mul CurveNodeAY dup mul CurveNodeAX CurveNodeAY 1
+ CurveNodeBX dup mul CurveNodeBY dup mul CurveNodeBX CurveNodeBY 1
+ CurveNodeCX dup mul CurveNodeCY dup mul CurveNodeCX CurveNodeCY 1
+ CurveNodeDX dup mul CurveNodeDY dup mul CurveNodeDX CurveNodeDY 1
+ CurveNodeEX dup mul CurveNodeEY dup mul CurveNodeEX CurveNodeEY 1
+ tx@EcldDict begin DeterminantFive end LinearDiscriminant div neg 2 div /CurveCoefb ED
+ CurveNodeAX CurveNodeAY mul CurveNodeAX dup mul CurveNodeAX CurveNodeAY 1
+ CurveNodeBX CurveNodeBY mul CurveNodeBX dup mul CurveNodeBX CurveNodeBY 1
+ CurveNodeCX CurveNodeCY mul CurveNodeCX dup mul CurveNodeCX CurveNodeCY 1
+ CurveNodeDX CurveNodeDY mul CurveNodeDX dup mul CurveNodeDX CurveNodeDY 1
+ CurveNodeEX CurveNodeEY mul CurveNodeEX dup mul CurveNodeEX CurveNodeEY 1
+ tx@EcldDict begin DeterminantFive end LinearDiscriminant div neg /CurveCoefc ED
+ CurveNodeAX CurveNodeAY mul CurveNodeAY dup mul CurveNodeAX dup mul CurveNodeAY 1
+ CurveNodeBX CurveNodeBY mul CurveNodeBY dup mul CurveNodeBX dup mul CurveNodeBY 1
+ CurveNodeCX CurveNodeCY mul CurveNodeCY dup mul CurveNodeCX dup mul CurveNodeCY 1
+ CurveNodeDX CurveNodeDY mul CurveNodeDY dup mul CurveNodeDX dup mul CurveNodeDY 1
+ CurveNodeEX CurveNodeEY mul CurveNodeEY dup mul CurveNodeEX dup mul CurveNodeEY 1
+ tx@EcldDict begin DeterminantFive end LinearDiscriminant div neg 2 div /CurveCoefd ED
+ CurveNodeAX CurveNodeAY mul CurveNodeAY dup mul CurveNodeAX CurveNodeAX dup mul 1
+ CurveNodeBX CurveNodeBY mul CurveNodeBY dup mul CurveNodeBX CurveNodeBX dup mul 1
+ CurveNodeCX CurveNodeCY mul CurveNodeCY dup mul CurveNodeCX CurveNodeCX dup mul 1
+ CurveNodeDX CurveNodeDY mul CurveNodeDY dup mul CurveNodeDX CurveNodeDX dup mul 1
+ CurveNodeEX CurveNodeEY mul CurveNodeEY dup mul CurveNodeEX CurveNodeEX dup mul 1
+ tx@EcldDict begin DeterminantFive end LinearDiscriminant div neg 2 div /CurveCoefe ED
+ CurveNodeAX CurveNodeAY mul CurveNodeAY dup mul CurveNodeAX CurveNodeAY CurveNodeAX dup mul
+ CurveNodeBX CurveNodeBY mul CurveNodeBY dup mul CurveNodeBX CurveNodeBY CurveNodeBX dup mul
+ CurveNodeCX CurveNodeCY mul CurveNodeCY dup mul CurveNodeCX CurveNodeCY CurveNodeCX dup mul
+ CurveNodeDX CurveNodeDY mul CurveNodeDY dup mul CurveNodeDX CurveNodeDY CurveNodeDX dup mul
+ CurveNodeEX CurveNodeEY mul CurveNodeEY dup mul CurveNodeEX CurveNodeEY CurveNodeEX dup mul
+ tx@EcldDict begin DeterminantFive end LinearDiscriminant div neg /CurveCoeff ED
+ % the following is same with pstGeneralEllipseCoef.
+ % I1=a+c
+ CurveCoefa CurveCoefc add /DiscriminantI ED
+ % I2=ac-b^2
+ CurveCoefa CurveCoefc mul CurveCoefb dup mul sub /DiscriminantII ED
+ DiscriminantII 0 le { % if I2\le0
+ 0 0
+ 0 /MyEllipseA ED
+ 0 /MyEllipseB ED
+ 0 /#9 ED
+ }{
+ CurveCoefa CurveCoefc sub dup mul 4 CurveCoefb dup mul mul add sqrt /CurveCoefTempA ED
+ CurveCoefa CurveCoefe dup mul mul CurveCoefc CurveCoefd dup mul mul add
+ CurveCoeff CurveCoefb dup mul mul add 2 CurveCoefb mul CurveCoefd mul
+ CurveCoefe mul sub CurveCoefa CurveCoefc mul CurveCoeff mul sub 2 mul /CurveCoefTempB ED
+ % Ra = sqrt((2(ae^2+cd^2+fb^2-2bde-acf))/((ac-b^2)[(a+c)-sqrt((a-c)^2+4b^2)]))
+ CurveCoefTempB DiscriminantII DiscriminantI CurveCoefTempA sub mul div /MyEllipseSquareA ED
+ % Rb = sqrt((2(ae^2+cd^2+fb^2-2bde-acf))/((ac-b^2)[(a+c)+sqrt((a-c)^2+4b^2)]))
+ CurveCoefTempB DiscriminantII DiscriminantI CurveCoefTempA add mul div /MyEllipseSquareB ED
+ MyEllipseSquareA 0 lt MyEllipseSquareB 0 lt or {
+ 0 0
+ 0 /MyEllipseA ED
+ 0 /MyEllipseB ED
+ 0 /#9 ED
+ } {
+ MyEllipseSquareA sqrt /MyEllipseA ED
+ MyEllipseSquareB sqrt /MyEllipseB ED
+ CurveCoefb abs 1E-5 lt { % b == 0
+ CurveCoefa CurveCoefc lt { % a < c
+ 0 /#9 ED
+ } {
+ 90 /#9 ED
+ } ifelse
+ } {
+ CurveCoefa CurveCoefc sub abs 1E-5 lt { % a = c
+ 45 /#9 ED
+ } {
+ CurveCoefb 0 lt {
+ 2 CurveCoefb mul neg CurveCoefc CurveCoefa sub atan /MyEllipseAngDbl ED
+ MyEllipseAngDbl 2 div /#9 ED
+ } {
+ 2 CurveCoefb mul CurveCoefa CurveCoefc sub atan /MyEllipseAngDbl ED
+ MyEllipseAngDbl 180 add 2 div /#9 ED
+ } ifelse
+ } ifelse
+ } ifelse
+ CurveCoefb CurveCoefe mul CurveCoefd CurveCoefc mul sub DiscriminantII div % x0
+ CurveCoefb CurveCoefd mul CurveCoefa CurveCoefe mul sub DiscriminantII div % y0
+ } ifelse
+ } ifelse
+ } ifelse
+ ){#7}
+ \Pst@geonodelabel{#7}%
+ \pnode(! MyEllipseA MyEllipseB){#8}
+ \ifPst@CodeFig
+ \begingroup\psset{PointName=none,linecolor=\psk@CodeFigColor}
+ \pstLineAA[nodesepA=-1.8,nodesepB=-0.8]{#7}{#9}{PST@ELLIPSE@ABCDE@A}
+ \pstLineAA[nodesepA=-1.8,nodesepB=-0.8]{#7}{#9 90 add}{PST@ELLIPSE@ABCDE@B}
+ \endgroup
+ \fi
+ \endgroup%
+}%
+%
%% \pstGeneralEllipseNode[Options](O)(a,b)[rotation]{t}{A}
%% Get the new node A whose parameter is the given value $t$ on the General Ellipse E.
%% If you not input rotation angle, the default value is $0^\circ$, which is same as \pstEllipse.
@@ -4937,6 +5906,340 @@
\endgroup%
}%
%
+%% \pstGeneralParabolaFl[Options]{F}{l_A}{l_B}{O}{p}{\theta}
+%% Calculate the vertex $O$ and the half of focal chord $p$, and the rotation angle of the symmetrical axis
+%% for the General Parabola with directrix line $l$ and focus $F$,
+%% then you can access the parabola with them.
+%% Parameters:
+%% #1 -> options
+%% #2 -> [input] the given focus F.
+%% #3 -> [input] the given node A on directrix line.
+%% #4 -> [input] the given node B on directrix line.
+%% #5 -> [output] the vertex of the parabola.
+%% #6 -> [output] the half of focal chord $p$.
+%% #7 -> [output] the rotation of the symmetrical axis.
+\def\pstGeneralParabolaFl{\@ifnextchar[\Pst@GeneralParabolaFl{\Pst@GeneralParabolaFl[]}}
+\def\Pst@GeneralParabolaFl[#1]#2#3#4#5#6#7{
+ \begingroup
+ \psset{#1}%
+ \pst@getcoor{#2}\pst@tempF%
+ \pst@getcoor{#3}\pst@tempA%
+ \pst@getcoor{#4}\pst@tempB%
+ \pnode(!
+ \pst@tempA \tx@UserCoor /Ay ED /Ax ED
+ \pst@tempB \tx@UserCoor /By ED /Bx ED
+ \pst@tempF \tx@UserCoor /Fy ED /Fx ED
+ % get coefficients of equation Ax+By+C=0 for line AB
+ By Ay sub /CoefA ED
+ Ax Bx sub /CoefB ED
+ Bx Ay mul By Ax mul sub /CoefC ED
+ % get projection point Hx=Fx-A(AFx+BFy+C)/(A^2+B^2), Hy=Fy-B(AFx+BFy+C)/(A^2+B^2)
+ Fx CoefA Fx mul CoefB Fy mul add CoefC add CoefA mul CoefA dup mul CoefB dup mul add div sub /Hx ED
+ Fy CoefA Fx mul CoefB Fy mul add CoefC add CoefB mul CoefA dup mul CoefB dup mul add div sub /Hy ED
+ % get distance F to AB
+ Fx Hx sub dup mul Fy Hy sub dup mul add sqrt /DistFAB ED % |FH|
+ DistFAB abs 1E-5 lt { % if F on AB
+ 0 0
+ }{
+ % theta={y2-y1 x2-x1 atan}
+ Ay By lt {
+ By Ay sub Bx Ax sub atan /#7 ED
+ }{
+ Ay By sub Ax Bx sub atan /#7 ED
+ } ifelse
+ Fx Hx sub abs 1E-5 lt {
+ Fy Hy lt {
+ DistFAB neg /#6 ED
+ } {
+ DistFAB /#6 ED
+ } ifelse
+ } {
+ Fx Hx lt {
+ DistFAB /#6 ED
+ } {
+ DistFAB neg /#6 ED
+ } ifelse
+ } ifelse
+ % CoefA = CoefB = CoefC = Hx = Hy = #6 = #7 = (--------) =
+ Fx Hx add 2 div Fy Hy add 2 div % x0, y0
+ } ifelse
+ ){#5}
+ \Pst@geonodelabel{#5}%
+ \ifPst@CodeFig
+ \begingroup\psset{PointName=none,linecolor=\psk@CodeFigColor}
+ \pnode(! Hx Hy){PST@PARABOLA@FL@H}
+ \Pst@geonodelabel{PST@PARABOLA@FL@H}%
+ \pstLineAB[nodesep=-0.6]{#3}{#4}
+ \pstLineAB[nodesepA=-2.5,nodesepB=-0.5]{#2}{PST@PARABOLA@FL@H}
+ \endgroup
+ \fi
+ \endgroup%
+}%
+%
+%% \pstGeneralParabolaCoef[Options]{Coefficients}{O}{p}{\theta}
+%% Calculate the vertex and the half focal chord of the parabola defined by the quadratic curve equation $ax^2+bxy+cy^2+dx+ey+f=0$,
+%% then you can access the parabola with them, the package pst-func provides macro \psplotImp to draw an implicit defined functions,
+%% but it don't tell you the geometrical elements like as center or radii.
+%% Parameters:
+%% #1 -> options
+%% #2 -> [input] the coefficents of the quadratic curve equation, with six numbers $a,b,c,d,e,f$ joined with comma.
+%% #3 -> [output] the vertex of the parabola.
+%% #4 -> [output] the half focal chord of the parabola.
+%% #5 -> [output] the rotation of the parabola symmetrical axis.
+\def\pstGeneralParabolaCoef{\@ifnextchar[\Pst@GeneralParabolaCoef{\Pst@GeneralParabolaCoef[]}}
+\def\Pst@GeneralParabolaCoef[#1]#2#3#4#5{
+ \begingroup
+ \psset{#1}%
+ \pstParseArg{CurveCoef}{a,b,c,d,e,f}{#2}
+ \pnode(!
+ \CurveCoefa /CurveCoefa ED
+ \CurveCoefb /CurveCoefb ED
+ \CurveCoefc /CurveCoefc ED
+ \CurveCoefd /CurveCoefd ED
+ \CurveCoefe /CurveCoefe ED
+ \CurveCoeff /CurveCoeff ED
+ % I1=a+c
+ CurveCoefa CurveCoefc add /DiscriminantI ED
+ % I2=b^2-4ac
+ CurveCoefb dup mul 4 CurveCoefa CurveCoefc mul mul sub /DiscriminantII ED
+ % I3=1/2|2a b d,b 2c e,d e 2f|
+ CurveCoefa 2 mul CurveCoefb CurveCoefd
+ CurveCoefb CurveCoefc 2 mul CurveCoefe
+ CurveCoefd CurveCoefe CurveCoeff 2 mul
+ tx@EcldDict begin DeterminantThree end 2 div /DiscriminantIII ED
+ %DiscriminantI = DiscriminantII = DiscriminantIII =
+ DiscriminantII abs 1E-5 lt DiscriminantIII 0 ne and { % if I2=0 and I3!=0
+ CurveCoefb abs 1E-5 lt { % b=0 -> sin2x=0 x=0
+ 0 /#5 ED
+ } {
+ CurveCoefa CurveCoefc sub abs 1E-5 lt { % a=c -> cos2x=0
+ 45 /#5 ED
+ } {
+ CurveCoefb 0 lt {
+ CurveCoefb neg CurveCoefc CurveCoefa sub atan /MyParabolaAngDbl ED
+ MyParabolaAngDbl 2 div /#5 ED
+ } {
+ CurveCoefb CurveCoefa CurveCoefc sub atan /MyParabolaAngDbl ED
+ MyParabolaAngDbl 2 div /#5 ED
+ } ifelse
+ } ifelse
+ } ifelse
+ #5 sin /MySin ED #5 cos /MyCos ED
+ CurveCoefa MyCos dup mul mul CurveCoefb MySin MyCos mul mul add
+ CurveCoefc MySin dup mul mul add /MyCoefa ED
+ CurveCoefa MySin dup mul mul CurveCoefb MySin MyCos mul mul sub
+ CurveCoefc MyCos dup mul mul add /MyCoefc ED
+ CurveCoefd MyCos mul CurveCoefe MySin mul add /MyCoefd ED
+ CurveCoefe MyCos mul CurveCoefd MySin mul sub /MyCoefe ED
+ MyCoefa abs 1E-5 lt { % a'=0
+ % c'y^2+d'x+e'y+f'=0
+ MyCoefd abs 1E-5 lt { % d'=0 two lines, not support
+ 0 /#4 ED
+ 0 0
+ } {
+ % c'(y+e'/2c')^2+d'(x+f'/d'-e'^2/4c'd')=0
+ MyCoefd MyCoefc div 2 div neg /#4 ED
+ MyCoefe MyCoefc div 2 div neg /MyVertexY ED
+ MyCoefe dup mul MyCoefc div MyCoefd div 4 div CurveCoeff MyCoefd div sub /MyVertexX ED
+ MyVertexX MyCos mul MyVertexY MySin mul sub
+ MyVertexY MyCos mul MyVertexX MySin mul add
+ #5 90 sub /#5 ED % inverse general hyperbola
+ } ifelse
+ } if
+ MyCoefc abs 1E-5 lt { % c'=0
+ % a'x^2+d'x+e'y+f'=0
+ MyCoefe abs 1E-5 lt { % e'=0 two lines, not support
+ 0 /#4 ED
+ 0 0
+ } {
+ % a'(x+d'/2a')^2+e'(y+f'/e'-d'^2/4a'e')=0
+ MyCoefe MyCoefa div 2 div neg /#4 ED
+ MyCoefd MyCoefa div 2 div neg /MyVertexX ED
+ MyCoefd dup mul MyCoefa div MyCoefe div 4 div CurveCoeff MyCoefe div sub /MyVertexY ED
+ MyVertexX MyCos mul MyVertexY MySin mul sub
+ MyVertexY MyCos mul MyVertexX MySin mul add
+ } ifelse
+ } if
+ %#4 = #5 = MySin = MyCos =
+ %MyCoefa = MyCoefc = MyCoefd = MyCoefe =
+ %(--------------) =
+ } {
+ 0 /#4 ED
+ 0 /#5 ED
+ 0 0
+ } ifelse
+ ){#3}
+ \Pst@geonodelabel{#3}%
+ \ifPst@CodeFig
+ \begingroup\psset{PointName=none,linecolor=\psk@CodeFigColor}
+ \pstLineAA[nodesepA=-1.8,nodesepB=-0.8]{#3}{#5}{PST@PARABOLA@COEF@A}
+ \pstLineAA[nodesepA=-1.8,nodesepB=-0.8]{#3}{#5 90 add}{PST@PARABOLA@COEF@B}
+ \endgroup
+ \fi
+ \endgroup%
+}%
+%
+%% \pstGeneralParabolaABCDE[Options]{A}{B}{C}{D}{E}{O}{p}{\theta}
+%% Calculate the center and the radii of the parabola defined by the five different points A,B,C,D,E,
+%% then you can access the parabola with them.
+%% Parameters:
+%% #1 -> options
+%% #2 -> [input] the given point A.
+%% #3 -> [input] the given point B.
+%% #4 -> [input] the given point C.
+%% #5 -> [input] the given point D.
+%% #6 -> [input] the given point E.
+%% #7 -> [output] the vertex of the parabola.
+%% #8 -> [output] the half focal chord of the parabola.
+%% #9 -> [output] the rotation of the parabola symmetrical axis.
+\def\pstGeneralParabolaABCDE{\@ifnextchar[\Pst@GeneralParabolaABCDE{\Pst@GeneralParabolaABCDE[]}}
+\def\Pst@GeneralParabolaABCDE[#1]#2#3#4#5#6#7#8#9{
+ \begingroup
+ \psset{#1}%
+ \pst@getcoor{#2}\pst@CurveNodeA%
+ \pst@getcoor{#3}\pst@CurveNodeB%
+ \pst@getcoor{#4}\pst@CurveNodeC%
+ \pst@getcoor{#5}\pst@CurveNodeD%
+ \pst@getcoor{#6}\pst@CurveNodeE%
+ \pnode(!
+ \pst@CurveNodeA \tx@UserCoor /CurveNodeAY ED /CurveNodeAX ED
+ \pst@CurveNodeB \tx@UserCoor /CurveNodeBY ED /CurveNodeBX ED
+ \pst@CurveNodeC \tx@UserCoor /CurveNodeCY ED /CurveNodeCX ED
+ \pst@CurveNodeD \tx@UserCoor /CurveNodeDY ED /CurveNodeDX ED
+ \pst@CurveNodeE \tx@UserCoor /CurveNodeEY ED /CurveNodeEX ED
+ %%
+ % the curve pass four points A,B,C,D can be represented as AB * CD + \lambda AC * BD=0,
+ % so we can use the fifth point E to resolve \lambda.
+ %%
+ % line AB: Ax+By+C=0
+ CurveNodeAX CurveNodeAY CurveNodeBX CurveNodeBY tx@EcldDict begin LineCoefABC end /CurveLineABCoefC ED /CurveLineABCoefB ED /CurveLineABCoefA ED
+ % CurveLineABCoefA = CurveLineABCoefB = CurveLineABCoefC =
+ % line CD: Ax+By+C=0
+ CurveNodeCX CurveNodeCY CurveNodeDX CurveNodeDY tx@EcldDict begin LineCoefABC end /CurveLineCDCoefC ED /CurveLineCDCoefB ED /CurveLineCDCoefA ED
+ % CurveLineCDCoefA = CurveLineCDCoefB = CurveLineCDCoefC =
+ % line AC: Ax+By+C=0
+ CurveNodeAX CurveNodeAY CurveNodeCX CurveNodeCY tx@EcldDict begin LineCoefABC end /CurveLineACCoefC ED /CurveLineACCoefB ED /CurveLineACCoefA ED
+ % CurveLineACCoefA = CurveLineACCoefB = CurveLineACCoefC =
+ % line BD: Ax+By+C=0
+ CurveNodeBX CurveNodeBY CurveNodeDX CurveNodeDY tx@EcldDict begin LineCoefABC end /CurveLineBDCoefC ED /CurveLineBDCoefB ED /CurveLineBDCoefA ED
+ % CurveLineBDCoefA = CurveLineBDCoefB = CurveLineBDCoefC =
+ % try to get lambda
+ CurveLineABCoefA CurveNodeEX mul CurveLineABCoefB CurveNodeEY mul add CurveLineABCoefC add /CurveValueABE ED % AB-E
+ CurveLineCDCoefA CurveNodeEX mul CurveLineCDCoefB CurveNodeEY mul add CurveLineCDCoefC add /CurveValueCDE ED % CD-E
+ CurveLineACCoefA CurveNodeEX mul CurveLineACCoefB CurveNodeEY mul add CurveLineACCoefC add /CurveValueACE ED % AC-E
+ CurveLineBDCoefA CurveNodeEX mul CurveLineBDCoefB CurveNodeEY mul add CurveLineBDCoefC add /CurveValueBDE ED % BD-E
+ % CurveValueABE = CurveValueCDE = CurveValueACE = CurveValueBDE =
+ CurveValueACE CurveValueBDE mul dup abs 1E-5 lt { % lambda can be any number, the cuver is not unique defined.
+ 0 /#8 ED
+ 0 /#9 ED
+ 0 0
+ } {
+ CurveValueABE CurveValueCDE mul exch div neg /CurveLambda ED
+ % (a_1x+b_1y+c_1)(a_2x+b_2y+c_2)+k(a_3x+b_3y+c_3)(a_4x+b_4y+c_4)
+ % =(a1a2+ka3a4)x^2+(a2b1+a1b2+ka4b3+ka3b4)xy+(b1b2+kb3b4)y^2+(a2c1+a1c2+ka4c3+ka3c4)x+(b2c1+b1c2+kb4c3+kb3c4)y+c1c2+kc3c4
+ CurveLineABCoefA CurveLineCDCoefA mul CurveLineACCoefA CurveLineBDCoefA mul CurveLambda mul add /CurveCoefa ED
+ CurveLineCDCoefA CurveLineABCoefB mul CurveLineABCoefA CurveLineCDCoefB mul add
+ CurveLineBDCoefA CurveLineACCoefB mul CurveLineACCoefA CurveLineBDCoefB mul add CurveLambda mul add /CurveCoefb ED
+ CurveLineABCoefB CurveLineCDCoefB mul CurveLineACCoefB CurveLineBDCoefB mul CurveLambda mul add /CurveCoefc ED
+ CurveLineCDCoefA CurveLineABCoefC mul CurveLineABCoefA CurveLineCDCoefC mul add
+ CurveLineBDCoefA CurveLineACCoefC mul CurveLineACCoefA CurveLineBDCoefC mul add CurveLambda mul add /CurveCoefd ED
+ CurveLineCDCoefB CurveLineABCoefC mul CurveLineABCoefB CurveLineCDCoefC mul add
+ CurveLineBDCoefB CurveLineACCoefC mul CurveLineACCoefB CurveLineBDCoefC mul add CurveLambda mul add /CurveCoefe ED
+ CurveLineABCoefC CurveLineCDCoefC mul CurveLineACCoefC CurveLineBDCoefC mul CurveLambda mul add /CurveCoeff ED
+ CurveCoefa abs 1E-5 lt {0 /CurveCoefa ED} if
+ CurveCoefb abs 1E-5 lt {0 /CurveCoefb ED} if
+ CurveCoefc abs 1E-5 lt {0 /CurveCoefc ED} if
+ CurveCoefd abs 1E-5 lt {0 /CurveCoefd ED} if
+ CurveCoefe abs 1E-5 lt {0 /CurveCoefe ED} if
+ CurveCoeff abs 1E-5 lt {0 /CurveCoeff ED} if
+ % CurveLambda = CurveCoefa = CurveCoefb = CurveCoefc = CurveCoefd = CurveCoefe = CurveCoeff =
+ % the following is same with pstGeneralParabolaCoef.
+ % I1=a+c
+ CurveCoefa CurveCoefc add /DiscriminantI ED
+ % I2=b^2-4ac
+ CurveCoefb dup mul 4 CurveCoefa CurveCoefc mul mul sub /DiscriminantII ED
+ % I3=1/2|2a b d,b 2c e,d e 2f|
+ CurveCoefa 2 mul CurveCoefb CurveCoefd
+ CurveCoefb CurveCoefc 2 mul CurveCoefe
+ CurveCoefd CurveCoefe CurveCoeff 2 mul
+ tx@EcldDict begin DeterminantThree end 2 div /DiscriminantIII ED
+ % DiscriminantI = DiscriminantII = DiscriminantIII =
+ DiscriminantII abs 1E-5 lt DiscriminantIII 0 ne and { % if I2=0 and I3!=0
+ CurveCoefb abs 1E-5 lt { % b=0 -> sin2x=0 x=0
+ 0 /#9 ED
+ } {
+ CurveCoefa CurveCoefc sub abs 1E-5 lt { % a=c -> cos2x=0
+ 45 /#9 ED
+ } {
+ CurveCoefb 0 lt {
+ CurveCoefb neg CurveCoefc CurveCoefa sub atan /MyParabolaAngDbl ED
+ MyParabolaAngDbl 2 div /#9 ED
+ } {
+ CurveCoefb CurveCoefa CurveCoefc sub atan /MyParabolaAngDbl ED
+ MyParabolaAngDbl 2 div /#9 ED
+ } ifelse
+ } ifelse
+ } ifelse
+ #9 sin /MySin ED #9 cos /MyCos ED
+ CurveCoefa MyCos dup mul mul CurveCoefb MySin MyCos mul mul add
+ CurveCoefc MySin dup mul mul add /MyCoefa ED
+ CurveCoefa MySin dup mul mul CurveCoefb MySin MyCos mul mul sub
+ CurveCoefc MyCos dup mul mul add /MyCoefc ED
+ CurveCoefd MyCos mul CurveCoefe MySin mul add /MyCoefd ED
+ CurveCoefe MyCos mul CurveCoefd MySin mul sub /MyCoefe ED
+ MyCoefa abs 1E-5 lt { % a'=0
+ % c'y^2+d'x+e'y+f'=0
+ MyCoefd abs 1E-5 lt { % d'=0 two lines, not support
+ 0 /#8 ED
+ 0 0
+ } {
+ % c'(y+e'/2c')^2+d'(x+f'/d'-e'^2/4c'd')=0
+ MyCoefd MyCoefc div 2 div neg /#8 ED
+ MyCoefe MyCoefc div 2 div neg /MyVertexY ED
+ MyCoefe dup mul MyCoefc div MyCoefd div 4 div CurveCoeff MyCoefd div sub /MyVertexX ED
+ MyVertexX MyCos mul MyVertexY MySin mul sub
+ MyVertexY MyCos mul MyVertexX MySin mul add
+ #9 90 sub /#9 ED % inverse general hyperbola
+ } ifelse
+ } if
+ MyCoefc abs 1E-5 lt { % c'=0
+ % a'x^2+d'x+e'y+f'=0
+ MyCoefe abs 1E-5 lt { % e'=0 two lines, not support
+ 0 /#8 ED
+ 0 0
+ } {
+ % a'(x+d'/2a')^2+e'(y+f'/e'-d'^2/4a'e')=0
+ MyCoefe MyCoefa div 2 div neg /#8 ED
+ MyCoefd MyCoefa div 2 div neg /MyVertexX ED
+ MyCoefd dup mul MyCoefa div MyCoefe div 4 div CurveCoeff MyCoefe div sub /MyVertexY ED
+ MyVertexX MyCos mul MyVertexY MySin mul sub
+ MyVertexY MyCos mul MyVertexX MySin mul add
+ } ifelse
+ } if
+ % #8 = #9 = MySin = MyCos = MyCoefa = MyCoefc = MyCoefd = MyCoefe = (--------------) =
+ } {
+ (These five points can not construct a parabola!) =
+ DiscriminantII 0 lt {
+ (May be they can construct an ellipse!) =
+ } {
+ (May be they can construct a hyperbola!) =
+ } ifelse
+ 0 /#8 ED
+ 0 /#9 ED
+ 0 0
+ } ifelse
+ } ifelse
+ ){#7}
+ \Pst@geonodelabel{#7}%
+ \ifPst@CodeFig
+ \begingroup\psset{PointName=none,linecolor=\psk@CodeFigColor}
+ \pstLineAA[nodesepA=-1.8,nodesepB=-0.8]{#7}{#9}{PST@PARABOLA@COEF@A}
+ \pstLineAA[nodesepA=-1.8,nodesepB=-0.8]{#7}{#9 90 add}{PST@PARABOLA@COEF@B}
+ \endgroup
+ \fi
+ \endgroup%
+}%
+%
%% \pstGeneralParabolaNode[Options](O){p}[rotation]{t}{A}
%% Create a new node on the given General Parabola P.
%% If you not input the rotation angle, the default value is $0^\circ$.
@@ -6187,7 +7490,7 @@
\pst@tempR \tx@UserCoor % a,b
dup mul exch dup mul add sqrt % c
2 index add 1 index % x0+c,y0
- 6 2 roll pop pop pop pop
+ 4 2 roll pop pop
){#5}%
\Pst@ManageParamList{#4}%
\Pst@ManageParamList{#5}%
@@ -7046,6 +8349,375 @@
}%
}%
%
+%% \pstGeneralHyperbolaFle[Options]{F}{l_A}{l_B}{e}{O}{R}{\theta}
+%% Calculate the center and the radii of a General Hyperbola with directrix line $l$, focus $F$ and eccentricity $e$,
+%% then you can access the hyperbola with them.
+%% Parameters:
+%% #1 -> options
+%% #2 -> [input] the given focus F
+%% #3 -> [input] the given node A on directrix line
+%% #4 -> [input] the given node B on directrix line
+%% #5 -> [input] the given eccentricity e
+%% #6 -> [output] the center of the hyperbola.
+%% #7 -> [output] the pair of real and imaginary radius of the hyperbola.
+%% #8 -> [output] the rotation of the hyperbola symmetrical axis.
+\def\pstGeneralHyperbolaFle{\@ifnextchar[\Pst@GeneralHyperbolaFle{\Pst@GeneralHyperbolaFle[]}}
+\def\Pst@GeneralHyperbolaFle[#1]#2#3#4#5#6#7#8{
+ \begingroup
+ \psset{#1}%
+ \pst@getcoor{#2}\pst@tempF%
+ \pst@getcoor{#3}\pst@tempA%
+ \pst@getcoor{#4}\pst@tempB%
+ \pnode(!
+ #5 abs /MyEccentricity ED
+ MyEccentricity 1.0 le { % if e\ge1
+ 0 0
+ }{
+ \pst@tempA \tx@UserCoor /Ay ED /Ax ED
+ \pst@tempB \tx@UserCoor /By ED /Bx ED
+ \pst@tempF \tx@UserCoor /Fy ED /Fx ED
+ % get coefficients of equation Ax+By+C=0 for line AB
+ By Ay sub /CoefA ED
+ Ax Bx sub /CoefB ED
+ Bx Ay mul By Ax mul sub /CoefC ED
+ % get projection point Hx=Fx-A(AFx+BFy+C)/(A^2+B^2), Hy=Fy-B(AFx+BFy+C)/(A^2+B^2)
+ Fx CoefA Fx mul CoefB Fy mul add CoefC add CoefA mul CoefA dup mul CoefB dup mul add div sub /Hx ED
+ Fy CoefA Fx mul CoefB Fy mul add CoefC add CoefB mul CoefA dup mul CoefB dup mul add div sub /Hy ED
+ % get distance F to AB
+ Fx Hx sub dup mul Fy Hy sub dup mul add sqrt /DistFAB ED % |FH|
+ DistFAB abs 1E-5 lt { % if F on AB
+ 0 0
+ }{
+ % theta={x2-x1 y1-y2 atan}
+ Ax Bx lt {
+ Bx Ax sub Ay By sub atan /#8 ED
+ }{
+ Ax Bx sub By Ay sub atan /#8 ED
+ } ifelse
+ % c^2=a^2+b^2, e=c/a, g=Dist(F,AB)=c-a^2/c => a=ge/(e^2-1), c=ge^2/(e^2-1), b=ge/sqrt(e^2-1)
+ DistFAB MyEccentricity mul MyEccentricity dup mul 1.0 sub div /MyHyperbolaA ED
+ DistFAB MyEccentricity mul MyEccentricity dup mul 1.0 sub sqrt div /MyHyperbolaB ED
+ DistFAB MyEccentricity dup mul mul MyEccentricity dup mul 1.0 sub div /MyHyperbolaC ED
+ % CoefA = CoefB = CoefC = Hx = Hy = DistFAB = MyHyperbolaC = #8 = (--------) =
+ Fx Hx sub abs 1E-5 lt {
+ Fy Hy lt {
+ Fx Fy MyHyperbolaC add
+ }{
+ Fx Fy MyHyperbolaC sub
+ } ifelse
+ } {
+ Fy Hy sub Fx Hx sub div /KFH ED
+ MyHyperbolaC KFH dup mul 1.0 add sqrt div /XDistFO ED
+ Fx Hx lt {
+ Fx XDistFO add
+ }{
+ Fx XDistFO sub
+ } ifelse
+ dup Fx sub KFH mul Fy add
+ } ifelse
+ } ifelse
+ } ifelse
+ ){#6}
+ \Pst@geonodelabel{#6}%
+ \pnode(! MyHyperbolaA MyHyperbolaB){#7}
+ \ifPst@CodeFig
+ \begingroup\psset{PointName=none,linecolor=\psk@CodeFigColor}
+ \pnode(! Hx Hy){PST@HYPERBOLA@FLE@H}
+ \Pst@geonodelabel{PST@HYPERBOLA@FLE@H}%
+ \pstLineAB[nodesep=-0.6]{#3}{#4}
+ \pstLineAB[nodesepA=-2.5,nodesepB=-0.5]{#2}{PST@HYPERBOLA@FLE@H}
+ \endgroup
+ \fi
+ \endgroup%
+}%
+%
+%% \pstGeneralHyperbolaCoef[Options]{Coefficients}{O}{R}{\theta}
+%% Calculate the center and the radii of the hyperbola defined by the quadratic curve equation $ax^2+bxy+cy^2+dx+ey+f=0$,
+%% then you can access the hyperbola with them, the package pst-func provides macro \psplotImp to draw an implicit defined functions,
+%% but it don't tell you the geometrical elements like as center or radii.
+%% Parameters:
+%% #1 -> options
+%% #2 -> [input] the coefficents of the quadratic curve equation, with six numbers $a,b,c,d,e,f$ joined with comma.
+%% #3 -> [output] the center of the hyperbola.
+%% #4 -> [output] the pair of real and imaginary radius of the hyperbola.
+%% #5 -> [output] the rotation of the hyperbola symmetrical axis.
+\def\pstGeneralHyperbolaCoef{\@ifnextchar[\Pst@GeneralHyperbolaCoef{\Pst@GeneralHyperbolaCoef[]}}
+\def\Pst@GeneralHyperbolaCoef[#1]#2#3#4#5{
+ \begingroup
+ \psset{#1}%
+ \pstParseArg{CurveCoef}{a,b,c,d,e,f}{#2}
+ \pnode(!
+ \CurveCoefa /CurveCoefa ED
+ \CurveCoefb /CurveCoefb ED
+ \CurveCoefc /CurveCoefc ED
+ \CurveCoefd /CurveCoefd ED
+ \CurveCoefe /CurveCoefe ED
+ \CurveCoeff /CurveCoeff ED
+ % I1=a+c
+ CurveCoefa CurveCoefc add /DiscriminantI ED
+ % I2=b^2-4ac
+ CurveCoefb dup mul 4 CurveCoefa CurveCoefc mul mul sub /DiscriminantII ED
+ % I3=1/2|2a b d,b 2c e,d e 2f|
+ CurveCoefa 2 mul CurveCoefb CurveCoefd
+ CurveCoefb CurveCoefc 2 mul CurveCoefe
+ CurveCoefd CurveCoefe CurveCoeff 2 mul
+ tx@EcldDict begin DeterminantThree end 2 div /DiscriminantIII ED
+ % DiscriminantI = DiscriminantII = DiscriminantIII =
+ DiscriminantII 0 gt DiscriminantIII 0 ne and { % if I2>0 and I3!=0
+ % Solve the Characteristic Equation: \lambda^2-I_1\lambda-I_2/4=0
+ DiscriminantI dup mul DiscriminantII add dup 0 lt {
+ 0 0
+ 0 /MyHyperbolaA ED
+ 0 /MyHyperbolaB ED
+ 0 /#5 ED
+ } {
+ sqrt dup DiscriminantI exch sub 2 div /CharacteristicLambdaI ED
+ DiscriminantI add 2 div /CharacteristicLambdaII ED
+ % CharacteristicLambdaI = CharacteristicLambdaII =
+ CurveCoefb 0 lt {
+ DiscriminantIII 0 lt {
+ DiscriminantIII CharacteristicLambdaI DiscriminantII mul div sqrt /MyHyperbolaA ED
+ DiscriminantIII CharacteristicLambdaII DiscriminantII mul div neg sqrt /MyHyperbolaB ED
+ } {
+ DiscriminantIII CharacteristicLambdaI DiscriminantII mul div neg sqrt /MyHyperbolaB ED
+ DiscriminantIII CharacteristicLambdaII DiscriminantII mul div sqrt /MyHyperbolaA ED
+ } ifelse
+ } {
+ DiscriminantIII 0 lt {
+ DiscriminantIII CharacteristicLambdaII DiscriminantII mul div neg sqrt /MyHyperbolaB ED
+ DiscriminantIII CharacteristicLambdaI DiscriminantII mul div sqrt /MyHyperbolaA ED
+ } {
+ DiscriminantIII CharacteristicLambdaII DiscriminantII mul div sqrt /MyHyperbolaA ED
+ DiscriminantIII CharacteristicLambdaI DiscriminantII mul div neg sqrt /MyHyperbolaB ED
+ } ifelse
+ } ifelse
+ CurveCoefb abs 1E-5 lt { % b == 0
+ CurveCoefa CurveCoefc lt { % a < c
+ 0 /#5 ED
+ } {
+ 90 /#5 ED
+ } ifelse
+ } {
+ CurveCoefa CurveCoefc sub abs 1E-5 lt { % a = c
+ 45 /#5 ED
+ } {
+ DiscriminantIII 0 lt {
+ CurveCoefb 0 lt {
+ CurveCoefb neg CurveCoefc CurveCoefa sub atan /MyHyperbolaAngDbl ED
+ MyHyperbolaAngDbl 2 div /#5 ED
+ } {
+ CurveCoefb CurveCoefa CurveCoefc sub atan /MyHyperbolaAngDbl ED
+ MyHyperbolaAngDbl 180 add 2 div /#5 ED
+ } ifelse
+ } {
+ CurveCoefb 0 lt {
+ CurveCoefb neg CurveCoefc CurveCoefa sub atan /MyHyperbolaAngDbl ED
+ MyHyperbolaAngDbl 180 add 2 div /#5 ED
+ } {
+ CurveCoefb CurveCoefa CurveCoefc sub atan /MyHyperbolaAngDbl ED
+ MyHyperbolaAngDbl 2 div /#5 ED
+ } ifelse
+ } ifelse
+ } ifelse
+ } ifelse
+ % MyHyperbolaA = MyHyperbolaB = #5 = (--------------) =
+ CurveCoefd CurveCoefc mul 2 mul CurveCoefb CurveCoefe mul sub DiscriminantII div % x0
+ CurveCoefa CurveCoefe mul 2 mul CurveCoefb CurveCoefd mul sub DiscriminantII div % y0
+ } ifelse
+ } {
+ 0 0
+ 0 /MyHyperbolaA ED
+ 0 /MyHyperbolaB ED
+ 0 /#5 ED
+ } ifelse
+ ){#3}
+ \Pst@geonodelabel{#3}%
+ \pnode(! MyHyperbolaA MyHyperbolaB){#4}
+ \ifPst@CodeFig
+ \begingroup\psset{PointName=none,linecolor=\psk@CodeFigColor}
+ \pstLineAA[nodesepA=-1.8,nodesepB=-0.8]{#3}{#5}{PST@HYPERBOLA@COEF@A}
+ \pstLineAA[nodesepA=-1.8,nodesepB=-0.8]{#3}{#5 90 add}{PST@HYPERBOLA@COEF@B}
+ \endgroup
+ \fi
+ \endgroup%
+}%
+%
+%% \pstGeneralHyperbolaABCDE[Options]{A}{B}{C}{D}{E}{O}{R}{\theta}
+%% Calculate the center and the radii of the hyperbola defined by the five different points A,B,C,D,E,
+%% then you can access the hyperbola with them.
+%% Parameters:
+%% #1 -> options
+%% #2 -> [input] the given point A.
+%% #3 -> [input] the given point B.
+%% #4 -> [input] the given point C.
+%% #5 -> [input] the given point D.
+%% #6 -> [input] the given point E.
+%% #7 -> [output] the center of the hyperbola.
+%% #8 -> [output] the pair of major and minor radius of the hyperbola.
+%% #9 -> [output] the rotation of the hyperbola real axis.
+\def\pstGeneralHyperbolaABCDE{\@ifnextchar[\Pst@GeneralHyperbolaABCDE{\Pst@GeneralHyperbolaABCDE[]}}
+\def\Pst@GeneralHyperbolaABCDE[#1]#2#3#4#5#6#7#8#9{
+ \begingroup
+ \psset{#1}%
+ \pst@getcoor{#2}\pst@CurveNodeA%
+ \pst@getcoor{#3}\pst@CurveNodeB%
+ \pst@getcoor{#4}\pst@CurveNodeC%
+ \pst@getcoor{#5}\pst@CurveNodeD%
+ \pst@getcoor{#6}\pst@CurveNodeE%
+ \pnode(!
+ \pst@CurveNodeA \tx@UserCoor /CurveNodeAY ED /CurveNodeAX ED
+ \pst@CurveNodeB \tx@UserCoor /CurveNodeBY ED /CurveNodeBX ED
+ \pst@CurveNodeC \tx@UserCoor /CurveNodeCY ED /CurveNodeCX ED
+ \pst@CurveNodeD \tx@UserCoor /CurveNodeDY ED /CurveNodeDX ED
+ \pst@CurveNodeE \tx@UserCoor /CurveNodeEY ED /CurveNodeEX ED
+ %%
+ % ax^2+bxy+cy^2+dx+ey+f=0, let a=1, we can use A,B,C,D,E to solve b,c,d,e,f, we have
+ % AxAy b + Ay^2 c + Ax d + Ay e + 1 f = -Ax^2
+ % BxBy b + By^2 c + Bx d + By e + 1 f = -Bx^2
+ % CxCy b + Cy^2 c + Cx d + Cy e + 1 f = -Cx^2
+ % DxDy b + Dy^2 c + Dx d + Dy e + 1 f = -Dx^2
+ % ExEy b + Ey^2 c + Ex d + Ey e + 1 f = -Ex^2
+ % by Cramer's Rule, we have
+ % |Ax^2 Ay^2 Ax Ay 1| |AxAy Ay^2 Ax Ay 1|
+ % |Bx^2 By^2 Bx By 1| |BxBy By^2 Bx By 1|
+ % b=-|Cx^2 Cy^2 Cx Cy 1|/|CxCy Cy^2 Cx Cy 1| etc.
+ % |Dx^2 Dy^2 Dx Dy 1| |DxDy Dy^2 Dx Dy 1|
+ % |Ex^2 Ey^2 Ex Ey 1| |ExEy Ey^2 Ex Ey 1|
+ %%
+ CurveNodeAX CurveNodeAY mul CurveNodeAY dup mul CurveNodeAX CurveNodeAY 1
+ CurveNodeBX CurveNodeBY mul CurveNodeBY dup mul CurveNodeBX CurveNodeBY 1
+ CurveNodeCX CurveNodeCY mul CurveNodeCY dup mul CurveNodeCX CurveNodeCY 1
+ CurveNodeDX CurveNodeDY mul CurveNodeDY dup mul CurveNodeDX CurveNodeDY 1
+ CurveNodeEX CurveNodeEY mul CurveNodeEY dup mul CurveNodeEX CurveNodeEY 1
+ tx@EcldDict begin DeterminantFive end /LinearDiscriminant ED
+ LinearDiscriminant abs 1E-5 lt { % D=0
+ 0 0
+ 0 /MyHyperbolaA ED
+ 0 /MyHyperbolaB ED
+ 0 /#9 ED
+ } {
+ 1 /CurveCoefa ED
+ CurveNodeAX dup mul CurveNodeAY dup mul CurveNodeAX CurveNodeAY 1
+ CurveNodeBX dup mul CurveNodeBY dup mul CurveNodeBX CurveNodeBY 1
+ CurveNodeCX dup mul CurveNodeCY dup mul CurveNodeCX CurveNodeCY 1
+ CurveNodeDX dup mul CurveNodeDY dup mul CurveNodeDX CurveNodeDY 1
+ CurveNodeEX dup mul CurveNodeEY dup mul CurveNodeEX CurveNodeEY 1
+ tx@EcldDict begin DeterminantFive end LinearDiscriminant div neg /CurveCoefb ED
+ CurveNodeAX CurveNodeAY mul CurveNodeAX dup mul CurveNodeAX CurveNodeAY 1
+ CurveNodeBX CurveNodeBY mul CurveNodeBX dup mul CurveNodeBX CurveNodeBY 1
+ CurveNodeCX CurveNodeCY mul CurveNodeCX dup mul CurveNodeCX CurveNodeCY 1
+ CurveNodeDX CurveNodeDY mul CurveNodeDX dup mul CurveNodeDX CurveNodeDY 1
+ CurveNodeEX CurveNodeEY mul CurveNodeEX dup mul CurveNodeEX CurveNodeEY 1
+ tx@EcldDict begin DeterminantFive end LinearDiscriminant div neg /CurveCoefc ED
+ CurveNodeAX CurveNodeAY mul CurveNodeAY dup mul CurveNodeAX dup mul CurveNodeAY 1
+ CurveNodeBX CurveNodeBY mul CurveNodeBY dup mul CurveNodeBX dup mul CurveNodeBY 1
+ CurveNodeCX CurveNodeCY mul CurveNodeCY dup mul CurveNodeCX dup mul CurveNodeCY 1
+ CurveNodeDX CurveNodeDY mul CurveNodeDY dup mul CurveNodeDX dup mul CurveNodeDY 1
+ CurveNodeEX CurveNodeEY mul CurveNodeEY dup mul CurveNodeEX dup mul CurveNodeEY 1
+ tx@EcldDict begin DeterminantFive end LinearDiscriminant div neg /CurveCoefd ED
+ CurveNodeAX CurveNodeAY mul CurveNodeAY dup mul CurveNodeAX CurveNodeAX dup mul 1
+ CurveNodeBX CurveNodeBY mul CurveNodeBY dup mul CurveNodeBX CurveNodeBX dup mul 1
+ CurveNodeCX CurveNodeCY mul CurveNodeCY dup mul CurveNodeCX CurveNodeCX dup mul 1
+ CurveNodeDX CurveNodeDY mul CurveNodeDY dup mul CurveNodeDX CurveNodeDX dup mul 1
+ CurveNodeEX CurveNodeEY mul CurveNodeEY dup mul CurveNodeEX CurveNodeEX dup mul 1
+ tx@EcldDict begin DeterminantFive end LinearDiscriminant div neg /CurveCoefe ED
+ CurveNodeAX CurveNodeAY mul CurveNodeAY dup mul CurveNodeAX CurveNodeAY CurveNodeAX dup mul
+ CurveNodeBX CurveNodeBY mul CurveNodeBY dup mul CurveNodeBX CurveNodeBY CurveNodeBX dup mul
+ CurveNodeCX CurveNodeCY mul CurveNodeCY dup mul CurveNodeCX CurveNodeCY CurveNodeCX dup mul
+ CurveNodeDX CurveNodeDY mul CurveNodeDY dup mul CurveNodeDX CurveNodeDY CurveNodeDX dup mul
+ CurveNodeEX CurveNodeEY mul CurveNodeEY dup mul CurveNodeEX CurveNodeEY CurveNodeEX dup mul
+ tx@EcldDict begin DeterminantFive end LinearDiscriminant div neg /CurveCoeff ED
+ % the following is same with pstGeneralHyperbolaCoef.
+ % I1=a+c
+ CurveCoefa CurveCoefc add /DiscriminantI ED
+ % I2=b^2-4ac
+ CurveCoefb dup mul 4 CurveCoefa CurveCoefc mul mul sub /DiscriminantII ED
+ % I3=1/2|2a b d,b 2c e,d e 2f|
+ CurveCoefa 2 mul CurveCoefb CurveCoefd
+ CurveCoefb CurveCoefc 2 mul CurveCoefe
+ CurveCoefd CurveCoefe CurveCoeff 2 mul
+ tx@EcldDict begin DeterminantThree end 2 div /DiscriminantIII ED
+ % DiscriminantI = DiscriminantII = DiscriminantIII =
+ DiscriminantII 0 gt DiscriminantIII 0 ne and { % if I2>0 and I3!=0
+ % Solve the Characteristic Equation: \lambda^2-I_1\lambda-I_2/4=0
+ DiscriminantI dup mul DiscriminantII add dup 0 lt {
+ 0 0
+ 0 /MyHyperbolaA ED
+ 0 /MyHyperbolaB ED
+ 0 /#9 ED
+ } {
+ sqrt dup DiscriminantI exch sub 2 div /CharacteristicLambdaI ED
+ DiscriminantI add 2 div /CharacteristicLambdaII ED
+ % CharacteristicLambdaI = CharacteristicLambdaII =
+ CurveCoefb 0 lt {
+ DiscriminantIII 0 lt {
+ DiscriminantIII CharacteristicLambdaI DiscriminantII mul div sqrt /MyHyperbolaA ED
+ DiscriminantIII CharacteristicLambdaII DiscriminantII mul div neg sqrt /MyHyperbolaB ED
+ } {
+ DiscriminantIII CharacteristicLambdaI DiscriminantII mul div neg sqrt /MyHyperbolaB ED
+ DiscriminantIII CharacteristicLambdaII DiscriminantII mul div sqrt /MyHyperbolaA ED
+ } ifelse
+ } {
+ DiscriminantIII 0 lt {
+ DiscriminantIII CharacteristicLambdaII DiscriminantII mul div neg sqrt /MyHyperbolaB ED
+ DiscriminantIII CharacteristicLambdaI DiscriminantII mul div sqrt /MyHyperbolaA ED
+ } {
+ DiscriminantIII CharacteristicLambdaII DiscriminantII mul div sqrt /MyHyperbolaA ED
+ DiscriminantIII CharacteristicLambdaI DiscriminantII mul div neg sqrt /MyHyperbolaB ED
+ } ifelse
+ } ifelse
+ CurveCoefb abs 1E-5 lt { % b == 0
+ CurveCoefa CurveCoefc lt { % a < c
+ 0 /#9 ED
+ } {
+ 90 /#9 ED
+ } ifelse
+ } {
+ CurveCoefa CurveCoefc sub abs 1E-5 lt { % a = c
+ 45 /#9 ED
+ } {
+ DiscriminantIII 0 lt {
+ CurveCoefb 0 lt {
+ CurveCoefb neg CurveCoefc CurveCoefa sub atan /MyHyperbolaAngDbl ED
+ MyHyperbolaAngDbl 2 div /#9 ED
+ } {
+ CurveCoefb CurveCoefa CurveCoefc sub atan /MyHyperbolaAngDbl ED
+ MyHyperbolaAngDbl 180 add 2 div /#9 ED
+ } ifelse
+ } {
+ CurveCoefb 0 lt {
+ CurveCoefb neg CurveCoefc CurveCoefa sub atan /MyHyperbolaAngDbl ED
+ MyHyperbolaAngDbl 180 add 2 div /#9 ED
+ } {
+ CurveCoefb CurveCoefa CurveCoefc sub atan /MyHyperbolaAngDbl ED
+ MyHyperbolaAngDbl 2 div /#9 ED
+ } ifelse
+ } ifelse
+ } ifelse
+ } ifelse
+ % MyHyperbolaA = MyHyperbolaB = #9 = (--------------) =
+ CurveCoefd CurveCoefc mul 2 mul CurveCoefb CurveCoefe mul sub DiscriminantII div % x0
+ CurveCoefa CurveCoefe mul 2 mul CurveCoefb CurveCoefd mul sub DiscriminantII div % y0
+ } ifelse
+ } {
+ 0 0
+ 0 /MyHyperbolaA ED
+ 0 /MyHyperbolaB ED
+ 0 /#9 ED
+ } ifelse
+ } ifelse
+ ){#7}
+ \Pst@geonodelabel{#7}%
+ \pnode(! MyHyperbolaA MyHyperbolaB){#8}
+ \ifPst@CodeFig
+ \begingroup\psset{PointName=none,linecolor=\psk@CodeFigColor}
+ \pstLineAA[nodesepA=-1.8,nodesepB=-0.8]{#7}{#9}{PST@HYPERBOLA@COEF@A}
+ \pstLineAA[nodesepA=-1.8,nodesepB=-0.8]{#7}{#9 90 add}{PST@HYPERBOLA@COEF@B}
+ \endgroup
+ \fi
+ \endgroup%
+}%
+%
%% \pstGeneralHyperbolaNode[Options](O)(a,b)[rotation]{t}{A}
%% Draw a node whose parameter value is the given value t on the General Hyperbola.
%% Parameters: