%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -*- Mode: Latex -*- %%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% pst-eucl.tex --- Generation of geometric figures in euclidean geometry
%% Copyright 2000-2013 Dominique RODRIGUEZ
%% Copyright 2014-...  Dominique RODRIGUEZ, Herbert Voß
%%
%% This program can be redistributed and/or modified under the terms
%% of the LaTeX Project Public License Distributed from CTAN
%% archives in directory macros/latex/base/lppl.txt.
%%
%% Authors         : Dominique RODRIGUEZ (EN) <dominique.rodriguez@waika9.com>
%%                 : hv hvoss@tug.org
%%                 : lx Liao Xiongfei
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Require PSTricks and pst-node packages
\ifx\PSTnodesLoaded\endinput\else\input pst-node.tex\fi
\ifx\PSTArrowLoaded\endinput\else\input pst-arrow.tex\fi
\ifx\PSTtoolsLoaded\endinput\else\input pst-tools.tex\fi
\ifx\PSTplotLoaded\endinput\else\input pst-plot.tex\fi
%\ifx\PSTXKeyLoaded\endinput\else \input pst-xkey\fi
\ifx\MultidoLoaded\endinput \else\input multido.tex \fi
\csname PSTEuclideLoaded\endcsname
\let\PSTEuclideLoaded\endinput
%
\def\fileversion{1.75}
\def\filedate{2020/09/29}
%%
\message{`PST-Euclide v\fileversion, \filedate\space (dr,hv)}%
%% prologue for postcript
\pstheader{pst-eucl.pro}%
\edef\PstAtCode{\the\catcode`\@}%
\catcode`\@=11\relax
\pst@addfams{pst-eucl}
% Definition of the parameters
% ----------------------------
% symbol used for the point
\define@key[psset]{pst-eucl}{PointSymbol}[*]{%
  \def\psk@PointSymbol{#1}%
  \def\psk@PointSymbolA{#1}%
  \def\psk@PointSymbolB{#1}%
  \def\psk@PointSymbolC{#1}%
}%
\define@key[psset]{pst-eucl}{PointSymbolA}[*]{\def\psk@PointSymbolA{#1}}%
\define@key[psset]{pst-eucl}{PointSymbolB}[*]{\def\psk@PointSymbolB{#1}}%
\define@key[psset]{pst-eucl}{PointSymbolC}[*]{\def\psk@PointSymbolC{#1}}%
% name used for the point

\define@key[psset]{pst-eucl}{PointName}[default]{\def\psk@PointName{#1}}%
\define@key[psset]{pst-eucl}{PointNameA}[undef]{\def\psk@PointNameA{#1}}%
\define@key[psset]{pst-eucl}{PointNameB}[undef]{\def\psk@PointNameB{#1}}%
\define@key[psset]{pst-eucl}{PointNameC}[undef]{\def\psk@PointNameC{#1}}%
% use math mode in point name
\newif\ifPst@PtNameMath%
\define@key[psset]{pst-eucl}{PtNameMath}[false]{\@nameuse{Pst@PtNameMath#1}}%
\define@key[psset]{pst-eucl}{PointNameSize}[\normalsize]{\def\Point@Name@Size{#1}}%
\define@key[psset]{pst-eucl}{PointNameMathSize}[\textnormal]{\def\Point@Name@MathSize{#1}}%
% symbol used for marking equal length segment
\define@key[psset]{pst-eucl}{SegmentSymbol}[MarkHashh]{\def\psk@SegmentSymbol{#1}}%
\define@key[psset]{pst-eucl}{SegmentSymbolA}[MarkHashh]{\def\psk@SegmentSymbolA{#1}}%
\define@key[psset]{pst-eucl}{SegmentSymbolB}[MarkHashh]{\def\psk@SegmentSymbolB{#1}}%
\define@key[psset]{pst-eucl}{SegmentSymbolC}[MarkHashh]{\def\psk@SegmentSymbolC{#1}}%
\define@key[psset]{pst-eucl}{Mark}[undef]{\def\psk@Mark{#1}}%
\define@key[psset]{pst-eucl}{mark}[undef]{\def\psk@mark{Angle#1}}%  for angles
\define@key[psset]{pst-eucl}{MarkAngle}[undef]{\edef\psk@MarkAngle{#1}}%
\newdimen\psMarkHashLength
\newdimen\psMarkHashSep
\define@key[psset]{pst-eucl}{MarkHashLength}[1.25mm]{\pssetlength\psMarkHashLength{#1}}
\define@key[psset]{pst-eucl}{MarkHashSep}[0.625mm]{\pssetlength\psMarkHashSep{#1}}
\psset{MarkHashLength,MarkHashSep}% sets the defaults
%
% disance from point to its label
\define@key[psset]{pst-eucl}{PointNameSep}{\edef\psk@PointNameSep{#1}}%
% position angle for positionning a point name
\define@key[psset]{pst-eucl}{PosAngle}{\edef\psk@PosAngle{#1}}%
\iffalse
\define@key[psset]{pst-eucl}{PosAngle}{\expandafter\psk@@Pos@Angle#1,,!}%
\def\psk@@Pos@Angle#1,#2,#3#4#5!{%
%  \typeout{1: #1; 2: #2; 3: #3; 4: #4; 5: #5}%
  \def\psk@PosAngle{#1}%
  \def\@temp{#1}%
  \ifx\@temp\@undef \typeout{Nichts machen}\else\typeout{Winkel setzen}%
    \ifx\relax#1\relax \def\psk@PosAngle{undef}\else\def\psk@PosAngleA{#1}\fi
    \ifx\relax#2\relax \else\def\psk@PosAngleB{#2}\fi
    \ifx\relax#3\relax \else\def\psk@PosAngleC{#3}\fi
  \fi
}
\fi
\define@key[psset]{pst-eucl}{PosAngleA}[undef]{\def\psk@PosAngleA{#1}}%
\define@key[psset]{pst-eucl}{PosAngleB}[undef]{\def\psk@PosAngleB{#1}}%
\define@key[psset]{pst-eucl}{PosAngleC}[undef]{\def\psk@PosAngleC{#1}}%
% dimension of the right angle mark
\define@key[psset]{pst-eucl}{RightAngleSize}[4]{\def\psk@RightAngleSize{#1}}%
\define@key[psset]{pst-eucl}{RightAngleType}[default]{\def\psk@RightAngleType{#1}}%
\define@key[psset]{pst-eucl}{RightAngleDotDistance}[1]{\def\psk@RightAngleDotDistance{#1 }}%
% radius of an angle mark
\define@key[psset]{pst-eucl}{MarkAngleRadius}[0.4]{\def\psk@MarkAngleRadius{#1}}%
\define@key[psset]{pst-eucl}{MarkAngleType}[default]{\def\psk@MarkAngleType{#1}}%
% angular offset position of the label for marking an angle
\define@key[psset]{pst-eucl}{LabelAngleOffset}[0]{\def\psk@LabelAngleOffset{#1}}%
% position radius of the label for marking an angle
\define@key[psset]{pst-eucl}{LabelSep}[1]{\def\psk@LabelSep{#1}}%
% ref point of the label
\define@key[psset]{pst-eucl}{LabelRefPt}[c]{\def\psk@LabelRefPt{#1}}%
% curve type for point list
\define@key[psset]{pst-eucl}{CurveType}[none]{\def\psk@CurveType{#1}}%
% coefficient of homothetie
\define@key[psset]{pst-eucl}{HomCoef}[0.5]{\def\psk@HomCoef{#1}}%
% angle of rotation
\define@key[psset]{pst-eucl}{RotAngle}[60]{\def\psk@RotAngle{#1}}%
% label for coding the transfortion
\define@key[psset]{pst-eucl}{TransformLabel}[none]{\edef\psk@TransformLabel{#1}}%
% private parameter
\newif\ifPst@CentralSym
\define@key[psset]{pst-eucl}{Central@Sym}[false]{\@nameuse{Pst@CentralSym#1}}%
% for drawing the circum-circle
\newif\ifPst@DrawCirABC
\define@key[psset]{pst-eucl}{DrawCirABC}[true]{\@nameuse{Pst@DrawCirABC#1}}%
% for coding a construction
\define@boolkey[psset]{pst-eucl}[Pst@]{CodeFig}[true]{}
%\define@boolkey[psset]{pst-eucl}[Pst@]{CodeFigA}[true]{\def\psk@CodeFigA{#1}}
%\define@boolkey[psset]{pst-eucl}[Pst@]{CodeFigB}[true]{\def\psk@CodeFigB{#1}}
\newif\ifPst@CodeFigA
\define@key[psset]{pst-eucl}{CodeFigA}[undef]{\edef\psk@CodeFigA{#1}\@nameuse{Pst@CodeFigA#1}}%
\newif\ifPst@CodeFigB
\define@key[psset]{pst-eucl}{CodeFigB}[undef]{\edef\psk@CodeFigB{#1}\@nameuse{Pst@CodeFigB#1}}%

\define@key[psset]{pst-eucl}{CodeFigColor}[cyan]{\edef\psk@CodeFigColor{#1}}%
\define@key[psset]{pst-eucl}{CodeFigStyle}[dashed]{\edef\psk@CodeFigStyle{#1}}%
\newif\ifPst@CodeFigAarc%
\define@key[psset]{pst-eucl}{CodeFigAarc}[true]{\@nameuse{Pst@CodeFigAarc#1}}
\newif\ifPst@CodeFigBarc%
\define@key[psset]{pst-eucl}{CodeFigBarc}[true]{\@nameuse{Pst@CodeFigBarc#1}}
%% for specifying a distance for the circle
\define@key[psset]{pst-eucl}{Radius}[none]{\edef\psk@Radius{#1}}%
\define@key[psset]{pst-eucl}{RadiusA}[undef]{\edef\psk@RadiusA{#1}}%
\define@key[psset]{pst-eucl}{RadiusB}[undef]{\edef\psk@RadiusB{#1}}%
\define@key[psset]{pst-eucl}{Diameter}[none]{\edef\psk@Diameter{#1}}%
\define@key[psset]{pst-eucl}{DiameterA}[undef]{\edef\psk@DiameterA{#1}}%
\define@key[psset]{pst-eucl}{DiameterB}[undef]{\edef\psk@DiameterB{#1}}%
% for specifying a distance for the circle
\define@key[psset]{pst-eucl}{DistCoef}[none]{\edef\psk@DistCoef{#1}}%
\define@key[psset]{pst-eucl}{AngleCoef}[none]{\edef\psk@AngleCoef{#1}}%
% for curvilign abscissa placement
\newif\ifPst@CurvAbsNeg%
\define@key[psset]{pst-eucl}{CurvAbsNeg}[false]{\@nameuse{Pst@CurvAbsNeg#1}}%
% first and last point of a generic curve
\define@key[psset]{pst-eucl}{GenCurvFirst}[none]{\edef\psk@GenCurvFirst{#1}}%
\define@key[psset]{pst-eucl}{GenCurvLast}[none]{\edef\psk@GenCurvLast{#1}}%
% increment of a generic curve
\define@key[psset]{pst-eucl}{GenCurvInc}[1]{\edef\psk@GenCurvInc{#1}}%
%% Default values
% --------------
\def\resetEUCLvalues{%
\psset[pst-eucl]{%
  PointSymbol=*, %PointSymbolA=*, PointSymbolB=*, PointSymbolC=*,
  PointName=default, PointNameA=undef, PointNameB=undef, PointNameC=undef,
  PtNameMath=true, PointNameMathSize=\textstyle, PointNameSize=\normalsize,
  PointNameSep=default, PosAngle=undef,
  PosAngleA=undef,
  PosAngleB=undef, PosAngleC=undef, Mark=undef, mark=undef,SegmentSymbol=MarkHashh,
  SegmentSymbolA=MarkHashh, SegmentSymbolB=MarkHash, SegmentSymbolC=MarkHashhh,
  RightAngleSize=.4, RightAngleType=default, RightAngleDotDistance=1,
  LabelAngleOffset=0, LabelSep=1,
  LabelRefPt=c, MarkAngle=undef, MarkAngleType=default, MarkAngleRadius=.4,
  HomCoef=.5, RotAngle=60,
  CurveType=none, TransformLabel=none, Central@Sym=false, DrawCirABC=true,
  CodeFig=false, CodeFigColor=cyan, CodeFigStyle=dashed, CodeFigA=undef,
  CodeFigB=undef, CodeFigAarc=true, CodeFigBarc=true, Radius=none, RadiusA=undef,
  RadiusB=undef, Diameter=none, DiameterA=undef, DiameterB=undef, DistCoef=none,
  AngleCoef=none, CurvAbsNeg=false, GenCurvFirst=none, GenCurvLast=none,
  GenCurvInc=1}}
\resetEUCLvalues
%\SpecialCoor        %% for using polar coordinates, node position, ...
\psset{dimen=middle}% remark of ML
\def\@undef{undef}%
\def\@default{default}%
\def\@german{german}%
\def\@suisseromand{suisseromand}%
\def\@double{double}%
\def\@triple{triple}%
\def\@polygon{polygon}
\def\@polyline{polyline}
\def\@curve{curve}
\def\@none{none}
\def\tx@PtoC{ tx@Dict begin PtoC end }
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% list for marking segment
\def\SegSymLst{MarkHash,MarkHashh,MarkHashhh,MarkCros,MarkCross,pstslash,pstslashh,pstslashhh,circ,times,cup,triangle,wedge}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% create a curve after a points list
\def\pst@MngTransformCurve{%DR 25032005
  \ifx\psk@CurveType\@none\else
    \ifx\psk@CurveType\@polygon\expandafter\pspolygon\@@GenCourbe\else
      \ifx\psk@CurveType\@polyline\expandafter\psline\@@GenCourbe\else
        \ifx\psk@CurveType\@curve\expandafter\pscurve\@@GenCourbe
  \fi\fi\fi\fi}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% macros for managing a list of parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
       %% begin DR 2005/04/10
\def\@List#1{\xdef\@NewList{none}\@List@i#1,\@nil\ignorespaces}
\def\@List@i#1,{%
\@List@ii#1==\@nil
\@ifnextchar\@nil{\@gobble}{\@List@i}}
\def\@List@ii#1=#2\@nil{%
\ifx\@NewList\@none\xdef\@NewList{#1}\else\xdef\@NewList{\@NewList,#1}\fi}%
       %% end DR 2005/04/10
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\@InitListMng{%
  \def\LastValidPN{default}\def\LastValidPNS{default}\def\LastValidPA{undef}\def\LastValidPS{undef}}
%% car(liste) -- param1,param2,... -> param1
\def\PstParamListFirst#1,#2/{#1}
%% cdr(liste) -- param1,param2,... -> param2,...

\def\PstParamListLasts#1,#2/{#2}

\def\Pst@ManageParamList#1{%DR 02092004 #1->point node name
  \edef\OldPointName{\psk@PointName}%
  \edef\psk@PointName{\expandafter\PstParamListFirst\OldPointName,undef/}%
  \ifx\psk@PointName\@undef\edef\psk@PointName{\LastValidPN}\else\edef\LastValidPN{\psk@PointName}\fi
  \edef\OldPointNameSep{\psk@PointNameSep}%
  \edef\psk@PointNameSep{\expandafter\PstParamListFirst\OldPointNameSep,default/}%
  \ifx\psk@PointNameSep\@default\edef\psk@PointNameSep{\LastValidPNS}\else\edef\LastValidPNS{\psk@PointNameSep}\fi
  \edef\OldPosAngle{\psk@PosAngle}%
  \edef\psk@PosAngle{\expandafter\PstParamListFirst\OldPosAngle,undef/}%
  \ifx\psk@PosAngle\@undef\edef\psk@PosAngle{\LastValidPA}\else\edef\LastValidPA{\psk@PosAngle}\fi
  \edef\OldPointSymbol{\psk@PointSymbol}%
  \edef\psk@PointSymbol{\expandafter\PstParamListFirst\OldPointSymbol,undef/}%
  \ifx\psk@PointSymbol\@undef\edef\psk@PointSymbol{\LastValidPS}\else\edef\LastValidPS{\psk@PointSymbol}\fi
  \Pst@geonodelabel{#1}%DR 02092004
  \edef\psk@PointName{\expandafter\PstParamListLasts\OldPointName,undef/}%
  \edef\psk@PointNameSep{\expandafter\PstParamListLasts\OldPointNameSep,default/}%
  \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
%% #3 -> node name
\def\pstGeonode{\@ifnextchar[\Pst@Geonode{\Pst@Geonode[]}}
\def\Pst@Geonode[#1]{\@ifnextchar({\Pst@Geonode@i[#1]}{\Pst@Geonode@i[#1](0,0)}}
\def\Pst@Geonode@i[#1]{%
  \begingroup
    \@InitListMng% DR 22032005
    \xdef\@@GenCourbe{}%%for accumulating points% DR 22032005
    \psset{#1}%
    \Pst@Geonode@ii}
\def\Pst@Geonode@ii(#1)#2{%
  \pnode(#1){#2}
  \xdef\@@GenCourbe{\@@GenCourbe(#2)}%%for accumulating points% DR 22032005
  \Pst@ManageParamList{#2}%
  \@ifnextchar(\Pst@Geonode@ii{\pst@MngTransformCurve\endgroup
  }}% DR 22032005

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% \pstPolygon[options](A)(B)(C)(D)...
%% create a polygon with some given node names, unlike the native pstrick pspolygon macro,
%% this macro group the options as local variables, i.e, it is same as
%% \begingroup
%% \pspolygon[options](A)(B)(C)(D)...
%% \endgroup
%% if you use pspolygon without the begingroup and endgroup, then the options will be
%% used for the subsequent macros.
%%
%% #1 -> options
%% #2,#3,#4,... -> node names
\def\pstPolygon{\@ifnextchar[\Pst@Polygon{\Pst@Polygon[]}}
\def\Pst@Polygon[#1]{%
  \begingroup
    \xdef\@@GenCourbe{}%%for accumulating points
    \psset{#1}%
    \ifx\psk@CurveType\@none\psset{CurveType=polygon}\fi
    \pstPolygon@ii%
}
\def\pstPolygon@ii(#1){%
    \xdef\@@GenCourbe{\@@GenCourbe(#1)}%
    \@ifnextchar(\pstPolygon@ii{\pst@MngTransformCurve\endgroup}%
}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Create a point with an associated node, in a new
%% landmark
%% #1 -> options
%% #2 -> coordinates
%% #3 -> node name
%% #4 -> O: new center of the landmark
%% #5 -> I: abscissa reference
%% #6 -> J: ordinate reference
\def\pstOIJGeonode{\@ifnextchar[\Pst@OIJGeonode{\Pst@OIJGeonode[]}}%
\def\Pst@OIJGeonode[#1]{%NEW DR 14112001 (for default (0,0) ccordinates)
  \@ifnextchar({\Pst@OIJGeonode@i[#1]}{\Pst@OIJGeonode[#1](0,0)}}%
\def\Pst@OIJGeonode@i[#1]{%
  \begingroup
    \@InitListMng% DR 22032005
    \edef\@@GenCourbe{}%%for accumulating points% DR 22032005
    \psset{#1}\Pst@OIJGeonode@ii}
\def\Pst@OIJGeonode@ii(#1)#2#3#4#5{\Pst@OIJGeonode@iii{#3}{#4}{#5}(#1){#2}}
\def\Pst@OIJGeonode@iii#1#2#3(#4)#5{%
  \rput(#1){%
    \pst@@getcoor{#4}%
    \rput(!\pst@coor\space
      tx@EcldDict begin /N@#2 GetNode /N@#3 GetNode end
      4 index mul 3 -1 roll 5 index mul add
      \pst@number\psyunit dup mul div  exch
      4 -1 roll mul 3 -1 roll 4 -1 roll mul add
      \pst@number\psxunit dup mul div exch){\pnode{#5}}}%
  \xdef\@@GenCourbe{\@@GenCourbe(#5)}%%for accumulating points% DR 22032005
  \Pst@ManageParamList{#5}%
  \@ifnextchar({\Pst@OIJGeonode@iii{#1}{#2}{#3}}{\pst@MngTransformCurve\endgroup}}% DR 22032005
%%end modif DR 11/2003
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% #1 -> point coordinates
\def\Pst@geonodelabel#1{%            % {nodename}
  \ifx\psk@PointSymbol\@none
    \ifx\psk@PointName\@none\else\Pst@PutPointLabel{#1}\fi
  \else
%      \ifx\psk@PointSymbol\@default \def\psk@PointSymbol{*}\fi%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      \psdot[dotstyle=\psk@PointSymbol](#1)%
      \Pst@PutPointLabel{#1}%DR 041104
  \fi%DR 02092004
%  \ifx\psk@PointName\@none\else\Pst@PutPointLabel{#1}\fi%DR 041104
}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\Pst@PutPointLabel#1{%DR 041104
  \ifx\psk@PointName\@none\else
    \rput{*0}([nodesep=\ifx\psk@PointNameSep\@default{1em}\else\psk@PointNameSep\fi,
               angle=\ifx\psk@PosAngle\@undef{0}\else\psk@PosAngle\fi]#1)%
      {\ifPst@PtNameMath $\Point@Name@MathSize\Pst@WhichLabel{#1}$\else\Point@Name@Size\Pst@WhichLabel{#1}\fi}
  \fi}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\Pst@WhichLabel#1{\ifx\psk@PointName\@default#1\else\psk@PointName\fi}%DR 0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% #2 #3 -> nodes defining the segment to mark
\def\pstSegmentMark{\@ifnextchar[\Pst@SegmentMark{\Pst@SegmentMark[]}}%
\def\Pst@SegmentMark[#1]#2#3{%
  \bgroup
  \psset{#1}%            % Affectation of local parameters
  \ncline[nodesep=0]{#2}{#3}
  \ncput[nrot=:U]{$\expandafter\@nameuse\expandafter{\psk@SegmentSymbol}$}%  $
  \egroup%
}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% macros for marking
\def\pstslash{/}%
\def\pstslashh{/\kern-2pt/}%
\let\pstslashslash=\pstslashh
\def\pstslashhh{/\kern-1.4pt/\kern-1.4pt/}%
\let\pstslashslashslash=\pstslashhh
\def\Anglepstslash{\rput{\ifx\psk@MarkAngle\@undef0\else\psk@MarkAngle\fi}(0,0){\pstslash}}
\def\Anglepstslashh{\rput{\ifx\psk@MarkAngle\@undef0\else\psk@MarkAngle\fi}(0,0){\pstslashh}}
\def\Anglepstslashhh{\rput{\ifx\psk@MarkAngle\@undef0\else\psk@MarkAngle\fi}(0,0){\pstslashhh}}
\let\Anglepstslashslash=\Anglepstslashh%
\let\Anglepstslashslashslash=\Anglepstslashhh%
%%begin modif alaindelplanque 11/2003
%%begin modif Germain Boyer 04/2014
\def\MarkHash{%
     \rput{\ifx\psk@MarkAngle\@undef45\else\psk@MarkAngle\fi}
     {\psline(-\psMarkHashLength,0)(\psMarkHashLength,0)}}
\def\MarkHashh{%
      \rput{\ifx\psk@MarkAngle\@undef45\else\psk@MarkAngle\fi}(-0.5\psMarkHashSep,0)
     {\psline(-\psMarkHashLength,0)(\psMarkHashLength,0)}
      \rput{\ifx\psk@MarkAngle\@undef45\else\psk@MarkAngle\fi}(0.5\psMarkHashSep,0)
     {\psline(-\psMarkHashLength,0)(\psMarkHashLength,0)}}
\def\MarkHashhh{%
     \rput{\ifx\psk@MarkAngle\@undef45\else\psk@MarkAngle\fi}(-\psMarkHashSep,0)
     {\psline(-\psMarkHashLength,0)(\psMarkHashLength,0)}
      \rput{\ifx\psk@MarkAngle\@undef45\else\psk@MarkAngle\fi}
     {\psline(-\psMarkHashLength,0)(\psMarkHashLength,0)}
      \rput{\ifx\psk@MarkAngle\@undef45\else\psk@MarkAngle\fi}(\psMarkHashSep,0)
     {\psline(-\psMarkHashLength,0)(\psMarkHashLength,0)}}
\iffalse         %%%%%% hv 2014/04/05
\def\MarkHash{%
  \rput{\ifx\psk@MarkAngle\@undef45\else\psk@MarkAngle\fi}
    {\psline(-10\pslinewidth,0)(10\pslinewidth,0)}}
\let\AngleMarkHash\MarkHash
\def\MarkHashh{%
  \rput{\ifx\psk@MarkAngle\@undef45\else\psk@MarkAngle\fi}(-3\pslinewidth,0)
    {\psline(-10\pslinewidth,0)(10\pslinewidth,0)}
  \rput{\ifx\psk@MarkAngle\@undef45\else\psk@MarkAngle\fi}(3\pslinewidth,0)
    {\psline(-10\pslinewidth,0)(10\pslinewidth,0)}}
\def\AngleMarkHashh{%
  \rput{\ifx\psk@MarkAngle\@undef0\else\psk@MarkAngle\fi}(0,0){%
    \psline(-10\pslinewidth,-3\pslinewidth)(10\pslinewidth,-3\pslinewidth)
    \psline(-10\pslinewidth,3\pslinewidth)(10\pslinewidth,3\pslinewidth)}}
\def\MarkHashhh{%
  \rput{\ifx\psk@MarkAngle\@undef45\else\psk@MarkAngle\fi}(-6\pslinewidth,0)
    {\psline(-10\pslinewidth,0)(10\pslinewidth,0)}
  \rput{\ifx\psk@MarkAngle\@undef45\else\psk@MarkAngle\fi}
    {\psline(-10\pslinewidth,0)(10\pslinewidth,0)}
  \rput{\ifx\psk@MarkAngle\@undef45\else\psk@MarkAngle\fi}(6\pslinewidth,0)
    {\psline(-10\pslinewidth,0)(10\pslinewidth,0)}}
\fi
\def\AngleMarkHashhh{%
  \rput[c]{\ifx\psk@MarkAngle\@undef0\else\psk@MarkAngle\fi}(0,0){%
    \psline(-10\pslinewidth,-4\pslinewidth)(10\pslinewidth,-4\pslinewidth)
    \psline(-10\pslinewidth,0)(10\pslinewidth,0)
    \psline(-10\pslinewidth,4\pslinewidth)(10\pslinewidth,4\pslinewidth)}}
\def\MarkCros{
  \psline(-4\pslinewidth,4\pslinewidth)(4\pslinewidth,-4\pslinewidth)
  \psline(-4\pslinewidth,-4\pslinewidth)(4\pslinewidth,4\pslinewidth)}
\let\AngleMarkCros\MarkCros
\def\MarkCross{
  \psline(-4\pslinewidth,8\pslinewidth)(4\pslinewidth,0)
  \psline(-4\pslinewidth,0)(4\pslinewidth,8\pslinewidth)
  \psline(-4\pslinewidth,-8\pslinewidth)(4\pslinewidth,0)
  \psline(-4\pslinewidth,0)(4\pslinewidth,-8\pslinewidth)}
\let\AngleMarkCross\MarkCross
\def\MarkCirc{\pscircle(0,0){2\pslinewidth}}
\let\AngleMarkCirc\MarkCirc
% MarkArrow >
\def\MarkArrow{%
  \psline[linestyle=none,veearrowlength=\psMarkHashLength,
          veearrowangle=90,veearrowlinewidth=\pslinewidth,
          ArrowInside=-v](-\psMarkHashLength,0)(\psMarkHashLength,0)}%
\def\MarkArroww{%
  \psline[linestyle=none,veearrowlength=\psMarkHashLength,
          veearrowangle=90,veearrowlinewidth=\pslinewidth,
          ArrowInsideNo=2,ArrowInside=-v](-2\psMarkHashLength,0)(2\psMarkHashLength,0)}%
\def\MarkArrowww{%
  \psline[linestyle=none,veearrowlength=\psMarkHashLength,
          veearrowangle=90,veearrowlinewidth=\pslinewidth,
          ArrowInsideNo=3,ArrowInside=-v](-2.5\psMarkHashLength,0)(2.5\psMarkHashLength,0)}%
%
%%end modif alaindelplanque 11/2003
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% #1 #2 #3 -> 3 nodes for defining the right angle
\def\pstRightAngle{\pst@object{pstRightAngle}}
\def\pstRightAngle@i#1#2#3{%
  \begingroup
  \addbefore@par{dimen=inner,dotscale=1}%linestyle=solid,linecolor=black,linewidth=\pslinewidth}
  \use@par%            % Affectation of local parameters
  %% not good at all, but \rput{0}(#3){\rput{(#2)}{stuff}} doesn't work...
  \rput(#2){%
    \ifx\psk@RightAngleType\@default
      \ifx\psk@fillstylename\@none\else
        \pspolygon[linestyle=none,dimen=inner](0,0)(!tx@EcldDict begin /N@#1 GetNode exch Atan \psk@RightAngleSize\space exch PtoC end)%
             (!tx@EcldDict begin /N@#1 GetNode exch Atan \psk@RightAngleSize\space exch PtoC end)%
             (!tx@EcldDict begin /N@#1 GetNode exch Atan /AngleNo1 ED
               tx@EcldDict begin /N@#3 GetNode exch Atan /AngleNo3 ED
               AngleNo1 AngleNo3 sub abs 180 gt { /Diff -45 def }{ /Diff 45 def } ifelse
               AngleNo1 AngleNo3 gt { AngleNo1 Diff sub }{ AngleNo3 Diff sub } ifelse
                 \psk@RightAngleSize\space 2 sqrt mul exch PtoC end)%
             (!tx@EcldDict begin /N@#3 GetNode exch Atan \psk@RightAngleSize\space exch PtoC end)%
      \fi
      \psline[fillstyle=none](!tx@EcldDict begin /N@#1 GetNode exch Atan \psk@RightAngleSize\space exch PtoC end)%
             (!tx@EcldDict begin /N@#1 GetNode exch Atan \psk@RightAngleSize\space exch PtoC end)%
             (!tx@EcldDict begin /N@#1 GetNode exch Atan /AngleNo1 ED
               tx@EcldDict begin /N@#3 GetNode exch Atan /AngleNo3 ED
               AngleNo1 AngleNo3 sub abs 180 gt { /Diff -45 def }{ /Diff 45 def } ifelse
               AngleNo1 AngleNo3 gt { AngleNo1 Diff sub }{ AngleNo3 Diff sub } ifelse
                 \psk@RightAngleSize\space 2 sqrt mul exch PtoC end)%
             (!tx@EcldDict begin /N@#3 GetNode exch Atan \psk@RightAngleSize\space exch PtoC end)%
    \else
      \ifx\psk@RightAngleType\@german
%        \ifx\psk@fillstylename\@none\else
%          \pscustom[linestyle=none,dimen=inner]{\psline(0,0)
%            \pstMarkAngle[MarkAngleRadius=\psk@RightAngleSize,LabelSep=\psk@RightAngleSize\space .5 mul]{#1}{#2}{#3}{}%
%            \psline(0,0)
%          }
%        \fi
        \pstMarkAngle[MarkAngleRadius=\psk@RightAngleSize,LabelSep=\psk@RightAngleSize\space .5 mul \psk@RightAngleDotDistance mul]{#1}{#2}{#3}%
           {\psscalebox{\psk@RightAngleSize}{\pscircle*{!.08 \psk@xdotscale\space mul}}}%
      \else
        \ifx\psk@RightAngleType\@suisseromand
          \rput{*0}%
            (!tx@EcldDict begin /N@#3 GetNode exch Atan /N@#1 GetNode exch Atan
              2 copy lt { exch 360 sub exch } if add 2 div .45 \psk@RightAngleSize\space mul \psk@RightAngleDotDistance mul exch PtoC end)%
              {\psscalebox{\psk@RightAngleSize}{\pscircle*{.08}}}%
            \psline(0,0)%
              (!tx@EcldDict begin /N@#3 GetNode exch Atan \psk@RightAngleSize\space exch PtoC end )%
              (!tx@EcldDict begin /N@#1 GetNode exch Atan \psk@RightAngleSize\space exch PtoC end )%
    \fi\fi\fi}%
  \endgroup\ignorespaces%  hv 20130312
}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% #2 #3 #4 -> 3 nodes for defining the angle
%% #5 -> label
\def\pstMarkAngle{\@ifnextchar[\Pst@MarkAngle{\Pst@MarkAngle[]}}%
%\def\pstMarkAngle{\@ifnextchar[\Pst@MarkAngle@i{\Pst@MarkAngle@i[]}}%
%\def\Pst@MarkAngle@i[#1]{\@ifnextchar+{\Pst@MarkAngle@ii[#1]}{\Pst@MarkAngle@iii[#1]}}%
%\def\Pst@MarkAngle@ii[#1]+#2#3#4#5{%
%
%%  here we should check the angle size for right angles
%
\def\Pst@MarkAngle[#1]#2#3#4#5{{%
  \psset{%MarkAngle=0,
    #1}%
  \rput(#3){%
    \ifx\psk@fillstylename\@none\else
      \pscustom[linestyle=none,linewidth=0.01pt,arrows=-]{%
        \psline(0,0)
        \psarc(0,0){\psk@MarkAngleRadius}{(#2)}{(#4)}
        \psline(0,0)
      }
    \fi
    \ifx\psk@MarkAngleType\@default
        \psarc[fillstyle=none](0,0){\psk@MarkAngleRadius}{(#2)}{(#4)}%
    \else
        \ifx\psk@MarkAngleType\@double
            \psarc[fillstyle=none](0,0){\psk@MarkAngleRadius}{(#2)}{(#4)}%
            \psarc[fillstyle=none](0,0){! \psk@MarkAngleRadius\space 0.85 mul}{(#2)}{(#4)}%
        \else
            \ifx\psk@MarkAngleType\@triple
                \psarc[fillstyle=none](0,0){\psk@MarkAngleRadius}{(#2)}{(#4)}%
                \psarc[fillstyle=none](0,0){! \psk@MarkAngleRadius\space 0.85 mul}{(#2)}{(#4)}%
                \psarc[fillstyle=none](0,0){! \psk@MarkAngleRadius\space 0.70 mul}{(#2)}{(#4)}%
    \fi\fi\fi
    \rput[\psk@LabelRefPt]{*0}(! tx@EcldDict begin
        /N@#4 GetNode exch Atan /N@#2 GetNode exch Atan end
        2 copy lt { exch 360 sub exch } if
        add 2 div dup /psRawLabelPos ED
        \psk@LabelAngleOffset\space add
        \psk@LabelSep\space exch PtoC){#5}%
    \def\pst@tempA{Angleundef}%
%% define \pst@rot@angle to make it compatible with xelatex for later use
    \edef\pst@rot@angle{ tx@EcldDict begin % expand the #4 and #2
        /N@#4 GetNode exch Atan /N@#2 GetNode exch Atan end
        2 copy lt \pslbrace exch 360 sub exch \psrbrace if
        add 2 div \psk@LabelAngleOffset\space add }%
    \rput[\psk@LabelRefPt]{!\pst@rot@angle\space \ifx\psk@MarkAngle\@undef 0 \else\psk@MarkAngle\space\fi add }%
      (! \psk@MarkAngleRadius\space psRawLabelPos PtoC)%
      {\ifx\psk@mark\pst@tempA\csname\psk@Mark\endcsname\else\csname\psk@mark\endcsname\fi}%
}%
}}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% #2 #4 #6 -> coordinates for nodes
%% #3 #5 #7 -> nodes name
\def\pstTriangle{\pst@object{pstTriangle}}%
\def\pstTriangle@i{\@ifnextchar(\pstTriangle@ii{\pstTriangle@ii(0,0)}}%
\def\pstTriangle@ii(#1)#2(#3)#4(#5)#6{%
  \pst@killglue
  %%begin modif alaindelplanque 11/2003
  \pst@getcoor{#1}\@@coordi
  \pst@getcoor{#3}\@@coordiii
  \pst@getcoor{#5}\@@coordv
  \pstVerb{
      \@@coordi\space\@@coordiii\space exch 4 1 roll \@@coordv\space exch 6 1 roll % x x x y y y
      add add 3 div /YS exch def add add 3 div /XS exch def
  }%
  \bgroup
  \use@keep@par
  \bgroup
  \ifx\psk@PosAngleA\@undef
    \psset{PosAngleA={!
      /AngleAB \@@coordi\space\@@coordiii\space tx@EcldDict begin ABVect end exch Atan def
      /AngleAC \@@coordi\space\@@coordv\space tx@EcldDict begin ABVect end exch Atan def
      AngleAB AngleAC add 2 div dup
      1 exch \tx@PtoC exch \@@coordi\space 4 1 roll add 3 1 roll add XS YS Pyth2 % test if inside/outside
      \@@coordi\space XS YS Pyth2 le { 180 add } if
    }}%% <------ hv
  \else
    \psset{PosAngle=\psk@PosAngleA}
  \fi
  \ifx\psk@PosAngleA\@undef\else\psset{PosAngle=\psk@PosAngleA}\fi
  \let\psk@PointSymbol=\psk@PointSymbolA
  \ifx\psk@PointNameA\@undef\else\psset{PointName=\psk@PointNameA}\fi
  \Pst@Geonode@i[](#1){#2}
  \egroup
  \bgroup
  \use@keep@par
  \ifx\psk@PosAngleB\@undef
    \psset{PosAngleB={!
      /AngleBC \@@coordiii\space\@@coordv\space tx@EcldDict begin ABVect end exch Atan def
      /AngleBA \@@coordiii\space\@@coordi\space tx@EcldDict begin ABVect end exch Atan def
      AngleBA AngleBC add 2 div dup 1 exch \tx@PtoC exch \@@coordiii\space  4 1 roll add 3 1 roll add XS YS Pyth2
      \@@coordiii\space XS YS Pyth2 le { 180 add } if
    }}%% <------ hv
  \else
    \psset{PosAngle=\psk@PosAngleB}
  \fi
  \ifx\psk@PosAngleB\@undef\else\psset{PosAngle=\psk@PosAngleB}\fi
  \let\psk@PointSymbol=\psk@PointSymbolB
  \ifx\psk@PointNameB\@undef\else\psset{PointName=\psk@PointNameB}\fi
  \Pst@Geonode@i[](#3){#4}%
  \egroup
  \ifx\psk@PosAngleC\@undef
   \psset{PosAngleC={!
      /AngleCB \@@coordv\space\@@coordiii\space tx@EcldDict begin ABVect end exch Atan def
      /AngleCA \@@coordv\space\@@coordi\space tx@EcldDict begin ABVect end exch Atan def
      AngleCB AngleCA add 2 div dup 1 exch \tx@PtoC exch \@@coordv\space  4 1 roll add 3 1 roll add XS YS Pyth2
      \@@coordv\space XS YS Pyth2 le { 180 add } if
   }}%% <------ hv
  \else
    \psset{PosAngle=\psk@PosAngleC}
  \fi
  \ifx\psk@PosAngleC\@undef\else\psset{PosAngle=\psk@PosAngleC}\fi
  \let\psk@PointSymbol=\psk@PointSymbolC
  \ifx\psk@PointNameC\@undef\else\psset{PointName=\psk@PointNameC}\fi
  \Pst@Geonode@i[](#5){#6}%%NEW DR 15112001
  \pst@TraceTriangle{#2}{#4}{#6}%
  \egroup
}%
%
\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 or the other node to specify the base line of the triangle
%% #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\ifx\Pst@TriangleSSS@pos\Pst@TriangleSSS@left
      \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
    \else% try to locate the triangle on the specific line
      \pstLocateAB[PointName=none,PointSymbol=none]{#2}{#1}{\pstDistConst{#5}}{#6}
      \pstInterCC[PointName=none,PointSymbol=none,RadiusA=\pstDistConst{#4},RadiusB=\pstDistConst{#3}]{#2}{}{#6}{}{#7}{#7Unused}
    \fi\fi\fi\fi%
    \Pst@ManageParamList{#6}%
    \Pst@ManageParamList{#7}%
    \pstPolygon(#2)(#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 or the other node to specify the base line of the triangle
%% #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\ifx\Pst@TriangleSAS@pos\Pst@TriangleSAS@left
      \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}%
    \else% try to locate the triangle on the specific line
      \pstLocateAB[PointName=none,PointSymbol=none]{#2}{#1}{\pstDistConst{#5}}{#6}
      \pstRotation[PointName=none,PointSymbol=none,RotAngle=#4]{#2}{#6}[#6Internal]
      \pstLocateAB[PointName=none,PointSymbol=none]{#2}{#6Internal}{\pstDistConst{#3}}{#7}
    \fi\fi\fi\fi%
    \Pst@ManageParamList{#6}%
    \Pst@ManageParamList{#7}%
    \pstPolygon(#2)(#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 or the other node to specify the base line of the triangle
%% #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\ifx\Pst@TriangleAAS@pos\Pst@TriangleAAS@left
      \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}%
    \else% try to locate the triangle on the specific line
      \pstLocateAB[PointName=none,PointSymbol=none]{#2}{#1}{\pstDistConst{#5}}{#6}
      \pstRotation[PointName=none,PointSymbol=none,RotAngle=#4]{#2}{#6}[#6Internal]
      \pstLocateAB[PointName=none,PointSymbol=none]{#2}{#6Internal}{\pstDistConst{#5} #3 #4 add sin #3 sin div mul}{#7}
    \fi\fi\fi\fi%
    \Pst@ManageParamList{#6}%
    \Pst@ManageParamList{#7}%
    \pstPolygon(#2)(#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 or the other node to specify the base line of the triangle
%% #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\ifx\Pst@TriangleASA@pos\Pst@TriangleASA@left
      \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}%
    \else% try to locate the triangle on the specific line
      \pstLocateAB[PointName=none,PointSymbol=none]{#2}{#1}{\pstDistConst{#4}}{#6}
      \pstRotation[PointName=none,PointSymbol=none,RotAngle=#3]{#2}{#6}[#6Internal]
      \pstLocateAB[PointName=none,PointSymbol=none]{#2}{#6Internal}{\pstDistConst{#4} #5 sin #3 #5 add sin div mul}{#7}
    \fi\fi\fi\fi%
    \Pst@ManageParamList{#6}%
    \Pst@ManageParamList{#7}%
    \pstPolygon(#2)(#6)(#7)%
  \endgroup%
}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%            Line, circle, Arc
%% #2 #3 -> 2 nodes defining the line
\def\pstLineAB{\@ifnextchar[\Pst@LineAB{\Pst@LineAB[]}}%
\def\Pst@LineAB[#1]#2#3{%
  \begingroup
    \psset{#1}%
    \ncline{#2}{#3}
  \endgroup%
}%
%
%% \pstCircleOA[Options]{O}{A}[angleA][angleB]
%% Draw a Circle with center O from angleA to angleB, going counter clockwise.
%% The circle is defined by center $O$ and the other node $A$ on the circle,
%% or the center $O$ and the given Radius/Diameter in options.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the circle center O
%% #3 -> [input] the node A on the circle or empty if you setup Radius/Diameter
%% #4 -> [input] optional. start angle from angleA to angleB, going counter clockwise.
%% #5 -> [input] optional, start angle from angleA to angleB, going counter clockwise.
\def\pstCircleOA{\pst@object{Pst@CircleOA}}
\def\Pst@CircleOA@i#1#2{%
    \def\pst@circle@center{#1}%
    \def\pst@circle@node{#2}%
    \@ifnextchar[\pstCircleOA@i\pstCircleOA@j}%
\def\pstCircleOA@i[#1][#2]{%
    \begin@OpenObj
      \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 #1 #2 arc}%
      \showpointsfalse
    \end@OpenObj
}%
\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}%
      \showpointsfalse
    \end@ClosedObj
}%
%% #2 #3 -> 2 nodes defining a diameter of the circle
\def\pstCircleAB{\pst@object{Pst@CircleAB}}
\def\Pst@CircleAB@i#1#2{%
    \def\pst@circle@diameter@A{#1}
    \def\pst@circle@diameter@B{#2}
    \@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
      \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 #1 #2 arc}%
      \showpointsfalse
    \end@OpenObj
}%
\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
}%
%% #2 #3 #4 -> 3 nodes defining the center and two points on the circle
\def\pstArcOAB{\pst@object{pstArcOAB}}%
\def\pstArcnOAB{\pst@object{pstArcnOAB}}%
\def\pstArcnOAB@i{\def\psarc@type{1}\pstArcOAB@i}%
\def\pstArcOAB@i{\pstArcOAB@ii}%\@ifnextchar[\pstArcOAB@ii{\pstArcOAB@ii[]}}%
%OLD%%\def\pstArcOAB@ii#1#2#3{%[#1]#2#3#4{%
%OLD%%  \bgroup\use@par%
%OLD%%  \rput(#1){\pstArcOAB@iii{#2}{#3}}%
%OLD%%  \egroup%
%OLD%%}%
%OLD%%\def\pstArcOAB@iii#1#2%
\def\pstArcOAB@ii#1#2#3{%
  \begin@OpenObj%
    %OLD%%\addto@pscode{\pstArcOAB@iv{#1}{#2} \pstArcOAB@v}%
    \addto@pscode{\pstArcOAB@iv{#1}{#2}{#3} \pstArcOAB@v}%
    \gdef\psarc@type{0}%
    \showpointsfalse
  \end@OpenObj%
}%% end \pstArcOAB@iii
%OLD%%\def\pstArcOAB@iv#1#2%
\def\pstArcOAB@iv#1#2#3{%
  %%\pst@coor /y ED /x ED /r
  %OLD%%0 0 /y ED /x ED /r %%new DR 2005/10/21
  tx@EcldDict begin /N@#1 GetNode end /y ED /x ED /r %%new DR 2005/10/21
  %OLD%%tx@EcldDict begin /N@#1 GetNode end
  tx@EcldDict begin /N@#2 GetNode /N@#1 GetNode ABVect end
  Pyth  def /c 57.2957 r \tx@Div def /angleA
  %OLD%%tx@EcldDict begin /N@#1 GetNode end
  tx@EcldDict begin /N@#2 GetNode /N@#1 GetNode ABVect end
  exch Atan \psk@arcsepA c mul 2 div
  \ifcase \psarc@type add \or sub \fi def
  /angleB
  %OLD%%tx@EcldDict begin /N@#2 GetNode end
  tx@EcldDict begin /N@#3 GetNode /N@#1 GetNode ABVect end
  exch Atan \psk@arcsepB c mul 2 div
  \ifcase \psarc@type sub \or add \fi def
  %ifshowpoints\psarc@showpoints\fi
  \ifx\psk@arrowA\@empty
    \ifnum\psk@liftpen=2 r angleA PtoC
      y add exch x add exch
      moveto
    \fi
  \fi%
}%% end \pstArcOAB@iv
\def\pstArcOAB@v{%
  x y r angleA
  \ifx\psk@arrowA\@empty\else
    { ArrowA CP } { \ifcase\psarc@type add \or sub \fi }%
    \tx@ArcArrow
  \fi
  angleB
  \ifx\psk@arrowB\@empty\else
    { ArrowB } { \ifcase\psarc@type sub \or add \fi }%
    \tx@ArcArrow
  \fi
  \ifcase\psarc@type arc \or arcn \fi%
}%% end \pstArcOAB@v
\def\pstArcOAB@showpoints{%
  gsave newpath x y moveto x y r \pst@tempa \pst@tempb
  \ifcase\psarc@type arc \or arcn \fi
  closepath CLW 2 div SLW [ \psk@dash\space ] 0 setdash stroke
  grestore %
}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%                     HOMOTETHIE
%% #2 -> centre
%% #3 -> antecedent
%% #4 -> node name of the homothetic of #1
\def\pstHomO{\@ifnextchar[\Pst@HomO{\Pst@HomO[]}}%
\expandafter\ifx\csname psteucl@old\endcsname\relax%% NEW SYNTAX %% DR 2005/04/10
\def\Pst@HomO[#1]#2{%
  \bgroup%
  \@InitListMng\def\LastValidSS{default}%%SS means SegmentSymbol
  \psset{#1}\def\@HomCtr{#2}% Affectation of local parameters
  \edef\@@GenCourbe{}%%for accumulating points
  \Pst@HomO@i%
}%
\def\Pst@HomO@i#1{%
  \@List{#1}\edef\@antecedentLst{\@NewList}
  \@ifnextchar[\Pst@HomO@ii{\Pst@HomO@ii[default]}%
}%
\def\Pst@HomO@ii[#1]{%
  \@List{#1}\edef\@imageLst{\@NewList}
  \edef\@antecedent{\expandafter\PstParamListFirst\@antecedentLst,undef/}
  \edef\@image{\expandafter\PstParamListFirst\@imageLst,default/}
  \Pst@HomO@iii%
}%
\def\Pst@HomO@iii{%
  \ifx\@image\@default\def\@image{\@antecedent '}\fi
  \rput(\@HomCtr){%
    \rput(!
      tx@EcldDict begin /N@\@antecedent\space GetNode end
      \psk@HomCoef\space mul exch \psk@HomCoef\space mul exch
      \pst@number\psyunit div exch \pst@number\psxunit div
      exch){\pnode{\@image}}%
      }%%end rput
  \xdef\@@GenCourbe{\@@GenCourbe(\@image)}%%for accumulating points
  \ifPst@CentralSym\ifPst@CodeFig
    \edef\psk@OldSegmentSymbol{\psk@SegmentSymbol}%
    \edef\psk@SegmentSymbol{\expandafter\PstParamListFirst\psk@OldSegmentSymbol,undef/}%
    \ifx\psk@SegmentSymbol\@undef\edef\psk@SegmentSymbol{\LastValidSS}\else\edef\LastValidSS{\psk@SegmentSymbol}\fi
    \bgroup%
    \psset{linecolor=\psk@CodeFigColor, linestyle=\psk@CodeFigStyle}%
    \pstSegmentMark{\@image}{\@HomCtr}%
    \pstSegmentMark{\@HomCtr}{\@antecedent}%
    \egroup%
    \edef\psk@SegmentSymbol{\expandafter\PstParamListLasts\psk@OldSegmentSymbol,undef/}%
  \fi\fi%
  \Pst@ManageParamList{\@image}%
  \edef\@antecedentLst{\expandafter\PstParamListLasts\@antecedentLst,undef/}%
  \edef\@imageLst{\expandafter\PstParamListLasts\@imageLst,default/}%
  \edef\@LastValidantecedent{\@antecedent}\def\@LastValidimage{\@image}
  \edef\@antecedent{\expandafter\PstParamListFirst\@antecedentLst,undef/}%
  \edef\@image{\expandafter\PstParamListFirst\@imageLst,default/}
  \ifx\@antecedent\@undef\def\@End{\pst@MngTransformCurve\egroup}
  \else\def\@End{\Pst@HomO@iii}\fi%
  \@End%
}%
\else%% OLD SYNTAX
\def\Pst@HomO[#1]#2{%
  \bgroup%
  \@InitListMng\def\LastValidSS{default}%%
  \psset{#1}\def\@HomCtr{#2}% Affectation of local parameters
  \edef\@@GenCourbe{}%%for accumulating points
  \Pst@HomO@i-%
}%
\def\Pst@HomO@i-#1#2{%
  \rput(\@HomCtr){%
    \rput(!
      tx@EcldDict begin /N@#1 GetNode end
      \psk@HomCoef\space mul exch \psk@HomCoef\space mul exch
      \pst@number\psyunit div exch \pst@number\psxunit div
      exch){\pnode{#2}}%
      }%%end rput
  \xdef\@@GenCourbe{\@@GenCourbe(#2)}%%for accumulating points
  \ifPst@CentralSym\ifPst@CodeFig
    \edef\psk@OldSegmentSymbol{\psk@SegmentSymbol}%
    \edef\psk@SegmentSymbol{\expandafter\PstParamListFirst\psk@OldSegmentSymbol,undef/}%
    \ifx\psk@SegmentSymbol\@undef\edef\psk@SegmentSymbol{\LastValidSS}\else\edef\LastValidSS{\psk@SegmentSymbol}\fi
    \bgroup%
    \psset{linecolor=\psk@CodeFigColor, linestyle=\psk@CodeFigStyle}%
    \pstSegmentMark{#2}{\@HomCtr}%
    \pstSegmentMark{\@HomCtr}{#1}%
    \egroup%
    \edef\psk@SegmentSymbol{\expandafter\PstParamListLasts\psk@OldSegmentSymbol,undef/}%
  \fi\fi%
  \Pst@ManageParamList{#2}%
  \@ifnextchar-{\Pst@HomO@i}{\pst@MngTransformCurve\egroup}%
}%
\fi% END OLD SYNTAX %% DR 2005/04/10
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%                   Central Symmetry
%% #2 -> centre
%% #3 -> antecedent
%% #4 -> node name of the symmetrical point of #3
\def\pstSymO{\@ifnextchar[\Pst@SymO{\Pst@SymO[]}}%
\def\Pst@SymO[#1]{\Pst@HomO[SegmentSymbol=\SegSymLst,#1, HomCoef=-1, Central@Sym=true]}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%                   Middle of a Segment
%% #2 #3 -> 2 nodes defining the segment
%% #4    -> node name of the middle of [#2 #3]
\def\pstMiddleAB{\@ifnextchar[\Pst@MiddleAB{\Pst@MiddleAB[]}}%
\def\Pst@MiddleAB[#1]#2#3#4{%
  \bgroup\psset{#1, HomCoef=.5}% % Affectation of local parameters
  %%begin modif alaindelplanque 11/2003
  \ifx\psk@PosAngle\@undef% Calcul automatique de PosAngle
    \psset{PosAngle={!tx@EcldDict begin /N@#3 GetNode exch /N@#2 GetNode end
        4 1 roll sub 3 1 roll sub Atan}}
  \fi
  %%end modif alaindelplanque 11/2003
  \expandafter\ifx\csname psteucl@old\endcsname\relax\Pst@HomO[]{#2}{#3}[#4]%
  \else\Pst@HomO[]{#2}{#3}{#4}\fi%%%DR 14042005
  \ifPst@CodeFig
    \psset{linecolor=\psk@CodeFigColor, linestyle=\psk@CodeFigStyle}%
    \pstSegmentMark{#2}{#4}%
    \pstSegmentMark{#4}{#3}%
  \fi%
  \egroup
}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%           Centre of Gravity of a Triangle
%% #2 #3 #4 -> 3 nodes defining the triangle
%% #5       -> node name of the centre of gravity of #2 #3 #4
\def\pstCGravABC{\@ifnextchar[\Pst@CGravABC{\Pst@CGravABC[]}}%
\def\Pst@CGravABC[#1]#2#3#4#5{%
  \bgroup\psset{#1}% % Affectation of local parameters
  \Pst@OIJGeonode@i[](! 1 3 div dup){#5}{#2}{#3}{#4}%DR: 22/03/03
  \egroup
}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%           Centre of the circoncrit circle
%% #2 #3 #4 -> 3 nodes defining the triangle
%% #5       -> node name of the centre of the circle
\def\pstCircleABC{\@ifnextchar[\Pst@CircleABC{\Pst@CircleABC[]}}%
\def\Pst@CircleABC[#1]#2#3#4#5{%
  \bgroup\psset{#1}% % Affectation of local parameters
  \rput(#2){%DR: 22/03/03
    \rput(!
      tx@EcldDict begin
        /N@#3 GetNode 2 copy Pyth 3 1 roll exch Atan %Rb Thetab
        dup 3 1 roll %Thetab Rb Thetab
        /N@#4 GetNode 2 copy Pyth 3 1 roll exch Atan %Thetab Rb Thetab Rc Thetac
        3 -1 roll sub dup cos 2 index mul 3 1 roll sin mul %Xb Xc Yc
        dup dup mul 2 index dup mul add 3 -1 roll 3 index mul sub 2 div exch div
        exch 2 div exch 3 -1 roll Rotate
        \pst@number\psyunit div exch \pst@number\psxunit div exch
     end){\Pst@Geonode@i[](0,0){#5}}}%
  %\Pst@InterLL[]{@Middle#2#3}{@Middle#2#3P}{@Middle#2#4}{@Middle#2#4P}{#5}%DR: 22/03/03
  \ifPst@DrawCirABC\pstCircleOA{#5}{#2}\fi
  \ifPst@CodeFig
    \psset{PointSymbol=none, PointName=none, linecolor=\psk@CodeFigColor, linestyle=\psk@CodeFigStyle, nodesep=-1}%
    \expandafter\ifx\csname psteucl@old\endcsname\relax%% NEW SYNTAX 14042005
      \Pst@HomO[HomCoef=.5]{#2}{#3}[@Middle#2#3]%
      \Pst@Rotation[RotAngle=90, CodeFig=false]{@Middle#2#3}{#2}[@Middle#2#3P]%
      \Pst@HomO[HomCoef=.5]{#2}{#4}[@Middle#2#4]%
      \Pst@Rotation[RotAngle=90, CodeFig=false]{@Middle#2#4}{#2}[@Middle#2#4P]%
      \Pst@HomO[HomCoef=.5]{#4}{#3}[@Middle#4#3]%
    \else%% OLD SYNTAX
      \Pst@HomO[HomCoef=.5]{#2}{#3}{@Middle#2#3}%
      \Pst@Rotation[RotAngle=90, CodeFig=false]{@Middle#2#3}{#2}{@Middle#2#3P}%
      \Pst@HomO[HomCoef=.5]{#2}{#4}{@Middle#2#4}%
      \Pst@Rotation[RotAngle=90, CodeFig=false]{@Middle#2#4}{#2}{@Middle#2#4P}%
      \Pst@HomO[HomCoef=.5]{#4}{#3}{@Middle#4#3}%
    \fi
    \ncline{#5}{@Middle#4#3}%
    \ncline{#5}{@Middle#2#3}%
    \ncline{#5}{@Middle#2#4}%
    \psset{linestyle=solid}%
    \pstRightAngle[]{#5}{@Middle#4#3}{#4}%
    \pstRightAngle[]{#5}{@Middle#2#3}{#3}%
    \pstRightAngle[]{#5}{@Middle#2#4}{#2}%
    \Pst@SegmentMark[SegmentSymbol=\psk@SegmentSymbolA]{#4}{@Middle#4#3}%
    \Pst@SegmentMark[SegmentSymbol=\psk@SegmentSymbolA]{@Middle#4#3}{#3}%
    \Pst@SegmentMark[SegmentSymbol=\psk@SegmentSymbolB]{#3}{@Middle#2#3}%
    \Pst@SegmentMark[SegmentSymbol=\psk@SegmentSymbolB]{@Middle#2#3}{#2}%
    \Pst@SegmentMark[SegmentSymbol=\psk@SegmentSymbolC]{#2}{@Middle#2#4}%
    \Pst@SegmentMark[SegmentSymbol=\psk@SegmentSymbolC]{@Middle#2#4}{#4}%
  \fi
  \egroup
}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%                     TRANSLATION
%% #2 #3 -> 2 nodes defining the translation vector
%% #4 -> antecedent
%% #5 -> node name of the image
\expandafter\ifx\csname psteucl@old\endcsname\relax%% NEW SYNTAX %% DR 2005/04/10
\def\pstTranslation{\@ifnextchar[\Pst@Translation{\Pst@Translation[]}}%
\def\Pst@Translation[#1]#2#3{%
  \bgroup%
  \@InitListMng%
  \psset{#1}\def\@VectorOrigin{#2}\def\@VectorEnd{#3}%
  \edef\@@GenCourbe{}%%for accumulating points
  \Pst@Translation@i%
}%
\def\Pst@Translation@i#1{%
  \@List{#1}\edef\@antecedentLst{\@NewList}
  \@ifnextchar[\Pst@Translation@ii{\Pst@Translation@ii[default]}%
}%
\def\Pst@Translation@ii[#1]{%
  \@List{#1}\edef\@imageLst{\@NewList}
  \edef\@antecedent{\expandafter\PstParamListFirst\@antecedentLst,undef/}
  \edef\@image{\expandafter\PstParamListFirst\@imageLst,default/}
  \Pst@Translation@iii%
}%
\def\Pst@Translation@iii{%
  \ifx\@image\@default\def\@image{\@antecedent '}\fi
  \rput(\@VectorOrigin){%
    \rput(!
      tx@EcldDict begin /N@\@VectorEnd\space GetNode
      \ifx\psk@DistCoef\@none
      \else\psk@DistCoef\space mul exch \psk@DistCoef\space mul exch\fi
      /N@\@antecedent\space GetNode end
      3 -1 roll add exch 3 -1 roll add exch
      \pst@number\psyunit div exch \pst@number\psxunit div exch)%
    {\pnode{\@image}}%
    }%
  \xdef\@@GenCourbe{\@@GenCourbe(\@image)}%%for accumulating points
  \ifPst@CodeFig
    \bgroup
    \psset{linecolor=\psk@CodeFigColor, linestyle=\psk@CodeFigStyle}%
    \ncline[arrows=->,nodesep=0]{\@antecedent}{\@image}
    \ifx\psk@TransformLabel\@none
    \else
      \ifx\psk@TransformLabel\@default%
        \ncput*{$\ifx\psk@DistCoef\@none\else\psk@DistCoef\fi\overrightarrow{\@VectorOrigin\@VectorEnd}$}
      \else\ncput{\psk@TransformLabel}\fi
    \fi%
    \egroup%
  \fi%
  \Pst@ManageParamList{\@image}%
  \edef\@antecedentLst{\expandafter\PstParamListLasts\@antecedentLst,undef/}%
  \edef\@imageLst{\expandafter\PstParamListLasts\@imageLst,default/}%
  \edef\@LastValidantecedent{\@antecedent}\def\@LastValidimage{\@image}
  \edef\@antecedent{\expandafter\PstParamListFirst\@antecedentLst,undef/}%
  \edef\@image{\expandafter\PstParamListFirst\@imageLst,default/}
  \ifx\@antecedent\@undef\def\@End{\pst@MngTransformCurve\egroup}
  \else\def\@End{\Pst@Translation@iii}\fi%
  \@End%
}%
\else%% OLD SYNTAX
\def\pstTranslation{\@ifnextchar[\Pst@Translation{\Pst@Translation[]}}%
\def\Pst@Translation[#1]#2#3{%
  \bgroup
  \@InitListMng%
  \psset{#1}\def\@VectorOrigin{#2}\def\@VectorEnd{#3}%
  \edef\@@GenCourbe{}%%for accumulating points
  \Pst@Translation@i-%
}%
\def\Pst@Translation@i-#1#2{%
  \rput(\@VectorOrigin){%
    \rput(!
      tx@EcldDict begin /N@\@VectorEnd\space GetNode
      \ifx\psk@DistCoef\@none
      \else\psk@DistCoef\space mul exch \psk@DistCoef\space mul exch\fi
      /N@#1 GetNode end
      3 -1 roll add exch 3 -1 roll add exch
      \pst@number\psyunit div exch \pst@number\psxunit div exch)%
    {\pnode{#2}}%
    }%
  \xdef\@@GenCourbe{\@@GenCourbe(#2)}%%for accumulating points
  \ifPst@CodeFig%
    \bgroup
    \psset{linecolor=\psk@CodeFigColor, linestyle=\psk@CodeFigStyle, nodesep=0}%
    \ncline[arrows=->]{#1}{#2}
    \ifx\psk@TransformLabel\@none
    \else%
      \ifx\psk@TransformLabel\@default%
      \ncput*{\ifx\psk@DistCoef\@none\else\psk@DistCoef\fi$\overrightarrow{\@VectorOrigin\@VectorEnd}$}
      \else\ncput{\psk@TransformLabel}\fi
    \fi%
    \egroup
  \fi
  \Pst@ManageParamList{#2}%
  \@ifnextchar-{\Pst@Translation@i}{\pst@MngTransformCurve\egroup}%
}%
%%%%%%%%%%%%%%%%%%%%%
\fi% END OLD SYNTAX %% DR 2005/04/10
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%                     ROTATION
%% #2 -> centre of rotation
%% #3 -> antecedent
%% #4 -> node name of the image
\expandafter\ifx\csname psteucl@old\endcsname\relax%% NEW SYNTAX %% DR 2005/04/10
\def\pstRotation{\@ifnextchar[\Pst@Rotation{\Pst@Rotation[]}}%
\def\Pst@Rotation[#1]#2{%
  \bgroup
  \@InitListMng%
  \psset{#1}\def\@RotCtr{#2}\edef\@@GenCourbe{}%%for accumulating points
  \Pst@Rotation@i%
}%
\def\Pst@Rotation@i#1{%
  \@List{#1}\edef\@antecedentLst{\@NewList}
  \@ifnextchar[\Pst@Rotation@ii{\Pst@Rotation@ii[default]}%
}%
\def\Pst@Rotation@ii[#1]{%
  \@List{#1}\edef\@imageLst{\@NewList}
  \edef\@antecedent{\expandafter\PstParamListFirst\@antecedentLst,undef/}
  \edef\@image{\expandafter\PstParamListFirst\@imageLst,default/}
  \Pst@Rotation@iii%
}%
\def\Pst@Rotation@iii{%
  \ifx\@image\@default\def\@image{\@antecedent '}\fi
  \rput(\@RotCtr){%
    \rput(!tx@EcldDict begin /N@\@antecedent\space GetNode \psk@RotAngle\space Rotate end
           \pst@number\psyunit div exch \pst@number\psxunit div exch)%
         {\pnode{\@image}}%
    }%% end \rput
  \xdef\@@GenCourbe{\@@GenCourbe(\@image)}%%for accumulating points
  \ifPst@CodeFig%
    \bgroup
    \psset{linecolor=\psk@CodeFigColor, linestyle=\psk@CodeFigStyle}%
    \pstArcOAB[arrows=->]{\@RotCtr}{\@antecedent}{\@image}%
    \ncline{\@RotCtr}{\@antecedent}\ncline{\@RotCtr}{\@image}
    \ifx\psk@TransformLabel\@none\else\pstMarkAngle{\@antecedent}{\@RotCtr}{\@image}{$\psk@TransformLabel$}\fi
    \egroup
  \fi%
  \Pst@ManageParamList{\@image}%
  \edef\@antecedentLst{\expandafter\PstParamListLasts\@antecedentLst,undef/}%
  \edef\@imageLst{\expandafter\PstParamListLasts\@imageLst,default/}%
  \edef\@LastValidantecedent{\@antecedent}\def\@LastValidimage{\@image}
  \edef\@antecedent{\expandafter\PstParamListFirst\@antecedentLst,undef/}%
  \edef\@image{\expandafter\PstParamListFirst\@imageLst,default/}
  \ifx\@antecedent\@undef\def\@End{\pst@MngTransformCurve\egroup}
  \else\def\@End{\Pst@Rotation@iii}\fi%
  \@End%
}%
%%%%%%%%%%%%%%%%%%%%%
\else%% OLD SYNTAX
\def\pstRotation{\@ifnextchar[\Pst@Rotation{\Pst@Rotation[]}}%
\def\Pst@Rotation[#1]#2{%
  \bgroup
  \@InitListMng%
  \psset{#1}\def\@RotCtr{#2}
  \edef\@@GenCourbe{}%%for accumulating points
  \Pst@Rotation@i-%
}%
\def\Pst@Rotation@i-#1#2{%
  \rput(\@RotCtr){%
    \rput(!tx@EcldDict begin /N@#1 GetNode \psk@RotAngle\space Rotate end
           \pst@number\psyunit div exch \pst@number\psxunit div exch)%
         {\pnode{#2}}%
    }%% end \rput
  \xdef\@@GenCourbe{\@@GenCourbe(#2)}%%for accumulating points
  \ifPst@CodeFig%
    \bgroup
    \psset{linecolor=\psk@CodeFigColor, linestyle=\psk@CodeFigStyle}%
    \pstArcOAB[arrows=->]{\@RotCtr}{#1}{#2}%
    \ncline{\@RotCtr}{#1}\ncline{\@RotCtr}{#2}
    \ifx\psk@TransformLabel\@none\else\pstMarkAngle{#1}{\@RotCtr}{#2}{$\psk@TransformLabel$}\fi
    \egroup
  \fi%
  \Pst@ManageParamList{#2}%
  \@ifnextchar-{\Pst@Rotation@i}{\pst@MngTransformCurve\egroup}%
}%
\fi% END OLD SYNTAX %% DR 2005/04/10
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%        Intersection between two lines
%% #2 #3 -> nodes defining the first line
%% #4 #5 -> nodes defining the second line
%% #6 -> node name of the image
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\pstInterLL{\@ifnextchar[\Pst@InterLL{\Pst@InterLL[]}}%
\def\Pst@InterLL[#1]#2#3#4#5#6{%
  \bgroup\psset{#1}%             % Affectation of local parameters
  \pnode(!
    tx@EcldDict begin
      /N@#2 GetNode /N@#3 GetNode /N@#4 GetNode /N@#5 GetNode InterLines
    end
    \pst@number\psyunit div exch \pst@number\psxunit div exch
    2 copy
    /#6.Y exch def /#6.X exch def % save the coors for futher use
    ){#6}%
  \Pst@geonodelabel{#6}%
  \egroup%
}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%   Intersection between one line and one circle
%% #2 #3 -> nodes defining the first line
%% #4 #5 -> nodes defining the center and a point onto C
%% #6 -> node name of the first point
%% #7 -> label
%% #8 -> node name of the second point
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\pstInterLC{\pst@object{pstInterLC}}
\def\pstInterLC@i#1#2#3#4#5#6{%
  \begingroup
  \pst@killglue
  \use@par
  \rput(#3){%
    \pnode(!
    tx@EcldDict begin
      /N@#1 GetNode /N@#2 GetNode 4 copy EqDr
      \ifx\psk@Radius\@none
        \ifx\psk@Diameter\@none
          /N@#3 GetNode /N@#4 GetNode ABDist
        \else\psk@Diameter 2 div
        \fi
      \else\psk@Radius
      \fi
    InterLineCircle /Glby exch def /Glbx exch def
      \pst@number\psyunit div exch \pst@number\psxunit div exch
    2 copy end
    /#5.Y exch def /#5.X exch def % save the coors for futher use
    ){#5}%
  \rput(!
    tx@EcldDict begin
      Glbx \pst@number\psxunit div Glby \pst@number\psyunit div
    end){\pnode{#6}}
  }%
  \begingroup
  \ifx\psk@PosAngleA\@undef    \else\psset{PosAngle=\psk@PosAngleA}\fi
  \let\psk@PointSymbol\psk@PointSymbolA
  \ifx\psk@PointNameA\@undef   \else\psset{PointName=\psk@PointNameA}\fi
  \Pst@geonodelabel{#5}
  \endgroup
  \ifx\psk@PosAngleB\@undef\else\psset{PosAngle=\psk@PosAngleB}\fi
  \let\psk@PointSymbol\psk@PointSymbolB
  \ifx\psk@PointNameB\@undef\else\psset{PointName=\psk@PointNameB}\fi
  \Pst@geonodelabel{#6}%
  \endgroup
  \ignorespaces
}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%   Intersection between two circles
%% #2 #3 -> nodes defining the first circle
%% #4 #5 -> nodes defining the second circle
%% #6 -> node name of the first point
%% #7 -> node name of the second point
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\pstInterCC{\@ifnextchar[\Pst@InterCC{\Pst@InterCC[]}}%
\def\Pst@InterCC[#1]#2#3#4#5#6#7{%
  \bgroup\psset{#1}%        % Affectation of local parameters
  \rput(#2){%
    \rput(!
      tx@EcldDict begin
        \ifx\psk@RadiusA\@undef
          \ifx\psk@DiameterA\@undef
            \ifx\psk@Radius\@none
              \ifx\psk@Diameter\@none
                /N@#3 GetNode Pyth
              \else\psk@Diameter 2 div
              \fi
            \else\psk@Radius\space
            \fi
          \else\psk@DiameterA 2 div
          \fi
        \else\psk@RadiusA\space
        \fi
        \ifx\psk@RadiusB\@undef
          \ifx\psk@DiameterB\@undef
            \ifx\psk@Radius\@none
              \ifx\psk@Diameter\@none
                /N@#4 GetNode /N@#5 GetNode ABDist
              \else\psk@Diameter 2 div
              \fi
            \else\psk@Radius\space
            \fi
          \else\psk@DiameterB 2 div
          \fi
        \else\psk@RadiusB\space
        \fi
        /N@#4 GetNode Pyth InterCircles /N@#4 GetNode
        exch Atan dup /xoC exch def Rotate /Glby exch def /Glbx exch def
        xoC Rotate
      end
      \pst@number\psyunit div exch \pst@number\psxunit div exch)
    {\pnode{#6}}%
    \rput(!
      tx@EcldDict begin
        Glbx \pst@number\psxunit div Glby \pst@number\psyunit div
      end)%
    {\pnode{#7}}%
    }%
  \bgroup
%  \ifx\psk@PosAngleA\@undef\else\psset{PosAngle=\psk@PosAngleA}\fi
%  \ifx\psk@PointSymbolA\@undef\else\psset{PointSymbol=\psk@PointSymbolA}\fi
%  \ifx\psk@PointNameA\@undef\else\psset{PointName=\psk@PointNameA}\fi
  \ifx\psk@PosAngleA\@undef\else\ifx\psk@PosAngleA\@none\else\psset{PosAngle=\psk@PosAngleA}\fi\fi
  \ifx\psk@PointSymbolA\@none\let\psk@PointSymbol=\@none\else\let\psk@PointSymbol=\psk@PointSymbolA\fi
  \ifx\psk@PointNameA\@undef\else\ifx\psk@PointNameA\@none\else\psset{PointName=\psk@PointNameA}\fi\fi
  \ifx\psk@PosAngleA\@undef\else\ifx\psk@PosAngle\@none\else\Pst@geonodelabel{#6}\fi\fi
  \egroup
  \bgroup
%  \ifx\psk@PosAngleB\@undef\else\psset{PosAngle=\psk@PosAngleB}\fi
%  \ifx\psk@PointSymbolB\@undef\else\psset{PointSymbol=\psk@PointSymbolB}\fi
%  \ifx\psk@PointNameB\@undef\else\psset{PointName=\psk@PointNameB}\fi
  \ifx\psk@PosAngleB\@undef\else\ifx\psk@PosAngleB\@none\else\psset{PosAngle=\psk@PosAngleB}\fi\fi
  \ifx\psk@PointSymbolB\@none\let\psk@PointSymbol=\@none\else\let\psk@PointSymbol=\psk@PointSymbolB\fi
  \ifx\psk@PointNameB\@undef\else\ifx\psk@PointNameB\@none\else\psset{PointName=\psk@PointNameB}\fi\fi
  \ifx\psk@PosAngleB\@undef\else\ifx\psk@PosAngleB\@none\else\Pst@geonodelabel{#7}\fi\fi
  \egroup
  \psset{linecolor=\psk@CodeFigColor, linestyle=\psk@CodeFigStyle, arcsep=-1}%
  \ifx\psk@CodeFigA\@undef%
    \ifx\psk@CodeFigB\@undef\ifPst@CodeFig\pstArcOAB{#2}{#6}{#7}\fi\fi
  \else%
    \ifPst@CodeFigAarc\pstArcOAB{#2}{#6}{#7}\else\pstArcnOAB{#2}{#6}{#7}\fi%
  \fi
  \ifx\psk@CodeFigB\@undef%
    \ifx\psk@CodeFigA\@undef\ifPst@CodeFig\pstArcOAB{#4}{#6}{#7}\fi\fi
  \else%
    \ifPst@CodeFigBarc\pstArcOAB{#4}{#6}{#7}\else\pstArcnOAB{#4}{#6}{#7}\fi%
  \fi
  \egroup
}%
%%   Intersection between two functions
%% #2 #3 -> f and g (functions)
%% #4 -> approximation of the root
%% #5 -> node name of the first point
\def\pstInterFF{\@ifnextchar[\Pst@InterFF{\Pst@InterFF[]}}%
\def\Pst@InterFF[#1]#2#3#4#5{%
  \bgroup\psset{#1}%             % Affectation of local parameters
%  \rput(!
%  tx@EcldDict begin
%    #4 { #3 } { #2 } NewtonSolving pop
%  end){\pnode{#5}}%
  \pnode(!
    tx@EcldDict begin
    #4
    { \ifPst@algebraic (#3) AlgParser cvx exec \else #3  \fi }
    { \ifPst@algebraic (#2) AlgParser cvx exec \else #2  \fi }
    NewtonSolving pop
    2 copy end
    /#5.Y exch def /#5.X exch def % save the coors for futher use
  ){#5}%
  \Pst@geonodelabel{#5}%
  \egroup%
}
%%   Intersection between a function and a line
%% #2 -> f (function)
%% #3 #4 -> points defining the line
%% #5 -> approximation of the root
%% #6 -> node name of the first point
\def\pstInterFL{\@ifnextchar[\Pst@InterFL{\Pst@InterFL[]}}%
\def\Pst@InterFL[#1]#2#3#4#5#6{%
  \bgroup\psset{#1}%             % Affectation of local parameters
%  \rput(!
%  tx@EcldDict begin
%    #5 { /N@#3 GetNode /N@#4 GetNode EqDr 1 index div
%  \pst@number\psxunit div 3 1 roll div x mul add } { #2 }
%  NewtonSolving pop
%  end){\pnode{#6}}%
  \pnode(!
    tx@EcldDict begin
    #5
    { /N@#3 GetNode /N@#4 GetNode EqDr 1 index div
      \pst@number\psxunit div 3 1 roll div x mul add }
    { \ifPst@algebraic (#2) AlgParser cvx exec \else #2  \fi }
    NewtonSolving pop 2 copy end
    /#6.Y exch def /#6.X exch def % save the coors for futher use
    ){#6}%
  \Pst@geonodelabel{#6}%
  \egroup%
}
%%   Intersection between a function and a circle
%% #1 -> f (function)
%% #2 #3 -> points defining the circle (center and point)
%% #4 -> approximation of the root
%% #5 -> node name of the first point
\def\pstInterFC{\pst@object{pstInterFC}}%
\def\pstInterFC@i#1#2#3#4#5{%
  \begingroup
  \pst@killglue
  \use@par
  \edef\@function{ \ifPst@algebraic (#1) AlgParser cvx exec \else #1 \fi\space }%
  \pnode(!
    tx@EcldDict begin
    #4
    { /N@#2 GetNode 2 copy /N@#3 GetNode ABDist \pst@number\psxunit div
      3 1 roll \pst@number\psyunit div exch \pst@number\psxunit div exch x \@function
       ABDist sub }
    { 0 }
    NewtonSolving pop
    pop dup /x exch def
    \@function
    2 copy end
    /#5.Y exch def /#5.X exch def % save the coors for futher use
    ){#5}%
  \Pst@geonodelabel{#5}%
  \endgroup
  \ignorespaces
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%              ORTHOGONAL PROJECTION
%% #2 #3 -> nodes defining the line where to project
%% #4 -> antecedent
%% #5 -> node name of the image
%% #6 -> label
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\expandafter\ifx\csname psteucl@old\endcsname\relax%% NEW SYNTAX %% DR 2005/04/10
\def\pstProjection{\@ifnextchar[\Pst@Projection{\Pst@Projection[]}}%
\def\Pst@Projection[#1]#2#3{%
  \bgroup%
  \@InitListMng%
  \psset{#1}\def\@FrstPt{#2}\def\@ScdPt{#3}% Affectation of local parameters
  \edef\@@GenCourbe{}%%for accumulating points
  \Pst@Projection@i%
}%
\def\Pst@Projection@i#1{%
  \@List{#1}\edef\@antecedentLst{\@NewList}
  \@ifnextchar[\Pst@Projection@ii{\Pst@Projection@ii[default]}%
}%
\def\Pst@Projection@ii[#1]{%
  \@List{#1}\edef\@imageLst{\@NewList}
  \edef\@antecedent{\expandafter\PstParamListFirst\@antecedentLst,undef/}
  \edef\@image{\expandafter\PstParamListFirst\@imageLst,default/}
  \Pst@Projection@iii%
}%
\def\Pst@Projection@iii{%
  \Pst@Projection@iv{\@antecedent}{\@image}
  %%begin modif alaindelplanque 11/2003
  %% automatic computation of PosAngle
  \ifx\psk@PosAngle\@undef%
    \psset{PosAngle={!tx@EcldDict begin /N@\@image\space GetNode exch /N@\@antecedent\space GetNode end 4 1 roll
                     sub 3 1 roll sub neg exch atan=20}}
  \fi
  %%end modif alaindelplanque 11/2003
  \xdef\@@GenCourbe{\@@GenCourbe(\@image)}%%for accumulating points
  \Pst@ManageParamList{\@image}%
  \ifPst@CodeFig%
    \psset{linecolor=\psk@CodeFigColor, linestyle=\psk@CodeFigStyle}%
    \pstRightAngle[linestyle=solid]{\@ScdPt}{\@image}{\@antecedent}%
    \ncline{\@antecedent}{\@image}%
  \fi%
  \edef\@antecedentLst{\expandafter\PstParamListLasts\@antecedentLst,undef/}%
  \edef\@imageLst{\expandafter\PstParamListLasts\@imageLst,default/}%
  \edef\@LastValidantecedent{\@antecedent}\def\@LastValidimage{\@image}
  \edef\@antecedent{\expandafter\PstParamListFirst\@antecedentLst,undef/}%
  \edef\@image{\expandafter\PstParamListFirst\@imageLst,default/}
  \ifx\@antecedent\@undef\def\@End{\pst@MngTransformCurve\egroup}
  \else\def\@End{\Pst@Projection@iii}\fi%
  \@End%
}%
\def\Pst@Projection@iv#1#2{%
  \ifx\@image\@default\def\@image{\@antecedent '}\fi
  \rput(\@FrstPt){% translation onto #1
    \rput(!tx@EcldDict begin /N@#1 GetNode /N@\@ScdPt\space GetNode Project end
          \pst@number\psyunit div exch \pst@number\psxunit div exch)%
         {\pnode{#2}}%
    }%
}%
%%%%%%%%%%%%%%%%%%%%%
\else%% OLD SYNTAX
\def\pstProjection{\@ifnextchar[\Pst@Projection{\Pst@Projection[]}}%
\def\Pst@Projection[#1]#2#3{%
  \bgroup%
  \@InitListMng%
  \psset{#1}\def\@FrstPt{#2}\def\@ScdPt{#3}% Affectation of local parameters
  \edef\@@GenCourbe{}%%for accumulating points
  \Pst@Projection@i-%
}%
\def\Pst@Projection@i-#1#2{%
  \Pst@Projection@ii{#1}{#2}
  %%begin modif alaindelplanque 11/2003
  %% automatic computation of PosAngle
  \ifx\psk@PosAngle\@undef%
    \psset{PosAngle={!tx@EcldDict begin /N@#2 GetNode exch /N@#1 GetNode end 4 1 roll
                     sub 3 1 roll sub neg exch atan=20}}
  \fi
  %%end modif alaindelplanque 11/2003
  \xdef\@@GenCourbe{\@@GenCourbe(#2)}%%for accumulating points
  \Pst@ManageParamList{#2}%
  \ifPst@CodeFig%
    \psset{linecolor=\psk@CodeFigColor, linestyle=\psk@CodeFigStyle}%
    \pstRightAngle[linestyle=solid]{#1}{#2}{\@ScdPt}%
    \ncline{#1}{#2}%
  \fi%
  \@ifnextchar-{\Pst@Projection@i}{\pst@MngTransformCurve\egroup}%
}%
\def\Pst@Projection@ii#1#2{%
  \rput(\@FrstPt){% translation onto #1
    \rput(!tx@EcldDict begin /N@#1 GetNode /N@\@ScdPt\space GetNode Project end
          \pst@number\psyunit div exch \pst@number\psxunit div exch)%
         {\pnode{#2}}%
    }%
}%
\fi% END OLD SYNTAX %% DR 2005/04/10
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%              ORTHOGONAL SYMMETRY
%% #2 #3 -> nodes defining the symmetrical axis
%% #4 -> antecedent node
%% #5 -> node name of the symmetrical point
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\expandafter\ifx\csname psteucl@old\endcsname\relax%% NEW SYNTAX %% DR 2005/04/10
\def\pstOrtSym{\@ifnextchar[\Pst@OrtSym{\Pst@OrtSym[]}}%
\def\Pst@OrtSym[#1]#2#3{%
  \bgroup%
  \@InitListMng%
  \psset{#1}\def\@FrstPt{#2}\def\@ScdPt{#3}%             % Affectation of local parameters
  \edef\@@GenCourbe{}%%for accumulating points
  \Pst@OrtSym@i%
}
\def\Pst@OrtSym@i#1{
  \@List{#1}\edef\@antecedentLst{\@NewList}
  \@ifnextchar[\Pst@OrtSym@ii{\Pst@OrtSym@ii[default]}%
}%
\def\Pst@OrtSym@ii[#1]{
  \@List{#1}\edef\@imageLst{\@NewList}
  \edef\@antecedent{\expandafter\PstParamListFirst\@antecedentLst,undef/}
  \edef\@image{\expandafter\PstParamListFirst\@imageLst,default/}
  \Pst@OrtSym@iii%
}%
\def\Pst@OrtSym@iii{
  \ifx\@image\@default\def\@image{\@antecedent '}\fi
  \rput(\@FrstPt){% translation onto #1
    \rput(!
      tx@EcldDict begin /N@\@antecedent\space GetNode 2 copy /N@\@ScdPt\space GetNode Project
      /N@\@antecedent\space GetNode ABVect 2 mul 3 -1 roll exch add 3 1 roll 2 mul add exch end
      \pst@number\psyunit div exch \pst@number\psxunit div exch)%
      {\pnode{\@image}}%
    }%
  \ifPst@CodeFig%
    \bgroup
    \Pst@Projection@iv{\@antecedent}{@ProjOrth\@antecedent on\@FrstPt\@ScdPt}
    \psset{linecolor=\psk@CodeFigColor, linestyle=\psk@CodeFigStyle}%
    \pstRightAngle[linestyle=solid]{\@FrstPt}{@ProjOrth\@antecedent on\@FrstPt\@ScdPt}{\@antecedent}%
    \Pst@SegmentMark[]{\@image}{@ProjOrth\@antecedent on\@FrstPt\@ScdPt}%
    \Pst@SegmentMark[]{@ProjOrth\@antecedent on\@FrstPt\@ScdPt}{\@antecedent}%
    \egroup
  \fi%
  \xdef\@@GenCourbe{\@@GenCourbe(\@image)}%%for accumulating points
  \Pst@ManageParamList{\@image}%
  \edef\@antecedentLst{\expandafter\PstParamListLasts\@antecedentLst,undef/}%
  \edef\@imageLst{\expandafter\PstParamListLasts\@imageLst,default/}%
  \edef\@LastValidantecedent{\@antecedent}\def\@LastValidimage{\@image}
  \edef\@antecedent{\expandafter\PstParamListFirst\@antecedentLst,undef/}%
  \edef\@image{\expandafter\PstParamListFirst\@imageLst,default/}
  \ifx\@antecedent\@undef\def\@End{\pst@MngTransformCurve\egroup}
  \else\def\@End{\Pst@OrtSym@iii}\fi%
  \@End%
}%
%%%%%%%%%%%%%%%%%%%%%
\else%% OLD SYNTAX
\def\pstOrtSym{\@ifnextchar[\Pst@OrtSym{\Pst@OrtSym[]}}%
\def\Pst@OrtSym[#1]#2#3{%
  \bgroup%
  \@InitListMng%
  \psset{#1}\def\@FrstPt{#2}\def\@ScdPt{#3}%             % Affectation of local parameters
  \edef\@@GenCourbe{}%%for accumulating points
  \Pst@OrtSym@i-%
}
\def\Pst@OrtSym@i-#1#2{
  \rput(\@FrstPt){% translation onto #1
    \rput(!
      tx@EcldDict begin /N@#1 GetNode 2 copy /N@\@ScdPt\space GetNode Project
      /N@#1 GetNode ABVect 2 mul 3 -1 roll exch add 3 1 roll 2 mul add exch end
      \pst@number\psyunit div exch \pst@number\psxunit div exch)%
      {\pnode{#2}}%
    }%
  \ifPst@CodeFig%
    \bgroup
    \Pst@Projection@ii{#1}{@ProjOrth#1on\@FrstPt\@ScdPt}
    \psset{linecolor=\psk@CodeFigColor, linestyle=\psk@CodeFigStyle}%
    \pstRightAngle[linestyle=solid]{\@FrstPt}{@ProjOrth#1on\@FrstPt\@ScdPt}{#1}%
    \Pst@SegmentMark[]{#2}{@ProjOrth#1on\@FrstPt\@ScdPt}%
    \Pst@SegmentMark[]{@ProjOrth#1on\@FrstPt\@ScdPt}{#1}%
    \egroup
  \fi%
  \xdef\@@GenCourbe{\@@GenCourbe(#2)}%%for accumulating points
  \Pst@ManageParamList{#2}%
  \@ifnextchar-{\Pst@OrtSym@i}{\pst@MngTransformCurve\egroup}%
}%
\fi% END OLD SYNTAX %% DR 2005/04/10
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%              mediator line
%% #2 #3 -> nodes defining the segment
%% #4 -> middle of the segment
%% #5 -> node belonging to the mediator line
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\pstMediatorAB{\@ifnextchar[\Pst@MediatorAB{\Pst@MediatorAB[]}}%
\def\Pst@MediatorAB[#1]#2#3#4#5{%
  \bgroup\psset{#1}%             % Affectation of local parameters
  \bgroup
    \ifx\psk@PointSymbolA\@none\let\psk@PointSymbol=\@none\else\let\psk@PointSymbol=\psk@PointSymbolA\fi
    \ifx\psk@PointNameA\@undef\else\psset{PointName=\psk@PointNameA}\fi
    \Pst@MiddleAB[]{#2}{#3}{#4}
  \egroup
  \bgroup
    \ifx\psk@PointSymbolB\@none\let\psk@PointSymbol=\@none\else\let\psk@PointSymbol=\psk@PointSymbolB\fi
    \ifx\psk@PointNameB\@undef\else\psset{PointName=\psk@PointNameB}\fi
  \expandafter\ifx\csname psteucl@old\endcsname\relax%
    \Pst@Rotation[RotAngle=90, CodeFig=false]{#4}{#3}[#5]%%%DR 26032005
  \else\Pst@Rotation[RotAngle=90, CodeFig=false]{#4}{#3}{#5}\fi%%%DR 14042005
  \egroup
  \ifPst@CodeFig
    \bgroup\psset{linecolor=\psk@CodeFigColor}
    \pstRightAngle[]{#3}{#4}{#5}
    \Pst@SegmentMark[]{#2}{#4}\Pst@SegmentMark[]{#4}{#3}%
    \egroup
  \fi
  \ncline{#4}{#5}
  \egroup
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%              bissectrice
%% #2 #3 #4 -> nodes defining the angle in #3 anti-clockwise
%% #5 -> node belonging to the bissectrice
%% #6 -> label
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\pstBissectBAC{\@ifnextchar[\Pst@BissectBAC{\Pst@BissectBAC[]}}%
\def\Pst@BissectBAC[#1]#2#3#4#5{%
  \bgroup\psset{#1}%             % Affectation of local parameters
  \rput(#3){%
    \rput(!
      tx@EcldDict begin /N@#4 GetNode exch Atan /N@#2 GetNode end
      2 copy 5 2 roll exch Atan 2 copy lt { exch 360 sub exch } if sub
      2 div tx@EcldDict begin Rotate end
      \pst@number\psyunit div exch \pst@number\psxunit div exch)%
      {\pnode{#5}}%
    \Pst@geonodelabel{#5}%
    \ncline{#3}{#5}%
    }%% end \rput
  \egroup%
}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%              outside bissectrice
%% #2 #3 #4 -> nodes defining the angle in #3 anti-clockwise
%% #5 -> node belonging to the bissectrice
%% #6 -> label
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\pstOutBissectBAC{\@ifnextchar[\Pst@OutBisBAC{\Pst@OutBisBAC[]}}%
\def\Pst@OutBisBAC[#1]#2#3#4#5{%
  \bgroup\psset{#1}%             % Affectation of local parameters
  \rput(#3){%
    \rput(!
      tx@EcldDict begin /N@#4 GetNode exch Atan /N@#2 GetNode end
      2 copy 5 2 roll exch Atan 2 copy lt { exch 360 sub exch } if sub
      2 div 90 add tx@EcldDict begin Rotate end
      \pst@number\psyunit div exch \pst@number\psxunit div exch)%
      {\pnode{#5}}%
    \Pst@geonodelabel{#5}%
    \ncline{#3}{#5}%
    }%% end \rput
  \egroup%
}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Creation of a point according to a curvilign abscissa
%% #2 -> center of the circle
%% #3 -> point origin of the circle
%% #4 -> point to be placed
\def\pstCurvAbsNode{\@ifnextchar[\Pst@CurvAbsNode{\Pst@CurvAbsNode[]}}%
\def\Pst@CurvAbsNode[#1]#2#3#4#5{%
  \bgroup\psset{#1}%             % Affectation of local parameters
  \Pst@@CurvAbsNode{#2}{#3}{#4}{#5}%
  %%begin modif alaindelplanque 11/2003
  %% \ifx\psk@PointSymbol\@none\else{\Pst@geonodelabel{#4}}\fi%
  \ifx\psk@PointSymbol\@none
  \else
    %% automatic computation of PosAngle
    \ifx\psk@PosAngle\@undef%
      \psset{PosAngle={!tx@EcldDict begin /N@#4 GetNode exch /N@#2 GetNode end 4 1 roll
                        sub 3 1 roll sub neg exch Atan}}
    \fi
    \Pst@geonodelabel{#4}
  \fi%
  %%end modif alaindelplanque 11/2003
  \Pst@geonodelabel{#4}%
  \egroup%
  %% AJOUTER LE MARQUAGE CodeFig
}%
\def\Pst@@CurvAbsNode#1#2#3#4{%
  \rput(#1){%
    \rput(!
      tx@EcldDict begin
        /N@#2 GetNode 2 copy 0 0 ABDist #4 exch div Pi div 180 mul
        \ifPst@CurvAbsNeg neg \fi Rotate
      end
      \pst@number\psyunit div exch \pst@number\psxunit div exch)%
    {\pnode{#3}}%
    }%% end \rput
}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%        GENERIC CURVES
%% #2 -> Radical name
%% #3 -> initial counter value
%% #4 -> maximal counter value
\def\pstGenericCurve{\@ifnextchar[\Pst@GenericCurve{\Pst@GenericCurve[]}}%
\def\Pst@GenericCurve[#1]#2#3#4{%
  \bgroup\psset{#1}%       % Affectation of local parameters
    \edef\@@GenCourbe{\ifx\psk@GenCurvFirst\@none\else(\psk@GenCurvFirst)\fi}%
    \pst@cnth=#4
    \advance\pst@cnth by -#3%\@GenCurve% del DR
    \advance\pst@cnth by \psk@GenCurvInc%1 modif DR 020225
    \divide\pst@cnth by \psk@GenCurvInc
    \multido{\i@GenCurve=#3+\psk@GenCurvInc}{\pst@cnth}{%
      \xdef\@@GenCourbe{\@@GenCourbe(#2\i@GenCurve)}}
    \edef\@@GenCourbe{%
      \@@GenCourbe%
      \ifx\psk@GenCurvLast\@none\else(\psk@GenCurvLast)\fi}%
    %\psset{showpoints=true}
    \expandafter\pscurve\@@GenCourbe
  \egroup%
}%
%
%% \pstTriangleIC[Options]{A}{B}{C}[I][D]
%% Draw the inner circle of triangle ABC
%% Parameters:
%% #1 -> options
%% #2 -> [input] the node A
%% #3 -> [input] the node B
%% #4 -> [input] the node C
%% #5 -> [output] optional, the inner circle center I
%% #6 -> [output] optional, the node D on inner circle
\def\pstTriangleIC{\@ifnextchar[\Pst@TriangleIC{\Pst@TriangleIC[]}}
\def\Pst@TriangleIC[#1]#2#3#4{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \def\pst@triangle@node@a{#2}
    \def\pst@triangle@node@b{#3}
    \def\pst@triangle@node@c{#4}
    \@ifnextchar[\Pst@TriangleIC@i{\Pst@TriangleIC@j[IC_O]}}
\def\Pst@TriangleIC@i[#1]{%
    \def\pst@triangle@inner@center{#1}
    \@ifnextchar[\Pst@TriangleIC@ii{\Pst@TriangleIC@ij[IC_OAB]}}
\def\Pst@TriangleIC@ii[#1]{% display both I and D
    \def\pst@triangle@inner@IBC{#1}
    \Pst@TriangleIC@k%
    \Pst@ManageParamList{\pst@triangle@inner@center}%
    \Pst@ManageParamList{\pst@triangle@inner@IBC}%
  \endgroup
}%
\def\Pst@TriangleIC@ij[#1]{% display I only
    \def\pst@triangle@inner@IBC{#1}
    \Pst@TriangleIC@k%
    \Pst@ManageParamList{\pst@triangle@inner@center}%
  \endgroup
}%
\def\Pst@TriangleIC@j[#1]{% display none point
    \def\pst@triangle@inner@center{#1}
    \def\pst@triangle@inner@IBC{IC_OAB}
    \Pst@TriangleIC@k%
  \endgroup
}%
\def\Pst@TriangleIC@k{% display none point
  \begingroup
    \pstBissectBAC[PointSymbol=none,PointName=none,linestyle=none,CodeFig=false]{\pst@triangle@node@c}{\pst@triangle@node@a}{\pst@triangle@node@b}{@PST@TRIANGLE@IC_BC}
    \pstBissectBAC[PointSymbol=none,PointName=none,linestyle=none,CodeFig=false]{\pst@triangle@node@b}{\pst@triangle@node@c}{\pst@triangle@node@a}{@PST@TRIANGLE@IC_AB}
    \pstInterLL[PointSymbol=none,PointName=none]{\pst@triangle@node@c}{@PST@TRIANGLE@IC_AB}{\pst@triangle@node@a}{@PST@TRIANGLE@IC_BC}{\pst@triangle@inner@center}
    \pstProjection[PointSymbol=none,PointName=none]{\pst@triangle@node@a}{\pst@triangle@node@b}{\pst@triangle@inner@center}[\pst@triangle@inner@IBC]
    \pstCircleOA{\pst@triangle@inner@center}{\pst@triangle@inner@IBC}
  \endgroup
}%
%
%% \pstTriangleOC[Options]{A}{B}{C}[O]
%% Draw the outer circle of triangle ABC
%% Parameters:
%% #1 -> options
%% #2 -> [input] the node A
%% #3 -> [input] the node B
%% #4 -> [input] the node C
%% #5 -> [output] optional, the outer circle center O
\def\pstTriangleOC{\@ifnextchar[\Pst@TriangleOC{\Pst@TriangleOC[]}}
\def\Pst@TriangleOC[#1]#2#3#4{%
  \begingroup
    \psset{#1}%
    \def\pst@triangle@node@a{#2}
    \def\pst@triangle@node@b{#3}
    \def\pst@triangle@node@c{#4}
    \@ifnextchar[\Pst@TriangleOC@i{\Pst@TriangleOC@j[OC_O]}}
\def\Pst@TriangleOC@i[#1]{%
    \pstCircleABC[PointSymbol=none,PointName=none,CodeFig=false]{\pst@triangle@node@a}{\pst@triangle@node@b}{\pst@triangle@node@c}{#1}
    \Pst@geonodelabel{#1}%
  \endgroup
}%
\def\Pst@TriangleOC@j[#1]{% don't output the center point
    \pstCircleABC[PointSymbol=none,PointName=none,CodeFig=false]{\pst@triangle@node@a}{\pst@triangle@node@b}{\pst@triangle@node@c}{#1}
  \endgroup
}%
%
%% \pstTriangleGC[Options]{A}{B}{C}{G}[M1][M2]
%% Draw the gravity center of triangle ABC
%% Parameters:
%% #1 -> options
%% #2 -> [input] the node A
%% #3 -> [input] the node B
%% #4 -> [input] the node C
%% #5 -> [output] the output gravity center G
%% #6 -> [output] the optional output Middle of BC
%% #7 -> [output] the optional output Middle of CA
\def\pstTriangleGC{\@ifnextchar[\Pst@TriangleGC{\Pst@TriangleGC[]}}
\def\Pst@TriangleGC[#1]#2#3#4#5{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \def\pst@triangle@node@A{#2}
    \def\pst@triangle@node@B{#3}
    \def\pst@triangle@node@C{#4}
    \def\pst@triangle@node@G{#5}
    \@ifnextchar[\Pst@TriangleGC@i{\Pst@TriangleGC@j[BC_M][CA_M]}}
\def\Pst@TriangleGC@i[#1][#2]{%
    \pstMiddleAB[PointName=none,PointSymbol=none]{\pst@triangle@node@B}{\pst@triangle@node@C}{#1}
    \pstMiddleAB[PointName=none,PointSymbol=none]{\pst@triangle@node@C}{\pst@triangle@node@A}{#2}
    \pstInterLL[PointName=none,PointSymbol=none]{\pst@triangle@node@A}{#1}{\pst@triangle@node@B}{#2}{\pst@triangle@node@G}
    \Pst@ManageParamList{\pst@triangle@node@G}%
    \Pst@ManageParamList{#1}%
    \Pst@ManageParamList{#2}%
  \endgroup
}%
\def\Pst@TriangleGC@j[#1][#2]{%
    \pstMiddleAB[PointName=none,PointSymbol=none]{\pst@triangle@node@B}{\pst@triangle@node@C}{#1}
    \pstMiddleAB[PointName=none,PointSymbol=none]{\pst@triangle@node@C}{\pst@triangle@node@A}{#2}
    \pstInterLL[PointName=none,PointSymbol=none]{\pst@triangle@node@A}{#1}{\pst@triangle@node@B}{#2}{\pst@triangle@node@G}
    \Pst@ManageParamList{\pst@triangle@node@G}%
  \endgroup
}%
%
%% \pstTriangleHC[Options]{A}{B}{C}{H}[H1][H2]
%% Draw the orthocenter of triangle ABC
%% Parameters:
%% #1 -> options
%% #2 -> [input] the node A
%% #3 -> [input] the node B
%% #4 -> [input] the node C
%% #5 -> [output] the output orthocenter H
%% #6 -> [output] the optional output perpendicular on BC
%% #7 -> [output] the optional output perpendicular on CA
\def\pstTriangleHC{\@ifnextchar[\Pst@TriangleHC{\Pst@TriangleHC[]}}
\def\Pst@TriangleHC[#1]#2#3#4#5{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \def\pst@triangle@node@A{#2}
    \def\pst@triangle@node@B{#3}
    \def\pst@triangle@node@C{#4}
    \def\pst@triangle@node@H{#5}
    \@ifnextchar[\Pst@TriangleHC@i{\Pst@TriangleHC@j[BC_H][CA_H]}}
\def\Pst@TriangleHC@i[#1][#2]{%
    \pstProjection[PointName=none,PointSymbol=none]{\pst@triangle@node@B}{\pst@triangle@node@C}{\pst@triangle@node@A}[#1]
    \pstProjection[PointName=none,PointSymbol=none]{\pst@triangle@node@C}{\pst@triangle@node@A}{\pst@triangle@node@B}[#2]
    \pstInterLL[PointName=none,PointSymbol=none]{\pst@triangle@node@A}{#1}{\pst@triangle@node@B}{#2}{\pst@triangle@node@H}
    \Pst@ManageParamList{\pst@triangle@node@H}%
    \Pst@ManageParamList{#1}%
    \Pst@ManageParamList{#2}%
  \endgroup
}%
\def\Pst@TriangleHC@j[#1][#2]{%
    \pstProjection[PointName=none,PointSymbol=none]{\pst@triangle@node@B}{\pst@triangle@node@C}{\pst@triangle@node@A}[#1]
    \pstProjection[PointName=none,PointSymbol=none]{\pst@triangle@node@C}{\pst@triangle@node@A}{\pst@triangle@node@B}[#2]
    \pstInterLL[PointName=none,PointSymbol=none]{\pst@triangle@node@A}{#1}{\pst@triangle@node@B}{#2}{\pst@triangle@node@H}
    \Pst@ManageParamList{\pst@triangle@node@H}%
  \endgroup
}%
%
%% \pstTriangleEC[Options]{A}{B}{C}{E}[H]
%% Draw the center of the escribed circle which lying out of BC of triangle ABC.
%
%% Parameters:
%% #1 -> options
%% #2 -> [input] the node A
%% #3 -> [input] the node B
%% #4 -> [input] the node C
%% #5 -> [output] the output excenter E
%% #6 -> [output] the optional output perpendicular on BC
\def\pstTriangleEC{\@ifnextchar[\Pst@TriangleEC{\Pst@TriangleEC[]}}
\def\Pst@TriangleEC[#1]#2#3#4#5{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \def\pst@triangle@node@A{#2}
    \def\pst@triangle@node@B{#3}
    \def\pst@triangle@node@C{#4}
    \def\pst@triangle@node@E{#5}
    \@ifnextchar[\Pst@TriangleEC@i{\Pst@TriangleEC@j[BC_H]}}
\def\Pst@TriangleEC@i[#1]{%
    \pstBissectBAC[PointName=none,PointSymbol=none,linestyle=none]{\pst@triangle@node@B}{\pst@triangle@node@A}{\pst@triangle@node@C}{@PST@TRIANGLE@EC_BC}
    \pstOutBissectBAC[PointName=none,PointSymbol=none,linestyle=none]{\pst@triangle@node@C}{\pst@triangle@node@B}{\pst@triangle@node@A}{@PST@TRIANGLE@EC_CA}
    \pstInterLL[PointName=none,PointSymbol=none]{\pst@triangle@node@A}{@PST@TRIANGLE@EC_BC}{\pst@triangle@node@B}{@PST@TRIANGLE@EC_CA}{\pst@triangle@node@E}
    \pstProjection[PointName=none,PointSymbol=none]{\pst@triangle@node@B}{\pst@triangle@node@C}{\pst@triangle@node@E}[#1]
    \Pst@ManageParamList{\pst@triangle@node@E}%
    \Pst@ManageParamList{#1}%
  \endgroup
}%
\def\Pst@TriangleEC@j[#1]{%
    \pstBissectBAC[PointName=none,PointSymbol=none,linestyle=none]{\pst@triangle@node@B}{\pst@triangle@node@A}{\pst@triangle@node@C}{@PST@TRIANGLE@EC_BC}
    \pstOutBissectBAC[PointName=none,PointSymbol=none,linestyle=none]{\pst@triangle@node@C}{\pst@triangle@node@B}{\pst@triangle@node@A}{@PST@TRIANGLE@EC_CA}
    \pstInterLL[PointName=none,PointSymbol=none]{\pst@triangle@node@A}{@PST@TRIANGLE@EC_BC}{\pst@triangle@node@B}{@PST@TRIANGLE@EC_CA}{\pst@triangle@node@E}
    \pstProjection[PointName=none,PointSymbol=none]{\pst@triangle@node@B}{\pst@triangle@node@C}{\pst@triangle@node@E}[#1]
    \Pst@ManageParamList{\pst@triangle@node@E}%
  \endgroup
}%
%
%% \pstTriangleNC[Options]{A}{B}{C}{N}[M1][M2][M3]
%% Draw the nine point circle center of triangle ABC
%% Parameters:
%% #1 -> options
%% #2 -> [input] the node A
%% #3 -> [input] the node B
%% #4 -> [input] the node C
%% #5 -> [output] the output nine point circle center N
%% #6 -> [output] the optional output Middle of BC
%% #7 -> [output] the optional output Middle of CA
%% #8 -> [output] the optional output Middle of AB
\def\pstTriangleNC{\@ifnextchar[\Pst@TriangleNC{\Pst@TriangleNC[]}}
\def\Pst@TriangleNC[#1]#2#3#4#5{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \def\pst@triangle@node@A{#2}
    \def\pst@triangle@node@B{#3}
    \def\pst@triangle@node@C{#4}
    \def\pst@triangle@node@N{#5}
    \@ifnextchar[\Pst@TriangleNC@i{\Pst@TriangleNC@j[BC_M][CA_M][AB_M]}}
\def\Pst@TriangleNC@i[#1][#2][#3]{%
    \pstMiddleAB[PointName=none,PointSymbol=none]{\pst@triangle@node@B}{\pst@triangle@node@C}{#1}
    \pstMiddleAB[PointName=none,PointSymbol=none]{\pst@triangle@node@C}{\pst@triangle@node@A}{#2}
    \pstMiddleAB[PointName=none,PointSymbol=none]{\pst@triangle@node@A}{\pst@triangle@node@B}{#3}
    \pstTriangleOC[PointName=none,PointSymbol=none]{#1}{#2}{#3}[\pst@triangle@node@N]
    \Pst@ManageParamList{\pst@triangle@node@N}%
    \Pst@ManageParamList{#1}%
    \Pst@ManageParamList{#2}%
    \Pst@ManageParamList{#3}%
  \endgroup
}%
\def\Pst@TriangleNC@j[#1][#2][#3]{%
    \pstMiddleAB[PointName=none,PointSymbol=none]{\pst@triangle@node@B}{\pst@triangle@node@C}{#1}
    \pstMiddleAB[PointName=none,PointSymbol=none]{\pst@triangle@node@C}{\pst@triangle@node@A}{#2}
    \pstMiddleAB[PointName=none,PointSymbol=none]{\pst@triangle@node@A}{\pst@triangle@node@B}{#3}
    \pstTriangleOC{#1}{#2}{#3}[\pst@triangle@node@N]
  \endgroup
}%
%
%% \pstTriangleLC[Options]{A}{B}{C}{L}[S1][S2][S3]
%% Draw the Lemonie of triangle ABC
%% Parameters:
%% #1 -> options
%% #2 -> [input] the node A
%% #3 -> [input] the node B
%% #4 -> [input] the node C
%% #5 -> [output] the output Lemoine Point L
%% #6 -> [output] the optional output point on BC
%% #7 -> [output] the optional output point on CA
%% #8 -> [output] the optional output point on AB
\def\pstTriangleLC{\@ifnextchar[\Pst@TriangleLC{\Pst@TriangleLC[]}}
\def\Pst@TriangleLC[#1]#2#3#4#5{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \def\pst@triangle@node@A{#2}
    \def\pst@triangle@node@B{#3}
    \def\pst@triangle@node@C{#4}
    \def\pst@triangle@node@L{#5}
    \@ifnextchar[\Pst@TriangleLC@i{\Pst@TriangleLC@j[BC_L][CA_L][AB_L]}}
\def\Pst@TriangleLC@i[#1][#2][#3]{%
    \pstMiddleAB[PointName=none,PointSymbol=none]{\pst@triangle@node@B}{\pst@triangle@node@C}{BC_M}
    \pstMiddleAB[PointName=none,PointSymbol=none]{\pst@triangle@node@C}{\pst@triangle@node@A}{CA_M}
    \pstBisectorAOB[PointName=none,PointSymbol=none]{\pst@triangle@node@B}{\pst@triangle@node@A}{\pst@triangle@node@C}{A_T}{A_S}
    \pstBisectorAOB[PointName=none,PointSymbol=none]{\pst@triangle@node@C}{\pst@triangle@node@B}{\pst@triangle@node@A}{B_T}{B_S}
    \pstOrtSym[PointName=none,PointSymbol=none]{\pst@triangle@node@A}{A_T}{BC_M}[BC_LL]
    \pstOrtSym[PointName=none,PointSymbol=none]{\pst@triangle@node@B}{B_T}{CA_M}[CA_LL]
    \pstInterLL[PointName=none,PointSymbol=none]{\pst@triangle@node@A}{BC_LL}{\pst@triangle@node@B}{CA_LL}{\pst@triangle@node@L}
    \pstInterLL[PointName=none,PointSymbol=none]{\pst@triangle@node@A}{\pst@triangle@node@L}{\pst@triangle@node@B}{\pst@triangle@node@C}{#1}
    \pstInterLL[PointName=none,PointSymbol=none]{\pst@triangle@node@B}{\pst@triangle@node@L}{\pst@triangle@node@C}{\pst@triangle@node@A}{#2}
    \pstInterLL[PointName=none,PointSymbol=none]{\pst@triangle@node@C}{\pst@triangle@node@L}{\pst@triangle@node@A}{\pst@triangle@node@B}{#3}
    \Pst@ManageParamList{\pst@triangle@node@L}%
    \Pst@ManageParamList{#1}%
    \Pst@ManageParamList{#2}%
    \Pst@ManageParamList{#3}%
  \endgroup
}%
\def\Pst@TriangleLC@j[#1][#2][#3]{%
    \pstMiddleAB[PointName=none,PointSymbol=none]{\pst@triangle@node@B}{\pst@triangle@node@C}{BC_M}
    \pstMiddleAB[PointName=none,PointSymbol=none]{\pst@triangle@node@C}{\pst@triangle@node@A}{CA_M}
    \pstBisectorAOB[PointName=none,PointSymbol=none]{\pst@triangle@node@B}{\pst@triangle@node@A}{\pst@triangle@node@C}{A_T}{A_S}
    \pstBisectorAOB[PointName=none,PointSymbol=none]{\pst@triangle@node@C}{\pst@triangle@node@B}{\pst@triangle@node@A}{B_T}{B_S}
    \pstOrtSym[PointName=none,PointSymbol=none]{\pst@triangle@node@A}{A_T}{BC_M}[BC_LL]
    \pstOrtSym[PointName=none,PointSymbol=none]{\pst@triangle@node@B}{B_T}{CA_M}[CA_LL]
    \pstInterLL{\pst@triangle@node@A}{BC_LL}{\pst@triangle@node@B}{CA_LL}{\pst@triangle@node@L}
  \endgroup
}%
%
%% Distance between two points
\def\pstDist#1#2{%
  tx@EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist end
}
\def\pstDistAB#1#2{% Obsoleted
  tx@EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist end
  \ifx\psk@DistCoef\@none\else
    \psk@DistCoef\space mul
  \fi
}
%
% \pstDistMul{A}{B}{\lambda} -> \lambda * |AB|
%% Distance |AB| multiply with coefficient \lambda
\def\pstDistMul#1#2#3{%
  tx@EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist #3 mul end
}
%
% \pstDistAdd{A}{B}{C}{D} -> |AB| + |CD|
%% Distance sum of two segments AB and CD
\def\pstDistAdd#1#2#3#4{%
  tx@EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist
  /N@#3 GetNode /N@#4 GetNode ABDist add end
}
%
% \pstDistAddVal{A}{B}{coef1}{val} -> |AB| * coef1 + val
\def\pstDistAddVal#1#2#3#4{%
  tx@EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist
  #3 mul #4 add end
}
%
% \pstDistAddCoef{A}{B}{coef1}{C}{D}{coef2} -> |AB| * coef1 + |CD| * coef2
\def\pstDistAddCoef#1#2#3#4#5#6{%
  tx@EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist
  #3 mul /N@#4 GetNode /N@#5 GetNode ABDist #6 mul add end
}
%
%% Distance difference between two segments AB and CD
\def\pstDistSub#1#2#3#4{%
  tx@EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist
  /N@#3 GetNode /N@#4 GetNode ABDist sub abs end
}
%
% \pstDistSubVal{A}{B}{coef1}{val} -> |AB| * coef1 - val
\def\pstDistSubVal#1#2#3#4{%
  tx@EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist
  #3 mul #4 sub abs end
}
%
% \pstDistSubCoef{A}{B}{coef1}{C}{D}{coef2} -> |AB| * coef1 - |CD| * coef2
\def\pstDistSubCoef#1#2#3#4#5#6{%
  tx@EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist
  #3 mul /N@#4 GetNode /N@#5 GetNode ABDist #6 mul sub abs end
}
%
%% Distance ratio of two segments AB and CD
\def\pstDistDiv#1#2#3#4{%
  tx@EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist
  /N@#3 GetNode /N@#4 GetNode ABDist div end
}
%
%% Distance specified with a number
\def\pstDistConst#1{#1 \pst@number\psxunit mul\space}
\def\pstDistVal#1{% Obsoleted
  #1 \pst@number\psxunit mul
  \ifx\psk@DistCoef\@none\else
    \psk@DistCoef\space mul
  \fi
}
\def\pstDistExpr#1{\pscalculate{#1} \pst@number\psxunit mul\space}
\def\pstDistCalc#1{% Obsoleted
  \pscalculate{#1} \pst@number\psxunit mul
  \ifx\psk@DistCoef\@none\else
    \psk@DistCoef\space mul
  \fi
}
%
\def\pstDistCoef#1{#1 \ifx\psk@DistCoef\@none\else\psk@DistCoef\space mul\space\fi}
\def\pstUserDist#1{#1 \pst@number\psxunit div\space}
\def\pstScreenDist#1{#1 \pst@number\psxunit mul\space}
%
% \pstDistABC{A}{B}{C} -> return the distance from C to AB.
\def\pstDistABC#1#2#3{%
  tx@EcldDict begin /N@#1 GetNode /N@#2 GetNode /N@#3 GetNode
  % x1 y1 x2 y2 x3 y3
  5 index 5 index 5 index 5 index ABDist % |AB|
  6 index 6 index 4 index 4 index ABDist % |AC|
  5 index 5 index 5 index 5 index ABDist % |BC|
  2 index 2 index add 1 index add 2 div % p
  0 index 4 index sub % p-|AB|
  1 index 4 index sub % p-|AC|
  2 index 4 index sub % p-|BC|
  mul mul mul sqrt 3 index div 2 mul
  10 1 roll pop pop pop pop pop pop pop pop pop end
}
%
%% angle defined by three points
\def\pstAngleAOB#1#2#3{%
%  \pstGeonode[PointName=none,PointSymbol=none](#1){temp@1}(#2){temp@2}(#3){temp@3}%
%  \pstAngleAOB@i{temp@1}{temp@2}{temp@3}}
%\def\pstAngleAOB@i#1#2#3{%
  tx@EcldDict begin /N@#2 GetNode /N@#3 GetNode ABVect /N@#2 GetNode /N@#1 GetNode ABVect end
  4 copy exch 4 -1 roll mul
  3 -2 roll mul add
  4 -2 roll mul 4 -2 roll mul sub exch Atan
  \ifx\psk@AngleCoef\@none\else
    \psk@AngleCoef\space mul
  \fi
}
%
\def\psGetDistanceAB{\pst@object{psGetDistanceAB}}%   Thmoas S\"{o}ll 20140512
\def\psGetDistanceAB@i(#1)(#2)#3{%
\begingroup%
\pst@killglue
\use@par
\pst@getcoor{#1}\pst@tempA
\pst@getcoor{#2}\pst@tempB
\pnode(!
  15 dict begin
  /dec \psk@decimals\space def
  \psk@PSfont findfont \psk@fontscale scalefont setfont
  /laenge {10 dec exp mul round 10 dec exp div 15 string cvs stringwidth } def
  /Wert { dec -1 le { /dec 15 def } if 10 dec exp mul round 10 dec exp div dec 0 eq {cvi 15 string cvs} {15 string cvs } ifelse
          \ifPst@comma dot2comma \fi show } def
  \pst@tempA \tx@UserCoor /y1 ED /x1 ED
  \pst@tempB \tx@UserCoor /y2 ED /x2 ED
  \pst@tempA /y3 ED /x3 ED
  \pst@tempB /y4 ED /x4 ED
  x3 x4 sub y3 y4 sub Pyth laenge /dx ED
  x3 x4 add 2 div dx 2 div sub \psk@xShift\space add y3 y4 add 2 div \psk@yShift\space add
  moveto %
  x1 x2 sub y1 y2 sub Pyth Wert
  x1 x2 add 2 div y1 y2 add 2 div
  end ){#3}
\endgroup
\ignorespaces
}
%
\define@boolkey[psset]{pst-eucl}[Pst@]{AngleValue}[false]{}
\define@boolkey[psset]{pst-eucl}[Pst@]{AngleArc}[true]{}
\define@boolkey[psset]{pst-eucl}[Pst@]{ShowWedge}[true]{}
\define@key[psset]{pst-eucl}{ArcColor}{\def\psk@ArcColor{#1}}%
\define@key[psset]{pst-eucl}{ArcLinestyle}{\def\psk@ArcLinestyle{#1}}%
\define@key[psset]{pst-eucl}{ArcLinewidth}{\def\psk@ArcLinewidth{#1}}%
\define@key[psset]{pst-eucl}{WedgeColor}{\def\psk@WedgeColor{#1}}%
\define@key[psset]{pst-eucl}{WedgeFillstyle}{\def\psk@WedgeFillstyle{#1}}%
\define@key[psset]{pst-eucl}{WedgeOpacity}{\def\psk@WedgeOpacity{#1}}%
\psset[pst-eucl]{ArcColor=black,WedgeColor=blue,WedgeOpacity=0.2,AngleValue=false,
                  AngleArc,ShowWedge,ArcLinestyle=solid,ArcLinewidth=0.8pt,WedgeFillstyle=solid}

\def\psGetAngleABC{\pst@object{psGetAngleABC}}%   Thmoas S\"{o}ll 20151018
\def\psGetAngleABC@i(#1)(#2)(#3)#4{%
  \begingroup
  \use@par
  \pst@killglue
  \pst@getcoor{#1}\pst@tempA
  \pst@getcoor{#2}\pst@tempB
  \pst@getcoor{#3}\pst@tempC
  \pst@Verb{
    \pst@tempA \tx@UserCoor /y1 ED /x1 ED
    \pst@tempB \tx@UserCoor /y2 ED /x2 ED
    \pst@tempC \tx@UserCoor /y3 ED /x3 ED
    y1 y2 sub x1 x2 sub Atan neg /delta1 ED
    y3 y2 sub x3 x2 sub Atan neg /delta2 ED
    delta1 delta2 le {180 delta2 delta1 add 2 div neg add /WiM ED} {delta2 delta1 add 2 div neg /WiM ED} ifelse
  }
  \ifPst@ShowWedge
    \pswedge[fillstyle=\psk@WedgeFillstyle,fillcolor=\psk@WedgeColor,opacity=\psk@WedgeOpacity](#2){\psk@MarkAngleRadius}{! delta1}{! delta2}%
  \fi
  \ifPst@AngleArc
    \psarc[linestyle=\psk@ArcLinestyle,linewidth=\psk@ArcLinewidth,linecolor=\psk@ArcColor](#2){\psk@MarkAngleRadius}{! delta1}{! delta2}%
  \fi
  \pnode(! %
    /dec \psk@decimals\space def
    \psk@PSfont findfont \psk@fontscale scalefont setfont \pst@usecolor\pslinecolor
    \ifpst@psfonts
      /s1 { /Symbol findfont \psk@fontscale\space scalefont setfont } bind def
    \else
      /s1 { /StandardSymL findfont \psk@fontscale\space scalefont setfont } bind def
    \fi
    /laenge {10 dec exp mul round 10 dec exp div 15 string cvs stringwidth } def
    /WertZeigen { dec -1 le { /dec 15 def } if 10 dec exp mul round 10 dec exp div dec 0 eq  {cvi 15 string cvs} {15 string cvs } ifelse
    \ifPst@comma dot2comma \fi show s1 (\string\260) show} def
    \pst@tempA \tx@UserCoor /y1 ED /x1 ED
    \pst@tempB \tx@UserCoor /y2 ED /x2 ED
    \pst@tempC \tx@UserCoor /y3 ED /x3 ED
    y1 y2 sub x1 x2 sub Atan neg /delta1 ED
    y3 y2 sub x3 x2 sub Atan neg /delta2 ED
    delta1 delta2 le {360 delta2 delta1 sub abs sub /WiWert ED} {delta2 delta1 sub abs /WiWert ED} ifelse
    delta1 delta2 le {180 delta2 delta1 add 2 div neg add /WiM ED} {delta2 delta1 add 2 div neg /WiM ED} ifelse
    \psk@MarkAngleRadius\space delta2 delta1 add 2 div PtoC \pst@tempB exch pop add /ym1 ED \pst@tempB pop add /xm1 ED
    xm1 \psk@MarkAngleRadius\space WiM cos mul \pst@number\psxunit mul add \psk@xShift\space add ym1
    \psk@MarkAngleRadius\space WiM sin mul \pst@number\psxunit mul add \psk@yShift\space add moveto %
    \ifPst@AngleValue WiWert WertZeigen \fi
    x2 0.8 WiM cos mul add y2 0.8 WiM sin mul add){#2-M}%
  \uput{\psk@LabelSep}[! WiM]{0}(#2){#4}%
  \endgroup
  \ignorespaces
}
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Here are some functions to operate the Coordinate
%% of a given node.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%% \pstAbscissa{A}
%% return the abscissa value of node A, which can be transformed to a new abscissa by pstricks raw code.
%% Parameters:
%% #1 -> [input] the input node
\def\pstAbscissa#1{%
  tx@EcldDict begin /N@#1 GetNode pop \pst@number\psxunit div end
}%
%
%% \pstOrdinate{A}
%% return the ordinate value of node A, which can be transformed to a new ordinate by pstricks raw code.
%% Parameters:
%% #1 -> [input] the input node
\def\pstOrdinate#1{%
  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.
%% Parameters:
%% #1 -> options
%% #2 -> abscissa increment
%% #3 -> ordinate increment
%% #4 -> orignal node name
%% #5 -> target node name
\def\pstMoveNode{\@ifnextchar[\Pst@MoveNode{\Pst@MoveNode[]}}
\def\Pst@MoveNode[#1]{%
  \begingroup
    \psset{#1}%
    \Pst@MoveNode@i}
\def\Pst@MoveNode@i(#1,#2)#3#4{%
  \pnode(! \pstAbscissa{#3} #1 add \pstOrdinate{#3} #2 add){#4}%
  \Pst@geonodelabel{#4}%
  \endgroup%
}%
%
%% \pstProportionNode[Options]{A}{B}{lambda}{C}{C'}
%% Create node C and C' which satisified the definite proportion function |AC|:|BC|=lamba,
%% where lambda is positive, C is inside segment AB, and C' is outside segment AB.
%% According to the definite proportion equation, we have
%% $$x_{C}=\dfrac{x_{A}+\lambda{}x_{B}}{1+\lambda},y_{C}=\dfrac{y_{A}+\lambda{}y_{B}}{1+\lambda}$$
%% and
%% $$x_{C'}=\dfrac{x_{A}-\lambda{}x_{B}}{1-\lambda},y_{C'}=\dfrac{y_{A}+-lambda{}y_{B}}{1-\lambda}$$
%% Parameters:
%% #1 -> options
%% #2 -> the given segment start node A
%% #3 -> the given segment end node B
%% #4 -> the definite proportion $\lambda$
%% #5 -> the target node C inside segment AB
%% #6 -> the target node C' outside segment AB
\def\pstProportionNode{\@ifnextchar[\Pst@ProportionNode{\Pst@ProportionNode[]}}
\def\Pst@ProportionNode[#1]{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \Pst@ProportionNode@i}
\def\Pst@ProportionNode@i#1#2#3#4#5{%
    \pst@getcoor{#1}\pst@tempA%
    \pst@getcoor{#2}\pst@tempB%
    \pnode(!
      \pst@tempA \tx@UserCoor % x1,y1
      \pst@tempB \tx@UserCoor % x2,y2
      #3 abs % \lambda
      4 index 1 index 4 index mul add 1 index 1 add div % (x1+\lambda*x2)/(1+\lambda)
      4 index 2 index 4 index mul add 2 index 1 add div % (y1+\lambda*y2)/(1+\lambda)
      7 2 roll pop pop pop pop pop
    ){#4}%
    \pnode(!
      \pst@tempA \tx@UserCoor % x1,y1
      \pst@tempB \tx@UserCoor % x2,y2
      #3 abs % \lambda
      dup 1 sub abs 1E-5 lt {
        pop pop pop pop pop 0 0
      } {
        4 index 1 index 4 index mul sub 1 index 1 exch sub div % (x1-\lambda*x2)/(1-\lambda)
        4 index 2 index 4 index mul sub 2 index 1 exch sub div % (y1-\lambda*y2)/(1-\lambda)
        7 2 roll pop pop pop pop pop
      } ifelse
    ){#5}%
    \Pst@ManageParamList{#4}%
    \Pst@ManageParamList{#5}%
  \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$.
%% Parameters:
%% #1 -> options
%% #2 -> the given collinear base node A
%% #3 -> the given collinear base node B
%% #4 -> the given collinear proportion node C
%% #5 -> the output proportion node D
\def\pstFourthHarmonicNode{\@ifnextchar[\Pst@FourthHarmonicNode{\Pst@FourthHarmonicNode[]}}
\def\Pst@FourthHarmonicNode[#1]{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \Pst@FourthHarmonicNode@i}
\def\Pst@FourthHarmonicNode@i#1#2#3#4{%
    \pst@getcoor{#1}\pst@tempA%
    \pst@getcoor{#2}\pst@tempB%
    \pst@getcoor{#3}\pst@tempC%
    \pnode(!
      \pst@tempA \tx@UserCoor % x1,y1
      \pst@tempB \tx@UserCoor % x2,y2
      \pst@tempC \tx@UserCoor % x3,y3
      5 index 4 index sub abs 1E-5 lt { % if x1=x2
        5 index 2 index sub abs 1E-5 lt { % if x1=x3
          4 index 1 index mul 3 index 2 index mul add 5 index 4 index mul 2 mul sub % y1y3+y2y3-2y1y2
          1 index 2 mul 6 index sub 4 index sub % 2y3-y1-y2
          dup abs 1E-5 lt {
            pop pop pop pop pop pop pop pop
            0 0
          } {
            div % y=\dfrac{y1y3+y2y3-2y1y2}{2y3-y1-y2}
            2 index exch % x=x3
            8 2 roll pop pop pop pop pop pop
          } ifelse
        } {
          % C is not collinear with AB.
          pop pop pop pop pop pop
          0 0
        } ifelse
      } {
        5 index 2 index sub abs 1E-5 lt { % if x1=x3
          pop pop pop pop pop pop 0 0
        } {
          2 index 5 index sub 4 index 7 index sub div % k(AB)=\dfrac{y2-y1}{x2-x1}
          4 index 6 index mul 7 index 5 index mul sub 5 index 8 index sub div % d(AB)=\dfrac{x2y1-x1y2}{x2-x1}
          2 index 7 index sub 4 index 9 index sub div % k(AC)=\dfrac{y3-y1}{x3-x1}
          4 index 8 index mul 9 index 5 index mul sub 5 index 10 index sub div % d(AC)=\dfrac{x3y1-x1y3}{x3-x1}
          3 index 2 index sub abs 1E-5 lt 3 index 2 index sub abs 1E-5 lt and { % k(AB)=k(AC) and d(AB)=d(AC)
            % x=\dfrac{x1x3+x2x3-2x1x2}{2x3-x1-x2}; y=k(AC)x+d(AC)
            9 index 6 index mul 8 index 7 index mul add 10 index 9 index mul 2 mul sub
            6 index 2 mul 11 index sub 9 index sub
            dup abs 1E-5 lt {
              pop pop pop pop pop pop
              pop pop pop pop pop pop
              0 0
            } {
              div
              2 index 1 index mul 2 index add
              12 2 roll pop pop pop pop pop
              pop pop pop pop pop
            } ifelse
          } {
            % C is not collinear with AB.
            pop pop pop pop pop pop pop pop
            0 0
          } ifelse
        } ifelse
      } ifelse
    ){#4}%
    \Pst@ManageParamList{#4}%
  \endgroup%
}%
%
%% \pstLine[Options]{node}{node}
%% \pstLine[Options]{node}(coor)
%% \pstLine[Options](coor){node}
%% \pstLine[Options](coor)(coor)
%% Create a new line with two nodes, or two coordinate or one node and one coordinate. This macro is similar with \pstLineAB, but more compatible.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the node or coordinate
%% #3 -> [input] the node or coordinate
\def\pstLine{\@ifnextchar[\Pst@Line{\Pst@Line[]}}
\def\Pst@Line[#1]{%
  \begingroup
  \psset{#1}%
  \@ifnextchar(\Pst@Line@i{\Pst@Line@j}}
\def\Pst@Line@i(#1){%
  \pnode(#1){@PSTLINE@AUXNODE@A}
  \@ifnextchar(\Pst@Line@ii{\Pst@Line@jj}}
\def\Pst@Line@j#1{%
  \pnode(#1){@PSTLINE@AUXNODE@A}
  \@ifnextchar(\Pst@Line@ii{\Pst@Line@jj}}
\def\Pst@Line@ii(#1){%
  \pnode(#1){@PSTLINE@AUXNODE@B}
  \ncline{@PSTLINE@AUXNODE@A}{@PSTLINE@AUXNODE@B}
  \endgroup}
\def\Pst@Line@jj#1{%
  \pnode(#1){@PSTLINE@AUXNODE@B}
  \ncline{@PSTLINE@AUXNODE@A}{@PSTLINE@AUXNODE@B}
  \endgroup}%
%
%% \pstLineAA[Options]{A}{angle}{B}
%% \pstLineAS[Options]{A}{gradient}{B}
%% Create a new line with Point A and the slope angle or the gradient. This macro will create the new node B on the line.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the point A on the line
%% #3 -> [input] the slope angle or the gradient
%% #4 -> [output] the new node B on the line
\def\pstLineAA{\@ifnextchar[\Pst@LineAA{\Pst@LineAA[]}}
\def\Pst@LineAA[#1]{%
  \begingroup
    \psset{#1}%
    \@ifnextchar(\Pst@LineAA@i{\Pst@LineAA@j}}
\def\Pst@LineAA@i(#1)#2#3{%
    \pnode(#1){@PSTLINEASAUX}
    \Pst@LineAA@k{@PSTLINEASAUX}{#2}{#3}}
\def\Pst@LineAA@j#1#2#3{%
    \pnode(#1){@PSTLINEASAUX}
    \Pst@LineAA@k{@PSTLINEASAUX}{#2}{#3}}
\def\Pst@LineAA@k#1#2#3{%
  \pnode(!
    \pstAbscissa{#1} #2 cos add
    \pstOrdinate{#1} #2 sin add
  ){#3}
  \Pst@geonodelabel{#3}%
  \pstLine{#1}{#3}
  \endgroup%
}%
%
\def\pstLineAS{\@ifnextchar[\Pst@LineAS{\Pst@LineAS[]}}
\def\Pst@LineAS[#1]{%
  \begingroup
    \psset{#1}%
    \@ifnextchar(\Pst@LineAS@i{\Pst@LineAS@j}}
\def\Pst@LineAS@i(#1)#2#3{%
    \pnode(#1){@PSTLINEASAUX}
    \Pst@LineAS@k{@PSTLINEASAUX}{#2}{#3}}
\def\Pst@LineAS@j#1#2#3{%
    \pnode(#1){@PSTLINEASAUX}
    \Pst@LineAS@k{@PSTLINEASAUX}{#2}{#3}}
\def\Pst@LineAS@k#1#2#3{%
  \pnode(!
    \pstAbscissa{#1} 1 add
    \pstOrdinate{#1} #2 add
  ){#3}
  \Pst@geonodelabel{#3}%
  \pstLine{#1}{#3}
  \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,
%% or use \pstAbscissa to get the abscissa of any node.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the line point A
%% #3 -> [input] the line point B
%% #4 -> [input] the abscissa value
%% #5 -> [output] the target node name
\def\pstLineAbsNode{\@ifnextchar[\Pst@LineAbsNode{\Pst@LineAbsNode[]}}
\def\Pst@LineAbsNode[#1]{%
  \begingroup
    \psset{#1}%
    \Pst@LineAbsNode@i}
\def\Pst@LineAbsNode@i#1#2#3#4{%
  \pnode(! #3 0){@LINEABSAUXA#1#2}\pnode(! #3 1){@LINEABSAUXB#1#2}%
  \pstInterLL{#1}{#2}{@LINEABSAUXA#1#2}{@LINEABSAUXB#1#2}{#4}%
  \Pst@geonodelabel{#4}%
  \endgroup%
}%
%
%% \pstLineOrdNode[Options]{A}{B}{$y_0$}{C}
%% Create a new node C on the line AB whose ordinate is the given value $y_0$.
%% You can input $y_0$ as any number(e.g, 2.0), and use \pscalculate{} to generate the value,
%% or use \pstOrdinate to get the ordinate of any node.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the line point A
%% #3 -> [input] the line point B
%% #4 -> [input] the ordinate value
%% #5 -> [output] the target node name
\def\pstLineOrdNode{\@ifnextchar[\Pst@LineOrdNode{\Pst@LineOrdNode[]}}
\def\Pst@LineOrdNode[#1]{%
  \begingroup
    \psset{#1}%
    \Pst@LineOrdNode@i}
\def\Pst@LineOrdNode@i#1#2#3#4{%
  \pnode(! 0 #3){@LINEORDAUXA#1#2}\pnode(! 1 #3){@LINEORDAUXB#1#2}%
  \pstInterLL{#1}{#2}{@LINEORDAUXA#1#2}{@LINEORDAUXB#1#2}{#4}%
  \Pst@geonodelabel{#4}%
  \endgroup%
}%
%
%% \pstLocateAB[Options]{A}{B}{distance}{C}
%% Locate node C on segment AB such that |AC|=distance, then create node C.
%% Note that locate C on BA will get the node C in the reverse order.
%% Parameters:
%% #1 -> options
%% #2 -> the given segment start node A
%% #3 -> the given segment end node B
%% #4 -> the specified length in screen coordinate
%% #5 -> the target node C
\def\pstLocateAB{\@ifnextchar[\Pst@LocateAB{\Pst@LocateAB[]}}
\def\Pst@LocateAB[#1]{%
  \begingroup
    \psset{#1}%
    \Pst@LocateAB@i}
\def\Pst@LocateAB@i#1#2#3#4{%
    \pst@getcoor{#1}\pst@tempA%
    \pst@getcoor{#2}\pst@tempB%
    \pnode(!
      \pst@tempA \tx@UserCoor % x1,y1
      \pst@tempB \tx@UserCoor % x2,y2
      #3 abs \pst@number\psxunit div % User distance
      4 index 3 index sub abs 1E-5 lt { % if x1=x2
        3 index 2 index lt { % if y1 < y2
          3 index 1 index add % y1 + l
        } {
          3 index 1 index sub % y1 - l
        } ifelse
        3 index exch
        7 2 roll pop pop pop pop pop
      } {
        1 index 4 index sub 3 index 6 index sub div % k = (y2-y1)/(x2-x1)
        1 index 1 index dup mul 1 add sqrt div % l/sqrt(k^2+1)
        4 index 7 index lt { % if x2<x1
          6 index exch sub % x1 - l/sqrt(k^2+1)
        } {
          6 index add % x1 + l/sqrt(k^2+1)
        } ifelse
        3 index 1 index 6 index sub 3 index mul add % y = y2+(x-x2)k
        8 2 roll pop pop pop pop pop pop
      } ifelse
    ){#4}%
    \Pst@geonodelabel{#4}%
  \endgroup%
}%
%
%% \pstLabelAB[Options]{A}{B}{label}
%% Print the label for segment AB.
%% Options:
%% - linestyle: the line style to control the ruler bar
%% - arrows: the line arrows to control the ruler bar
%% - offset: the seperation between label and segment
%% - nrot: the rotation of the label
%% - npos: the proportion of the label
\def\pstLabelAB{\pst@object{pstLabelAB}}
\def\pstLabelAB@i#1#2#3{%
  \begingroup
  \addbefore@par{linestyle=none,offset=10pt,nrot=:U,npos=0.5}% the defaults
  \use@par
  \if@star
    \ncline{#1}{#2}\ncput*{#3}%
  \else
    \ncline{#1}{#2}\ncput{#3}%
  \fi
  \endgroup
}%
%% \pstExtendAB[Options]{A}{B}{distance}{C}
%% Extend AB to C such that |BC|=distance, then create node C.
%% Note that extend BA to C will get the node C in the reverse order.
%% Parameters:
%% #1 -> options
%% #2 -> the given segment start node A
%% #3 -> the given segment end node B
%% #4 -> the specified length in screen coordinate
%% #5 -> the target node C
\def\pstExtendAB{\@ifnextchar[\Pst@ExtendAB{\Pst@ExtendAB[]}}
\def\Pst@ExtendAB[#1]{%
  \begingroup
    \psset{#1}%
    \Pst@ExtendAB@i}
\def\Pst@ExtendAB@i#1#2#3#4{%
    \pst@getcoor{#1}\pst@tempA%
    \pst@getcoor{#2}\pst@tempB%
    \pnode(!
      \pst@tempA \tx@UserCoor % x1,y1
      \pst@tempB \tx@UserCoor % x2,y2
      #3 abs \pst@number\psxunit div % User distance
      4 index 3 index sub abs 1E-5 lt { % if x1=x2
        3 index 2 index lt { % if y1 < y2
          1 index 1 index add % y2 + l
        } {
          1 index 1 index sub % y2 - l
        } ifelse
        3 index exch
        7 2 roll pop pop pop pop pop
      } {
        1 index 4 index sub 3 index 6 index sub div % k = (y2-y1)/(x2-x1)
        1 index 1 index dup mul 1 add sqrt div % l/sqrt(k^2+1)
        4 index 7 index lt { % if x2<x1
          4 index exch sub % x2 - l/sqrt(k^2+1)
        } {
          4 index add % x2 + l/sqrt(k^2+1)
        } ifelse
        3 index 1 index 6 index sub 3 index mul add % y = y2+(x-x2)k
        8 2 roll pop pop pop pop pop pop
      } ifelse
    ){#4}%
    \Pst@geonodelabel{#4}%
  \endgroup%
}%
%
%% \pstInversion[Options]{O}{A}{C}{C'}
%% Find the inversion point $C'$ of $C$ such that $|OC|*|OC'|=|OA|^2$, then create node $C'$.
%% We call $O$ as the inversion center, and |OA| as the inversion radius.
%% Parameters:
%% #1 -> options
%% #2 -> the inversion center O
%% #3 -> the inversion radius OA, or the specified Radius/Diameter if empty
%% #4 -> the initial node C
%% #5 -> the target node C'
\def\pstInversion{\@ifnextchar[\Pst@Inversion{\Pst@Inversion[]}}
\def\Pst@Inversion[#1]{%
  \begingroup
    \psset{#1}%
    \Pst@Inversion@i}
\def\Pst@Inversion@i#1#2#3#4{%
    \pstLocateAB{#1}{#3}{%
      tx@EcldDict begin /N@#1 GetNode /N@#3 GetNode ABDist end % |OC|
      % use Radius or Diameter to get the inversion radius.
      \ifx\psk@Radius\@none
        \ifx\psk@Diameter\@none
          tx@EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist end
        \else
          \psk@Diameter\space 2 div
        \fi
      \else
        \psk@Radius\space
      \fi
      dup mul exch div % |OA|^2/|OC|
    }{#4}
  \endgroup%
}%
%
%% \pstGeometricMean[Options]{A}{B}{l1}{l2}{C}
%% Find the point $C$ on segment AB such that $|AC|^2=l_1*l_2$, then create node $C$.
%% Parameters:
%% #1 -> options
%% #2 -> the first node A on the given segment
%% #3 -> the second node B on the given segment
%% #4 -> the given segment length l1
%% #5 -> the given segment length l2
%% #6 -> the target node C
\def\pstGeometricMean{\@ifnextchar[\Pst@GeometricMean{\Pst@GeometricMean[]}}
\def\Pst@GeometricMean[#1]{%
  \begingroup
    \psset{#1}%
    \Pst@GeometricMean@i}
\def\Pst@GeometricMean@i#1#2#3#4#5{%
    \pstLocateAB{#1}{#2}{#3 #4 mul sqrt}{#5}
  \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:
%% #1 -> options
%% #2 -> the first node A on the given segment
%% #3 -> the second node B on the given segment
%% #4 -> the given segment length l1
%% #5 -> the given segment length l2
%% #6 -> the target node C
\def\pstHarmonicMean{\@ifnextchar[\Pst@HarmonicMean{\Pst@HarmonicMean[]}}
\def\Pst@HarmonicMean[#1]{%
  \begingroup
    \psset{#1}%
    \Pst@HarmonicMean@i}
\def\Pst@HarmonicMean@i#1#2#3#4#5{%
    \pstLocateAB{#1}{#2}{#3 #4 2 copy mul 3 1 roll add div 2 mul}{#5}
  \endgroup%
}%
%
%% \pstCircleAbsNode[Options]{O}{A}{$x_0$}{C}{D}
%% Create the new nodes C and D on the Circle O whose abscissas are the given value $x_0$.
%% The circle O is defined by center O and point A on the circle or Radius in parameter.
%% You can input $x_0$ as any number(e.g, 2.0), and use \pscalculate{} to generate the value,
%% or use \pstAbscissa to get the abscissa of any node.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the circle center O
%% #3 -> [input] the circle point A or empty with Radius parameter
%% #4 -> [input] the abscissa value
%% #5 -> [output] the target node name
%% #6 -> [output] the target node name
\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(!
    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%
}%
%
%% \pstCircleOrdNode[Options]{O}{A}{$y_0$}{C}{D}
%% Create the new nodes C and D on the Circle O whose ordinates are the given value.
%% The circle O is defined by center O and point A on the circle or Radius in parameter.
%% You can input $y_0$ as any number(e.g, 2.0), and use \pscalculate{} to generate the value,
%% or use \pstOrdinate to get the ordinate of any node.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the circle center O
%% #3 -> [input] the circle point A or empty with Radius parameter
%% #4 -> [input] the ordinate value
%% #5 -> [output] the target node name
%% #6 -> [output] the target node name
\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(!
    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%
}%
%
%% \pstCircleNode[Options]{O}{A}{anglge}{X}
%% Create a new node X on the Circle O whose angle is the given value.
%% The circle O is defined by center O and point A on the circle or Radius in parameter.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the circle center O
%% #3 -> [input] the circle point A or empty with Radius parameter
%% #4 -> [input] the input angle value
%% #4 -> [output] the target node name
\def\pstCircleNode{\@ifnextchar[\Pst@CircleNode{\Pst@CircleNode[]}}
\def\Pst@CircleNode[#1]{%
  \begingroup
    \psset{#1}%
    \Pst@CircleNode@i}
\def\Pst@CircleNode@i#1#2#3#4{%
  \pnode(!
    tx@EcldDict begin
      /N@#1 GetNode
      \ifx\psk@Radius\@none
        \ifx\psk@Diameter\@none
          2 copy /N@#2 GetNode ABDist
        \else\psk@Diameter 2 div
        \fi
      \else\psk@Radius\space
      \fi
    end
    #3 dup sin exch cos
    2 index mul 4 index add \pst@number\psxunit\space div %
    5 1 roll mul add \pst@number\psyunit\space div exch pop%
  ){#4}%
  \Pst@geonodelabel{#4}%
  \endgroup%
}%
%
%% \pstCircleRotNode[Options]{O}{A}{X}
%% Create a new node X on the Circle O whose RotAngle is the given value.
%% The circle O is defined by center O and point A on the circle or Radius in parameter.
%% If you not set RotAngle, the default value is $60^\circ$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the circle center O
%% #3 -> [input] the circle point A or empty with Radius parameter
%% #4 -> [output] the target node name
\def\pstCircleRotNode{\@ifnextchar[\Pst@CircleRotNode{\Pst@CircleRotNode[]}}
\def\Pst@CircleRotNode[#1]{%
  \begingroup
    \psset{#1}%
    \Pst@CircleRotNode@i}
\def\Pst@CircleRotNode@i#1#2#3{%
  \pnode(!
    tx@EcldDict begin
      /N@#1 GetNode
      \ifx\psk@Radius\@none
        \ifx\psk@Diameter\@none
          2 copy /N@#2 GetNode ABDist
        \else\psk@Diameter 2 div
        \fi
      \else\psk@Radius\space
      \fi
    end
    \psk@RotAngle\space dup sin exch cos %
    2 index mul 4 index add \pst@number\psxunit\space div %
    5 1 roll mul add \pst@number\psyunit\space div exch pop%
  ){#3}%
  \Pst@geonodelabel{#3}%
  \endgroup%
}%
%
%% \pstCircleChordNode[Options]{O}{A}{L}{B}
%% Create a new node B on the Circle O such that the length of chord AB is the given value L.
%% The circle O is defined by center O and point A on the circle.
%% The direction can be controled by parameter CurvAbsNeg.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the circle center O
%% #3 -> [input] the point A on the circle
%% #4 -> [input] the given chord length
%% #5 -> [output] the target node name B
\def\pstCircleChordNode{\@ifnextchar[\Pst@CircleChordNode{\Pst@CircleChordNode[]}}
\def\Pst@CircleChordNode[#1]{%
  \begingroup
    \psset{#1}%
    \Pst@CircleChordNode@i}
\def\Pst@CircleChordNode@i#1#2#3#4{%
  \pst@getcoor{#1}\pst@tempO%
  \pst@getcoor{#2}\pst@tempA%
  \pnode(!
    \pst@tempO \tx@UserCoor % x0,y0
    \pst@tempA \tx@UserCoor % x1,y1
    1 index 4 index sub dup mul 1 index 4 index sub dup mul add sqrt % R
    1 index 4 index sub 3 index 6 index sub atan % RotAngle of A
    #3 \pst@number\psxunit\space div % chord length in user screen
    2 index 2 mul 1 index lt {
      pop pop pop pop pop pop pop 0 0
    } {
      0 index 3 index dup mul 4 mul 2 index dup mul sub sqrt atan 2 mul % tan(AOB/2)=d/sqrt(4r^2-d^2)
      \ifPst@CurvAbsNeg 2 index exch sub \else 2 index add \fi % RotAngle of B = RotAngle of A +/- <AOB
      dup sin exch cos % sin(B) cos(B)
      4 index mul 8 index add exch % x=r*cos(AOB)+x0
      4 index mul 7 index add % y=r*sin(AOB)+y0
      9 2 roll pop pop pop pop pop pop pop
    } ifelse
  ){#4}%
  \Pst@geonodelabel{#4}%
  \endgroup%
}%
%
%% \pstCircleTangentLine[Options]{O}{A}{T}
%% Draw the tangent line from A on the circle, and give the other node B on the line.
%% The circle O is defined by center O and point A on the circle.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the circle center O
%% #3 -> [input] the circle point A.
%% #4 -> [output] the target node name on the tangent line
\def\pstCircleTangentLine{\@ifnextchar[\Pst@CircleTangentLine{\Pst@CircleTangentLine[]}}
\def\Pst@CircleTangentLine[#1]{%
  \begingroup
    \psset{#1}%
    \Pst@CircleTangentLine@i}
\def\Pst@CircleTangentLine@i#1#2#3{%
  \pst@getcoor{#1}\pst@tempO%
  \pst@getcoor{#2}\pst@tempA%
  \pnode(!
    \pst@tempO \tx@UserCoor % x0,y0
    \pst@tempA \tx@UserCoor % x1,y1
    0 index 3 index sub abs 1E-5 lt { % if y1=y0
      1 index 1 index 1 add
      6 2 roll pop pop pop pop
    } {
      1 index 4 index sub abs 1E-5 lt { % if x1=x0
        1 index 1 add 1 index
        6 2 roll pop pop pop pop
      } {
        1 index 4 index sub % x1-x0
        1 index 4 index sub % y1-y0
        div neg 1 index add % -(x1-x0)/(y1-y0) + y1
        2 index 1 add % x=x1+1
        exch 6 2 roll pop pop pop pop
      } ifelse
    } ifelse
  ){#3}%
  \Pst@geonodelabel{#3}%
  \pstLine{#2}{#3}
  \endgroup%
}%
%
%% \pstCircleTangentNode[Options]{O}{A}{P}{T1}{T2}
%% Draw the tangent line from P out of the circle A(O), and give the two tangent nodes T1/T2 on the line.
%% The circle O is defined by center O and point A on the circle or Radius in parameter.
%% Suppose the coordinate of tangent node is (x,y), and node T is (a,b), the circle radius is r, then we have
%% $$(y-y0)(y-b)+(x-x0)(x-a)=0$$
%% but (x,y) is on the circle, so we have
%% $$x=rcos\theta+x_0, y=rcos\theta+y_0$$
%% then
%% $$(x_0-a)\cos\theta+(b-y_0)\sin\theta=r$$
%% if we take $e=a-x_0$, $f=b-y_0$, we have
%% $$(e^2+f^2)\sin^\theta-2rf\sin\theta+r^2-e^2=0$$
%% so
%% $$\sin\theta=\dfrac{rf\pm{}e\sqrt{e^2+f^2-r^2}}{e^2+f^2}$$
%% $$\cos\theta=\dfrac{re\mp{}f\sqrt{e^2+f^2-r^2}}{e^2+f^2}$$
%% Parameters:
%% #1 -> options
%% #2 -> [input] the circle center O
%% #3 -> [input] the circle point A or empty with Radius parameter
%% #4 -> [input] the node name T out of circle
%% #5 -> [output] the first target name on the circle
%% #6 -> [output] the second target name on the circle
\def\pstCircleTangentNode{\@ifnextchar[\Pst@CircleTangentNode{\Pst@CircleTangentNode[]}}
\def\Pst@CircleTangentNode[#1]{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \Pst@CircleTangentNode@i}
\def\Pst@CircleTangentNode@i#1#2#3#4#5{%
  \pst@getcoor{#1}\pst@tempO%
  \ifx\relax#2\relax\else\pst@getcoor{#2}\pst@tempV\fi%
  \pst@getcoor{#3}\pst@tempT%
  \pnode(!
    \pst@tempO \tx@UserCoor % x0,y0
    \pst@tempT \tx@UserCoor % a,b
    \ifx\psk@Radius\@none
      \ifx\psk@Diameter\@none
        \pst@tempV \tx@UserCoor % nx,ny
        4 index sub dup mul exch 5 index sub dup mul add sqrt
      \else\psk@Diameter\space 2 div \pst@number\psxunit div
      \fi
    \else\psk@Radius\space \pst@number\psxunit div
    \fi % r
    2 index 5 index sub % e=a-x0
    2 index 5 index sub % f=b-y0
    1 index dup mul 1 index dup mul add % e^2+f^2
    0 index 4 index dup mul sub
    dup abs 1E-5 lt {
      pop pop pop pop pop pop
      pop pop pop 0 0
    } {
      sqrt % sqrt(e^2+f^2-r^2)
      4 index 3 index mul 4 index 2 index mul sub 2 index div % \sin\theta
      5 index 5 index mul 4 index 3 index mul add 3 index div % \cos\theta
      6 index 1 index mul 11 index add % x_1
      7 index 3 index mul 11 index add % y_1
      13 2 roll pop pop pop pop pop
      pop pop pop pop pop pop
    } ifelse
  ){#4}%
  \pnode(!
    \pst@tempO \tx@UserCoor % x0,y0
    \pst@tempT \tx@UserCoor % a,b
    \ifx\psk@Radius\@none
      \ifx\psk@Diameter\@none
        \pst@tempV \tx@UserCoor % nx,ny
        4 index sub dup mul exch 5 index sub dup mul add sqrt
      \else\psk@Diameter\space 2 div \pst@number\psxunit div
      \fi
    \else\psk@Radius\space \pst@number\psxunit div
    \fi % r
    2 index 5 index sub % e=a-x0
    2 index 5 index sub % f=b-y0
    1 index dup mul 1 index dup mul add % e^2+f^2
    0 index 4 index dup mul sub
    dup abs 1E-5 lt {
      pop pop pop pop pop pop
      pop pop pop 0 0
    } {
      sqrt % sqrt(e^2+f^2-r^2)
      4 index 3 index mul 4 index 2 index mul add 2 index div % \sin\theta
      5 index 5 index mul 4 index 3 index mul sub 3 index div % \cos\theta
      6 index 1 index mul 11 index add % x_1
      7 index 3 index mul 11 index add % y_1
      13 2 roll pop pop pop pop pop
      pop pop pop pop pop pop
    } ifelse
  ){#5}%
  \Pst@ManageParamList{#4}%
  \Pst@ManageParamList{#5}%
  \pstLine{#3}{#4}
  \pstLine{#3}{#5}
  \endgroup%
}%
%
%% \pstCircleExternalCommonTangent[Options]{O1}{A}{O2}{B}{T1}{T2}{T3}{T4}
%% Find the external common tangent lines of the circle A(O1) and B(O2), mark the two tangent nodes T1/T2 on circle A(O1),
%% and the two tangent nodes T3/T4 on circle B(O2).
%% The circle A(O1) is defined by center O1 and point A on the circle or RadiusA/DiameterA in parameter.
%% The circle B(O1) is defined by center O2 and point B on the circle or RadiusB/DiameterB in parameter.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the first circle center O1
%% #3 -> [input] the first circle point A or empty with RadiusA/DiameterA parameter
%% #4 -> [input] the second circle center O2
%% #5 -> [input] the second circle point B or empty with RadiusB/DiameterB parameter
%% #6 -> [output] the first node name T1 lies on circle A(O1)
%% #7 -> [output] the second node name T2 lies on circle A(O1)
%% #8 -> [output] the first node name T3 lies on circle B(O2)
%% #9 -> [output] the second node name T4 lies on circle B(O2)
\def\pstCircleExternalCommonTangent{\@ifnextchar[\Pst@CircleExternalCommonTangent{\Pst@CircleExternalCommonTangent[]}}
\def\Pst@CircleExternalCommonTangent[#1]{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \Pst@CircleExternalCommonTangent@i}
\def\Pst@CircleExternalCommonTangent@i#1#2#3#4#5#6#7#8{%
    % use edef to save the second Radius or Diameter.
    \edef\pst@RadiusB@temp{\psk@RadiusB}
    \edef\pst@DiameterB@temp{\psk@DiameterB}
    % use RadiusA or DiameterA to find the intersection of A(O1) and O1O2.
    \ifx\psk@RadiusA\@undef
        \ifx\psk@DiameterA\@undef\relax\else
            \psset{Diameter=\psk@DiameterA}
        \fi
    \else\psset{Radius=\psk@RadiusA}\fi
    \pstInterLC[PointName=none,PointSymbol=none]{#1}{#3}{#1}{#2}{@PST@CIRCLE@INTER@A}{@PST@CIRCLE@INTER@C}
    % clear the used options
    \let\psk@Radius\@none\let\psk@Diameter\@none
    % use RadiusB or DiameterB to find the intersection of B(O2) and O1O2.
    \ifx\psk@RadiusB\@undef
        \ifx\psk@DiameterB\@undef\relax\else
            \psset{Diameter=\psk@DiameterB}
        \fi
    \else\psset{Radius=\psk@RadiusB}\fi
    \pstInterLC[PointName=none,PointSymbol=none]{#1}{#3}{#3}{#4}{@PST@CIRCLE@INTER@B}{@PST@CIRCLE@INTER@D}
    % clear the used options
    \let\psk@Radius\@none\let\psk@Diameter\@none
    \pstRotation[RotAngle=90,PointName=none,PointSymbol=none]{#1}{@PST@CIRCLE@INTER@A}[@PST@CIRCLE@INTER@AA]
    \pstRotation[RotAngle=90,PointName=none,PointSymbol=none]{#3}{@PST@CIRCLE@INTER@B}[@PST@CIRCLE@INTER@BB]
    \pstInterLL[PointName=none,PointSymbol=none]{#1}{#3}{@PST@CIRCLE@INTER@AA}{@PST@CIRCLE@INTER@BB}{@PST@CIRCLE@INTER@K}
    \pstMiddleAB[PointName=none,PointSymbol=none]{#1}{@PST@CIRCLE@INTER@K}{@PST@CIRCLE@CENTER@X}
    \pstMiddleAB[PointName=none,PointSymbol=none]{#3}{@PST@CIRCLE@INTER@K}{@PST@CIRCLE@CENTER@Y}
    % use RadiusA or DiameterA to find the intersection of A(O1) and K(X).
    % Note that we should set Radius to @none and set RadiusB and DiameterB to @undef.
    \ifx\psk@RadiusA\@undef\relax\else\psset{RadiusA=\psk@RadiusA}\fi
    \ifx\psk@RadiusA\@undef
        \ifx\psk@DiameterA\@undef\relax\else
            \psset{DiameterA=\psk@DiameterA}
        \fi
    \else\psset{RadiusA=\psk@RadiusA}\fi
    \let\psk@Radius\@none\let\psk@Diameter\@none
    \let\psk@RadiusB\@undef\let\psk@DiameterB\@undef
    \pstInterCC[PointName=none,PointSymbol=none]{#1}{#2}{@PST@CIRCLE@CENTER@X}{#1}{#5}{#6}
    % use RadiusB or DiameterB to find the intersection of B(O2) and K(Y).
    % Note that we should set Radius to @none and set RadiusB and DiameterB to @undef.
    \ifx\pst@RadiusB@temp\@undef
        \ifx\pst@DiameterB@temp\@undef\relax\else
            \psset{DiameterA=\pst@DiameterB@temp}
        \fi
    \else\psset{RadiusA=\pst@RadiusB@temp}\fi
    \let\psk@Radius\@none\let\psk@Diameter\@none
    \let\psk@RadiusB\@undef\let\psk@DiameterB\@undef
    \pstInterCC[PointName=none,PointSymbol=none]{#3}{#4}{@PST@CIRCLE@CENTER@Y}{#3}{#7}{#8}
    % CodeFig:
    %\pstLine{#1}{@PST@CIRCLE@INTER@AA}
    %\pstLine{#3}{@PST@CIRCLE@INTER@BB}
    %\pstLine{#1}{@PST@CIRCLE@INTER@K}
    %\pstLine{@PST@CIRCLE@INTER@K}{@PST@CIRCLE@INTER@AA}
    %\let\psk@Radius\@none\let\psk@Diameter\@none
    %\pstCircleOA[linestyle=dashed,linecolor=gray!30]{@PST@CIRCLE@CENTER@X}{#1}
    %\pstCircleOA[linestyle=dashed,linecolor=blue!30]{@PST@CIRCLE@CENTER@Y}{#3}
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
    \Pst@ManageParamList{#7}%
    \Pst@ManageParamList{#8}%
  \endgroup%
}%
%
%% \pstCircleInternalCommonTangent[Options]{O1}{A}{O2}{B}{T1}{T2}{T3}{T4}
%% Find the internal common tangent lines of the circle A(O1) and B(O2), mark the two tangent nodes T1/T2 on circle A(O1),
%% and the two tangent nodes T3/T4 on circle B(O2).
%% The circle A(O1) is defined by center O1 and point A on the circle or RadiusA/DiameterA in parameter.
%% The circle B(O1) is defined by center O2 and point B on the circle or RadiusB/DiameterB in parameter.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the first circle center O1
%% #3 -> [input] the first circle point A or empty with RadiusA/DiameterA parameter
%% #4 -> [input] the second circle center O2
%% #5 -> [input] the second circle point B or empty with RadiusB/DiameterB parameter
%% #6 -> [output] the first node name T1 lies on circle A(O1)
%% #7 -> [output] the second node name T2 lies on circle A(O1)
%% #8 -> [output] the first node name T3 lies on circle B(O2)
%% #9 -> [output] the second node name T4 lies on circle B(O2)
\def\pstCircleInternalCommonTangent{\@ifnextchar[\Pst@CircleInternalCommonTangent{\Pst@CircleInternalCommonTangent[]}}
\def\Pst@CircleInternalCommonTangent[#1]{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \Pst@CircleInternalCommonTangent@i}
\def\Pst@CircleInternalCommonTangent@i#1#2#3#4#5#6#7#8{%
    % use edef to save the second Radius or Diameter.
    \edef\pst@RadiusB@temp{\psk@RadiusB}
    \edef\pst@DiameterB@temp{\psk@DiameterB}
    % use RadiusA or DiameterA to find the intersection of A(O1) and O1O2.
    \ifx\psk@RadiusA\@undef
        \ifx\psk@DiameterA\@undef\relax\else
            \psset{Diameter=\psk@DiameterA}
        \fi
    \else\psset{Radius=\psk@RadiusA}\fi
    \pstInterLC[PointName=none,PointSymbol=none]{#1}{#3}{#1}{#2}{@PST@CIRCLE@INTER@A}{@PST@CIRCLE@INTER@C}
    % clear the used options
    \let\psk@Radius\@none\let\psk@Diameter\@none
    % use RadiusB or DiameterB to find the intersection of B(O2) and O1O2.
    \ifx\psk@RadiusB\@undef
        \ifx\psk@DiameterB\@undef\relax\else
            \psset{Diameter=\psk@DiameterB}
        \fi
    \else\psset{Radius=\psk@RadiusB}\fi
    \pstInterLC[PointName=none,PointSymbol=none]{#1}{#3}{#3}{#4}{@PST@CIRCLE@INTER@B}{@PST@CIRCLE@INTER@D}
    % clear the used options
    \let\psk@Radius\@none\let\psk@Diameter\@none
    \pstRotation[RotAngle=90,PointName=none,PointSymbol=none]{#1}{@PST@CIRCLE@INTER@A}[@PST@CIRCLE@INTER@AA]
    \pstRotation[RotAngle=-90,PointName=none,PointSymbol=none]{#3}{@PST@CIRCLE@INTER@B}[@PST@CIRCLE@INTER@BB]
    \pstInterLL[PointName=none,PointSymbol=none]{#1}{#3}{@PST@CIRCLE@INTER@AA}{@PST@CIRCLE@INTER@BB}{@PST@CIRCLE@INTER@K}
    \pstMiddleAB[PointName=none,PointSymbol=none]{#1}{@PST@CIRCLE@INTER@K}{@PST@CIRCLE@CENTER@X}
    \pstMiddleAB[PointName=none,PointSymbol=none]{#3}{@PST@CIRCLE@INTER@K}{@PST@CIRCLE@CENTER@Y}
    % use RadiusA or DiameterA to find the intersection of A(O1) and K(X).
    % Note that we should set Radius to @none and set RadiusB and DiameterB to @undef.
    \ifx\psk@RadiusA\@undef\relax\else\psset{RadiusA=\psk@RadiusA}\fi
    \ifx\psk@RadiusA\@undef
        \ifx\psk@DiameterA\@undef\relax\else
            \psset{DiameterA=\psk@DiameterA}
        \fi
    \else\psset{RadiusA=\psk@RadiusA}\fi
    \let\psk@Radius\@none\let\psk@Diameter\@none
    \let\psk@RadiusB\@undef\let\psk@DiameterB\@undef
    \pstInterCC[PointName=none,PointSymbol=none]{#1}{#2}{@PST@CIRCLE@CENTER@X}{#1}{#5}{#6}
    % use RadiusB or DiameterB to find the intersection of B(O2) and K(Y).
    % Note that we should set Radius to @none and set RadiusB and DiameterB to @undef.
    \ifx\pst@RadiusB@temp\@undef
        \ifx\pst@DiameterB@temp\@undef\relax\else
            \psset{DiameterA=\pst@DiameterB@temp}
        \fi
    \else\psset{RadiusA=\pst@RadiusB@temp}\fi
    \let\psk@Radius\@none\let\psk@Diameter\@none
    \let\psk@RadiusB\@undef\let\psk@DiameterB\@undef
    \pstInterCC[PointName=none,PointSymbol=none]{#3}{#4}{@PST@CIRCLE@CENTER@Y}{#3}{#7}{#8}
    % CodeFig:
    %\pstLine{#1}{@PST@CIRCLE@INTER@AA}
    %\pstLine{#3}{@PST@CIRCLE@INTER@BB}
    %\pstLine{#1}{@PST@CIRCLE@INTER@K}
    %\pstLine{@PST@CIRCLE@INTER@K}{@PST@CIRCLE@INTER@AA}
    %\let\psk@Radius\@none\let\psk@Diameter\@none
    %\pstCircleOA[linestyle=dashed,linecolor=gray!30]{@PST@CIRCLE@CENTER@X}{#1}
    %\pstCircleOA[linestyle=dashed,linecolor=blue!30]{@PST@CIRCLE@CENTER@Y}{#3}
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
    \Pst@ManageParamList{#7}%
    \Pst@ManageParamList{#8}%
  \endgroup%
}%
%
%% \pstCircleRadicalAxis[Options]{O1}{A}{O2}{B}{C}{D}
%% Draw the radical axis of the circle A(O1) and B(O2), and create two nodes $C$ and $D$ on the axis.
%% The circle A(O1) is defined by center O1 and point A on the circle or RadiusA/DiameterA in parameter.
%% The circle B(O1) is defined by center O2 and point B on the circle or RadiusB/DiameterB in parameter.
%% For any point P(x,y) on the radical axis, we have
%% $$(x-x_1)^2+(y-y_1)^2-r_1^2=(x-x_2)^2+(y-y_2)^2-r_2^2$$
%% case 1. when $x_1=x_2$, we have
%% $$2(y_2-y_1)y+y_1^2-r_1^2=y_2^2-r_2^2$$
%% case 1.1. when $y_1=y_2$, there is none radical axis.
%% case 1.2. else we have
%% $$y=\dfrac{(y_2^2-r_2^2)-(y_1^2-r_1^2)}{2(y_2-y_1)}$$
%% case 1.2.1. when $r_1^2-(y-y_1)^2<0$, there is none intersection of two circle, we select $x=x_1$ and $x=x_1+1$ at this time.
%% case 1.2.2. else we select $x=x_1\pm\sqrt{r_1^2-(y-y_1)^2}$
%% case 2. when $x_1\neq{}x_2$, we have
%% case 2.1. when $y_1=y_2$, we have
%% $$x=\dfrac{(x_2^2-r_2^2)-(x_1^2-r_1^2)}{2(x_2-x_1)}$$
%% case 2.1.1. when $r_1^2-(x-x_1)^2<0$, there is none intersection of two circle, we select $y=y_1$ and $y=y_1+1$ at this time.
%% case 2.1.2. else we select $y=y_1\pm\sqrt{r_1^2-(x-x_1)^2}$
%% case 2.2. else we have
%% $$2(x_2-x_1)x+2(y_2-y_1)y=(x_2^2+y_2^2-r_2^2)-(x_1^2+y_1^2-r_1^2)$$
%% set $a=2(x_2-x_1)$,$b=2(y_2-y_1)$,$m=x_2^2+y_2^2-r_2^2$,$n=x_1^2+y_1^2-r_1^2$, $d=m-n$,we have
%% $$ax+by=d$$
%% when $(x-x_1)^2+(y-y_1)^2-r_1^2=0$, let $X=x-x_1$, $Y=y-y_1$, we have
%% $$X^2+Y^2=r_1^2$$
%% and
%% $$aX+bY=d-ax_1-by_1$$
%% let $e=d-ax_1-by_1$, then
%% $$(a^2+b^2)X^2-2aeX+e^2-b^2r_1^2=0$$
%% case 2.2.1 when $(a^2+b^2)r_1^2-e^2>0$, we have
%% $$x=x_1+\dfrac{ae\pm{}b\sqrt{(a^2+b^2)r_1^2-e^2}}{a^2+b^2}$$
%% $$y=y_1+\dfrac{be\mp{}a\sqrt{(a^2+b^2)r_1^2-e^2}}{a^2+b^2}$$
%% case 2.2.2 else we select $x=\dfrac{r_1x_1+r_2x_2}{r_1+r_2}$ and $x=\dfrac{r_2x_1+r_1x_2}{r_1+r_2}$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the first circle center O1
%% #3 -> [input] the first circle point A or empty with RadiusA/DiameterA parameter
%% #4 -> [input] the second circle center O2
%% #5 -> [input] the second circle point B or empty with RadiusB/DiameterB parameter
%% #6 -> [output] the first node name C lies on radical axis
%% #7 -> [output] the second node name D lies on radical axis
\def\pstCircleRadicalAxis{\@ifnextchar[\Pst@CircleRadicalAxis{\Pst@CircleRadicalAxis[]}}
\def\Pst@CircleRadicalAxis[#1]{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \Pst@CircleRadicalAxis@i}
\def\Pst@CircleRadicalAxis@i#1#2#3#4#5#6{%
    \pst@getcoor{#1}\pst@tempA%
    \pst@getcoor{#3}\pst@tempB%
    \pnode(!
      \pst@tempA \tx@UserCoor % x1,y1
      \pst@tempB \tx@UserCoor % x2,y2
      \ifx\psk@RadiusA\@undef
         \ifx\psk@DiameterA\@undef
           tx@EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist end
         \else
           \psk@DiameterA\space 2 div
         \fi
      \else\psk@RadiusA\space\fi
      \pst@number\psxunit div %r1
      \ifx\psk@RadiusB\@undef
         \ifx\psk@DiameterB\@undef
           tx@EcldDict begin /N@#3 GetNode /N@#4 GetNode ABDist end
         \else
           \psk@DiameterB\space 2 div
         \fi
      \else\psk@RadiusB\space\fi
      \pst@number\psxunit div %r2
      5 index 4 index sub abs 1E-5 lt { % if x1=x2
        4 index 3 index sub abs 1E-5 lt { % if y1=y2
          pop pop pop pop pop pop 0 0
        } {
          % x1 y1 x2 y2 r1 r2
          2 index dup mul 1 index dup mul sub % y2^2-r2^2
          5 index dup mul 3 index dup mul sub % y1^2-r1^2
          sub 3 index 6 index sub 2 mul div % y=\dfrac{(y2^2-r2^2)-(y1^2-r1^2)}{2(y2-y1)}
          6 index 3 index dup mul 2 index 8 index sub dup mul sub
          dup 0 lt {
            pop % x=x1
          } {
            sqrt sub % x=x1\pm\sqrt{r1^2-(y-y1)^2)}
          } ifelse
          exch 8 2 roll pop pop pop pop pop pop
        } ifelse
      } {
        4 index 3 index sub abs 1E-5 lt { % if y1=y2
          % x1 y1 x2 y2 r1 r2
          3 index dup mul 1 index dup mul sub % x2^2-r2^2
          6 index dup mul 3 index dup mul sub % x1^2-r1^2
          sub 4 index 7 index sub 2 mul div % x=\dfrac{(x2^2-r2^2)-(x1^2-r1^2)}{2(x2-x1)}
          5 index 3 index dup mul 2 index 9 index sub dup mul sub
          dup 0 lt {
            pop % y=y1
          } {
            sqrt sub % y=y1\pm\sqrt{r1^2-(x-x1)^2)}
          } ifelse
          8 2 roll pop pop pop pop pop pop
        } {
          % x1 y1 x2 y2 r1 r2
          3 index dup mul 3 index dup mul add 1 index dup mul sub % m=x2^2+y2^2-r2^2
          6 index dup mul 6 index dup mul add 3 index dup mul sub % n=x1^2+y1^2-r1^2
          1 index 1 index sub % d=m-n
          6 index 9 index sub 2 mul % a=2(x2-x1)
          6 index 9 index sub 2 mul % b=2(y2-y1)
          2 index 2 index 12 index mul sub 1 index 11 index mul sub % e=d-ax1-by1
          2 index dup mul 2 index dup mul add 8 index dup mul mul 1 index dup mul sub % f=(a^2+b^2)r1^2-e^2
          dup 0 lt {
            % we select x=\dfrac{r1x1+r2x2}{r1+r2}
            8 index 13 index mul 8 index 12 index mul add 9 index 9 index add div % x
            % y=\dfrac{d-ax}{b}
            5 index 5 index 2 index mul sub 4 index div
            15 2 roll pop pop pop pop pop pop pop
            pop pop pop pop pop pop
          } {
            sqrt % sqrt(f)
            % x=x_1+\dfrac{ae\pm{}b\sqrt{(a^2+b^2)r_1^2-e^2}}{a^2+b^2}
            0 index 3 index mul 4 index 3 index mul exch sub 4 index dup mul 4 index dup mul add div 13 index add
            % y=y_1+\dfrac{be\mp{}a\sqrt{(a^2+b^2)r_1^2-e^2}}{a^2+b^2}
            1 index 5 index mul 4 index 4 index mul add 5 index dup mul 5 index dup mul add div 13 index add
            15 2 roll pop pop pop pop pop pop
            pop pop pop pop pop pop pop
          } ifelse
        } ifelse
      } ifelse
    ){#5}
    \pnode(!
      \pst@tempA \tx@UserCoor % x1,y1
      \pst@tempB \tx@UserCoor % x2,y2
      \ifx\psk@RadiusA\@undef
         \ifx\psk@DiameterA\@undef
           tx@EcldDict begin /N@#1 GetNode /N@#2 GetNode ABDist end
         \else
           \psk@DiameterA\space 2 div
         \fi
      \else\psk@RadiusA\space\fi
      \pst@number\psxunit div %r1
      \ifx\psk@RadiusB\@undef
         \ifx\psk@DiameterB\@undef
           tx@EcldDict begin /N@#3 GetNode /N@#4 GetNode ABDist end
         \else
           \psk@DiameterB\space 2 div
         \fi
      \else\psk@RadiusB\space\fi
      \pst@number\psxunit div %r2
      5 index 4 index sub abs 1E-5 lt { % if x1=x2
        4 index 3 index sub abs 1E-5 lt { % if y1=y2
          pop pop pop pop pop pop 0 0
        } {
          % x1 y1 x2 y2 r1 r2
          2 index dup mul 1 index dup mul sub % y2^2-r2^2
          5 index dup mul 3 index dup mul sub % y1^2-r1^2
          sub 3 index 6 index sub 2 mul div % y=\dfrac{(y2^2-r2^2)-(y1^2-r1^2)}{2(y2-y1)}
          6 index 3 index dup mul 2 index 8 index sub dup mul sub
          dup 0 lt {
            pop 1 add % x=x1+1
          } {
            sqrt add % x=x1\pm\sqrt{r1^2-(y-y1)^2)}
          } ifelse
          exch 8 2 roll pop pop pop pop pop pop
        } ifelse
      } {
        4 index 3 index sub abs 1E-5 lt { % if y1=y2
          3 index dup mul 1 index dup mul sub % x2^2-r2^2
          6 index dup mul 3 index dup mul sub % x1^2-r1^2
          sub 4 index 7 index sub 2 mul div % x=\dfrac{(x2^2-r2^2)-(x1^2-r1^2)}{2(x2-x1)}
          5 index 3 index dup mul 2 index 9 index sub dup mul sub
          dup 0 lt {
            pop 1 add % y=y1+1
          } {
            sqrt add % y=y1\pm\sqrt{r1^2-(x-x1)^2)}
          } ifelse
          8 2 roll pop pop pop pop pop pop
        } {
          % x1 y1 x2 y2 r1 r2
          3 index dup mul 3 index dup mul add 1 index dup mul sub % m=x2^2+y2^2-r2^2
          6 index dup mul 6 index dup mul add 3 index dup mul sub % n=x1^2+y1^2-r1^2
          1 index 1 index sub % d=m-n
          6 index 9 index sub 2 mul % a=2(x2-x1)
          6 index 9 index sub 2 mul % b=2(y2-y1)
          2 index 2 index 12 index mul sub 1 index 11 index mul sub % e=d-ax1-by1
          2 index dup mul 2 index dup mul add 8 index dup mul mul 1 index dup mul sub % f=(a^2+b^2)r1^2-e^2
          dup 0 lt {
            % we select x=\dfrac{r2x1+r1x2}{r1+r2}
            7 index 13 index mul 9 index 12 index mul add 9 index 9 index add div % x
            % y=\dfrac{d-ax}{b}
            5 index 5 index 2 index mul sub 4 index div
            15 2 roll pop pop pop pop pop pop pop
            pop pop pop pop pop pop
          } {
            sqrt % sqrt(f)
            % x=x_1+\dfrac{ae\pm{}b\sqrt{(a^2+b^2)r_1^2-e^2}}{a^2+b^2}
            0 index 3 index mul 4 index 3 index mul add 4 index dup mul 4 index dup mul add div 13 index add
            % y=y_1+\dfrac{be\mp{}a\sqrt{(a^2+b^2)r_1^2-e^2}}{a^2+b^2}
            1 index 5 index mul 4 index 4 index mul exch sub 5 index dup mul 5 index dup mul add div 13 index add
            15 2 roll pop pop pop pop pop pop
            pop pop pop pop pop pop pop
          } ifelse
        } ifelse
      } ifelse
    ){#6}
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
    \pstLineAB{#5}{#6}%
  \endgroup%
}%
%
%% \pstCircleABR[Options]{A}{B}{R}{O}
%% Draw a circle with node A and node B on it, and Radius R, output the center O.
%% Parameters:
%% #1 -> options
%% #2 -> the input node A
%% #3 -> the input node B
%% #4 -> the input radius length in screen coordinate
%% #5 -> the output center O
\def\pstCircleABR{\@ifnextchar[\Pst@CircleABR{\Pst@CircleABR[]}}%
\def\Pst@CircleABR[#1]#2#3#4#5{%
  \begingroup%
  \psset{#1}
  \pst@getcoor{#2}\pst@tempA%
  \pst@getcoor{#3}\pst@tempB%
  \pnode(!
    \pst@tempA \tx@UserCoor /y1 ED /x1 ED
    \pst@tempB \tx@UserCoor /y2 ED /x2 ED
    \pstUserDist{#4}\space /R ED
    x2 x1 sub abs 1E-5 lt { % if x1=x2
      y2 y1 sub abs 1E-5 lt { % if y1=y2
        0 0
      } {
        y2 y1 add 2 div /y0 ED
        y2 y1 lt {
          R dup mul y1 y0 sub dup mul sub sqrt x1 add /x0 ED
        } {
          R dup mul y1 y0 sub dup mul sub sqrt neg x1 add /x0 ED
        } ifelse
        x0 y0
      } ifelse
    } {
      x2 dup mul x1 dup mul sub y2 dup mul y1 dup mul sub add x2 x1 sub div 2 div /Consta ED
      y2 y1 sub x2 x1 sub div /Constb ED
      Constb dup mul 1 add /CoefA ED
      x1 Consta sub 2 mul Constb mul y1 2 mul sub /CoefB ED
      x1 Consta sub dup mul y1 dup mul add R dup mul sub /CoefC ED
      x1 x2 lt {
        CoefB dup mul CoefA CoefC mul 4 mul sub sqrt CoefB sub CoefA 2 mul div /y0 ED
      } {
        CoefB dup mul CoefA CoefC mul 4 mul sub sqrt neg CoefB sub CoefA 2 mul div /y0 ED
      } ifelse
      Consta Constb y0 mul sub /x0 ED
      x0 y0
    } ifelse
  ){#5}
  \Pst@geonodelabel{#5}
  \pstCircleOA{#5}{#2}
  \endgroup%
}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Regular Polygons
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% \pstETriangleAB[Options]{A}{B}{C}
%% Draw an equilateral triangle ABC on given side AB in anti-clockwise.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the node A
%% #3 -> [input] the node B
%% #4 -> [output] the node C
\def\pstETriangleAB{\@ifnextchar[\Pst@ETriangleAB{\Pst@ETriangleAB[]}}
\def\Pst@ETriangleAB[#1]#2#3#4{%
  \begingroup
    \psset{#1}%
    \pstRotation[RotAngle=60,PointName=none,PointSymbol=none]{#2}{#3}[#4]
    \Pst@geonodelabel{#4}
    \pstPolygon(#2)(#3)(#4)%
  \endgroup
}
%
%% \pstSquareAB[Options]{A}{B}{C}{D}
%% Draw a square ABCD on given side AB in anti-clockwise.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the node A
%% #3 -> [input] the node B
%% #4 -> [output] the node C
%% #5 -> [output] the node D
\def\pstSquareAB{\@ifnextchar[\Pst@SquareAB{\Pst@SquareAB[]}}
\def\Pst@SquareAB[#1]#2#3#4#5{%
  \begingroup
    \@InitListMng%
    \psset{#1}%
    \pstRotation[RotAngle=90,PointName=none,PointSymbol=none]{#2}{#3}[#5]
    \pstRotation[RotAngle=-90,PointName=none,PointSymbol=none]{#3}{#2}[#4]
    \Pst@ManageParamList{#4}%
    \Pst@ManageParamList{#5}%
    \pstPolygon(#2)(#3)(#4)(#5)%
  \endgroup
}
%
%% \pstRegularPolygonAB[Options]{A_0}{A_1}{n}{A_2,A_3,A_4,...,A_{n-1}}
%% Draw a $n$ side regular polygon with given side $A_0A_1$, output the other points.
%% Parameters:
%% #1 -> options
%% #2 -> the input node A_0
%% #3 -> the input node A_1
%% #4 -> the input side number n
%% #5 -> the output points A_2,A_3,A_4,...,A_{n-1}
\def\pstRegularPolygonAB{\@ifnextchar[\Pst@RegularPolygonAB{\Pst@RegularPolygonAB[]}}%
\def\Pst@RegularPolygonAB[#1]#2#3#4{%
  \bgroup%
  \@InitListMng%
  \def\@PolyPointA{#2}\def\@PolyPointB{#3}\def\@PointLast{#3}%
  \pst@cnth=#4\pst@cntg=2 % next point idx (start from 0)
  \edef\@@GenCourbe{(#2)(#3)}%%for accumulating points
  \ifPst@CodeFig
    \pstCircleABR[PointName=O,PosAngle=-90,PointSymbol=*,linecolor=\psk@CodeFigColor,linestyle=\psk@CodeFigStyle]{#2}{#3}{\pstDist{#2}{#3} 2 div 180 #4 div sin div}{PolyCenter}
  \else
    \pstCircleABR[PointName=none,PointSymbol=none,linestyle=none]{#2}{#3}{\pstDist{#2}{#3} 2 div 180 #4 div sin div}{PolyCenter}
  \fi
  \psset{#1} % use parameters after calling \pstCircleABR.
  \Pst@RegularPolygonAB@i%
}%
\def\Pst@RegularPolygonAB@i#1{%
  \@List{#1}\edef\@PointOutLst{\@NewList}
  \edef\@point{\expandafter\PstParamListFirst\@PointOutLst,undef/}
  \Pst@RegularPolygonAB@iii%
}%
\def\Pst@RegularPolygonAB@iii{%
  \ifx\@point\@undef\def\@point{\@PolyPointB\the\pst@cntg}\fi
  \pstCircleChordNode[PointName=none,PointSymbol=none]{PolyCenter}{\@PointLast}{\pstDist{\@PolyPointA}{\@PolyPointB}}{\@point}
  \xdef\@@GenCourbe{\@@GenCourbe(\@point)}%%for accumulating points
  %\typeout{\@@GenCourbe}
  \Pst@ManageParamList{\@point}\xdef\@PointLast{\@point}%
  \edef\@PointOutLst{\expandafter\PstParamListLasts\@PointOutLst,undef/}%
  \advance\pst@cntg by 1
  \edef\@point{\expandafter\PstParamListFirst\@PointOutLst,undef/}
  \ifnum\pst@cntg<\pst@cnth%
    \def\@End{\Pst@RegularPolygonAB@iii}
  \else
    \def\@End{\pst@MngTransformCurve\egroup}
  \fi%
  \@End%
}%
%
%% \pstRegularPolygonOA[Options]{O}{A_0}{n}{A_1,A_2,A_3,...,A_{n-1}}
%% Draw a $n$ side regular polygon with given center O and the first node $A_1$, output the other points.
%% Parameters:
%% #1 -> options
%% #2 -> the input center node O
%% #3 -> the input first node A_0
%% #4 -> the input side number n
%% #5 -> the output points A_1,A_2,A_3,...,A_{n-1}
\def\pstRegularPolygonOA{\@ifnextchar[\Pst@RegularPolygonOA{\Pst@RegularPolygonOA[]}}%
\def\Pst@RegularPolygonOA[#1]#2#3#4{%
  \bgroup%
  \@InitListMng%
  \psset{#1}\def\@PolyCenter{#2}\def\@PolyPointA{#3}\def\@PointLast{#3}\def\@PolySideNum{#4}%
  \pst@cnth=#4\pst@cntg=1 % next point idx (start from 0)
  \edef\@@GenCourbe{(#3)}%%for accumulating points
  \Pst@RegularPolygonOA@i%
}%
\def\Pst@RegularPolygonOA@i#1{%
  \@List{#1}\edef\@PointOutLst{\@NewList}
  \edef\@point{\expandafter\PstParamListFirst\@PointOutLst,undef/}
  \Pst@RegularPolygonOA@iii%
}%
\def\Pst@RegularPolygonOA@iii{%
  \ifx\@point\@undef\def\@point{\@PolyPointA\the\pst@cntg}\fi
  \pstCircleChordNode[PointName=none,PointSymbol=none]{\@PolyCenter}{\@PointLast}{\pstDist{\@PolyCenter}{\@PolyPointA} 180 \@PolySideNum\space div sin mul 2 mul}{\@point}
  \xdef\@@GenCourbe{\@@GenCourbe(\@point)}%%for accumulating points
  %\typeout{\@@GenCourbe}
  \Pst@ManageParamList{\@point}\xdef\@PointLast{\@point}%
  \edef\@PointOutLst{\expandafter\PstParamListLasts\@PointOutLst,undef/}%
  \advance\pst@cntg by 1
  \edef\@point{\expandafter\PstParamListFirst\@PointOutLst,undef/}
  \ifnum\pst@cntg<\pst@cnth%
    \def\@End{\Pst@RegularPolygonOA@iii}
  \else
    \def\@End{\pst@MngTransformCurve\egroup}
  \fi%
  \@End%
}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Here are some functions to operate the conic curves.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% 1. Standard Ellipse with coordinate translation
%% ----------------------------------------------------------
%% The Ellipse E is defined by center O, the half of the major axis $max(abs(a),abs(b))$,
%% the half of the minor axis $min(abs(a),abs(b))$, the equation as following:
%% \begin{equation}\label{FunctionOfStandardEllipse}
%% \dfrac{(x-x_o)^2}{a^2}+\dfrac{(y-y_o)^2}{b^2}=1
%% \end{equation}
%% Sometimes we use the parametric function of the ellipse:
%% \begin{equation}\label{ParametricFunctionOfEllipse}
%% \left\{\begin{array}{l}
%% x=a\cos\alpha+x_o\\
%% y=b\sin\alpha+y_0
%% \end{array}\right.
%% \end{equation}
%
%% \pstEllipse[Options](O)(a,b)[angleA][angleB]
%% Draw a Ellipse with center O from angleA to angleB, going counter clockwise,
%% the half of the major axis $max(abs(a),abs(b))$, and the half of the minor axis $min(abs(a),abs(b))$.
%% This macro is like \psellipse and \psellipticarc in \PST.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the ellipse center O
%% #3 -> [input] the horizontal and vertical radii
%% #4 -> [input] start angle from angleA to angleB, going counter clockwise.
%% #5 -> [input] start angle from angleA to angleB, going counter clockwise.
\def\pstEllipse{\@ifnextchar[\Pst@Ellipse{\Pst@Ellipse[]}}
\def\Pst@Ellipse[#1](#2)(#3){%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@Ellipse@i{\Pst@Ellipse@i[0][360]}}%
\def\Pst@Ellipse@i[#1][#2]{%
    \parametricplot{#1}{#2}{%
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      3 index 2 index t cos mul add % x0+a\cos{t}
      3 index 2 index t sin mul add % y0+b\sin{t}
      6 2 roll pop pop pop pop
    }%
  \endgroup%
}%
%
%% \pstEllipseNode[Options](O)(a,b){t}{P}
%% Create a new node P on the Ellipse E whose parameter is the given value $t$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the ellipse center O
%% #3 -> [input] the horizontal and vertical radii
%% #4 -> [input] the parametric argument t.
%% #5 -> [output] the target node name.
\def\pstEllipseNode{\@ifnextchar[\Pst@pstEllipseNode{\Pst@pstEllipseNode[]}}
\def\Pst@pstEllipseNode[#1](#2)(#3)#4#5{%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      3 index 2 index #4 cos mul add % x0+a\cos{t}
      3 index 2 index #4 sin mul add % y0+b\sin{t}
      6 2 roll pop pop pop pop
    ){#5}%
    \Pst@geonodelabel{#5}%
  \endgroup%
}%
%
%% \pstEllipseRotNode[Options](O)(a,b){P}
%% Create a new node P on the Ellipse E whose RotAngle is the given value.
%% If you not set RotAngle, the default value is $60^\circ$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the ellipse center O
%% #3 -> [input] the horizontal and vertical radii
%% #4 -> [output] the target node name
\def\pstEllipseRotNode{\@ifnextchar[\Pst@EllipseRotNode{\Pst@EllipseRotNode[]}}
\def\Pst@EllipseRotNode[#1]{%
  \begingroup
    \psset{#1}%
    \Pst@EllipseRotNode@i}
\def\Pst@EllipseRotNode@i(#1)(#2)#3{%
  \pst@getcoor{#1}\pst@tempO%
  \pst@getcoor{#2}\pst@tempR%
  \pnode(!
    \pst@tempO \tx@UserCoor % x_o,y_o
    \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
    3 index 2 index \psk@RotAngle\space cos mul add % x0+a\cos{t}
    3 index 2 index \psk@RotAngle\space sin mul add % y0+b\sin{t}
    6 2 roll pop pop pop pop
  ){#3}%
  \Pst@geonodelabel{#3}%
  \endgroup%
}%
%
%% \pstEllipseAbsNode[Options](O)(a,b){x_1}{A}{B}
%% Create the two nodes A and B whose abscissas are the given value $x_1$ on the Ellipse E.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the ellipse center O
%% #3 -> [input] the horizontal and vertical radii
%% #4 -> [input] the given abscissa value $x_1$
%% #5 -> [output] the first target node name $A$
%% #6 -> [output] the second target node name $B$
\def\pstEllipseAbsNode{\@ifnextchar[\Pst@EllipseAbsNode{\Pst@EllipseAbsNode[]}}
\def\Pst@EllipseAbsNode[#1]{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \Pst@EllipseAbsNode@i}
\def\Pst@EllipseAbsNode@i(#1)(#2)#3#4#5{%
  \pst@getcoor{#1}\pst@tempO%
  \pst@getcoor{#2}\pst@tempR%
  \pnode(!
    \pst@tempO \tx@UserCoor % x_o,y_o
    \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
    #3 % x_1
    2 index dup mul 1 index 6 index sub dup mul sub % a^2-(x_1-x_o)^2
    dup 0 lt {
      pop pop pop pop pop pop 0 0
    }{
      sqrt 2 index mul 3 index div % b/a sqrt(a^2-(x_1-x_o)^2)
      4 index exch sub % y_o-ditto
      6 2 roll pop pop pop pop
    } ifelse
  ){#4}%
  \pnode(!
    \pst@tempO \tx@UserCoor % x_o,y_o
    \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
    #3 % x_1
    2 index dup mul 1 index 6 index sub dup mul sub % a^2-(x_1-x_o)^2
    dup 0 lt {
      pop pop pop pop pop pop 0 0
    }{
      sqrt 2 index mul 3 index div % b/a sqrt(a^2-(x_1-x_o)^2)
      4 index add % y_o+ditto
      6 2 roll pop pop pop pop
    } ifelse
  ){#5}%
  \Pst@ManageParamList{#4}%
  \Pst@ManageParamList{#5}%
  \endgroup%
}%
%
%% \pstEllipseOrdNode[Options](O)(a,b){y_1}{A}{B}
%% Create the two nodes A and B whose ordinates are the given value $y_1$ on the Ellipse E.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the ellipse center O
%% #3 -> [input] the horizontal and vertical radii
%% #4 -> [input] the given ordinate value $y_1$
%% #5 -> [output] the first target node name $A$
%% #6 -> [output] the second target node name $B$
\def\pstEllipseOrdNode{\@ifnextchar[\Pst@EllipseOrdNode{\Pst@EllipseOrdNode[]}}
\def\Pst@EllipseOrdNode[#1]{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \Pst@EllipseOrdNode@i}
\def\Pst@EllipseOrdNode@i(#1)(#2)#3#4#5{%
  \pst@getcoor{#1}\pst@tempO%
  \pst@getcoor{#2}\pst@tempR%
  \pnode(!
    \pst@tempO \tx@UserCoor % x_o,y_o
    \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
    #3 % y_1
    1 index dup mul 1 index 5 index sub dup mul sub % b^2-(y_1-y_o)^2
    dup 0 lt {
      pop pop pop pop pop pop 0 0
    }{
      sqrt 3 index mul 2 index div % a/b sqrt(b^2-(y_1-y_o)^2)
      5 index exch sub % x_o-ditto
      exch 6 2 roll pop pop pop pop
    } ifelse
  ){#4}%
  \pnode(!
    \pst@tempO \tx@UserCoor % x_o,y_o
    \pst@tempR \tx@UserCoor % a,b
    abs exch abs exch % |a|,|b|
    #3 % y_1
    1 index dup mul 1 index 5 index sub dup mul sub % b^2-(y_1-y_o)^2
    dup 0 lt {
      pop pop pop pop pop pop 0 0
    }{
      sqrt 3 index mul 2 index div % a/b sqrt(b^2-(y_1-y_o)^2)
      5 index add % x_o+ditto
      exch 6 2 roll pop pop pop pop
    } ifelse
  ){#5}%
  \Pst@ManageParamList{#4}%
  \Pst@ManageParamList{#5}%
  \endgroup%
}%
%
%% \pstEllipseFocusNode[Options](O)(a,b){$F_1$}{$F_2$}
%% Get the two focus $F_1$ and $F_2$ point of the Ellipse E and create two new nodes.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the ellipse center O
%% #3 -> [input] the horizontal and vertical radii
%% #4 -> [output] the left/down node name
%% #5 -> [output] the right/up node name
\def\pstEllipseFocusNode{\@ifnextchar[\Pst@EllipseFocusNode{\Pst@EllipseFocusNode[]}}
\def\Pst@EllipseFocusNode[#1]{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \Pst@EllipseFocusNode@i}
\def\Pst@EllipseFocusNode@i(#1)(#2)#3#4{%
  \pst@getcoor{#1}\pst@tempO%
  \pst@getcoor{#2}\pst@tempR%
  \pnode(!
    \pst@tempO % x0,y0
    \pst@tempR % a,b
    abs exch abs exch % |a|,|b|
    2 copy gt {% Focus on haxis
    1 index dup mul 1 index dup mul sub sqrt % c=sqrt(a^2-b^2)
    4 index exch sub % x0-c
    3 index 6 2 roll pop pop pop pop % Left(x0-c,y0)
    }{% Focus on vaxis
    0 index dup mul 2 index dup mul sub sqrt % c=sqrt(b^2-a^2)
    3 index exch sub % y0-c
    4 index exch 6 2 roll pop pop pop pop % Down(x0,y0-c)
    } ifelse
    \tx@UserCoor %
  ){#3}%
  \pnode(!
    \pst@tempO % x0,y0
    \pst@tempR % a,b
    abs exch abs exch % |a|,|b|
    2 copy gt {% Focus on haxis
    1 index dup mul 1 index dup mul sub sqrt % c=sqrt(a^2-b^2)
    4 index add % x0+c
    3 index 6 2 roll pop pop pop pop % Right(x0+c,y0)
    }{% Focus on vaxis
    0 index dup mul 2 index dup mul sub sqrt % c=sqrt(b^2-a^2)
    3 index add % y0+c
    4 index exch 6 2 roll pop pop pop pop % Up(x0,y0+c)
    } ifelse
    \tx@UserCoor %
  ){#4}%
  \Pst@ManageParamList{#3}%
  \Pst@ManageParamList{#4}%
  \endgroup%
}%
%
%% \pstEllipseDirectrixLine[Options](O)(a,b){Lx}{Ly}{Rx}{Ry}
%% Get the two directrix line of the Ellipse E and create two new nodes on each of them.
%% the nodes Lx Ly Rx Ry lie on the tangent line of the vertex on the other axis.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the ellipse center O
%% #3 -> [input] the horizontal and vertical radii
%% #4 -> [output] the A node name on the left/down directrix line
%% #5 -> [output] the B node name on the left/down directrix line
%% #6 -> [output] the A node name on the right/up directrix line
%% #7 -> [output] the B node name on the right/up directrix line
\def\pstEllipseDirectrixLine{\@ifnextchar[\Pst@EllipseDirectrixLine{\Pst@EllipseDirectrixLine[]}}
\def\Pst@EllipseDirectrixLine[#1]{%
  \begingroup
    \@InitListMng %
    \psset{#1} %
    \Pst@EllipseDirectrixLine@i}
\def\Pst@EllipseDirectrixLine@i(#1)(#2)#3#4#5#6{%
  \pst@getcoor{#1}\pst@tempO%
  \pst@getcoor{#2}\pst@tempR%
  \pnode(!
    \pst@tempO % x0,y0
    \pst@tempR % a,b
    abs exch abs exch % |a|,|b|
    2 copy gt {% left directrix line perpendicular to the haxis
    1 index dup mul 1 index dup mul sub sqrt % c=sqrt(a^2-b^2)
    2 index dup mul exch div % a^2/c
    4 index exch sub % x0-a^2/c
    3 index 2 index sub % y0-b
    6 2 roll pop pop pop pop % First A(x0-a^2/c,y0-b)
    }{% down directrix line perpendicular to the vaxis
    0 index dup mul 2 index dup mul sub sqrt % c=sqrt(b^2-a^2)
    1 index dup mul exch div % b^2/c
    3 index exch sub % y0-b^2/c
    4 index 3 index sub % x0-a
    exch 6 2 roll pop pop pop pop % Fisrt A(x0-a,y0-b^2/c)
    } ifelse
    \tx@UserCoor %
  ){#3}%
  \pnode(!
    \pst@tempO % x0,y0
    \pst@tempR % a,b
    abs exch abs exch % |a|,|b|
    2 copy gt {% left directrix line perpendicular to the haxis
    1 index dup mul 1 index dup mul sub sqrt % c=sqrt(a^2-b^2)
    2 index dup mul exch div % a^2/c
    4 index exch sub % x0-a^2/c
    3 index 2 index add % y0+b
    6 2 roll pop pop pop pop % First B(x0-a^2/c,y0+b)
    }{% down directrix line perpendicular to the vaxis
    0 index dup mul 2 index dup mul sub sqrt % c=sqrt(b^2-a^2)
    1 index dup mul exch div % b^2/c
    3 index exch sub % y0-b^2/c
    4 index 3 index add % x0+a
    exch 6 2 roll pop pop pop pop % Fisrt B(x0+a,y0-b^2/c)
    } ifelse
    \tx@UserCoor %
  ){#4}%
  \pnode(!
    \pst@tempO % x0,y0
    \pst@tempR % a,b
    abs exch abs exch % |a|,|b|
    2 copy gt {% right directrix line perpendicular to the haxis
    1 index dup mul 1 index dup mul sub sqrt % c=sqrt(a^2-b^2)
    2 index dup mul exch div % a^2/c
    4 index add % x0+a^2/c
    3 index 2 index sub % y0-b
    6 2 roll pop pop pop pop % Second A(x0+a^2/c,y0-b)
    }{% up directrix line perpendicular to the vaxis
    0 index dup mul 2 index dup mul sub sqrt % c=sqrt(b^2-a^2)
    1 index dup mul exch div % b^2/c
    3 index add % y0+b^2/c
    4 index 3 index sub % x0-a
    exch 6 2 roll pop pop pop pop % Second A(x0-a,y0+b^2/c)
    } ifelse
    \tx@UserCoor %
  ){#5}%
  \pnode(!
    \pst@tempO % x0,y0
    \pst@tempR % a,b
    abs exch abs exch % |a|,|b|
    2 copy gt {% right directrix line perpendicular to the haxis
    1 index dup mul 1 index dup mul sub sqrt % c=sqrt(a^2-b^2)
    2 index dup mul exch div % a^2/c
    4 index add % x0+a^2/c
    3 index 2 index add % y0+b
    6 2 roll pop pop pop pop % Second B(x0+a^2/c,y0+b)
    }{% up directrix line perpendicular to the vaxis
    0 index dup mul 2 index dup mul sub sqrt % c=sqrt(b^2-a^2)
    1 index dup mul exch div % b^2/c
    3 index add % y0+b^2/c
    4 index 3 index add % x0+a
    exch 6 2 roll pop pop pop pop % Second B(x0+a,y0+b^2/c)
    } ifelse
    \tx@UserCoor %
  ){#6}%
  \Pst@ManageParamList{#3}%
  \Pst@ManageParamList{#4}%
  \Pst@ManageParamList{#5}%
  \Pst@ManageParamList{#6}%
  \pstLineAB{#3}{#4}
  \pstLineAB{#5}{#6}
  \endgroup%
}%
%
%% \pstEllipseLineInter[Options](O)(a,b){A}{B}{C}{D}
%% Get the two intersection $C$ and $D$ of the Ellipse E and the given line AB.
%% We can represent the line AB as the following function when line AB is not vertical:
%% $$y=kx+t$$ where $$k=\dfrac{y_2-y_1}{x_2-x_1}, t=\dfrac{x_2y_1-x_1y_2}{x_2-x_1}$$
%% the intersection points are:
%% $$x1=x_o-\dfrac{a^2km+ab\sqrt{w}}{u}, x2=x_o-\dfrac{a^2km-ab\sqrt{w}}{u}$$
%% $$y_{1,2}=kx_{1,2}+t$$
%% where,
%% $$u=a^2k^2+b^2, m=kx_o-y_o+t, w=u-m^2$$
%% Parameters:
%% #1 -> options
%% #2 -> [input] the ellipse center O
%% #3 -> [input] the horizontal and vertical radii
%% #4 -> [input] the node name A on the given line
%% #5 -> [input] the node name B on the given line
%% #6 -> [output] the first intersection node name
%% #7 -> [output] the second intersection node name
\def\pstEllipseLineInter{\@ifnextchar[\Pst@EllipseLineInter{\Pst@EllipseLineInter[]}}
\def\Pst@EllipseLineInter[#1](#2)(#3)#4#5#6#7{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \pst@getcoor{#4}\pst@tempA%
    \pst@getcoor{#5}\pst@tempB%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      \pst@tempA \tx@UserCoor % x1,y1
      \pst@tempB \tx@UserCoor % x2,y2
      3 index 2 index sub abs 1E-5 lt { % if the line AB is vertical
        pop pop pop
        2 index dup mul 1 index 6 index sub dup mul sub % a^2-(x_1-x_o)^2
        dup 0 lt {
          pop pop pop pop pop pop 0 0
        }{
          sqrt 2 index mul 3 index div % b/a sqrt(a^2-(x_1-x_o)^2)
          4 index exch sub % y_o-ditto
          6 2 roll pop pop pop pop
        } ifelse
      } {
        0 index 3 index sub 2 index 5 index sub div % k
        2 index 4 index mul 2 index 6 index mul sub 3 index 6 index sub div % t
        7 index dup mul 2 index dup mul mul 7 index dup mul add % u
        2 index 11 index mul 10 index sub 2 index add % m
        1 index 1 index dup mul sub dup 0 lt { % w
          pop pop pop pop pop pop pop pop pop pop pop pop pop 0 0
        } {
          sqrt 10 index mul 9 index mul 10 index dup mul 2 index mul 5 index mul add 2 index div 12 index exch sub % x1
          dup 5 index mul 4 index add % y1
          14 2 roll pop pop pop pop pop pop pop pop pop pop pop pop
        } ifelse
      } ifelse
    ){#6}%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      \pst@tempA \tx@UserCoor % x1,y1
      \pst@tempB \tx@UserCoor % x2,y2
      3 index 2 index sub abs 1E-5 lt { % if the line AB is vertical
        pop pop pop
        2 index dup mul 1 index 6 index sub dup mul sub % a^2-(x_1-x_o)^2
        dup 0 lt {
          pop pop pop pop pop pop 0 0
        }{
          sqrt 2 index mul 3 index div % b/a sqrt(a^2-(x_1-x_o)^2)
          4 index add % y_o+ditto
          6 2 roll pop pop pop pop
        } ifelse
      } {
        0 index 3 index sub 2 index 5 index sub div % k
        2 index 4 index mul 2 index 6 index mul sub 3 index 6 index sub div % t
        7 index dup mul 2 index dup mul mul 7 index dup mul add % u
        2 index 11 index mul 10 index sub 2 index add % m
        1 index 1 index dup mul sub dup 0 lt { % w
          pop pop pop pop pop pop pop pop pop pop pop pop pop 0 0
        } {
          sqrt 10 index mul 9 index mul 10 index dup mul 2 index mul 5 index mul sub 2 index div 12 index add % x2
          dup 5 index mul 4 index add % y2
          14 2 roll pop pop pop pop pop pop pop pop pop pop pop pop
        } ifelse
      } ifelse
    ){#7}%
    \Pst@ManageParamList{#6}%
    \Pst@ManageParamList{#7}%
  \endgroup%
}%
%
%% \pstEllipsePolarNode[Options](O)(a,b){A}{B}{T}
%% Draw the every tangent line through the point $A$ and $B$ on the Ellipse E and get the insection node T of the two tangent lines. We call T as the polar point of chord AB.
%% We use the intersection of two polar lines to get the tangent line. The proposition can be represented as:
%% Give chord AB on the ellipse, we draw any other two chords PQ and RS, AB and PQ intersect at I, AQ and BP intersect at X, AP and BQ intersect at Y, we call XY is the polar line of point I. Also AB and RS intersect at J, AR and BS intersect at M, AS and BR intersect at N, we call MN is the polar line of point J. Then the intersection T of XY and MN is the polar point of chord AB, i.e. TA is the tangent line through A and TB is the tangent line through B.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the ellipse center O
%% #3 -> [input] the horizontal and vertical radii
%% #4 -> [input] the node name A on the ellipse
%% #5 -> [input] the node name B on the ellipse
%% #6 -> [output] the polar point of chord AB
\def\pstEllipsePolarNode{\@ifnextchar[\Pst@EllipsePolarNode{\Pst@EllipsePolarNode[]}}
\def\Pst@EllipsePolarNode[#1](#2)(#3)#4#5#6{%
  \begingroup
    \psset{#1}%
    \pstEllipseRotNode[PointName=none,PointSymbol=none,RotAngle=71](#2)(#3){@PSTELLIPSE@POLARAUX@P}
    \pstEllipseRotNode[PointName=none,PointSymbol=none,RotAngle=-31](#2)(#3){@PSTELLIPSE@POLARAUX@Q}
    \pstEllipseRotNode[PointName=none,PointSymbol=none,RotAngle=-122](#2)(#3){@PSTELLIPSE@POLARAUX@R}
    \pstEllipseRotNode[PointName=none,PointSymbol=none,RotAngle=13](#2)(#3){@PSTELLIPSE@POLARAUX@S}
    \pstInterLL[PointName=none,PointSymbol=none]{#4}{@PSTELLIPSE@POLARAUX@Q}{#5}{@PSTELLIPSE@POLARAUX@P}{@PSTELLIPSE@POLARAUX@X}
    \pstInterLL[PointName=none,PointSymbol=none]{#4}{@PSTELLIPSE@POLARAUX@P}{#5}{@PSTELLIPSE@POLARAUX@Q}{@PSTELLIPSE@POLARAUX@Y}
    \pstInterLL[PointName=none,PointSymbol=none]{#4}{@PSTELLIPSE@POLARAUX@R}{#5}{@PSTELLIPSE@POLARAUX@S}{@PSTELLIPSE@POLARAUX@M}
    \pstInterLL[PointName=none,PointSymbol=none]{#4}{@PSTELLIPSE@POLARAUX@S}{#5}{@PSTELLIPSE@POLARAUX@R}{@PSTELLIPSE@POLARAUX@N}
    \pstInterLL[PointName=none,PointSymbol=none]{@PSTELLIPSE@POLARAUX@X}{@PSTELLIPSE@POLARAUX@Y}{@PSTELLIPSE@POLARAUX@M}{@PSTELLIPSE@POLARAUX@N}{#6}
    \Pst@geonodelabel{#6}%
    \pstLineAB{#4}{#6}
    \pstLineAB{#5}{#6}
  \endgroup%
}%
%
%% \pstEllipseTangentNode[Options](O)(a,b){T}{A}{B}
%% Draw the two tangent lines through the point $T$ to the Ellipse E and get the node A and B on the Ellipse.
%% We use the following proposition to find the tangent node of T:
%% Give point T outside of the ellipse, we draw any other two chords TPQ and TRS, PS and QR intersect at I, PR and QS intersect at X, XI and Ellipse intersect at A and B, then TA is the tangent line through A and TB is the tangent line through B.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the ellipse center O
%% #3 -> [input] the horizontal and vertical radii
%% #4 -> [input] the node name T outside the ellipse
%% #5 -> [output] the node name A on the ellipse
%% #6 -> [output] the node name B on the ellipse
\def\pstEllipseTangentNode{\@ifnextchar[\Pst@EllipseTangentNode{\Pst@EllipseTangentNode[]}}
\def\Pst@EllipseTangentNode[#1](#2)(#3)#4#5#6{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pstEllipseRotNode[PointName=none,PointSymbol=none,RotAngle=71](#2)(#3){@PSTELLIPSE@TANGENTAUX@P0}
    \pstEllipseRotNode[PointName=none,PointSymbol=none,RotAngle=31](#2)(#3){@PSTELLIPSE@TANGENTAUX@R0}
    \pstEllipseLineInter[PointName=none,PointSymbol=none](#2)(#3){#4}{@PSTELLIPSE@TANGENTAUX@P0}{@PSTELLIPSE@TANGENTAUX@P}{@PSTELLIPSE@TANGENTAUX@Q}
    \pstEllipseLineInter[PointName=none,PointSymbol=none](#2)(#3){#4}{@PSTELLIPSE@TANGENTAUX@R0}{@PSTELLIPSE@TANGENTAUX@R}{@PSTELLIPSE@TANGENTAUX@S}
    \pstInterLL[PointName=none,PointSymbol=none]{@PSTELLIPSE@TANGENTAUX@P}{@PSTELLIPSE@TANGENTAUX@S}{@PSTELLIPSE@TANGENTAUX@Q}{@PSTELLIPSE@TANGENTAUX@R}{@PSTELLIPSE@TANGENTAUX@I}
    \pstInterLL[PointName=none,PointSymbol=none]{@PSTELLIPSE@TANGENTAUX@P}{@PSTELLIPSE@TANGENTAUX@R}{@PSTELLIPSE@TANGENTAUX@Q}{@PSTELLIPSE@TANGENTAUX@S}{@PSTELLIPSE@TANGENTAUX@X}
    \pstEllipseLineInter[PointName=none,PointSymbol=none](#2)(#3){@PSTELLIPSE@TANGENTAUX@X}{@PSTELLIPSE@TANGENTAUX@I}{#5}{#6}
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
    \pstLineAB{#4}{#5}
    \pstLineAB{#4}{#6}
  \endgroup%
}%
%
% 2. General Ellipse with coordinate translation and rotation
%% ----------------------------------------------------------
%% The General Ellipse E is defined by center O, the half of the major axis $max(abs(a),abs(b))$,
%% the half of the minor axis $min(abs(a),abs(b))$, and the rotation angle $\theta$ of the major axis.
%%
%% The equation can be got from the parametric function of the ellipse \ref{ParametricFunctionOfEllipse},
%% using the rotation transform formula:
%% \begin{equation}\label{RotationTransformFormula}
%% \left\{\begin{array}{l}
%% x'=x\cos\theta-y\sin\theta\\
%% y'=x\sin\theta+y\cos\theta
%% \end{array}\right.
%% \end{equation}
%% then we have
%% \begin{equation}
%% \left\{\begin{array}{l}
%% x'=(a\cos\alpha+x_o)\cos\theta-(b\sin\alpha+y_o)\sin\theta=a\cos\alpha\cos\theta-b\sin\alpha\sin\theta+x_o'\\
%% y'=(a\cos\alpha+x_o)\sin\theta+(b\sin\alpha+y_o)\cos\theta=a\cos\alpha\sin\theta+b\sin\alpha\cos\theta+y_o'
%% \end{array}\right.
%% \end{equation}
%% where the $x_o'$ and $y_o'$ are the coordinate of the given center O after rotation.
%% So we get the parametric function of the general Ellipse with coordinate translation and rotation as following:
%% \begin{equation}\label{ParametricFunctionOfGeneralEllipse}
%% \left\{\begin{array}{l}
%% x=a\cos\alpha\cos\theta-b\sin\alpha\sin\theta+x_o\\
%% y=a\cos\alpha\sin\theta+b\sin\alpha\cos\theta+y_o
%% \end{array}\right.
%% \end{equation}
%
%% \pstGeneralEllipse[Options](O)(a,b)[rotation][angleA][angleB]
%% Draw a General Ellipse with center O from angleA to angleB, going counter clockwise,
%% the half of the major axis $max(abs(a),abs(b))$, the half of the minor axis $min(abs(a),abs(b))$,
%% and the rotation angle $\theta$ of the major axis.
%% If you not input rotation angle, the default value is $0^\circ$, which is same as \pstEllipse.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the ellipse center O
%% #3 -> [input] the horizontal and vertical radii
%% #4 -> [input] the rotation angle $\theta$ of the major axis.
%% #5 -> [input] start angle from angleA to angleB, going counter clockwise.
%% #6 -> [input] start angle from angleA to angleB, going counter clockwise.
\def\pstGeneralEllipse{\@ifnextchar[\Pst@GeneralEllipse{\Pst@GeneralEllipse[]}}
\def\Pst@GeneralEllipse[#1](#2)(#3){%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralEllipse@i{\Pst@GeneralEllipse[0]}}%
\def\Pst@GeneralEllipse@i[#1]{%
    \def\PST@GENERALELLIPSE@ROTATION{#1}%
    \@ifnextchar[\Pst@GeneralEllipse@ii{\Pst@GeneralEllipse@ii[0][360]}}%
\def\Pst@GeneralEllipse@ii[#1][#2]{%
    \parametricplot{#1}{#2}{%
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor % a,b
      abs exch abs exch % |a|,|b|
      \PST@GENERALELLIPSE@ROTATION\space dup cos exch sin % \cos\theta \sin\theta
      3 index 2 index mul % a\cos\theta
      3 index 2 index mul % b\sin\theta
      5 index 3 index mul % a\sin\theta
      5 index 5 index mul % b\cos\theta
      10 4 roll pop pop pop pop % a\cos\theta b\sin\theta a\sin\theta b\cos\theta x0 y0
      5 index t cos mul % a\cos\theta\cos{t}
      5 index t sin mul sub 2 index add % a\cos\theta\cos{t}-b\sin\theta\sin{t}+x0
      4 index t cos mul % a\sin\theta\cos{t}
      4 index t sin mul add 2 index add % a\sin\theta\cos{t}+b\cos\theta\sin{t}+y0
      8 2 roll pop pop pop pop pop pop
    }
  \endgroup%
}%
%
%% \pstGeneralEllipseFFN[Options]{F1}{F2}{N}{O}{R}{\theta}
%% Calculate the center and the radii of a General Ellipse with two focus $F_1$, $F_2$, and one node $N$ on it,
%% then you can access the ellipse with them.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the given focus F_1
%% #3 -> [input] the given focus F_2
%% #4 -> [input] the given node N on the ellipse
%% #5 -> [output] the center of the ellipse.
%% #6 -> [output] the pair of major and minor radius of the ellipse.
%% #7 -> [output] the rotation of the ellipse major axis.
\def\pstGeneralEllipseFFN{\@ifnextchar[\Pst@GeneralEllipseFFN{\Pst@GeneralEllipseFFN[]}}
\def\Pst@GeneralEllipseFFN[#1]#2#3#4#5#6#7{
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempFa%
    \pst@getcoor{#3}\pst@tempFb%
    \pst@getcoor{#4}\pst@tempN%
    \pnode(!
      \pst@tempFa \tx@UserCoor /Fay ED /Fax ED
      \pst@tempFb \tx@UserCoor /Fby ED /Fbx ED
      \pst@tempN \tx@UserCoor /Ny ED /Nx ED
      Fax Fbx add 2 div /EllipseOx ED
      Fay Fby add 2 div /EllipseOy ED
      Fax Fay Fbx Fby
      tx@EcldDict begin ABDist end
      2 div /EllipseC ED
      Nx Ny Fax Fay
      tx@EcldDict begin ABDist end
      Nx Ny Fbx Fby
      tx@EcldDict begin ABDist end
      add 2 div /EllipseA ED
      EllipseA dup mul EllipseC dup mul sub sqrt /EllipseB ED
      Fay Fby lt {
        Fby Fay sub Fbx Fax sub atan /#7 ED
      } {
        Fay Fby sub Fax Fbx sub atan /#7 ED
      } ifelse
      EllipseOx EllipseOy
    ){#5}
    \Pst@geonodelabel{#5}%
    \pnode(! EllipseA EllipseB){#6}
    \ifPst@CodeFig
    \begingroup\psset{PointName=none,linecolor=\psk@CodeFigColor}
    \pstLineAB[nodesep=-0.6]{#2}{#3}
    \pstLineAA[nodesepA=-1.5,nodesepB=-0.5]{#5}{#7 90 add}{PST@ELLIPSE@Y}
    \endgroup
    \fi
  \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
      % CurveCoefa = CurveCoefb = CurveCoefc = CurveCoefd = CurveCoefe = CurveCoeff =
      % I1=a+c
      CurveCoefa CurveCoefc add /DiscriminantI ED
      % I2=ac-b^2
      CurveCoefa CurveCoefc mul CurveCoefb dup mul sub /DiscriminantII ED
      % I3=|a b d,b c e,d e f|
      CurveCoefa CurveCoefb CurveCoefd
      CurveCoefb CurveCoefc CurveCoefe
      CurveCoefd CurveCoefe CurveCoeff
      tx@EcldDict begin DeterminantThree end /DiscriminantIII ED
      % DiscriminantI = DiscriminantII = DiscriminantIII =
      DiscriminantII 0 gt { % if I2>0
        % Solve the Characteristic Equation: \lambda^2-I_1\lambda+I_2=0
        DiscriminantI dup mul 4 DiscriminantII mul sub dup 0 lt {
          0 0
          0 /MyEllipseA ED
          0 /MyEllipseB ED
          0 /#5 ED
        } {
          sqrt dup DiscriminantI exch sub 2 div /CharacteristicLambdaI ED
          DiscriminantI add 2 div /CharacteristicLambdaII ED
          % CharacteristicLambdaI = CharacteristicLambdaII =
          % 20200726 Liaoxiongfei
          % fix how to get the rotation of the ellipse major axis.
          % since we can reduce the ellipse to
          % \lambda_1x^2+\lambda_2y^2+I_3/I_2=0
          % so the major axis is determined by the characteristic root with the small absolute value,
          % and the slope of major axis is $(\lambda_1-a)/b$, or $(c-\lambda_2)/b$, where |\lambda_1|\leq|\lambda_2|
          CharacteristicLambdaI abs CharacteristicLambdaII abs lt {
            DiscriminantIII CharacteristicLambdaI DiscriminantII mul div neg sqrt /MyEllipseA ED
            DiscriminantIII CharacteristicLambdaII DiscriminantII mul div neg sqrt /MyEllipseB ED
            CharacteristicLambdaI CurveCoefa lt {
              CharacteristicLambdaI CurveCoefa sub neg CurveCoefb neg atan /#5 ED
            } {
              CharacteristicLambdaI CurveCoefa sub abs 1E-5 lt CurveCoefb abs 1E-5 lt and {
                /#5 0 def
              }{
                CharacteristicLambdaI CurveCoefa sub CurveCoefb atan /#5 ED
              } ifelse
            } ifelse
          } {
            DiscriminantIII CharacteristicLambdaII DiscriminantII mul div neg sqrt /MyEllipseA ED
            DiscriminantIII CharacteristicLambdaI DiscriminantII mul div neg sqrt /MyEllipseB ED
            CharacteristicLambdaII CurveCoefa lt {
              CharacteristicLambdaII CurveCoefa sub neg CurveCoefb neg atan /#5 ED
            } {
              CharacteristicLambdaII CurveCoefa sub CurveCoefb atan /#5 ED
            } ifelse
          } ifelse
          % MyEllipseA = MyEllipseB = #5 = (--------------) =
          % F_1(x,y)=ax+by+d=0
          % F_2(x,y)=bx+cy+e=0
          CurveCoefb CurveCoefe mul CurveCoefc CurveCoefd mul sub DiscriminantII div % x0
          CurveCoefb CurveCoefd mul CurveCoefa CurveCoefe mul sub DiscriminantII div % y0
        } ifelse
      } {
        0 0
        0 /MyEllipseA ED
        0 /MyEllipseB ED
        0 /#5 ED
      } 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, since $I_2=ac-b^2/4>0$, so $a\neq0$.
      % 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 /CurveCoefb ED
        0 /CurveCoefc ED
        0 /CurveCoefd ED
        0 /CurveCoefe ED
        0 /CurveCoeff 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
      } ifelse
      % CurveCoefa = CurveCoefb = CurveCoefc = CurveCoefd = CurveCoefe = CurveCoeff =
      0 /CurveCoefMax ED 1E8 /CurveCoefMin ED
      CurveCoefa abs CurveCoefMax gt {CurveCoefa abs /CurveCoefMax ED} if
      CurveCoefb abs CurveCoefMax gt {CurveCoefb abs /CurveCoefMax ED} if
      CurveCoefc abs CurveCoefMax gt {CurveCoefc abs /CurveCoefMax ED} if
      CurveCoefd abs CurveCoefMax gt {CurveCoefd abs /CurveCoefMax ED} if
      CurveCoefe abs CurveCoefMax gt {CurveCoefe abs /CurveCoefMax ED} if
      CurveCoeff abs CurveCoefMax gt {CurveCoeff abs /CurveCoefMax ED} if
      CurveCoefa abs CurveCoefMin lt {CurveCoefa abs /CurveCoefMin ED} if
      CurveCoefb abs CurveCoefMin lt {CurveCoefb abs /CurveCoefMin ED} if
      CurveCoefc abs CurveCoefMin lt {CurveCoefc abs /CurveCoefMin ED} if
      CurveCoefd abs CurveCoefMin lt {CurveCoefd abs /CurveCoefMin ED} if
      CurveCoefe abs CurveCoefMin lt {CurveCoefe abs /CurveCoefMin ED} if
      CurveCoeff abs CurveCoefMin lt {CurveCoeff abs /CurveCoefMin ED} if
      % CurveCoefMin = CurveCoefMax =
      CurveCoefMin CurveCoefMax div 1E-5 lt {
        CurveCoefa CurveCoefMax div /CurveCoefa ED
        CurveCoefb CurveCoefMax div /CurveCoefb ED
        CurveCoefc CurveCoefMax div /CurveCoefc ED
        CurveCoefd CurveCoefMax div /CurveCoefd ED
        CurveCoefe CurveCoefMax div /CurveCoefe ED
        CurveCoeff CurveCoefMax div /CurveCoeff ED
      } if
      % CurveCoefa = CurveCoefb = CurveCoefc = CurveCoefd = CurveCoefe = CurveCoeff =
      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
      % the following is same with pstGeneralEllipseCoef.
      % CurveCoefa = CurveCoefb = CurveCoefc = CurveCoefd = CurveCoefe = CurveCoeff =
      % I1=a+c
      CurveCoefa CurveCoefc add /DiscriminantI ED
      % I2=ac-b^2
      CurveCoefa CurveCoefc mul CurveCoefb dup mul sub /DiscriminantII ED
      % I3=|a b d,b c e,d e f|
      CurveCoefa CurveCoefb CurveCoefd
      CurveCoefb CurveCoefc CurveCoefe
      CurveCoefd CurveCoefe CurveCoeff
      tx@EcldDict begin DeterminantThree end /DiscriminantIII ED
      % DiscriminantI = DiscriminantII = DiscriminantIII =
      DiscriminantII 0 gt { % if I2>0
        % Solve the Characteristic Equation: \lambda^2-I_1\lambda+I_2=0
        DiscriminantI dup mul 4 DiscriminantII mul sub dup 0 lt {
          0 0
          0 /MyEllipseA ED
          0 /MyEllipseB ED
          0 /#9 ED
        } {
          sqrt dup DiscriminantI exch sub 2 div /CharacteristicLambdaI ED
          DiscriminantI add 2 div /CharacteristicLambdaII ED
          % CharacteristicLambdaI = CharacteristicLambdaII =
          % 20200726 Liaoxiongfei
          % fix how to get the rotation of the ellipse major axis.
          % since we can reduce the ellipse to
          % \lambda_1x^2+\lambda_2y^2+I_3/I_2=0
          % so the major axis is determined by the characteristic root with the small absolute value,
          % and the slope of major axis is $(\lambda_1-a)/b$, or $(c-\lambda_2)/b$, where |\lambda_1|\leq|\lambda_2|
          CharacteristicLambdaI abs CharacteristicLambdaII abs lt {
            DiscriminantIII CharacteristicLambdaI DiscriminantII mul div neg sqrt /MyEllipseA ED
            DiscriminantIII CharacteristicLambdaII DiscriminantII mul div neg sqrt /MyEllipseB ED
            CharacteristicLambdaI CurveCoefa lt {
              CharacteristicLambdaI CurveCoefa sub neg CurveCoefb neg atan /#9 ED
            } {
              CharacteristicLambdaI CurveCoefa sub CurveCoefb atan /#9 ED
            } ifelse
          } {
            DiscriminantIII CharacteristicLambdaII DiscriminantII mul div neg sqrt /MyEllipseA ED
            DiscriminantIII CharacteristicLambdaI DiscriminantII mul div neg sqrt /MyEllipseB ED
            CharacteristicLambdaII CurveCoefa lt {
              CharacteristicLambdaII CurveCoefa sub neg CurveCoefb neg atan /#9 ED
            } {
              CharacteristicLambdaII CurveCoefa sub CurveCoefb atan /#9 ED
            } ifelse
          } ifelse
          % MyEllipseA = MyEllipseB = #9 = (--------------) =
          % F_1(x,y)=ax+by+d=0
          % F_2(x,y)=bx+cy+e=0
          CurveCoefb CurveCoefe mul CurveCoefc CurveCoefd mul sub DiscriminantII div % x0
          CurveCoefb CurveCoefd mul CurveCoefa CurveCoefe mul sub DiscriminantII div % y0
        } ifelse
      } {
        0 0
        0 /MyEllipseA ED
        0 /MyEllipseB ED
        0 /#9 ED
      } 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.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the ellipse center O
%% #3 -> [input] the horizontal and vertical radii
%% #4 -> [input] the rotation angle $\theta$ of the major axis.
%% #5 -> [input] the parameter value $t$.
%% #6 -> [output] the new node name on the ellipse
\def\pstGeneralEllipseNode{\@ifnextchar[\Pst@GeneralEllipseNode{\Pst@GeneralEllipseNode[]}}
\def\Pst@GeneralEllipseNode[#1](#2)(#3){%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralEllipseNode@i{\Pst@GeneralEllipseNode@i[0]}}
\def\Pst@GeneralEllipseNode@i[#1]#2#3{%
  \pnode(!
    \pst@tempO \tx@UserCoor % x0,y0
    \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
    #1 dup cos exch sin % \cos\theta \sin\theta
    #2 cos #2 sin %
    5 index 4 index mul 2 index mul % a\cos\theta\cos\alpha
    5 index 4 index mul 2 index mul % b\sin\theta\sin\alpha
    sub 8 index add % a\cos\theta\cos\alpha - b\sin\theta\sin\alpha + x_o
    6 index 4 index mul 3 index mul % a\sin\theta\cos\alpha
    6 index 6 index mul 3 index mul % b\cos\theta\sin\alpha
    add 8 index add % a\sin\theta\cos\alpha + b\cos\theta\sin\alpha + y_o
    10 2 roll pop pop pop pop pop pop pop pop
  ){#3}%
  \Pst@geonodelabel{#3}%
  \endgroup%
}%
%
%% \pstGeneralEllipseRotNode[Options,RotAngle=<degree>](O)(a,b)[rotation]{A}
%% Get the new node A whose RotAngle is the given value on the General Ellipse E.
%% If you not input rotation angle, the default value is $0^\circ$, which is same as \pstEllipse.
%% If you not set RotAngle, the default value is $60^\circ$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the ellipse center O
%% #3 -> [input] the horizontal and vertical radii
%% #4 -> [input] the rotation angle $\theta$ of the major axis.
%% #5 -> [output] the new node name on the ellipse
\def\pstGeneralEllipseRotNode{\@ifnextchar[\Pst@GeneralEllipseRotNode{\Pst@GeneralEllipseRotNode[]}}
\def\Pst@GeneralEllipseRotNode[#1](#2)(#3){%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralEllipseRotNode@i{\Pst@GeneralEllipseRotNode@i[0]}}
\def\Pst@GeneralEllipseRotNode@i[#1]#2{%
  \pnode(!
    \pst@tempO \tx@UserCoor % x0,y0
    \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
    #1 dup cos exch sin % \cos\theta \sin\theta
    \psk@RotAngle\space cos \psk@RotAngle\space sin %
    5 index 4 index mul 2 index mul % a\cos\theta\cos\alpha
    5 index 4 index mul 2 index mul % b\sin\theta\sin\alpha
    sub 8 index add % a\cos\theta\cos\alpha - b\sin\theta\sin\alpha + x_o
    6 index 4 index mul 3 index mul % a\sin\theta\cos\alpha
    6 index 6 index mul 3 index mul % b\cos\theta\sin\alpha
    add 8 index add % a\sin\theta\cos\alpha + b\cos\theta\sin\alpha + y_o
    10 2 roll pop pop pop pop pop pop pop pop
  ){#2}%
  \Pst@geonodelabel{#2}%
  \endgroup%
}%
%
%% \pstGeneralEllipseAbsNode[Options](O)(a,b)[rotation]{x_1}{A}{B}
%% Create the node A and B whose abbscissa are the given value $x_1$ on the General Ellipse E.
%% If you not input rotation angle, the default value is $0^\circ$, which is same as \pstEllipse.
%% When x equals $x_1$, we have
%% $$y_{1,2}=gc_{1,2}+hs_{1,2}+y_o$$
%% where,
%% $$c_1=\dfrac{de+f\sqrt{w}}{u}, s_1=\dfrac{-df+e\sqrt{w}}{u}$$
%% $$c_2=\dfrac{de-f\sqrt{w}}{u}, s_2=\dfrac{-df-e\sqrt{w}}{u}$$
%% $$e=a\cos\theta,f=b\sin\theta,g=a\sin\theta,h=b\cos\theta$$
%% $$d=x_1-x_o,u=e^2+f^2,w=u-d^2$$
%% Parameters:
%% #1 -> options
%% #2 -> [input] the ellipse center O
%% #3 -> [input] the horizontal and vertical radii
%% #4 -> [input] the rotation angle $\theta$ of the major axis.
%% #5 -> [input] the given abscissa value $x_1$.
%% #6 -> [output] the first intersection node $A$
%% #7 -> [output] the second intersection node $B$
\def\pstGeneralEllipseAbsNode{\@ifnextchar[\Pst@GeneralEllipseAbsNode{\Pst@GeneralEllipseAbsNode[]}}
\def\Pst@GeneralEllipseAbsNode[#1](#2)(#3){%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralEllipseAbsNode@i{\Pst@GeneralEllipseAbsNode@i[0]}}
\def\Pst@GeneralEllipseAbsNode@i[#1]#2#3#4{%
  \pnode(!
    \pst@tempO \tx@UserCoor % x0,y0
    \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
    #1 dup cos exch sin % \cos\theta \sin\theta
    3 index 2 index mul % e=a\cos\theta
    3 index 2 index mul % f=b\sin\theta
    5 index 3 index mul % g=a\sin\theta
    5 index 5 index mul % h=b\cos\theta
    #2 9 index sub % d=x_1-x_o
    4 index dup mul 4 index dup mul add % u=e^2+f^2
    0 index 2 index dup mul sub dup 0 lt { % w=u-d^2
      pop pop pop pop pop pop pop
      pop pop pop pop pop pop
      0 0
    } {
      sqrt % sqrt(w)
      %% c_1=(de+f sqrt(w))/u, s_1=(-df+e sqrt(w))/u
      2 index 7 index mul 6 index 2 index mul add 2 index div % c1
      3 index 7 index mul 8 index 3 index mul exch sub 3 index div % s1
      %% y_{1,2}=gc_{1,2}+hs_{1,2}+y_o
      6 index 2 index mul 6 index 2 index mul add 14 index add % y1
      #2 exch 17 2 roll pop pop pop pop pop
      pop pop pop pop pop
      pop pop pop pop pop
    } ifelse
  ){#3}%
  \pnode(!
    \pst@tempO \tx@UserCoor % x0,y0
    \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
    #1 dup cos exch sin % \cos\theta \sin\theta
    3 index 2 index mul % e=a\cos\theta
    3 index 2 index mul % f=b\sin\theta
    5 index 3 index mul % g=a\sin\theta
    5 index 5 index mul % h=b\cos\theta
    #2 9 index sub % d=x_1-x_o
    4 index dup mul 4 index dup mul add % u=e^2+f^2
    0 index 2 index dup mul sub dup 0 lt { % w=u-d^2
      pop pop pop pop pop pop pop
      pop pop pop pop pop pop
      0 0
    } {
      sqrt % sqrt(w)
      %% c_2=(de-f sqrt(w))/u, s_2=(-df-e sqrt(w))/u
      2 index 7 index mul 6 index 2 index mul sub 2 index div % c2
      3 index 7 index mul 8 index 3 index mul add neg 3 index div % s2
      %% y_{1,2}=gc_{1,2}+hs_{1,2}+y_o
      6 index 2 index mul 6 index 2 index mul add 14 index add % y2
      #2 exch 17 2 roll pop pop pop pop pop
      pop pop pop pop pop
      pop pop pop pop pop
    } ifelse
  ){#4}%
  \Pst@ManageParamList{#3}%
  \Pst@ManageParamList{#4}%
  \endgroup%
}%
%
%% \pstGeneralEllipseOrdNode[Options](O)(a,b)[rotation]{y_1}{A}{B}
%% Create the node A and B whose ordinates are the given value $y_1$ on the General Ellipse E.
%% If you not input rotation angle, the default value is $0^\circ$, which is same as \pstEllipse.
%% when y equals $y_1$, we have
%% x_{1,2}=ec_{1,2}-fs_{1,2}+x_o
%% where,
%% $$c_1=\dfrac{dg+h\sqrt{w}}{u}, s_1=\dfrac{dh-g\sqrt{w}}{u}$$
%% $$c_2=\dfrac{dg-h\sqrt(w}}{u}, s_2=\dfrac{dh+g\sqrt{w}}{u}$$
%% $$e=a\cos\theta,f=b\sin\theta,g=a\sin\theta,h=b\cos\theta$$
%% $$d=y_1-y_o,u=h^2+g^2,w=u-d^2$$
%% Parameters:
%% #1 -> options
%% #2 -> [input] the ellipse center O
%% #3 -> [input] the horizontal and vertical radii
%% #4 -> [input] the rotation angle $\theta$ of the major axis.
%% #5 -> [input] the given ordinate value $y_1$.
%% #6 -> [output] the first intersection node $A$
%% #7 -> [output] the second intersection node $B$
\def\pstGeneralEllipseOrdNode{\@ifnextchar[\Pst@GeneralEllipseOrdNode{\Pst@GeneralEllipseOrdNode[]}}
\def\Pst@GeneralEllipseOrdNode[#1](#2)(#3){%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralEllipseOrdNode@i{\Pst@GeneralEllipseOrdNode@i[0]}}
\def\Pst@GeneralEllipseOrdNode@i[#1]#2#3#4{%
  \pnode(!
    \pst@tempO \tx@UserCoor % x0,y0
    \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
    #1 dup cos exch sin % \cos\theta \sin\theta
    3 index 2 index mul % e=a\cos\theta
    3 index 2 index mul % f=b\sin\theta
    5 index 3 index mul % g=a\sin\theta
    5 index 5 index mul % h=b\cos\theta
    #2 9 index sub % d=y_1-y_o
    2 index dup mul 2 index dup mul add % u=h^2+g^2
    0 index 2 index dup mul sub dup 0 lt { % w=u-d^2
      pop pop pop pop pop pop pop
      pop pop pop pop pop pop
      0 0
    } {
      sqrt % sqrt(w)
      %% c_1=(dg+h sqrt(w))/u, s_1=(dh-g sqrt(w))/u
      2 index 5 index mul 4 index 2 index mul add 2 index div % c1
      3 index 5 index mul 6 index 3 index mul sub 3 index div % s1
      %% x_{1,2}=ec_{1,2}-fs_{1,2}+x_o
      8 index 2 index mul 8 index 2 index mul sub 15 index add % x1
      #2 17 2 roll pop pop pop pop pop
      pop pop pop pop pop
      pop pop pop pop pop
    } ifelse
  ){#3}%
  \pnode(!
    \pst@tempO \tx@UserCoor % x0,y0
    \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
    #1 dup cos exch sin % \cos\theta \sin\theta
    3 index 2 index mul % e=a\cos\theta
    3 index 2 index mul % f=b\sin\theta
    5 index 3 index mul % g=a\sin\theta
    5 index 5 index mul % h=b\cos\theta
    #2 9 index sub % d=y_1-y_o
    2 index dup mul 2 index dup mul add % u=h^2+g^2
    0 index 2 index dup mul sub dup 0 lt { % w=u-d^2
      pop pop pop pop pop pop pop
      pop pop pop pop pop pop
      0 0
    } {
      sqrt % sqrt(w)
      %% c_2=(dg-h sqrt(w))/u, s_2=(dh+g sqrt(w))/u
      2 index 5 index mul 4 index 2 index mul sub 2 index div % c2
      3 index 5 index mul 6 index 3 index mul add 3 index div % s2
      %% x_{1,2}=ec_{1,2}-fs_{1,2}+x_o
      8 index 2 index mul 8 index 2 index mul sub 15 index add % x2
      #2 17 2 roll pop pop pop pop pop
      pop pop pop pop pop
      pop pop pop pop pop
    } ifelse
  ){#4}%
  \Pst@ManageParamList{#3}%
  \Pst@ManageParamList{#4}%
  \endgroup%
}%
%
%% \pstGeneralEllipseFocusNode[Options](O)(a,b)[rotation]{$F_1$}{$F_2$}
%% Get the two focus $F_1$ and $F_2$ point of the General Ellipse E and create two new nodes.
%% If you not input rotation angle, the default value is $0^\circ$, which is same as \pstEllipse.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the ellipse center O
%% #3 -> [input] the horizontal and vertical radii
%% #4 -> [input] the rotation angle $\theta$ of the major axis.
%% #5 -> [output] the left/down node name
%% #6 -> [output] the right/up node name
\def\pstGeneralEllipseFocusNode{\@ifnextchar[\Pst@GeneralEllipseFocusNode{\Pst@GeneralEllipseFocusNode[]}}
\def\Pst@GeneralEllipseFocusNode[#1](#2)(#3){%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralEllipseFocusNode@i{\Pst@GeneralEllipseFocusNode@i[0]}}
\def\Pst@GeneralEllipseFocusNode@i[#1]#2#3{%
  \pnode(!
    \pst@tempO \tx@UserCoor % x0,y0
    \pst@tempR \tx@UserCoor % a,b
    abs exch abs exch % |a|,|b|
    2 copy gt {% Focus on haxis
    1 index dup mul 1 index dup mul sub sqrt % c=sqrt(a^2-b^2)
    4 index 1 index #1 cos mul sub % x_o-c\cos\alpha
    4 index 2 index #1 sin mul sub % y_o-c\sin\alpha
    }{% Focus on vaxis
    0 index dup mul 2 index dup mul sub sqrt % c=sqrt(b^2-a^2)
    4 index 1 index #1 sin mul add % x_o+c\sin\alpha
    4 index 2 index #1 cos mul sub % y_o-c\cos\alpha
    } ifelse
    7 2 roll pop pop pop pop pop
  ){#2}%
  \pnode(!
    \pst@tempO \tx@UserCoor % x0,y0
    \pst@tempR \tx@UserCoor % a,b
    abs exch abs exch % |a|,|b|
    2 copy gt {% Focus on haxis
    1 index dup mul 1 index dup mul sub sqrt % c=sqrt(a^2-b^2)
    4 index 1 index #1 cos mul add % x_o+c\cos\alpha
    4 index 2 index #1 sin mul add % y_o+c\sin\alpha
    }{% Focus on vaxis
    0 index dup mul 2 index dup mul sub sqrt % c=sqrt(b^2-a^2)
    4 index 1 index #1 sin mul sub % x_o-c\sin\alpha
    4 index 2 index #1 cos mul add % y_o+c\cos\alpha
    } ifelse
    7 2 roll pop pop pop pop pop
  ){#3}%
  \Pst@ManageParamList{#2}%
  \Pst@ManageParamList{#3}%
  \endgroup%
}%
%
%% \pstGeneralEllipseDirectrixLine[Options](O)(a,b)[rotation]{Lx}{Ly}{Rx}{Ry}
%% Get the two directrix line of the General Ellipse E and create two new nodes for each one.
%% If you not input rotation angle, the default value is $0^\circ$, which is same as \pstEllipse.
%% the nodes Lx Ly Rx Ry lie on the tangent line of the vertex on the other axis,
%% they can be got after the orig nodes rotation $\theta$ about the center $O$, we have
%% \begin{equation}\label{ExtensionRotationTransformFormula}
%% \left\{\begin{array}{l}
%% x=x_o+(x-x_o)\cos\theta-(y-y_o)\sin\theta\\
%% y=y_o+(x-x_o)\sin\theta+(y-y_o)\cos\theta
%% \end{array}\right.
%% \end{equation}
%% Parameters:
%% #1 -> options
%% #2 -> [input] the ellipse center O
%% #3 -> [input] the horizontal and vertical radii
%% #4 -> [input] the rotation angle $\theta$ of the major axis.
%% #5 -> [output] the A node name on the left/down directrix line
%% #6 -> [output] the B node name on the left/down directrix line
%% #7 -> [output] the A node name on the right/up directrix line
%% #8 -> [output] the B node name on the right/up directrix line
\def\pstGeneralEllipseDirectrixLine{\@ifnextchar[\Pst@GeneralEllipseDirectrixLine{\Pst@GeneralEllipseDirectrixLine[]}}
\def\Pst@GeneralEllipseDirectrixLine[#1](#2)(#3){%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralEllipseDirectrixLine@i{\Pst@GeneralEllipseDirectrixLine@i[0]}}
\def\Pst@GeneralEllipseDirectrixLine@i[#1]#2#3#4#5{%
  \pnode(!
    \pst@tempO \tx@UserCoor % x0,y0
    \pst@tempR \tx@UserCoor % a,b
    abs exch abs exch % |a|,|b|
    2 copy gt {% Focus on haxis
    1 index dup mul 1 index dup mul sub sqrt % c=sqrt(a^2-b^2)
    4 index 3 index dup mul 2 index div sub % x0-a^2/c
    4 index 3 index sub
    7 2 roll pop pop pop % (x0-a^2/c,y0-b)
    }{% Focus on vaxis
    0 index dup mul 2 index dup mul sub sqrt % c=sqrt(b^2-a^2)
    4 index 3 index sub % x0-a
    4 index 3 index dup mul 3 index div sub
    7 2 roll pop pop pop % (x0-a,y0-b^2/c)
    } ifelse
    #1 cos #1 sin % x y x0 y0 \cos\theta \sin\theta
    3 index 6 index 5 index sub 3 index mul add 5 index 4 index sub 2 index mul sub % x0+(x-x0)\cos\theta-(y-y0)\sin\theta
    3 index 7 index 6 index sub 3 index mul add 6 index 5 index sub 4 index mul add % y0+(x-x0)\sin\theta+(y-y0)\cos\theta
    8 2 roll pop pop pop pop pop pop
  ){#2}%
  \pnode(!
    \pst@tempO \tx@UserCoor % x0,y0
    \pst@tempR \tx@UserCoor % a,b
    abs exch abs exch % |a|,|b|
    2 copy gt {% Focus on haxis
    1 index dup mul 1 index dup mul sub sqrt % c=sqrt(a^2-b^2)
    4 index 3 index dup mul 2 index div sub % x0-a^2/c
    4 index 3 index add
    7 2 roll pop pop pop % (x0-a^2/c,y0+b)
    }{% Focus on vaxis
    0 index dup mul 2 index dup mul sub sqrt % c=sqrt(b^2-a^2)
    4 index 3 index add % x0+a
    4 index 3 index dup mul 3 index div sub
    7 2 roll pop pop pop % (x0+a,y0-b^2/c)
    } ifelse
    #1 cos #1 sin % x y x0 y0 \cos\theta \sin\theta
    3 index 6 index 5 index sub 3 index mul add 5 index 4 index sub 2 index mul sub % x0+(x-x0)\cos\theta-(y-y0)\sin\theta
    3 index 7 index 6 index sub 3 index mul add 6 index 5 index sub 4 index mul add % y0+(x-x0)\sin\theta+(y-y0)\cos\theta
    8 2 roll pop pop pop pop pop pop
  ){#3}%
  \pnode(!
    \pst@tempO \tx@UserCoor % x0,y0
    \pst@tempR \tx@UserCoor % a,b
    abs exch abs exch % |a|,|b|
    2 copy gt {% Focus on haxis
    1 index dup mul 1 index dup mul sub sqrt % c=sqrt(a^2-b^2)
    4 index 3 index dup mul 2 index div add % x0+a^2/c
    4 index 3 index sub
    7 2 roll pop pop pop % (x0+a^2/c,y0-b)
    }{% Focus on vaxis
    0 index dup mul 2 index dup mul sub sqrt % c=sqrt(b^2-a^2)
    4 index 3 index sub % x0-a
    4 index 3 index dup mul 3 index div add
    7 2 roll pop pop pop % (x0-a,y0+b^2/c)
    } ifelse
    #1 cos #1 sin % x y x0 y0 \cos\theta \sin\theta
    3 index 6 index 5 index sub 3 index mul add 5 index 4 index sub 2 index mul sub % x0+(x-x0)\cos\theta-(y-y0)\sin\theta
    3 index 7 index 6 index sub 3 index mul add 6 index 5 index sub 4 index mul add % y0+(x-x0)\sin\theta+(y-y0)\cos\theta
    8 2 roll pop pop pop pop pop pop
  ){#4}%
  \pnode(!
    \pst@tempO \tx@UserCoor % x0,y0
    \pst@tempR \tx@UserCoor % a,b
    abs exch abs exch % |a|,|b|
    2 copy gt {% Focus on haxis
    1 index dup mul 1 index dup mul sub sqrt % c=sqrt(a^2-b^2)
    4 index 3 index dup mul 2 index div add % x0+a^2/c
    4 index 3 index add
    7 2 roll pop pop pop % (x0+a^2/c,y0+b)
    }{% Focus on vaxis
    0 index dup mul 2 index dup mul sub sqrt % c=sqrt(b^2-a^2)
    4 index 3 index add % x0+a
    4 index 3 index dup mul 3 index div add
    7 2 roll pop pop pop % (x0+a,y0+b^2/c)
    } ifelse
    #1 cos #1 sin % x y x0 y0 \cos\theta \sin\theta
    3 index 6 index 5 index sub 3 index mul add 5 index 4 index sub 2 index mul sub % x0+(x-x0)\cos\theta-(y-y0)\sin\theta
    3 index 7 index 6 index sub 3 index mul add 6 index 5 index sub 4 index mul add % y0+(x-x0)\sin\theta+(y-y0)\cos\theta
    8 2 roll pop pop pop pop pop pop
  ){#5}%
  \Pst@ManageParamList{#2}%
  \Pst@ManageParamList{#3}%
  \Pst@ManageParamList{#4}%
  \Pst@ManageParamList{#5}%
  \pstLineAB{#2}{#3}
  \pstLineAB{#4}{#5}
  \endgroup%
}%
%
%% \pstGeneralEllipseLineInter[Options](O)(a,b)[rotation]{A}{B}{C}{D}
%% Get the two intersection $C$ and $D$ of the General Ellipse E and the given line AB.
%% If you not input rotation angle, the default value is $0^\circ$, which is same as \pstEllipse.
%% We can represent the line AB as the following function when line AB is not vertical:
%% $$y=kx+t$$ where $$k=\dfrac{y_2-y_1}{x_2-x_1},t=\dfrac{x_2y_1-x_1y_2}{x_2-x_1}$$
%% The intersections are:
%% $$x_{1,2}=ec_{1,2}-fs_{1,2}+x_o,y_{1,2}=kx_{1,2}+t$$
%% where,
%% $$e=a\cos\theta,f=b\sin\theta,g=a\sin\theta,h=b\cos\theta$$
%% $$c_1=\dfrac{mA+B\sqrt{w}}{A^2+B^2}$$
%% $$s_1=\dfrac{mB-A\sqrt{w}}{A^2+B^2}$$
%% $$c_2=\dfrac{mA-B\sqrt{w}}{A^2+B^2}$$
%% $$s_2=\dfrac{mB+A\sqrt{w}}{A^2+B^2}$$
%% $$w=A^2+B^2-m^2, m=kx_o-y_o+t, A=g-ke, B=h+kf$$
%% Parameters:
%% #1 -> options
%% #2 -> [input] the ellipse center O
%% #3 -> [input] the horizontal and vertical radii
%% #4 -> [input] the rotation angle $\theta$ of the major axis.
%% #5 -> [input] the node name A on the given line
%% #6 -> [input] the node name B on the given line
%% #7 -> [output] the first intersection node name
%% #8 -> [output] the second intersection node name
\def\pstGeneralEllipseLineInter{\@ifnextchar[\Pst@GeneralEllipseLineInter{\Pst@GeneralEllipseLineInter[]}}
\def\Pst@GeneralEllipseLineInter[#1](#2)(#3){%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralEllipseLineInter@i{\Pst@GeneralEllipseLineInter@i[0]}}
\def\Pst@GeneralEllipseLineInter@i[#1]#2#3#4#5{%
  \pst@getcoor{#2}\pst@tempA%
  \pst@getcoor{#3}\pst@tempB%
  \pnode(!
    \pst@tempO \tx@UserCoor % x0,y0
    \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
    \pst@tempA \tx@UserCoor % x1,y1
    \pst@tempB \tx@UserCoor % x2,y2
    3 index 2 index sub abs 1E-5 lt { % if the line AB is vertical
      pop pop pop pop
      #1 dup cos exch sin % \cos\theta \sin\theta
      3 index 2 index mul % e=a\cos\theta
      3 index 2 index mul % f=b\sin\theta
      5 index 3 index mul % g=a\sin\theta
      5 index 5 index mul % h=b\cos\theta
      \pst@tempA \tx@UserCoor pop % x1
      9 index sub % d=x_1-x_o
      4 index dup mul 4 index dup mul add % u=e^2+f^2
      0 index 2 index dup mul sub dup 0 lt { % w=u-d^2
        pop pop pop pop pop pop pop
        pop pop pop pop pop pop
        0 0
      } {
        sqrt % sqrt(w)
        %% c_1=(de+f sqrt(w))/u, s_1=(-df+e sqrt(w))/u
        2 index 7 index mul 6 index 2 index mul add 2 index div % c1
        3 index 7 index mul 8 index 3 index mul exch sub 3 index div % s1
        %% y_{1,2}=gc_{1,2}+hs_{1,2}+y_o
        6 index 2 index mul 6 index 2 index mul add 14 index add % y1
        \pst@tempA \tx@UserCoor pop % x1
        exch 17 2 roll pop pop pop pop pop
        pop pop pop pop pop
        pop pop pop pop pop
      } ifelse
    }{
      0 index 3 index sub 2 index 5 index sub div % k
      2 index 4 index mul 2 index 6 index mul sub 3 index 6 index sub div % t
      #1 dup cos exch sin % \cos\theta \sin\theta
      9 index 2 index mul % e=a\cos\theta
      9 index 2 index mul % f=b\sin\theta
      11 index 3 index mul % g=a\sin\theta
      11 index 5 index mul % h=b\cos\theta
      1 index 8 index 5 index mul sub % A=g-ke
      1 index 9 index 5 index mul add % B=h+kf
      1 index dup mul 1 index dup mul add % C=A^2+B^2
      10 index 19 index mul 18 index sub 10 index add % m=kx_o-y_o+t
      1 index 1 index dup mul sub dup 0 lt { % w=C-m^2
        pop pop pop pop pop pop pop
        pop pop pop pop pop pop pop
        pop pop pop pop pop pop pop
        0 0
      } {
        sqrt % sqrt(w)
        1 index 5 index mul 4 index 2 index mul add 3 index div % c1
        2 index 5 index mul 6 index 3 index mul sub 4 index div % s1
        %% x_{1,2}=ec_{1,2}-fs_{1,2}+x_o,y_{1,2}=kx_{1,2}+t
        10 index 2 index mul 10 index 2 index mul sub 23 index add % x1
        dup 16 index mul 15 index add % y1
        25 2 roll pop pop
        pop pop pop pop pop pop pop
        pop pop pop pop pop pop pop
        pop pop pop pop pop pop pop
      } ifelse
    } ifelse
  ){#4}%
  \pnode(!
    \pst@tempO \tx@UserCoor % x0,y0
    \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
    \pst@tempA \tx@UserCoor % x1,y1
    \pst@tempB \tx@UserCoor % x2,y2
    3 index 2 index sub abs 1E-5 lt { % if the line AB is vertical
      pop pop pop pop
      #1 dup cos exch sin % \cos\theta \sin\theta
      3 index 2 index mul % e=a\cos\theta
      3 index 2 index mul % f=b\sin\theta
      5 index 3 index mul % g=a\sin\theta
      5 index 5 index mul % h=b\cos\theta
      \pst@tempA \tx@UserCoor pop % x1
      9 index sub % d=x_1-x_o
      4 index dup mul 4 index dup mul add % u=e^2+f^2
      0 index 2 index dup mul sub dup 0 lt { % w=u-d^2
        pop pop pop pop pop pop pop
        pop pop pop pop pop pop
        0 0
      } {
        sqrt % sqrt(w)
        %% c_2=(de-f sqrt(w))/u, s_2=(-df-e sqrt(w))/u
        2 index 7 index mul 6 index 2 index mul sub 2 index div % c2
        3 index 7 index mul 8 index 3 index mul add neg 3 index div % s2
        %% y_{1,2}=gc_{1,2}+hs_{1,2}+y_o
        6 index 2 index mul 6 index 2 index mul add 14 index add % y2
        \pst@tempA \tx@UserCoor pop % x1
        exch 17 2 roll pop pop pop pop pop
        pop pop pop pop pop
        pop pop pop pop pop
      } ifelse
    }{
      0 index 3 index sub 2 index 5 index sub div % k
      2 index 4 index mul 2 index 6 index mul sub 3 index 6 index sub div % t
      #1 dup cos exch sin % \cos\theta \sin\theta
      9 index 2 index mul % e=a\cos\theta
      9 index 2 index mul % f=b\sin\theta
      11 index 3 index mul % g=a\sin\theta
      11 index 5 index mul % h=b\cos\theta
      1 index 8 index 5 index mul sub % A=g-ke
      1 index 9 index 5 index mul add % B=h+kf
      1 index dup mul 1 index dup mul add % C=A^2+B^2
      10 index 19 index mul 18 index sub 10 index add % m=kx_o-y_o+t
      1 index 1 index dup mul sub dup 0 lt { % w=C-m^2
        pop pop pop pop pop pop pop
        pop pop pop pop pop pop pop
        pop pop pop pop pop pop pop
        0 0
      } {
        sqrt % sqrt(w)
        1 index 5 index mul 4 index 2 index mul sub 3 index div % c2
        2 index 5 index mul 6 index 3 index mul add 4 index div % s2
        %% x_{1,2}=ec_{1,2}-fs_{1,2}+x_o,y_{1,2}=kx_{1,2}+t
        10 index 2 index mul 10 index 2 index mul sub 23 index add % x2
        dup 16 index mul 15 index add % y2
        25 2 roll pop pop
        pop pop pop pop pop pop pop
        pop pop pop pop pop pop pop
        pop pop pop pop pop pop pop
      } ifelse
    } ifelse
  ){#5}%
  \Pst@ManageParamList{#4}%
  \Pst@ManageParamList{#5}%
  \endgroup%
}%
%
%% \pstGeneralEllipsePolarNode[Options](O)(a,b)[rotation]{A}{B}{T}
%% Draw the every tangent line through the point $A$ and $B$ on the General Ellipse E and get the insection node T of the two tangent lines.
%% If you not input rotation angle, the default value is $0^\circ$, which is same as \pstEllipse.
%% We call T as the polar point of chord AB, which can be got by the following proposition:
%% Give chord AB on the ellipse, we draw any other two chords PQ and RS, AB and PQ intersect at I, AQ and BP intersect at X, AP and BQ intersect at Y, we call XY is the polar line of point I. Also AB and RS intersect at J, AR and BS intersect at M, AS and BR intersect at N, we call MN is the polar line of point J. Then the intersection T of XY and MN is the polar point of chord AB, i.e. TA is the tangent line through A and TB is the tangent line through B.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the ellipse center O
%% #3 -> [input] the horizontal and vertical radii
%% #4 -> [input] the rotation angle $\theta$ of the major axis.
%% #5 -> [input] the node name A on the ellipse
%% #6 -> [input] the node name B on the ellipse
%% #7 -> [output] the polar point of chord AB
\def\pstGeneralEllipsePolarNode{\@ifnextchar[\Pst@GeneralEllipsePolarNode{\Pst@GeneralEllipsePolarNode[]}}
\def\Pst@GeneralEllipsePolarNode[#1](#2)(#3){%
  \begingroup
    \psset{#1}%
    \def\PST@GENERALELLIPSE@CENTER{#2}%
    \def\PST@GENERALELLIPSE@RADIUS{#3}%
    \@ifnextchar[\Pst@GeneralEllipsePolarNode@i{\Pst@GeneralEllipsePolarNode@i[0]}}
\def\Pst@GeneralEllipsePolarNode@i[#1]#2#3#4{%
    \pstGeneralEllipseRotNode[PointName=none,PointSymbol=none,RotAngle=71](\PST@GENERALELLIPSE@CENTER)(\PST@GENERALELLIPSE@RADIUS)[#1]{@PST@GENERALELLIPSE@POLARAUX@P}
    \pstGeneralEllipseRotNode[PointName=none,PointSymbol=none,RotAngle=-31](\PST@GENERALELLIPSE@CENTER)(\PST@GENERALELLIPSE@RADIUS)[#1]{@PST@GENERALELLIPSE@POLARAUX@Q}
    \pstGeneralEllipseRotNode[PointName=none,PointSymbol=none,RotAngle=-122](\PST@GENERALELLIPSE@CENTER)(\PST@GENERALELLIPSE@RADIUS)[#1]{@PST@GENERALELLIPSE@POLARAUX@R}
    \pstGeneralEllipseRotNode[PointName=none,PointSymbol=none,RotAngle=13](\PST@GENERALELLIPSE@CENTER)(\PST@GENERALELLIPSE@RADIUS)[#1]{@PST@GENERALELLIPSE@POLARAUX@S}
    \pstInterLL[PointName=none,PointSymbol=none]{#2}{@PST@GENERALELLIPSE@POLARAUX@Q}{#3}{@PST@GENERALELLIPSE@POLARAUX@P}{@PST@GENERALELLIPSE@POLARAUX@X}
    \pstInterLL[PointName=none,PointSymbol=none]{#2}{@PST@GENERALELLIPSE@POLARAUX@P}{#3}{@PST@GENERALELLIPSE@POLARAUX@Q}{@PST@GENERALELLIPSE@POLARAUX@Y}
    \pstInterLL[PointName=none,PointSymbol=none]{#2}{@PST@GENERALELLIPSE@POLARAUX@R}{#3}{@PST@GENERALELLIPSE@POLARAUX@S}{@PST@GENERALELLIPSE@POLARAUX@M}
    \pstInterLL[PointName=none,PointSymbol=none]{#2}{@PST@GENERALELLIPSE@POLARAUX@S}{#3}{@PST@GENERALELLIPSE@POLARAUX@R}{@PST@GENERALELLIPSE@POLARAUX@N}
    \pstInterLL[PointName=none,PointSymbol=none]{@PST@GENERALELLIPSE@POLARAUX@X}{@PST@GENERALELLIPSE@POLARAUX@Y}{@PST@GENERALELLIPSE@POLARAUX@M}{@PST@GENERALELLIPSE@POLARAUX@N}{#4}
    \Pst@geonodelabel{#4}%
    \pstLineAB{#2}{#4}
    \pstLineAB{#3}{#4}
  \endgroup%
}%
%
%% \pstGeneralEllipseTangentNode[Options](O)(a,b)[rotation]{T}{A}{B}
%% Draw the two tangent lines through the point $T$ to the General Ellipse E and get the node A and B on the Ellipse.
%% If you not input rotation angle, the default value is $0^\circ$, which is same as \pstEllipse.
%% We use the following proposition to find the tangent node of T:
%% Give point T outside of the ellipse, we draw any other two chords TPQ and TRS, PS and QR intersect at I, PR and QS intersect at X, XI and Ellipse intersect at A and B, then TA is the tangent line through A and TB is the tangent line through B.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the ellipse center O
%% #3 -> [input] the horizontal and vertical radii
%% #4 -> [input] the rotation angle $\theta$ of the major axis.
%% #5 -> [input] the node name T outside the ellipse
%% #6 -> [output] the node name A on the ellipse
%% #7 -> [output] the node name B on the ellipse
\def\pstGeneralEllipseTangentNode{\@ifnextchar[\Pst@GeneralEllipseTangentNode{\Pst@GeneralEllipseTangentNode[]}}
\def\Pst@GeneralEllipseTangentNode[#1](#2)(#3){%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \def\PST@GENERALELLIPSE@CENTER{#2}%
    \def\PST@GENERALELLIPSE@RADIUS{#3}%
    \@ifnextchar[\Pst@GeneralEllipseTangentNode@i{\Pst@GeneralEllipseTangentNode@i[0]}}
\def\Pst@GeneralEllipseTangentNode@i[#1]#2#3#4{%
    \pstGeneralEllipseRotNode[PointName=none,PointSymbol=none,RotAngle=71](\PST@GENERALELLIPSE@CENTER)(\PST@GENERALELLIPSE@RADIUS)[#1]{@PST@GENERALELLIPSE@TANGENTAUX@P0}
    \pstGeneralEllipseRotNode[PointName=none,PointSymbol=none,RotAngle=31](\PST@GENERALELLIPSE@CENTER)(\PST@GENERALELLIPSE@RADIUS)[#1]{@PST@GENERALELLIPSE@TANGENTAUX@R0}
    \pstGeneralEllipseLineInter[PointName=none,PointSymbol=none](\PST@GENERALELLIPSE@CENTER)(\PST@GENERALELLIPSE@RADIUS)[#1]{#2}{@PST@GENERALELLIPSE@TANGENTAUX@P0}{@PST@GENERALELLIPSE@TANGENTAUX@P}{@PST@GENERALELLIPSE@TANGENTAUX@Q}
    \pstGeneralEllipseLineInter[PointName=none,PointSymbol=none](\PST@GENERALELLIPSE@CENTER)(\PST@GENERALELLIPSE@RADIUS)[#1]{#2}{@PST@GENERALELLIPSE@TANGENTAUX@R0}{@PST@GENERALELLIPSE@TANGENTAUX@R}{@PST@GENERALELLIPSE@TANGENTAUX@S}
    \pstInterLL[PointName=none,PointSymbol=none]{@PST@GENERALELLIPSE@TANGENTAUX@P}{@PST@GENERALELLIPSE@TANGENTAUX@S}{@PST@GENERALELLIPSE@TANGENTAUX@Q}{@PST@GENERALELLIPSE@TANGENTAUX@R}{@PST@GENERALELLIPSE@TANGENTAUX@I}
    \pstInterLL[PointName=none,PointSymbol=none]{@PST@GENERALELLIPSE@TANGENTAUX@P}{@PST@GENERALELLIPSE@TANGENTAUX@R}{@PST@GENERALELLIPSE@TANGENTAUX@Q}{@PST@GENERALELLIPSE@TANGENTAUX@S}{@PST@GENERALELLIPSE@TANGENTAUX@X}
    \pstGeneralEllipseLineInter[PointName=none,PointSymbol=none](\PST@GENERALELLIPSE@CENTER)(\PST@GENERALELLIPSE@RADIUS)[#1]{@PST@GENERALELLIPSE@TANGENTAUX@X}{@PST@GENERALELLIPSE@TANGENTAUX@I}{#3}{#4}
    \Pst@ManageParamList{#3}%
    \Pst@ManageParamList{#4}%
    \pstLineAB{#2}{#3}
    \pstLineAB{#2}{#4}
  \endgroup%
}%
%
% 3. Standard Parabola with coordinate translation
%% ----------------------------------------------------------
%% The Parabola P is defined by vertex O, the half of the focus chord axis $abs(p)$, the sign of $p$ indicates the direction of the parabola.
%% The equation can be written as:
%% \begin{equation}\label{FunctionOfStandardParabola}
%% (x-x0)^2=2p(y-y0)
%% \end{equation}
%% and the parametric function can be written as:
%% \begin{equation}\label{ParametricFunctionOfStandardParabola}
%% \left\{\begin{array}{l}
%% x=t+x_o\\
%% y=\dfrac{t^2}{2p}+y_o
%% \end{array}\right.
%% \end{equation}
%
%% \pstParabola[Options](O){p}{x0}{x1}
%% Draw a Parabola from x0 to x1 with Vertex O, the half of the focus chord axis $abs(p)$, the sign of $p$ indicates the direction of the parabola.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the start of independent variable $x$
%% #5 -> [input] the end of independent variable $x$
\def\pstParabola{\@ifnextchar[\Pst@Parabola{\Pst@Parabola[]}}
\def\Pst@Parabola[#1](#2)#3#4#5{%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \parametricplot{#4}{#5}{%
      \pst@tempO \tx@UserCoor % x0,y0
      #3 % p
      2 index t add % t+x0
      2 index t dup mul 3 index 2 mul div add % t^2/(2p)+y0
      5 2 roll pop pop pop % t+x0,t^2/(2p)+y0
    }
  \endgroup%
}%
%
%% \pstParabolaNode[Options](O){p}{$t$}{A}
%% Draw the node whose parameter is the given value $t$ on the Parabola P.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the given parameter value $t$
%% #5 -> [output] the node $A$ on the parabola
\def\pstParabolaNode{\@ifnextchar[\Pst@ParabolaNode{\Pst@ParabolaNode[]}}
\def\Pst@ParabolaNode[#1](#2)#3#4#5{%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      #3 % p
      2 index #4 add % t+x0
      2 index #4 dup mul 3 index 2 mul div add % t^2/(2p)+y0
      5 2 roll pop pop pop % t+x0,t^2/(2p)+y0
    ){#5}
    \Pst@geonodelabel{#5}%
  \endgroup%
}%
%
%% \pstParabolaAbsNode[Options](O){p}{$x_1$}{A}
%% Draw the node whose abscissa is the given value $x_1$ on the Parabola P.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the given abscissa value $x_1$
%% #5 -> [output] the node $A$ on the parabola
\def\pstParabolaAbsNode{\@ifnextchar[\Pst@ParabolaAbsNode{\Pst@ParabolaAbsNode[]}}
\def\Pst@ParabolaAbsNode[#1](#2)#3#4#5{%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      #3 #4 % p x_1
      2 index 1 index 5 index sub dup mul 3 index 2 mul div add % y0+(x_1-x_0)^2/(2p)
      5 2 roll pop pop pop
    ){#5}
    \Pst@geonodelabel{#5}%
  \endgroup%
}%
%
%% \pstParabolaOrdNode[Options](O){p}{$y_1$}{A}{B}
%% Draw the nodes whose ordinate is the given value $y_1$ on the Parabola P.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the given abscissa value $x_1$
%% #5 -> [output] the first node $A$ on the parabola
%% #6 -> [output] the second node $B$ on the parabola
\def\pstParabolaOrdNode{\@ifnextchar[\Pst@ParabolaOrdNode{\Pst@ParabolaOrdNode[]}}
\def\Pst@ParabolaOrdNode[#1](#2)#3#4#5#6{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      #3 #4 % p y_1
      2 index sub mul 2 mul dup 0 lt {
        pop pop pop 0 0
      }{
        sqrt 2 index exch sub
        #4 4 2 roll pop pop
      } ifelse
    ){#5}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      #3 #4 % p y_1
      2 index sub mul 2 mul dup 0 lt {
        pop pop pop 0 0
      }{
        sqrt 2 index add
        #4 4 2 roll pop pop
      } ifelse
    ){#6}
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
  \endgroup%
}%
%
%% \pstParabolaFocusNode[Options](O){p}{F}
%% Draw the focus node of a Parabola P.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [output] the focus node $F$
\def\pstParabolaFocusNode{\@ifnextchar[\Pst@ParabolaFocusNode{\Pst@ParabolaFocusNode[]}}
\def\Pst@ParabolaFocusNode[#1](#2)#3#4{%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      #3 %p
      2 index % x0
      2 index 2 index 2 div add % y0+p/2
      5 2 roll pop pop pop
    ){#4}
    \Pst@geonodelabel{#4}%
  \endgroup%
}%
%
%% \pstParabolaDirectrixLine[Options](O){p}{LA}{LB}
%% Draw the directrix line of a Parabola P.
%% The node LA also lies on the symmetrical axis line, and node LB is another one on the directrix line.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [output] the first node $A$ on the directrix line
%% #5 -> [output] the second node $B$ on the directrix line
\def\pstParabolaDirectrixLine{\@ifnextchar[\Pst@ParabolaDirectrixLine{\Pst@ParabolaDirectrixLine[]}}
\def\Pst@ParabolaDirectrixLine[#1](#2)#3#4#5{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      #3 %p
      2 index % x0
      2 index 2 index 2 div sub % y0-p/2
      5 2 roll pop pop pop
    ){#4}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      #3 %p
      2 index 1 add % x0+1
      2 index 2 index 2 div sub % y0-p/2
      5 2 roll pop pop pop
    ){#5}
    \Pst@ManageParamList{#4}%
    \Pst@ManageParamList{#5}%
    \pstLineAB{#4}{#5}
  \endgroup%
}%
%
%% \pstParabolaLineInter[Options](O){p}{A}{B}{C}{D}
%% Find the intersections C and D of line AB and the Parabola P.
%% We can represent the line AB as the following function when line AB is not vertical:
%% $$y=kx+t$$ where $$k=\dfrac{y_2-y_1}{x_2-x_1},t=\dfrac{x_2y_1-x_1y_2}{x_2-x_1}$$
%% The intersections are:
%% $$x_{1,2}=e\pm\sqrt{w}+x_o, y_{1,2}=kx_{1,2}+t$$
%% where,
%% $$e=pk, w=e^2+2f, f=pm, m=kx_o-y_o+t$$
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the node $A$ on the given line
%% #5 -> [input] the node $B$ on the given line
%% #6 -> [output] the first intersection node $C$
%% #7 -> [output] the second intersection node $D$
\def\pstParabolaLineInter{\@ifnextchar[\Pst@ParabolaLineInter{\Pst@ParabolaLineInter[]}}
\def\Pst@ParabolaLineInter[#1](#2)#3#4#5#6#7{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#4}\pst@tempA%
    \pst@getcoor{#5}\pst@tempB%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempA \tx@UserCoor % x1,y1
      \pst@tempB \tx@UserCoor % x2,y2
      3 index 2 index sub abs 1E-5 lt { % if the line AB is vertical
        3 index 6 index sub dup mul #3 2 mul div 5 index add % y=(x1-x0)^2/(2p)+y0
        2 index exch 8 2 roll pop pop pop pop pop pop
      } {
        0 index 3 index sub 2 index 5 index sub div % k
        2 index 4 index mul 2 index 6 index mul sub 3 index 6 index sub div % t
        #3 %p
        2 index 1 index mul % e=pk
        3 index 10 index mul 9 index sub 3 index add % m=kx_o-y_o+t
        2 index 1 index mul % f=pm
        2 index dup mul 1 index 2 mul add % w=e^2+2f
        dup 0 lt {
          pop pop pop pop pop pop pop
          pop pop pop pop pop pop 0 0
        } {
          sqrt % sqrt(w)
          %% x_{1,2}=e \pm sqrt(w)+x_o,y_{1,2}=kx_{1,2}+t
          3 index 1 index sub 13 index add % x1
          7 index 1 index mul 7 index add % y1
          15 2 roll
          pop pop pop pop pop pop pop
          pop pop pop pop pop pop
        } ifelse
      } ifelse
    ){#6}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempA \tx@UserCoor % x1,y1
      \pst@tempB \tx@UserCoor % x2,y2
      3 index 2 index sub abs 1E-5 lt { % if the line AB is vertical
        pop pop pop pop pop pop 0 0
      } {
        0 index 3 index sub 2 index 5 index sub div % k
        2 index 4 index mul 2 index 6 index mul sub 3 index 6 index sub div % t
        #3 %p
        2 index 1 index mul % e=pk
        3 index 10 index mul 9 index sub 3 index add % m=kx_o-y_o+t
        2 index 1 index mul % f=pm
        2 index dup mul 1 index 2 mul add % w=e^2+2f
        dup 0 lt {
          pop pop pop pop pop pop pop
          pop pop pop pop pop pop 0 0
        } {
          sqrt % sqrt(w)
          %% x_{1,2}=e \pm sqrt(w)+x_o,y_{1,2}=kx_{1,2}+t
          3 index 1 index add 13 index add % x2
          7 index 1 index mul 7 index add % y2
          15 2 roll
          pop pop pop pop pop pop pop
          pop pop pop pop pop pop
        } ifelse
      } ifelse
    ){#7}
    \Pst@ManageParamList{#6}%
    \Pst@ManageParamList{#7}%
  \endgroup%
}%
%
%% \pstParabolaPolarNode[Options](O){p}(F)[L1][L2]{A}{B}{T}
%% Find the polar point of chord AB on Parabola P.
%% We use the following proposition to find the polar point of chord AB:
%% Give any chord AB, drawing two focal chord AFC and BFD, where F is the focus, then drawing FX which is perpendicular to AFC at point F, and intersect with the directrix line at X; also drawing FY which is perpendicular to BFD at point F, and intersect with the directrix line at Y. Then the intersection T of AX and BY is the polar point of chord AB.
%% If you don't know the focus F, or the directrix line, we will find them automated, otherwise you can pass them to this macro.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] optional, the focus node/coordinate F of the parabola.
%% #5 -> [input] optional, the node/coordinate L1 on the directrix line of the parabola.
%% #6 -> [input] optional, the node/coordinate L2 on the directrix line of the parabola.
%% #7 -> [input] the node A on the parabola.
%% #8 -> [input] the node B on the parabola.
%% #9 -> [output] the polar node T of chord AB.
\def\pstParabolaPolarNode{\@ifnextchar[\Pst@ParabolaPolarNode{\Pst@ParabolaPolarNode[]}}
\def\Pst@ParabolaPolarNode[#1](#2)#3{%
  \begingroup
    \psset{#1}%
    \def\pst@parabola@vertex{#2}%
    \def\pst@parabola@semifocalchord{#3}%
    \@ifnextchar(\Pst@ParabolaPolarNode@i{\Pst@ParabolaPolarNode@j}}%
\def\Pst@ParabolaPolarNode@i(#1){%
    \def\pst@parabola@focus{#1}%
    \@ifnextchar[\Pst@ParabolaPolarNode@ii{\Pst@ParabolaPolarNode@jj}}%
\def\Pst@ParabolaPolarNode@j{%
    \pstParabolaFocusNode[PointName=none,PointSymbol=none](\pst@parabola@vertex){\pst@parabola@semifocalchord}{@PST@PARABOLA@FOCUS}
    \Pst@ParabolaPolarNode@i(@PST@PARABOLA@FOCUS)}%
\def\Pst@ParabolaPolarNode@jj{%
    \pstParabolaDirectrixLine[PointName=none,PointSymbol=none,linestyle=none](\pst@parabola@vertex){\pst@parabola@semifocalchord}{@PST@PARABOLA@LA}{@PST@PARABOLA@LB}
    \Pst@ParabolaPolarNode@ii[@PST@PARABOLA@LA][@PST@PARABOLA@LB]}%
\def\Pst@ParabolaPolarNode@ii[#1][#2]#3#4#5{%
    \pstParabolaLineInter[PointName=none,PointSymbol=none,linestyle=none](\pst@parabola@vertex){\pst@parabola@semifocalchord}{#3}{\pst@parabola@focus}{@PST@PARABOLA@FOCALCHORDAFC@A}{@PST@PARABOLA@FOCALCHORDAFC@C}
    \pstParabolaLineInter[PointName=none,PointSymbol=none,linestyle=none](\pst@parabola@vertex){\pst@parabola@semifocalchord}{#4}{\pst@parabola@focus}{@PST@PARABOLA@FOCALCHORDBFD@B}{@PST@PARABOLA@FOCALCHORDBFD@D}
    \pstRotation[PointName=none,PointSymbol=none,RotAngle=90]{\pst@parabola@focus}{@PST@PARABOLA@FOCALCHORDAFC@A}[@PST@PARABOLA@FOCALCHORDAFC@AA]
    \pstRotation[PointName=none,PointSymbol=none,RotAngle=90]{\pst@parabola@focus}{@PST@PARABOLA@FOCALCHORDBFD@B}[@PST@PARABOLA@FOCALCHORDBFD@BB]
    \pstInterLL[PointName=none,PointSymbol=none]{#1}{#2}{\pst@parabola@focus}{@PST@PARABOLA@FOCALCHORDAFC@AA}{@PST@PARABOLA@FOCALCHORD@X}
    \pstInterLL[PointName=none,PointSymbol=none]{#1}{#2}{\pst@parabola@focus}{@PST@PARABOLA@FOCALCHORDBFD@BB}{@PST@PARABOLA@FOCALCHORD@Y}
    \pstInterLL{#3}{@PST@PARABOLA@FOCALCHORD@X}{#4}{@PST@PARABOLA@FOCALCHORD@Y}{#5}
    \Pst@geonodelabel{#5}%
    \pstLineAB{#3}{#5}
    \pstLineAB{#4}{#5}
    \endgroup
}%
%
%% \pstParabolaTangentNode[Options](O){p}{T}{A}{B}
%% Draw the two tangent lines through the point $T$ to the Parabola P and get the node A and B on the Parabola.
%% We use the following proposition to find the tangent node of T:
%% Give point T outside of the parabola, we draw any other two chords TPQ and TRS, PS and QR intersect at I, PR and QS intersect at X, XI and Parabola intersect at A and B, then TA is the tangent line through A and TB is the tangent line through B.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the node name T outside the parabola
%% #5 -> [output] the tangent node name A on the parabola
%% #6 -> [output] the tangent node name B on the parabola
\def\pstParabolaTangentNode{\@ifnextchar[\Pst@ParabolaTangentNode{\Pst@ParabolaTangentNode[]}}
\def\Pst@ParabolaTangentNode[#1](#2)#3#4#5#6{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pstParabolaAbsNode[PointName=none,PointSymbol=none](#2){#3}{\pstAbscissa{#4} \pstAbscissa{#2} le {\pstAbscissa{#2} #3 abs 2 div add}{\pstAbscissa{#2} #3 abs 2 div sub} ifelse}{@PST@PARABOLA@TANGENTAUX@P0}
    \pstParabolaAbsNode[PointName=none,PointSymbol=none](#2){#3}{\pstAbscissa{#4} \pstAbscissa{#2} le {\pstAbscissa{#2} #3 abs 4 div add}{\pstAbscissa{#2} #3 abs 4 div sub} ifelse}{@PST@PARABOLA@TANGENTAUX@R0}
    \pstParabolaLineInter[PointName=none,PointSymbol=none](#2){#3}{#4}{@PST@PARABOLA@TANGENTAUX@P0}{@PST@PARABOLA@TANGENTAUX@P}{@PST@PARABOLA@TANGENTAUX@Q}
    \pstParabolaLineInter[PointName=none,PointSymbol=none](#2){#3}{#4}{@PST@PARABOLA@TANGENTAUX@R0}{@PST@PARABOLA@TANGENTAUX@R}{@PST@PARABOLA@TANGENTAUX@S}
    \pstInterLL[PointName=none,PointSymbol=none]{@PST@PARABOLA@TANGENTAUX@P}{@PST@PARABOLA@TANGENTAUX@S}{@PST@PARABOLA@TANGENTAUX@Q}{@PST@PARABOLA@TANGENTAUX@R}{@PST@PARABOLA@TANGENTAUX@I}
    \pstInterLL[PointName=none,PointSymbol=none]{@PST@PARABOLA@TANGENTAUX@P}{@PST@PARABOLA@TANGENTAUX@R}{@PST@PARABOLA@TANGENTAUX@Q}{@PST@PARABOLA@TANGENTAUX@S}{@PST@PARABOLA@TANGENTAUX@X}
    \pstParabolaLineInter(#2){#3}{@PST@PARABOLA@TANGENTAUX@X}{@PST@PARABOLA@TANGENTAUX@I}{#5}{#6}
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
    \pstLineAB{#4}{#5}
    \pstLineAB{#4}{#6}
  \endgroup%
}%
%
% 4. Standard Conjugate Parabola with coordinate translation
%% ----------------------------------------------------------
%% The Conjugate Parabola P is defined by vertex O, the half of the focus chord axis $abs(p)$, the sign of $p$ indicates the direction of the parabola.
%% The equation can be written as:
%% \begin{equation}\label{StandardConjugateParabola}
%% (y-y0)^2=2p(x-x0)
%% \end{equation}
%% and the parametric function can be written as:
%% \begin{equation}\label{ParametricFunctionOfStandardConjugateParabola}
%% \left\{\begin{array}{l}
%% x=\dfrac{t^2}{2p}+x_o\\
%% y=t+y_o
%% \end{array}\right.
%% \end{equation}
%
%% \pstIParabola[Options](O){p}{y0}{y1}
%% Draw a Conjugate Parabola from y0 to y1 with Vertex O, the half of the focus chord axis $abs{p}$, the sign of $p$ indicates the direction of the parabola.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the start of independent variable $y$
%% #5 -> [input] the end of independent variable $y$
\def\pstIParabola{\@ifnextchar[\Pst@IParabola{\Pst@IParabola[]}}
\def\Pst@IParabola[#1](#2)#3#4#5{%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \parametricplot{#4}{#5}{%
      \pst@tempO \tx@UserCoor % x0,y0
      #3 % p
      1 index t add % t+y0
      3 index t dup mul 3 index 2 mul div add % t^2/(2p)+x0
      5 2 roll pop pop pop % t+y0,t^2/(2p)+x0
      exch % 2pt^2+x0,t+y0
    }
  \endgroup%
}%
%
%% \pstIParabolaNode[Options](O){p}{t}{A}
%% Draw the node whose paramater is the given value $t$ on the Conjugate Parabola P.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the given parameter value $t$
%% #5 -> [output] the node $A$ on the parabola
\def\pstIParabolaNode{\@ifnextchar[\Pst@IParabolaNode{\Pst@IParabolaNode[]}}
\def\Pst@IParabolaNode[#1](#2)#3#4#5{%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      #3 % p
      1 index #4 add % t+y0
      3 index #4 dup mul 3 index 2 mul div add % t^2/(2p)+x0
      5 2 roll pop pop pop % t+y0,t^2/(2p)+x0
      exch % 2pt^2+x0,t+y0
    ){#5}
    \Pst@geonodelabel{#5}%
  \endgroup%
}%
%
%% \pstIParabolaOrdNode[Options](O){p}{$y_1$}{A}
%% Draw the node whose ordinate is the given value $y_1$ on the Conjugate Parabola P.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the given ordinate value $y_1$
%% #5 -> [output] the node $A$ on the parabola
\def\pstIParabolaOrdNode{\@ifnextchar[\Pst@IParabolaOrdNode{\Pst@IParabolaOrdNode[]}}
\def\Pst@IParabolaOrdNode[#1](#2)#3#4#5{%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      #3 #4 % p y_1
      3 index 1 index 4 index sub dup mul 3 index 2 mul div add % x0+(y_1-y_0)^2/(2p)
      exch 5 2 roll pop pop pop
    ){#5}
    \Pst@geonodelabel{#5}%
  \endgroup%
}%
%
%% \pstIParabolaAbsNode[Options](O){p}{$x_1$}{A}{B}
%% Draw the nodes whose abscissa is the given value $x_1$ on the Conjugate Parabola P.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the given abscissa value $x_1$
%% #5 -> [output] the first node $A$ on the parabola
%% #6 -> [output] the second node $B$ on the parabola
\def\pstIParabolaAbsNode{\@ifnextchar[\Pst@IParabolaAbsNode{\Pst@IParabolaAbsNode[]}}
\def\Pst@IParabolaAbsNode[#1](#2)#3#4#5#6{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      #3 #4 % p x_1
      3 index sub mul 2 mul dup 0 lt {
        pop pop pop 0 0
      }{
        sqrt 1 index exch sub
        #4 exch 4 2 roll pop pop
      } ifelse
    ){#5}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      #3 #4 % p x_1
      3 index sub mul 2 mul dup 0 lt {
        pop pop pop 0 0
      }{
        sqrt 1 index add
        #4 exch 4 2 roll pop pop
      } ifelse
    ){#6}
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
  \endgroup%
}%
%
%% \pstIParabolaFocusNode[Options](O){p}{F}
%% Draw the focus node of a Conjugate Parabola P.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [output] the focus node $F$
\def\pstIParabolaFocusNode{\@ifnextchar[\Pst@IParabolaFocusNode{\Pst@IParabolaFocusNode[]}}
\def\Pst@IParabolaFocusNode[#1](#2)#3#4{%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      #3 %p
      2 index 1 index 2 div add % x0+p/2
      2 index % y0
      5 2 roll pop pop pop
    ){#4}
  \Pst@geonodelabel{#4}%
  \endgroup%
}%
%
%% \pstIParabolaDirectrixLine[Options](O){p}{LA}{LB}
%% Draw the directrix line of a Conjugate Parabola P.
%% The node LA also lies on the symmetrical axis line, and node LB is another one on the directrix line.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [output] the first node $A$ on the directrix line
%% #5 -> [output] the second node $B$ on the directrix line
\def\pstIParabolaDirectrixLine{\@ifnextchar[\Pst@IParabolaDirectrixLine{\Pst@IParabolaDirectrixLine[]}}
\def\Pst@IParabolaDirectrixLine[#1](#2)#3#4#5{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      #3 %p
      2 index 1 index 2 div sub % x0-p/2
      2 index % y0
      5 2 roll pop pop pop
    ){#4}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      #3 %p
      2 index 1 index 2 div sub % x0-p/2
      2 index 1 add % y0+1
      5 2 roll pop pop pop
    ){#5}
    \Pst@ManageParamList{#4}%
    \Pst@ManageParamList{#5}%
    \pstLineAB{#4}{#5}
  \endgroup%
}%
%
%% \pstIParabolaLineInter[Options](O){p}{A}{B}{C}{D}
%% Find the intersections C and D of line AB and the Conjugate Parabola P.
%% We can represent the line AB as the following function when line AB is not vertical:
%% $$y=kx+t$$ where $$k=\dfrac{y_2-y_1}{x_2-x_1}, t=\dfrac{x_2y_1-x_1y_2}{x_2-x_1}$$
%% The intersections are:
%% $$x_{1,2}=\dfrac{e\pm\sqrt{w}{k^2+x_o}, y_{1,2}=kx_{1,2}+t$$
%% where,
%% $$e=p-km, w=p^2-2pkm, m=kx_o-y_o+t$$
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the node $A$ on the given line
%% #5 -> [input] the node $B$ on the given line
%% #6 -> [output] the first intersection node $C$
%% #7 -> [output] the second intersection node $D$
\def\pstIParabolaLineInter{\@ifnextchar[\Pst@IParabolaLineInter{\Pst@IParabolaLineInter[]}}
\def\Pst@IParabolaLineInter[#1](#2)#3#4#5#6#7{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#4}\pst@tempA%
    \pst@getcoor{#5}\pst@tempB%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempA \tx@UserCoor % x1,y1
      \pst@tempB \tx@UserCoor % x2,y2
      2 index 1 index sub abs 1E-5 lt { % if the line AB is horizontal
        2 index 5 index sub dup mul #3 2 mul div 6 index add % x=(y1-y0)^2/(2p)+x0
        3 index 8 2 roll pop pop pop pop pop pop
      } {
        3 index 2 index sub abs 1E-5 lt { % if the line AB is vertical
          % y_{1,2}=y0 \pm sqrt(2p(x1-x0))
          4 index #3 2 mul 5 index 8 index sub mul dup 0 lt {
            pop pop pop pop pop pop pop pop 0 0
          }{
            sqrt sub % y1
            2 index exch 8 2 roll pop pop pop pop pop pop
          } ifelse
        } {
          0 index 3 index sub 2 index 5 index sub div % k
          2 index 4 index mul 2 index 6 index mul sub 3 index 6 index sub div % t
          #3 %p
          2 index 9 index mul 8 index sub 2 index add % m=kx_o-y_o+t
          1 index 4 index 2 index mul sub % e=p-km
          2 index dup mul 3 index 2 mul 3 index mul 6 index mul sub % w=p^2-2pkm
          dup 0 lt {
            pop pop pop pop pop pop
            pop pop pop pop pop pop 0 0
          } {
            sqrt % sqrt(w)
            %% x_{1,2}=(e \pm sqrt(w))/k^2+x_o,y_{1,2}=kx_{1,2}+t
            1 index 1 index sub 6 index dup mul div 12 index add % x1
            6 index 1 index mul 6 index add % y1
            14 2 roll
            pop pop pop pop pop pop
            pop pop pop pop pop pop
          } ifelse
        } ifelse
      } ifelse
    ){#6}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempA \tx@UserCoor % x1,y1
      \pst@tempB \tx@UserCoor % x2,y2
      2 index 1 index sub abs 1E-5 lt { % if the line AB is horizontal
        pop pop pop pop pop pop 0 0
      } {
        3 index 2 index sub abs 1E-5 lt { % if the line AB is vertical
          % y_{1,2}=y0 \pm sqrt(2p(x1-x0))
          4 index #3 2 mul 5 index 8 index sub mul dup 0 lt {
            pop pop pop pop pop pop pop pop 0 0
          }{
            sqrt add % y2
            2 index exch 8 2 roll pop pop pop pop pop pop
          } ifelse
        } {
          0 index 3 index sub 2 index 5 index sub div % k
          2 index 4 index mul 2 index 6 index mul sub 3 index 6 index sub div % t
          #3 %p
          2 index 9 index mul 8 index sub 2 index add % m=kx_o-y_o+t
          1 index 4 index 2 index mul sub % e=p-km
          2 index dup mul 3 index 2 mul 3 index mul 6 index mul sub % w=p^2-2pkm
          dup 0 lt {
            pop pop pop pop pop pop
            pop pop pop pop pop pop 0 0
          } {
            sqrt % sqrt(w)
            %% x_{1,2}=(e \pm sqrt(w))/k^2+x_o,y_{1,2}=kx_{1,2}+t
            1 index 1 index add 6 index dup mul div 12 index add % x1
            6 index 1 index mul 6 index add % y1
            14 2 roll
            pop pop pop pop pop pop
            pop pop pop pop pop pop
          } ifelse
        } ifelse
      } ifelse
    ){#7}
    \Pst@ManageParamList{#6}%
    \Pst@ManageParamList{#7}%
  \endgroup%
}%
%
%% \pstIParabolaPolarNode[Options](O){p}(F)[L1][L2]{A}{B}{T}
%% Find the polar point of chord AB on Conjugate Parabola P.
%% We use the following proposition to find the polar point of chord AB:
%% Give any chord AB, drawing two focal chord AFC and BFD, where F is the focus, then drawing FX which is perpendicular to AFC at point F, and intersect with the directrix line at X; also drawing FY which is perpendicular to BFD at point F, and intersect with the directrix line at Y. Then the intersection T of AX and BY is the polar point of chord AB.
%% If you don't know the focus F, or the directrix line, we will find them automated, otherwise you can pass them to this macro.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] optional, the focus node/coordinate F of the parabola.
%% #5 -> [input] optional, the node/coordinate L1 on the directrix line of the parabola.
%% #6 -> [input] optional, the node/coordinate L2 on the directrix line of the parabola.
%% #7 -> [input] the node A on the parabola.
%% #8 -> [input] the node B on the parabola.
%% #9 -> [output] the polar node T of chord AB.
\def\pstIParabolaPolarNode{\@ifnextchar[\Pst@IParabolaPolarNode{\Pst@IParabolaPolarNode[]}}
\def\Pst@IParabolaPolarNode[#1](#2)#3{%
  \begingroup
    \psset{#1}%
    \def\pst@parabola@vertex{#2}%
    \def\pst@parabola@semifocalchord{#3}%
    \@ifnextchar(\Pst@IParabolaPolarNode@i{\Pst@IParabolaPolarNode@j}}%
\def\Pst@IParabolaPolarNode@i(#1){%
    \def\pst@parabola@focus{#1}%
    \@ifnextchar[\Pst@IParabolaPolarNode@ii{\Pst@IParabolaPolarNode@jj}}%
\def\Pst@IParabolaPolarNode@j{%
    \pstIParabolaFocusNode[PointName=none,PointSymbol=none](\pst@parabola@vertex){\pst@parabola@semifocalchord}{@PST@IPARABOLA@FOCUS}
    \Pst@IParabolaPolarNode@i(@PST@IPARABOLA@FOCUS)}%
\def\Pst@IParabolaPolarNode@jj{%
    \pstIParabolaDirectrixLine[PointName=none,PointSymbol=none,linestyle=none](\pst@parabola@vertex){\pst@parabola@semifocalchord}{@PST@IPARABOLA@LA}{@PST@IPARABOLA@LB}
    \Pst@IParabolaPolarNode@ii[@PST@IPARABOLA@LA][@PST@IPARABOLA@LB]}%
\def\Pst@IParabolaPolarNode@ii[#1][#2]#3#4#5{%
    \pstIParabolaLineInter[PointName=none,PointSymbol=none,linestyle=none](\pst@parabola@vertex){\pst@parabola@semifocalchord}{#3}{\pst@parabola@focus}{@PST@IPARABOLA@FOCALCHORDAFC@A}{@PST@IPARABOLA@FOCALCHORDAFC@C}
    \pstIParabolaLineInter[PointName=none,PointSymbol=none,linestyle=none](\pst@parabola@vertex){\pst@parabola@semifocalchord}{#4}{\pst@parabola@focus}{@PST@IPARABOLA@FOCALCHORDBFD@B}{@PST@IPARABOLA@FOCALCHORDBFD@D}
    \pstRotation[PointName=none,PointSymbol=none,RotAngle=90]{\pst@parabola@focus}{@PST@IPARABOLA@FOCALCHORDAFC@A}[@PST@IPARABOLA@FOCALCHORDAFC@AA]
    \pstRotation[PointName=none,PointSymbol=none,RotAngle=90]{\pst@parabola@focus}{@PST@IPARABOLA@FOCALCHORDBFD@B}[@PST@IPARABOLA@FOCALCHORDBFD@BB]
    \pstInterLL[PointName=none,PointSymbol=none]{#1}{#2}{\pst@parabola@focus}{@PST@IPARABOLA@FOCALCHORDAFC@AA}{@PST@IPARABOLA@FOCALCHORD@X}
    \pstInterLL[PointName=none,PointSymbol=none]{#1}{#2}{\pst@parabola@focus}{@PST@IPARABOLA@FOCALCHORDBFD@BB}{@PST@IPARABOLA@FOCALCHORD@Y}
    \pstInterLL{#3}{@PST@IPARABOLA@FOCALCHORD@X}{#4}{@PST@IPARABOLA@FOCALCHORD@Y}{#5}
    \Pst@geonodelabel{#5}%
    \pstLineAB{#3}{#5}
    \pstLineAB{#4}{#5}
    \endgroup
}%
%
%% \pstIParabolaTangentNode[Options](O){p}{T}{A}{B}
%% Draw the two tangent lines through the point $T$ to the Conjugate Parabola P and get the node A and B on the Conjugate Parabola.
%% We use the following proposition to find the tangent node of T:
%% Give point T outside of the parabola, we draw any other two chords TPQ and TRS, PS and QR intersect at I, PR and QS intersect at X, XI and Parabola intersect at A and B, then TA is the tangent line through A and TB is the tangent line through B.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the node name T outside the parabola
%% #5 -> [output] the tangent node name A on the parabola
%% #6 -> [output] the tangent node name B on the parabola
\def\pstIParabolaTangentNode{\@ifnextchar[\Pst@IParabolaTangentNode{\Pst@IParabolaTangentNode[]}}
\def\Pst@IParabolaTangentNode[#1](#2)#3#4#5#6{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pstIParabolaOrdNode[PointName=none,PointSymbol=none](#2){#3}{\pstOrdinate{#4} \pstOrdinate{#2} le {\pstOrdinate{#2} #3 abs 2 div add}{\pstOrdinate{#2} #3 abs 2 div sub} ifelse}{@PST@IPARABOLA@TANGENTAUX@P0}
    \pstIParabolaOrdNode[PointName=none,PointSymbol=none](#2){#3}{\pstOrdinate{#4} \pstOrdinate{#2} le {\pstOrdinate{#2} #3 abs 4 div add}{\pstOrdinate{#2} #3 abs 4 div sub} ifelse}{@PST@IPARABOLA@TANGENTAUX@R0}
    \pstIParabolaLineInter[PointName=none,PointSymbol=none](#2){#3}{#4}{@PST@IPARABOLA@TANGENTAUX@P0}{@PST@IPARABOLA@TANGENTAUX@P}{@PST@IPARABOLA@TANGENTAUX@Q}
    \pstIParabolaLineInter[PointName=none,PointSymbol=none](#2){#3}{#4}{@PST@IPARABOLA@TANGENTAUX@R0}{@PST@IPARABOLA@TANGENTAUX@R}{@PST@IPARABOLA@TANGENTAUX@S}
    \pstInterLL[PointName=none,PointSymbol=none]{@PST@IPARABOLA@TANGENTAUX@P}{@PST@IPARABOLA@TANGENTAUX@S}{@PST@IPARABOLA@TANGENTAUX@Q}{@PST@IPARABOLA@TANGENTAUX@R}{@PST@IPARABOLA@TANGENTAUX@I}
    \pstInterLL[PointName=none,PointSymbol=none]{@PST@IPARABOLA@TANGENTAUX@P}{@PST@IPARABOLA@TANGENTAUX@R}{@PST@IPARABOLA@TANGENTAUX@Q}{@PST@IPARABOLA@TANGENTAUX@S}{@PST@IPARABOLA@TANGENTAUX@X}
    \pstIParabolaLineInter(#2){#3}{@PST@IPARABOLA@TANGENTAUX@X}{@PST@IPARABOLA@TANGENTAUX@I}{#5}{#6}
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
    \pstLineAB{#4}{#5}
    \pstLineAB{#4}{#6}
  \endgroup%
}%
%
% 5. General Parabola with coordinate translation and rotation
%% ----------------------------------------------------------
%% The General Parabola P is defined by vertex O, 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 equation can be got from the parametric function of the parabola \ref{ParametricFunctionOfStandardParabola},
%% using the rotation transform formula \ref{RotationTransformFormula}, then we have
%% \begin{equation}
%% \left\{\begin{array}{l}
%% x'=(t+x_o)\cos\theta-(\dfrac{t^2}{2p}+y_o)\sin\theta=x_o'+t\cos\theta-t^2\dfrac{\sin\theta}{2p}\\
%% y'=(t+x_o)\sin\theta+(\dfrac{t^2}{2p}+y_o)\cos\theta=y_o'+t\sin\theta+t^2\dfrac{\cos\theta}{2p}
%% \end{array}\right.
%% \end{equation}
%% where the $x_o'$ and $y_o'$ are the coordinate of the given vertex O after rotation.
%% So we get the parametric function of the General Parabola with coordinate translation and rotation as following:
%% \begin{equation}\label{ParametricFunctionOfGeneralParabola}
%% \left\{\begin{array}{l}
%% x=x_o+t\cos\theta-t^2\dfrac{\sin\theta}{2p}\\
%% y=y_o+t\sin\theta+t^2\dfrac{\cos\theta}{2p}
%% \end{array}\right.
%% \end{equation}
%
%% \pstGeneralParabola[Options](O){p}[rotation]{x0}{x1}
%% Draw a General Parabola from x0 to x1 with Vertex O, the half of the focus chord axis $p$, the sign of $p$ indicates the direction of the parabola,
%% and the rotation angle $\theta$ of the symmetrical axis.
%% If you not input the rotation angle, the default value is $0^\circ$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the start of independent variable $x$
%% #6 -> [input] the end of independent variable $x$
\def\pstGeneralParabola{\@ifnextchar[\Pst@GeneralParabola{\Pst@GeneralParabola[]}}
\def\Pst@GeneralParabola[#1](#2)#3{%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO %
    \def\pst@parabola@semifocalchord{#3}%
    \@ifnextchar[\Pst@GeneralParabola@i{\Pst@GeneralParabola@i[0]}}%
\def\Pst@GeneralParabola@i[#1]#2#3{%
    \parametricplot{#2}{#3}{%
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@parabola@semifocalchord\space % p
      #1 dup cos exch sin % \cos\theta \sin\theta
      4 index 2 index t mul add % x_o+t\cos\theta
      3 index 2 mul t dup mul exch div % t^2/(2p)
      2 index mul sub % x_o+t\cos\theta-t^2\dfrac{\sin\theta}{2p}
      4 index 2 index t mul add % y_o+t\sin\theta
      4 index 2 mul t dup mul exch div % t^2/(2p)
      4 index mul add % y_o+t\sin\theta+t^2\dfrac{\cos\theta}{2p}
      7 2 roll pop pop pop pop pop
    }
  \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\space 2 div /CurveCoefb ED
      \CurveCoefc /CurveCoefc ED
      \CurveCoefd\space 2 div /CurveCoefd ED
      \CurveCoefe\space 2 div /CurveCoefe ED
      \CurveCoeff /CurveCoeff ED
      % CurveCoefa = CurveCoefb = CurveCoefc = CurveCoefd = CurveCoefe = CurveCoeff =
      % I1=a+c
      CurveCoefa CurveCoefc add /DiscriminantI ED
      % I2=ac-b^2
      CurveCoefa CurveCoefc mul CurveCoefb dup mul sub /DiscriminantII ED
      % I3=|a b d,b c e,d e f|
      CurveCoefa CurveCoefb CurveCoefd
      CurveCoefb CurveCoefc CurveCoefe
      CurveCoefd CurveCoefe CurveCoeff
      tx@EcldDict begin DeterminantThree end /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 {
              2 CurveCoefb mul neg CurveCoefc CurveCoefa sub atan /MyParabolaAngDbl ED
              MyParabolaAngDbl 2 div /#5 ED
            } {
              2 CurveCoefb mul 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 2 CurveCoefb mul MySin MyCos mul mul add
        CurveCoefc MySin dup mul mul add /MyCoefa ED
        CurveCoefa MySin dup mul mul 2 CurveCoefb mul MySin MyCos mul mul sub
        CurveCoefc MyCos dup mul mul add /MyCoefc ED
        2 CurveCoefd mul MyCos mul 2 CurveCoefe mul MySin mul add /MyCoefd ED
        2 CurveCoefe mul MyCos mul 2 CurveCoefd mul 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 % general conjugate 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 =
        %(--------------) =
      } {
        (These five points can not construct a parabola!) =
        DiscriminantII abs 1E-5 lt DiscriminantIII abs 1E-5 lt and { % if I2=0 and I3=0
          (May be they are two lines!) =
        } {
          DiscriminantII 0 gt {
            (May be they can construct an ellipse!) =
          } {
            (May be they can construct a hyperbola!) =
          } ifelse
        } ifelse
        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 curve 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 2 div /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 2 div /CurveCoefd ED
        CurveLineCDCoefB CurveLineABCoefC mul CurveLineABCoefB CurveLineCDCoefC mul add
        CurveLineBDCoefB CurveLineACCoefC mul CurveLineACCoefB CurveLineBDCoefC mul add CurveLambda mul add 2 div /CurveCoefe ED
        CurveLineABCoefC CurveLineCDCoefC mul CurveLineACCoefC CurveLineBDCoefC mul CurveLambda mul add /CurveCoeff ED
        % CurveCoefa = CurveCoefb = CurveCoefc = CurveCoefd = CurveCoefe = CurveCoeff =
        0 /CurveCoefMax ED 1E8 /CurveCoefMin ED
        CurveCoefa abs CurveCoefMax gt {CurveCoefa abs /CurveCoefMax ED} if
        CurveCoefb abs CurveCoefMax gt {CurveCoefb abs /CurveCoefMax ED} if
        CurveCoefc abs CurveCoefMax gt {CurveCoefc abs /CurveCoefMax ED} if
        CurveCoefd abs CurveCoefMax gt {CurveCoefd abs /CurveCoefMax ED} if
        CurveCoefe abs CurveCoefMax gt {CurveCoefe abs /CurveCoefMax ED} if
        CurveCoeff abs CurveCoefMax gt {CurveCoeff abs /CurveCoefMax ED} if
        CurveCoefa abs CurveCoefMin lt {CurveCoefa abs /CurveCoefMin ED} if
        CurveCoefb abs CurveCoefMin lt {CurveCoefb abs /CurveCoefMin ED} if
        CurveCoefc abs CurveCoefMin lt {CurveCoefc abs /CurveCoefMin ED} if
        CurveCoefd abs CurveCoefMin lt {CurveCoefd abs /CurveCoefMin ED} if
        CurveCoefe abs CurveCoefMin lt {CurveCoefe abs /CurveCoefMin ED} if
        CurveCoeff abs CurveCoefMin lt {CurveCoeff abs /CurveCoefMin ED} if
        % CurveCoefMin = CurveCoefMax =
        CurveCoefMin CurveCoefMax div 1E-5 lt {
          CurveCoefa CurveCoefMax div /CurveCoefa ED
          CurveCoefb CurveCoefMax div /CurveCoefb ED
          CurveCoefc CurveCoefMax div /CurveCoefc ED
          CurveCoefd CurveCoefMax div /CurveCoefd ED
          CurveCoefe CurveCoefMax div /CurveCoefe ED
          CurveCoeff CurveCoefMax div /CurveCoeff ED
        } if
        % CurveCoefa = CurveCoefb = CurveCoefc = CurveCoefd = CurveCoefe = CurveCoeff =
        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=ac-b^2
        CurveCoefa CurveCoefc mul CurveCoefb dup mul sub /DiscriminantII ED
        % I3=|a b d,b c e,d e f|
        CurveCoefa CurveCoefb CurveCoefd
        CurveCoefb CurveCoefc CurveCoefe
        CurveCoefd CurveCoefe CurveCoeff
        tx@EcldDict begin DeterminantThree end /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 {
                2 CurveCoefb mul neg CurveCoefc CurveCoefa sub atan /MyParabolaAngDbl ED
                MyParabolaAngDbl 2 div /#9 ED
              } {
                2 CurveCoefb mul 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 2 CurveCoefb mul MySin MyCos mul mul add
          CurveCoefc MySin dup mul mul add /MyCoefa ED
          CurveCoefa MySin dup mul mul 2 CurveCoefb mul MySin MyCos mul mul sub
          CurveCoefc MyCos dup mul mul add /MyCoefc ED
          2 CurveCoefd mul MyCos mul 2 CurveCoefe mul MySin mul add /MyCoefd ED
          2 CurveCoefe mul MyCos mul 2 CurveCoefd mul 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 % general conjugate 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 abs 1E-5 lt DiscriminantIII abs 1E-5 lt and { % if I2=0 and I3=0
            (May be they are two lines!) =
          } {
            DiscriminantII 0 gt {
              (May be they can construct an ellipse!) =
            } {
              (May be they can construct a hyperbola!) =
            } ifelse
          } 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$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the parameter t to get the node on the parabola.
%% #6 -> [output] the target node A on the parabola.
\def\pstGeneralParabolaNode{\@ifnextchar[\Pst@GeneralParabolaNode{\Pst@GeneralParabolaNode[]}}
\def\Pst@GeneralParabolaNode[#1](#2)#3{%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO %
    \def\pst@parabola@semifocalchord{#3}%
    \@ifnextchar[\Pst@GeneralParabolaNode@i{\Pst@GeneralParabolaNode@i[0]}}%
\def\Pst@GeneralParabolaNode@i[#1]#2#3{%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@parabola@semifocalchord\space % p
      #1 dup cos exch sin % \cos\theta \sin\theta
      4 index 2 index #2 mul add % x_o+t\cos\theta
      3 index 2 mul #2 dup mul exch div % t^2/(2p)
      2 index mul sub % x_o+t\cos\theta-t^2\dfrac{\sin\theta}{2p}
      4 index 2 index #2 mul add % y_o+t\sin\theta
      4 index 2 mul #2 dup mul exch div % t^2/(2p)
      4 index mul add % y_o+t\sin\theta+t^2\dfrac{\cos\theta}{2p}
      7 2 roll pop pop pop pop pop
    ){#3}
    \Pst@geonodelabel{#3}%
  \endgroup%
}%
%
%% \pstGeneralParabolaAbsNode[Options](O){p}[rotation]{$x_1$}{A}{B}
%% Draw the nodes whose abscissas are the given value $x_1$ on the General Parabola P.
%% If you not input the rotation angle, the default value is $0^\circ$.
%% We use the parametric function \ref{ParametricFunctionOfGeneralParabola}, when $x$ equals $x_1$, we have
%% $$t=\dfrac{p\cos\theta \pm \sqrt{p^2\cos^2\theta-2p(x_1-x_o)\sin\theta}}{\sin\theta} or x_1-x_o when \sin\theta=0$$
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the given abscissa value $x_1$
%% #6 -> [output] the target node A on the parabola.
%% #7 -> [output] the target node B on the parabola.
\def\pstGeneralParabolaAbsNode{\@ifnextchar[\Pst@GeneralParabolaAbsNode{\Pst@GeneralParabolaAbsNode[]}}
\def\Pst@GeneralParabolaAbsNode[#1](#2)#3{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \def\pst@parabola@semifocalchord{#3}%
    \@ifnextchar[\Pst@GeneralParabolaAbsNode@i{\Pst@GeneralParabolaAbsNode@i[0]}}%
\def\Pst@GeneralParabolaAbsNode@i[#1]#2#3#4{%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@parabola@semifocalchord\space #2 % p x_1
      #1 dup cos exch sin % \cos\theta \sin\theta
      dup abs 1E-5 lt { % like ZeroEq
        2 index 6 index sub % t
        5 index 1 index dup mul 6 index 2 mul div add % y=y_o+t^2/(2p)
        4 index exch 9 2 roll pop pop pop pop pop pop pop
      } {
        3 index dup mul 2 index dup mul mul % p^2\cos^2\theta
        4 index 2 mul 4 index 8 index sub mul 2 index mul % 2p(x_1-x_o)\sin\theta
        sub dup 0 lt {
          pop pop pop pop pop pop pop 0 0
        } {
          sqrt 4 index 3 index mul exch sub 1 index div % t_1
          5 index 1 index 3 index mul add 1 index dup mul 6 index 2 mul div 4 index mul add % y_1
          4 index exch 9 2 roll pop pop pop pop pop pop pop
        } ifelse
      } ifelse
    ){#3}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@parabola@semifocalchord\space #2 % p x_1
      #1 dup cos exch sin % \cos\theta \sin\theta
      dup abs 1E-5 lt { % like ZeroEq
        pop pop pop pop pop pop 0 0
      } {
        3 index dup mul 2 index dup mul mul % p^2\cos^2\theta
        4 index 2 mul 4 index 8 index sub mul 2 index mul % 2p(x_1-x_o)\sin\theta
        sub dup 0 lt {
          pop pop pop pop pop pop pop 0 0
        } {
          sqrt 4 index 3 index mul add 1 index div % t_2
          5 index 1 index 3 index mul add 1 index dup mul 6 index 2 mul div 4 index mul add % y_2
          4 index exch 9 2 roll pop pop pop pop pop pop pop
        } ifelse
      } ifelse
    ){#4}
    \Pst@ManageParamList{#3}%
    \Pst@ManageParamList{#4}%
  \endgroup%
}%
%
%% \pstGeneralParabolaOrdNode[Options](O){p}[rotation]{$y_1$}{A}{B}
%% Draw the nodes whose ordinates are the given value $y_1$ on the General Parabola P.
%% If you not input the rotation angle, the default value is $0^\circ$.
%% We use the parametric function \ref{ParametricFunctionOfGeneralParabola}, when y equals $y_1$, we have
%% $$t=\dfrac{-p\sin\theta \pm \sqrt{p^2\sin^2\theta+2p(y_1-y_0)\cos\theta}{\cos\theta} or y_1-y_o when \cos\theta=0$$
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the given ordinate value $y_1$
%% #6 -> [output] the target node A on the parabola.
%% #7 -> [output] the target node B on the parabola.
\def\pstGeneralParabolaOrdNode{\@ifnextchar[\Pst@GeneralParabolaOrdNode{\Pst@GeneralParabolaOrdNode[]}}
\def\Pst@GeneralParabolaOrdNode[#1](#2)#3{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \def\pst@parabola@semifocalchord{#3}%
    \@ifnextchar[\Pst@GeneralParabolaOrdNode@i{\Pst@GeneralParabolaOrdNode@i[0]}}%
\def\Pst@GeneralParabolaOrdNode@i[#1]#2#3#4{%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@parabola@semifocalchord\space #2 % p y_1
      #1 dup cos exch sin % \cos\theta \sin\theta
      1 index abs 1E-5 lt { % if \cos\theta=0
        2 index 5 index sub % t
        6 index 1 index dup mul 6 index 2 mul div sub % x=x_o-t^2/(2p)
        4 index 9 2 roll pop pop pop pop pop pop pop
      } {
        3 index dup mul 1 index dup mul mul % p^2\sin^2\theta
        4 index 2 mul 4 index 7 index sub mul 3 index mul % 2p(y_1-y_o)\cos\theta
        add dup 0 lt {
          pop pop pop pop pop pop pop 0 0
        } {
          sqrt 4 index 2 index mul add neg 2 index div % t_1
          6 index 1 index 4 index mul add 1 index dup mul 6 index 2 mul div 3 index mul sub % x_1
          4 index 9 2 roll pop pop pop pop pop pop pop
        } ifelse
      } ifelse
    ){#3}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@parabola@semifocalchord\space #2 % p y_1
      #1 dup cos exch sin % \cos\theta \sin\theta
      1 index abs 1E-5 lt { % if \cos\theta=0
        pop pop pop pop pop pop 0 0
      } {
        3 index dup mul 1 index dup mul mul % p^2\sin^2\theta
        4 index 2 mul 4 index 7 index sub mul 3 index mul % 2p(y_1-y_o)\cos\theta
        add dup 0 lt {
          pop pop pop pop pop pop pop 0 0
        } {
          sqrt 4 index 2 index mul sub 2 index div % t_2
          6 index 1 index 4 index mul add 1 index dup mul 6 index 2 mul div 3 index mul sub % x_2
          4 index 9 2 roll pop pop pop pop pop pop pop
        } ifelse
      } ifelse
    ){#4}
    \Pst@ManageParamList{#3}%
    \Pst@ManageParamList{#4}%
  \endgroup%
}%
%
%% \pstGeneralParabolaFocusNode[Options](O){p}[rotation]{F}
%% Draw the focus nodes of the General Parabola P.
%% If you not input the rotation angle, the default value is $0^\circ$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [output] the focus node A of the parabola.
\def\pstGeneralParabolaFocusNode{\@ifnextchar[\Pst@GeneralParabolaFocusNode{\Pst@GeneralParabolaFocusNode[]}}
\def\Pst@GeneralParabolaFocusNode[#1](#2)#3{%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \def\pst@parabola@semifocalchord{#3}%
    \@ifnextchar[\Pst@GeneralParabolaFocusNode@i{\Pst@GeneralParabolaFocusNode@i[0]}}%
\def\Pst@GeneralParabolaFocusNode@i[#1]#2{%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@parabola@semifocalchord\space 2 div % p/2
      #1 dup cos exch sin % \cos\theta \sin\theta
      4 index 3 index 2 index mul sub % x=x0-p/2\sin\theta
      4 index 4 index 4 index mul add % y=y0+p/2\cos\theta
      7 2 roll pop pop pop pop pop
    ){#2}
    \Pst@geonodelabel{#2}%
  \endgroup%
}%
%
%% \pstGeneralParabolaDirectrixLine[Options](O){p}[rotation]{LA}{LB}
%% Draw the directrix line of the General Parabola P.
%% If you not input the rotation angle, the default value is $0^\circ$.
%% The node LA also lies on the symmetrical axis line, and node LB is another one on the directrix line.
%% they can be got after the orig nodes rotation $\theta$ about the vertex $O$,
%% please refer to the extension rotation formula \ref{ExtensionRotationTransformFormula}.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [output] the first node LA on the directrix line.
%% #6 -> [output] the second node LB on the directrix line.
\def\pstGeneralParabolaDirectrixLine{\@ifnextchar[\Pst@GeneralParabolaDirectrixLine{\Pst@GeneralParabolaDirectrixLine[]}}
\def\Pst@GeneralParabolaDirectrixLine[#1](#2)#3{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \def\pst@parabola@semifocalchord{#3}%
    \@ifnextchar[\Pst@GeneralParabolaDirectrixLine@i{\Pst@GeneralParabolaDirectrixLine@i[0]}}%
\def\Pst@GeneralParabolaDirectrixLine@i[#1]#2#3{%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@parabola@semifocalchord\space 2 div % p/2
      2 index 2 index 2 index sub 5 2 roll pop
      #1 cos #1 sin % x y x0 y0 \cos\theta \sin\theta
      3 index 6 index 5 index sub 3 index mul add 5 index 4 index sub 2 index mul sub % x0+(x-x0)\cos\theta-(y-y0)\sin\theta
      3 index 7 index 6 index sub 3 index mul add 6 index 5 index sub 4 index mul add % y0+(x-x0)\sin\theta+(y-y0)\cos\theta
      8 2 roll pop pop pop pop pop pop
    ){#2}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@parabola@semifocalchord\space 2 div % p/2
      2 index 1 add 2 index 2 index sub 5 2 roll pop
      #1 cos #1 sin % x y x0 y0 \cos\theta \sin\theta
      3 index 6 index 5 index sub 3 index mul add 5 index 4 index sub 2 index mul sub % x0+(x-x0)\cos\theta-(y-y0)\sin\theta
      3 index 7 index 6 index sub 3 index mul add 6 index 5 index sub 4 index mul add % y0+(x-x0)\sin\theta+(y-y0)\cos\theta
      8 2 roll pop pop pop pop pop pop
    ){#3}
    \Pst@ManageParamList{#2}%
    \Pst@ManageParamList{#3}%
    \pstLineAB{#2}{#3}
  \endgroup%
}%
%
%% \pstGeneralParabolaLineInter[Options](O){p}[rotation]{A}{B}{C}{D}
%% Find the intersections C and D of line AB and the General Parabola P.
%% If you not input the rotation angle, the default value is $0^\circ$.
%%
%% Case 1. When line AB is vertical, i.e, $x_1=x_2$, we have
%% Case 1.1 When $\sin\theta=0$, we have
%% $$t=x_1-x_o$$
%% and $x_{C}=x_1,y_{C}=y_o+\dfrac{t^2}{2p}$, but D is not defined.
%% Case 1.2 When $\sin\theta\neq0$, we have
%% $$t_{1,2}=\dfrac{p\cos\theta \pm \sqrt{p^2\cos^2\theta-2p(x_1-x_o)\sin\theta}}{\sin\theta}$$
%% and $x_{C,D}=x_1,y_{C,D}=y_o+t_{1,2}\sin\theta+\dfrac{t_{1,2}^2}{2p}\cos\theta$.
%% Case 2. When line AB is not vertical, we can represent the line AB as the following function:
%% $$y=kx+d$$ where $$k=\dfrac{y_2-y_1}{x_2-x_1}, d=\dfrac{x_2y_1-x_1y_2}{x_2-x_1}
%% refer to equation (\ref{ParametricFunctionOfGeneralParabola}), we have
%% $$ft^2-2pet-2pm=0$$
%% where
%% $$m=kx_o-y_o+d,e=k\cos\theta-\sin\theta,f=k\sin\theta+\cos\theta$$
%% Case 2.1 When $f=k\sin\theta+\cos\theta=0$, which gives $\sin\theta\neq0$ and $k=-\dfrac{\cos\theta}{\sin\theta}$,
%% at this time, we have $t=m\sin\theta$ and then
%% $$x_{C}=x_o+t\cos\theta-\dfrac{t^2}{2p}\sin\theta, y_{C}=y_o+t\sin\theta+\dfrac{t^2}{2p}\cos\theta$$
%% but D is not defined.
%% Case 2.2 When $f=k\sin\theta+\cos\theta\neq0$, we have $t_{1,2}=\dfrac{pe\pm\sqrt{(pe)^2+2fmp}}{f}$, and then
%% $$x_{C,D}=x_o+t_{1,2}\cos\theta-\dfrac{t_{1,2}^2}{2p}\sin\theta, y_{C,D}=y_o+t_{1,2}\sin\theta+\dfrac{t_{1,2}^2}{2p}\cos\theta$$
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the node $A$ on the given line
%% #6 -> [input] the node $B$ on the given line
%% #7 -> [output] the first intersection node $C$
%% #8 -> [output] the second intersection node $D$
\def\pstGeneralParabolaLineInter{\@ifnextchar[\Pst@GeneralParabolaLineInter{\Pst@GeneralParabolaLineInter[]}}
\def\Pst@GeneralParabolaLineInter[#1](#2)#3{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \def\pst@parabola@semifocalchord{#3}%
    \@ifnextchar[\Pst@GeneralParabolaLineInter@i{\Pst@GeneralParabolaLineInter@i[0]}}%
\def\Pst@GeneralParabolaLineInter@i[#1]#2#3#4#5{%
    \pst@getcoor{#2}\pst@tempA%
    \pst@getcoor{#3}\pst@tempB%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempA \tx@UserCoor % x1,y1
      \pst@tempB \tx@UserCoor % x2,y2
      3 index 2 index sub abs 1E-5 lt { % if the line AB is vertical
        #1 dup cos exch sin % \cos\theta \sin\theta
        dup abs 1E-5 lt { % like ZeroEq % if \sin\theta=0
          5 index 8 index sub % t=x1-x0
          7 index 1 index dup mul \pst@parabola@semifocalchord\space 2 mul div add % y=y_o+t^2/(2p)
          7 index exch 9 2 roll pop pop pop pop pop pop pop
        } {
          \pst@parabola@semifocalchord\space %p
          2 index 1 index mul % p\cos\theta
          dup dup mul 2 index 2 mul 9 index 12 index sub mul 4 index mul sub % p^2\cos^2\theta-2p(x_1-x_o)\sin\theta
          dup 0 lt {
            pop pop pop pop pop
            pop pop pop pop pop
            pop 0 0
          } {
            sqrt 1 index exch sub 3 index div % t_1
            9 index 1 index 5 index mul add 1 index dup mul 4 index 2 mul div 6 index mul add % y_1
            9 index exch 11 2 roll pop pop pop pop
            pop pop pop pop pop
          } ifelse
        } ifelse
      } {
          0 index 3 index sub 2 index 5 index sub div % k
          2 index 4 index mul 2 index 6 index mul sub 3 index 6 index sub div % d
          \pst@parabola@semifocalchord\space %p
          2 index 9 index mul 8 index sub 2 index add % m=kx_o-y_o+t
          #1 dup cos exch sin % \cos\theta \sin\theta
          5 index 2 index mul 1 index sub % e=k\cos\theta-\sin\theta
          6 index 2 index mul 3 index add % f=k\sin\theta+\cos\theta
          % (aaaaaa----) print pstack (aaaaaa===) print
          dup abs 1E-5 lt { % like ZeroEq
            4 index 3 index mul % t=m\sin\theta
            14 index 1 index 6 index mul add 1 index dup mul 8 index 2 mul div 5 index mul sub % x_1
            14 index 2 index 6 index mul add 2 index dup mul 9 index 2 mul div 7 index mul add % y_1
            % (xxxxxx----) print pstack (xxxxxx===) print
            17 2 roll pop pop pop pop pop pop
            pop pop pop pop pop pop
            pop pop pop
          } {
            5 index 2 index mul % pe
            dup dup mul 2 index 7 index mul 8 index 2 mul mul add % (pe)^2+2fmp
            dup 0 lt {
              pop pop pop pop pop pop pop pop pop pop
              pop pop pop pop pop pop 0 0
            } {
              sqrt 1 index exch sub 2 index div % t_1
              15 index 1 index 7 index mul add 1 index dup mul 9 index 2 mul div 6 index mul sub % x_1
              15 index 2 index 7 index mul add 2 index dup mul 10 index 2 mul div 8 index mul add % y_1
              % (bbbbbb----) print pstack (bbbbbb===) print
              18 2 roll pop pop pop pop pop pop
              pop pop pop pop pop pop
              pop pop pop pop
            } ifelse
          } ifelse
      } ifelse
    ){#4}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempA \tx@UserCoor % x1,y1
      \pst@tempB \tx@UserCoor % x2,y2
      3 index 2 index sub abs 1E-5 lt { % if the line AB is vertical
        #1 dup cos exch sin % \cos\theta \sin\theta
        dup abs 1E-5 lt { % like ZeroEq % if \sin\theta=0
          pop pop pop pop pop pop pop pop 0 0
        } {
          \pst@parabola@semifocalchord\space %p
          2 index 1 index mul % p\cos\theta
          dup dup mul 2 index 2 mul 9 index 12 index sub mul 4 index mul sub % p^2\cos^2\theta-2p(x_1-x_o)\sin\theta
          dup 0 lt {
            pop pop pop pop pop
            pop pop pop pop pop
            pop 0 0
          } {
            sqrt 1 index add 3 index div % t_2
            9 index 1 index 5 index mul add 1 index dup mul 4 index 2 mul div 6 index mul add % y_2
            9 index exch 11 2 roll pop pop pop pop
            pop pop pop pop pop
          } ifelse
        } ifelse
      } {
          0 index 3 index sub 2 index 5 index sub div % k
          2 index 4 index mul 2 index 6 index mul sub 3 index 6 index sub div % d
          \pst@parabola@semifocalchord\space %p
          2 index 9 index mul 8 index sub 2 index add % m=kx_o-y_o+d
          #1 dup cos exch sin % \cos\theta \sin\theta
          5 index 2 index mul 1 index sub % e=k\cos\theta-\sin\theta
          6 index 2 index mul 3 index add % f=k\sin\theta+\cos\theta
          dup abs 1E-5 lt { % like ZeroEq
            pop pop pop pop pop pop pop
            pop pop pop pop pop pop pop 0 0
          } {
            5 index 2 index mul % pe
            dup dup mul 2 index 7 index mul 8 index 2 mul mul add % (pe)^2+2fmp
            dup 0 lt {
              pop pop pop pop pop pop pop pop pop pop
              pop pop pop pop pop pop 0 0
            } {
              sqrt 1 index add 2 index div % t_2
              15 index 1 index 7 index mul add 1 index dup mul 9 index 2 mul div 6 index mul sub % x_2
              15 index 2 index 7 index mul add 2 index dup mul 10 index 2 mul div 8 index mul add % y_2
              % (ccccccc----) print pstack (ccccccc===) print
              18 2 roll pop pop pop pop pop pop
              pop pop pop pop pop pop
              pop pop pop pop
            } ifelse
          } ifelse
      } ifelse
    ){#5}
    \Pst@ManageParamList{#4}%
    \Pst@ManageParamList{#5}%
  \endgroup%
}%
%
%% \pstGeneralParabolaPolarNode[Options](O){p}[rotation](F)[L1][L2]{A}{B}{T}
%% Find the polar point of chord AB on General Parabola P.
%% If you not input the rotation angle, the default value is $0^\circ$.
%% We use the following proposition to find the polar point of chord AB:
%% Give any chord AB, drawing two focal chord AFC and BFD, where F is the focus, then drawing FX which is perpendicular to AFC at point F, and intersect with the directrix line at X; also drawing FY which is perpendicular to BFD at point F, and intersect with the directrix line at Y. Then the intersection T of AX and BY is the polar point of chord AB.
%% If you don't know the focus F, or the directrix line, we will find them automated, otherwise you can pass them to this macro.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] optional, the focus node/coordinate F of the parabola.
%% #6 -> [input] optional, the node/coordinate L1 on the directrix line of the parabola.
%% #7 -> [input] optional, the node/coordinate L2 on the directrix line of the parabola.
%% #8 -> [input] the node A on the parabola.
%% #9 -> [input] the node B on the parabola.
%% #10 -> [output] the polar node T of chord AB.
\def\pstGeneralParabolaPolarNode{\@ifnextchar[\Pst@GeneralParabolaPolarNode{\Pst@GeneralParabolaPolarNode[]}}
\def\Pst@GeneralParabolaPolarNode[#1](#2)#3{%
  \begingroup
    \psset{#1}%
    \def\pst@generalparabola@vertex{#2}%
    \def\pst@generalparabola@semifocalchord{#3}%
    \@ifnextchar[\Pst@GeneralParabolaPolarNode@i{\Pst@GeneralParabolaPolarNode@i[0]}}%
\def\Pst@GeneralParabolaPolarNode@i[#1]{%
    \def\pst@generalparabola@gradientangle{#1}%
    \@ifnextchar(\Pst@GeneralParabolaPolarNode@j{\Pst@GeneralParabolaPolarNode@k}}%
\def\Pst@GeneralParabolaPolarNode@j(#1){%
    \def\pst@generalparabola@focus{#1}%
    \@ifnextchar[\Pst@GeneralParabolaPolarNode@jj{\Pst@GeneralParabolaPolarNode@kk}}%
\def\Pst@GeneralParabolaPolarNode@k{%
      \pstGeneralParabolaFocusNode[PointName=none,PointSymbol=none](\pst@generalparabola@vertex){\pst@generalparabola@semifocalchord}[\pst@generalparabola@gradientangle]{@PST@GENERALPARABOLA@FOCUS}
      \Pst@GeneralParabolaPolarNode@j(@PST@GENERALPARABOLA@FOCUS)}%
\def\Pst@GeneralParabolaPolarNode@kk{%
      \pstGeneralParabolaDirectrixLine[linestyle=none,PointName=none,PointSymbol=none](\pst@generalparabola@vertex){\pst@generalparabola@semifocalchord}[\pst@generalparabola@gradientangle]{@PST@GENERALPARABOLA@DIRECTRIXLINEA}{@PST@GENERALPARABOLA@DIRECTRIXLINEB}
      \Pst@GeneralParabolaPolarNode@jj[@PST@GENERALPARABOLA@DIRECTRIXLINEA][@PST@GENERALPARABOLA@DIRECTRIXLINEB]}%
\def\Pst@GeneralParabolaPolarNode@jj[#1][#2]#3#4#5{%
    \pstGeneralParabolaLineInter[PointName=none,PointSymbol=none,linestyle=none](\pst@generalparabola@vertex){\pst@generalparabola@semifocalchord}[\pst@generalparabola@gradientangle]{#3}{\pst@generalparabola@focus}{@PST@GENERALPARABOLA@FOCALCHORDAFC@A}{@PST@GENERALPARABOLA@FOCALCHORDAFC@C}
    \pstGeneralParabolaLineInter[PointName=none,PointSymbol=none,linestyle=none](\pst@generalparabola@vertex){\pst@generalparabola@semifocalchord}[\pst@generalparabola@gradientangle]{#4}{\pst@generalparabola@focus}{@PST@GENERALPARABOLA@FOCALCHORDBFD@B}{@PST@GENERALPARABOLA@FOCALCHORDBFD@D}
    \pstRotation[PointName=none,PointSymbol=none,RotAngle=90]{\pst@generalparabola@focus}{@PST@GENERALPARABOLA@FOCALCHORDAFC@A}[@PST@GENERALPARABOLA@FOCALCHORDAFC@AA]
    \pstRotation[PointName=none,PointSymbol=none,RotAngle=90]{\pst@generalparabola@focus}{@PST@GENERALPARABOLA@FOCALCHORDBFD@B}[@PST@GENERALPARABOLA@FOCALCHORDBFD@BB]
    \pstInterLL[PointName=none,PointSymbol=none]{#1}{#2}{\pst@generalparabola@focus}{@PST@GENERALPARABOLA@FOCALCHORDAFC@AA}{@PST@GENERALPARABOLA@FOCALCHORD@X}
    \pstInterLL[PointName=none,PointSymbol=none]{#1}{#2}{\pst@generalparabola@focus}{@PST@GENERALPARABOLA@FOCALCHORDBFD@BB}{@PST@GENERALPARABOLA@FOCALCHORD@Y}
    \pstInterLL{#3}{@PST@GENERALPARABOLA@FOCALCHORD@X}{#4}{@PST@GENERALPARABOLA@FOCALCHORD@Y}{#5}
    \Pst@geonodelabel{#5}%
    \pstLineAB{#3}{#5}
    \pstLineAB{#4}{#5}
    \endgroup
}%
%
%% \pstGeneralParabolaTangentNode[Options](O){p}[rotation]{T}{A}{B}
%% Draw the two tangent lines through the point $T$ to the General Parabola P and get the node A and B on the General Parabola.
%% We use the following proposition to find the tangent node of T:
%% Give point T outside of the parabola, we draw any other two chords TPQ and TRS, PS and QR intersect at I, PR and QS intersect at X, XI and GeneralParabola intersect at A and B, then TA is the tangent line through A and TB is the tangent line through B.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the given node T outside the parabola
%% #6 -> [output] the tangent node name A on the parabola
%% #7 -> [output] the tangent node name B on the parabola
\def\pstGeneralParabolaTangentNode{\@ifnextchar[\Pst@GeneralParabolaTangentNode{\Pst@GeneralParabolaTangentNode[]}}
\def\Pst@GeneralParabolaTangentNode[#1](#2)#3{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \def\pst@generalparabola@vertex{#2}%
    \def\pst@generalparabola@semifocalchord{#3}%
    \@ifnextchar[\Pst@GeneralParabolaTangentNode@i{\Pst@GeneralParabolaTangentNode@i[0]}}%
\def\Pst@GeneralParabolaTangentNode@i[#1]#2#3#4{%
    \pstGeneralParabolaAbsNode[PointName=none,PointSymbol=none](\pst@generalparabola@vertex){\pst@generalparabola@semifocalchord}[#1]{\pstAbscissa{#2} \pstAbscissa{\pst@generalparabola@vertex} le {\pstAbscissa{\pst@generalparabola@vertex} \pst@generalparabola@semifocalchord\space abs 2 div add}{\pstAbscissa{\pst@generalparabola@vertex} \pst@generalparabola@semifocalchord\space abs 2 div sub} ifelse}{@PST@GENERALPARABOLA@TANGENTAUX@P0}{@PST@GENERALPARABOLA@TANGENTAUX@P1}
    \pstGeneralParabolaAbsNode[PointName=none,PointSymbol=none](\pst@generalparabola@vertex){\pst@generalparabola@semifocalchord}[#1]{\pstAbscissa{#2} \pstAbscissa{\pst@generalparabola@vertex} le {\pstAbscissa{\pst@generalparabola@vertex} \pst@generalparabola@semifocalchord\space abs 4 div add}{\pstAbscissa{\pst@generalparabola@vertex} \pst@generalparabola@semifocalchord\space abs 4 div sub} ifelse}{@PST@GENERALPARABOLA@TANGENTAUX@R0}{@PST@GENERALPARABOLA@TANGENTAUX@R1}
    \pstGeneralParabolaLineInter[PointName=none,PointSymbol=none](\pst@generalparabola@vertex){\pst@generalparabola@semifocalchord}[#1]{#2}{@PST@GENERALPARABOLA@TANGENTAUX@P0}{@PST@GENERALPARABOLA@TANGENTAUX@P}{@PST@GENERALPARABOLA@TANGENTAUX@Q}
    \pstGeneralParabolaLineInter[PointName=none,PointSymbol=none](\pst@generalparabola@vertex){\pst@generalparabola@semifocalchord}[#1]{#2}{@PST@GENERALPARABOLA@TANGENTAUX@R0}{@PST@GENERALPARABOLA@TANGENTAUX@R}{@PST@GENERALPARABOLA@TANGENTAUX@S}
    \pstInterLL[PointName=none,PointSymbol=none]{@PST@GENERALPARABOLA@TANGENTAUX@P}{@PST@GENERALPARABOLA@TANGENTAUX@S}{@PST@GENERALPARABOLA@TANGENTAUX@Q}{@PST@GENERALPARABOLA@TANGENTAUX@R}{@PST@GENERALPARABOLA@TANGENTAUX@I}
    \pstInterLL[PointName=none,PointSymbol=none]{@PST@GENERALPARABOLA@TANGENTAUX@P}{@PST@GENERALPARABOLA@TANGENTAUX@R}{@PST@GENERALPARABOLA@TANGENTAUX@Q}{@PST@GENERALPARABOLA@TANGENTAUX@S}{@PST@GENERALPARABOLA@TANGENTAUX@X}
    \pstGeneralParabolaLineInter(\pst@generalparabola@vertex){\pst@generalparabola@semifocalchord}[#1]{@PST@GENERALPARABOLA@TANGENTAUX@X}{@PST@GENERALPARABOLA@TANGENTAUX@I}{#3}{#4}
    \Pst@ManageParamList{#3}%
    \Pst@ManageParamList{#4}%
    \pstLineAB{#2}{#3}
    \pstLineAB{#2}{#4}
  \endgroup%
}%
%
% 6. General Conjugate Parabola with coordinate translation and rotation
%% ----------------------------------------------------------
%% The General Conjugate Parabola P is defined by vertex O, 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 equation can be got from the parametric function of the conjugate parabola \ref{ParametricFunctionOfStandardConjugateParabola},
%% using the rotation transform formula \ref{RotationTransformFormula}, then we have
%% \begin{equation}
%% \left\{\begin{array}{l}
%% x'=(\dfrac{t^2}{2p}+x_o)\cos\theta-(t+y_o)\sin\theta=x_o'-t\sin\theta+t^2\dfrac{\cos\theta}{2p}\\
%% y'=(\dfrac{t^2}{2p}+x_o)\sin\theta+(t+y_o)\cos\theta=y_o'+t\cos\theta+t^2\dfrac{\sin\theta}{2p}
%% \end{array}\right.
%% \end{equation}
%% where the $x_o'$ and $y_o'$ are the coordinate of the given vertex O after rotation.
%% So we get the parametric function of the General Conjugate Parabola with coordinate translation and rotation as following:
%% \begin{equation}\label{ParametricFunctionOfGeneralConjugateParabola}
%% \left\{\begin{array}{l}
%% x=x_o-t\sin\theta+t^2\dfrac{\cos\theta}{2p}\\
%% y=y_o+t\cos\theta+t^2\dfrac{\sin\theta}{2p}
%% \end{array}\right.
%% \end{equation}
%
%% \pstGeneralIParabola[Options](O){p}[rotation]{y0}{y1}
%% Draw a General Conjugate Parabola from y0 to y1 with Vertex O, the half of the focus chord axis $p$,
%% and the rotation angle $\theta$ of the symmetrical axis.
%% If you not input the rotation angle, the default value is $0^\circ$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the start of independent variable $y$
%% #6 -> [input] the end of independent variable $y$
\def\pstGeneralIParabola{\@ifnextchar[\Pst@GeneralIParabola{\Pst@GeneralIParabola[]}}
\def\Pst@GeneralIParabola[#1](#2)#3{%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO %
    \def\pst@parabola@semifocalchord{#3}%
    \@ifnextchar[\Pst@GeneralIParabola@i{\Pst@GeneralIParabola@i[0]}}%
\def\Pst@GeneralIParabola@i[#1]#2#3{%
    \parametricplot{#2}{#3}{%
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@parabola@semifocalchord\space % p
      #1 dup cos exch sin % \cos\theta \sin\theta
      4 index 1 index t mul sub % x_o-t\sin\theta
      3 index 2 mul t dup mul exch div % t^2/(2p)
      3 index mul add % x_o-t\sin\theta+t^2\dfrac{\cos\theta}{2p}
      4 index 3 index t mul add % y_o+t\cos\theta
      4 index 2 mul t dup mul exch div % t^2/(2p)
      3 index mul add % y_o+t\cos\theta+t^2\dfrac{\sin\theta}{2p}
      7 2 roll pop pop pop pop pop
    }
  \endgroup%
}%
%
%% \pstGeneralIParabolaNode[Options](O){p}[rotation]{t}{A}
%% Create a new node $A$ whose parameter is the the given value $t$ on the given General Conjugate Parabola P.
%% If you not input the rotation angle, the default value is $0^\circ$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the parameter t to get the node on the parabola.
%% #6 -> [output] the target node A on the parabola.
\def\pstGeneralIParabolaNode{\@ifnextchar[\Pst@GeneralIParabolaNode{\Pst@GeneralIParabolaNode[]}}
\def\Pst@GeneralIParabolaNode[#1](#2)#3{%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO %
    \def\pst@parabola@semifocalchord{#3}%
    \@ifnextchar[\Pst@GeneralIParabolaNode@i{\Pst@GeneralIParabolaNode@i[0]}}%
\def\Pst@GeneralIParabolaNode@i[#1]#2#3{%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@parabola@semifocalchord\space % p
      #1 dup cos exch sin % \cos\theta \sin\theta
      4 index 1 index #2 mul sub % x_o-t\sin\theta
      3 index 2 mul #2 dup mul exch div % t^2/(2p)
      3 index mul add % x_o-t\sin\theta+t^2\dfrac{\cos\theta}{2p}
      4 index 3 index #2 mul add % y_o+t\cos\theta
      4 index 2 mul #2 dup mul exch div % t^2/(2p)
      3 index mul add % y_o+t\cos\theta+t^2\dfrac{\sin\theta}{2p}
      7 2 roll pop pop pop pop pop
    ){#3}
    \Pst@geonodelabel{#3}%
  \endgroup%
}%
%
%% \pstGeneralIParabolaAbsNode[Options](O){p}[rotation]{x_1}{A}{B}
%% Find the nodes $A$ and $B$ whose abscissa are the the given value $x_1$ on the given General Conjugate Parabola P.
%% If you not input the rotation angle, the default value is $0^\circ$.
%% when $x=x_1$, we have
%% $$t^2\dfrac{\cos\theta}{2p}-t\sin\theta-(x_1-x_o)=0$$
%% when $\cos\theta=0$, we have $t=-(x_1-x_o)$, so
%% $$x=x_1, y=y_o+\dfrac{t^2}{2p}$$
%% when $\cos\theta\neq0$, we have
%% $$t_{1,2}=\dfrac{-b\pm\sqrt{b^2-4ac}}{2a}=\dfrac{\sin\theta\pm\sqrt{\sin^2\theta+4\cos\theta/(2p)(x_1-x_o)}}{2\cos\theta/(2p)}$$
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the abscissa $x_1$ to get the node on the parabola.
%% #6 -> [output] the first node A on the parabola.
%% #7 -> [output] the second node B on the parabola.
\def\pstGeneralIParabolaAbsNode{\@ifnextchar[\Pst@GeneralIParabolaAbsNode{\Pst@GeneralIParabolaAbsNode[]}}
\def\Pst@GeneralIParabolaAbsNode[#1](#2)#3{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO %
    \def\pst@parabola@semifocalchord{#3}%
    \@ifnextchar[\Pst@GeneralIParabolaAbsNode@i{\Pst@GeneralIParabolaAbsNode@i[0]}}%
\def\Pst@GeneralIParabolaAbsNode@i[#1]#2#3#4{%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@parabola@semifocalchord\space % p
      #1 dup cos exch sin % \cos\theta \sin\theta
      1 index abs 1E-5 lt { % if \cos\theta=0
        4 index #2 sub % t=x0-x1
        4 index 1 index dup mul 5 index 2 mul div add % y=y0+t^2/(2p)
        #2 exch 8 2 roll pop pop pop pop pop pop
      } {
        1 index 3 index div % \cos\theta/p
        #2 6 index sub 1 index mul 2 mul 2 index dup mul add % 2(x1-x0)\cos\theta/p+\sin^2\theta
        dup 0 lt {
          pop pop pop pop pop pop pop 0 0
        } {
          sqrt 2 index exch sub 1 index div % t1
          5 index 1 index 5 index mul add 1 index dup mul 4 index mul 6 index 2 mul div add % y1
          #2 exch 9 2 roll pop pop pop pop pop pop pop
        } ifelse
      } ifelse
    ){#3}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@parabola@semifocalchord\space % p
      #1 dup cos exch sin % \cos\theta \sin\theta
      1 index abs 1E-5 lt { % if \cos\theta=0
        pop pop pop pop pop 0 0
      } {
        1 index 3 index div % \cos\theta/p
        #2 6 index sub 1 index mul 2 mul 2 index dup mul add % 2(x1-x0)\cos\theta/p+\sin^2\theta
        dup 0 lt {
          pop pop pop pop pop pop pop 0 0
        } {
          sqrt 2 index add 1 index div % t2
          5 index 1 index 5 index mul add 1 index dup mul 4 index mul 6 index 2 mul div add % y2
          #2 exch 9 2 roll pop pop pop pop pop pop pop
        } ifelse
      } ifelse
    ){#4}
    \Pst@ManageParamList{#3}%
    \Pst@ManageParamList{#4}%
  \endgroup%
}%
%
%% \pstGeneralIParabolaOrdNode[Options](O){p}[rotation]{y_1}{A}{B}
%% Find the nodes $A$ and $B$ whose ordinate are the the given value $y_1$ on the given General Conjugate Parabola P.
%% If you not input the rotation angle, the default value is $0^\circ$.
%% when $y=y_1$, we have
%% $$t^2\dfrac{\sin\theta}{2p}+t\cos\theta-(y_1-y_o)=0$$
%% when $\sin\theta=0$, we have $t=(y_1-y_o)$, so
%% $$y=y_1, x=x_o+\dfrac{t^2}{2p}$$
%% when $\sin\theta\neq0$, we have
%% $$t_{1,2}=\dfrac{-b\pm\sqrt{b^2-4ac}}{2a}=\dfrac{-\cos\theta\pm\sqrt{\cos^2\theta+4\sin\theta/(2p)(y_1-y_o)}}{2\sin\theta/(2p)}$$
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the ordinate $y_1$ to get the node on the parabola.
%% #6 -> [output] the first node A on the parabola.
%% #7 -> [output] the second node B on the parabola.
\def\pstGeneralIParabolaOrdNode{\@ifnextchar[\Pst@GeneralIParabolaOrdNode{\Pst@GeneralIParabolaOrdNode[]}}
\def\Pst@GeneralIParabolaOrdNode[#1](#2)#3{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO %
    \def\pst@parabola@semifocalchord{#3}%
    \@ifnextchar[\Pst@GeneralIParabolaOrdNode@i{\Pst@GeneralIParabolaOrdNode@i[0]}}%
\def\Pst@GeneralIParabolaOrdNode@i[#1]#2#3#4{%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@parabola@semifocalchord\space % p
      #1 dup cos exch sin % \cos\theta \sin\theta
      0 index abs 1E-5 lt { % if \sin\theta=0
        #2 4 index sub % t=y1-y0
        5 index 1 index dup mul 5 index 2 mul div add % x=x0+t^2/(2p)
        #2 exch 8 2 roll pop pop pop pop pop pop
      } {
        0 index 3 index div % \sin\theta/p
        #2 5 index sub 1 index mul 2 mul 3 index dup mul add % 2(y1-y0)\sin\theta/p+\cos^2\theta
        dup 0 lt {
          pop pop pop pop pop pop pop 0 0
        } {
          sqrt 3 index add neg 1 index div % t1
          6 index 1 index 4 index mul sub 1 index dup mul 5 index mul 6 index 2 mul div add % x1
          #2 9 2 roll pop pop pop pop pop pop pop
        } ifelse
      } ifelse
    ){#3}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@parabola@semifocalchord\space % p
      #1 dup cos exch sin % \cos\theta \sin\theta
      0 index abs 1E-5 lt { % if \sin\theta=0
        #2 4 index sub % t=y1-y0
        5 index 1 index dup mul 5 index 2 mul div add % x=x0+t^2/(2p)
        #2 exch 8 2 roll pop pop pop pop pop pop
      } {
        0 index 3 index div % \sin\theta/p
        #2 5 index sub 1 index mul 2 mul 3 index dup mul add % 2(y1-y0)\sin\theta/p+\cos^2\theta
        dup 0 lt {
          pop pop pop pop pop pop pop 0 0
        } {
          sqrt 3 index sub 1 index div % t2
          6 index 1 index 4 index mul sub 1 index dup mul 5 index mul 6 index 2 mul div add % x2
          #2 9 2 roll pop pop pop pop pop pop pop
        } ifelse
      } ifelse
    ){#4}
    \Pst@ManageParamList{#3}%
    \Pst@ManageParamList{#4}%
  \endgroup%
}%
%
%% \pstGeneralIParabolaFocusNode[Options](O){p}[rotation]{F}
%% Find the focus node $F$ of the given General Conjugate Parabola P.
%% If you not input the rotation angle, the default value is $0^\circ$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [output] the focus node F of the parabola.
\def\pstGeneralIParabolaFocusNode{\@ifnextchar[\Pst@GeneralIParabolaFocusNode{\Pst@GeneralIParabolaFocusNode[]}}
\def\Pst@GeneralIParabolaFocusNode[#1](#2)#3{%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO %
    \def\pst@parabola@semifocalchord{#3}%
    \@ifnextchar[\Pst@GeneralIParabolaFocusNode@i{\Pst@GeneralIParabolaFocusNode@i[0]}}%
\def\Pst@GeneralIParabolaFocusNode@i[#1]#2{%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@parabola@semifocalchord\space 2 div % p/2
      #1 dup cos exch sin % \cos\theta \sin\theta
      4 index 3 index 3 index mul add % x=x0+p/2\cos\theta
      4 index 4 index 3 index mul add % y=y0+p/2\sin\theta
      7 2 roll pop pop pop pop pop
    ){#2}
    \Pst@geonodelabel{#2}%
  \endgroup%
}%
%
%% \pstGeneralIParabolaDirectrixLine[Options](O){p}[rotation]{LA}{LB}
%% Draw the directrix line of the General Conjugate Parabola P.
%% If you not input the rotation angle, the default value is $0^\circ$.
%% The node LA also lies on the symmetrical axis line, and node LB is another one on the directrix line.
%% they can be got after the orig nodes rotation $\theta$ about the vertex $O$,
%% please refer to the extension rotation formula \ref{ExtensionRotationTransformFormula}.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [output] the first node LA on the directrix line.
%% #6 -> [output] the second node LB on the directrix line.
\def\pstGeneralIParabolaDirectrixLine{\@ifnextchar[\Pst@GeneralIParabolaDirectrixLine{\Pst@GeneralIParabolaDirectrixLine[]}}
\def\Pst@GeneralIParabolaDirectrixLine[#1](#2)#3{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \def\pst@parabola@semifocalchord{#3}%
    \@ifnextchar[\Pst@GeneralIParabolaDirectrixLine@i{\Pst@GeneralIParabolaDirectrixLine@i[0]}}%
\def\Pst@GeneralIParabolaDirectrixLine@i[#1]#2#3{%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@parabola@semifocalchord\space 2 div % p/2
      2 index 1 index sub 2 index 5 2 roll pop
      #1 cos #1 sin % x y x0 y0 \cos\theta \sin\theta
      3 index 6 index 5 index sub 3 index mul add 5 index 4 index sub 2 index mul sub % x0+(x-x0)\cos\theta-(y-y0)\sin\theta
      3 index 7 index 6 index sub 3 index mul add 6 index 5 index sub 4 index mul add % y0+(x-x0)\sin\theta+(y-y0)\cos\theta
      8 2 roll pop pop pop pop pop pop
    ){#2}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@parabola@semifocalchord\space 2 div % p/2
      2 index 1 index sub 2 index 1 add 5 2 roll pop
      #1 cos #1 sin % x y x0 y0 \cos\theta \sin\theta
      3 index 6 index 5 index sub 3 index mul add 5 index 4 index sub 2 index mul sub % x0+(x-x0)\cos\theta-(y-y0)\sin\theta
      3 index 7 index 6 index sub 3 index mul add 6 index 5 index sub 4 index mul add % y0+(x-x0)\sin\theta+(y-y0)\cos\theta
      8 2 roll pop pop pop pop pop pop
    ){#3}
    \Pst@ManageParamList{#2}%
    \Pst@ManageParamList{#3}%
    \pstLineAB{#2}{#3}
  \endgroup%
}%
%
%% \pstGeneralIParabolaLineInter[Options](O){p}[rotation]{A}{B}{C}{D}
%% Find the intersections C and D of line AB and the General Imversion Parabola P.
%% If you not input the rotation angle, the default value is $0^\circ$.
%%
%% Case 1. When line AB is vertical, i.e, $x_1=x_2$, we have
%% $$t^2\dfrac{\cos\theta}{2p}-t\sin\theta-(x_1-x_o)=0$$
%% Case 1.1 When $\cos\theta=0$, we have $t=x_o-x_1$,and then
%% $$x_{C}=x_1,y_{C}=y_o+\dfrac{t^2}{2p}$$
%% but D is not defined.
%%
%% Case 1.2 When $\cos\theta\neq0$, we have
%% $$t_{1,2}=\dfrac{p\sin\theta \pm \sqrt{p^2\sin^2\theta+2p(x_1-x_o)\cos\theta}}{\cos\theta}$$
%% and then
%% $$x_{C,D}=x_1,y_{C,D}=y_o+t_{1,2}\sin\theta+\dfrac{t_{1,2}^2}{2p}\cos\theta$$
%%
%% Case 2. When line AB is not vertical, we can represent the line AB as the following function:
%% $$y=kx+d$$ where $$k=\dfrac{y_2-y_1}{x_2-x_1}, d=\dfrac{x_2y_1-x_1y_2}{x_2-x_1}$$
%% refer to equation (\ref{ParametricFunctionOfGeneralConjugateParabola}), we have
%% $$ft^2+2pet-2pm=0$$
%% where
%% $$m=kx_o-y_o+d,e=\cos\theta+k\sin\theta,f=\sin\theta-k\cos\theta$$
%%
%% Case 2.1 When $f=0$, which gives $\sin\theta\neq0$ and $k=\dfrac{\sin\theta}{\cos\theta}$,
%% at this time, we have $t=m\cos\theta$, and then
%% $$x_{C}=x_o-t\sin\theta+t^2\dfrac{\cos\theta}{2p},y_{C}=y_o+t\cos\theta+t^2\dfrac{\sin\theta}{2p}$$
%% but D is not defined.
%% Case 2.2 When $f\neq0$, we have
%% $$t_{1,2}=\dfrac{-pe\pm\sqrt{(pe)^2+2fmp}}{f}$$
%% and then
%% $$x_{C,D}=x_o-t_{1,2}\sin\theta+t_{1,2}^2\dfrac{\cos\theta}{2p},y_{C,D}=y_o+t_{1,2}\cos\theta+t_{1,2}^2\dfrac{\sin\theta}{2p}$$
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the node $A$ on the given line
%% #6 -> [input] the node $B$ on the given line
%% #7 -> [output] the first intersection node $C$
%% #8 -> [output] the second intersection node $D$
\def\pstGeneralIParabolaLineInter{\@ifnextchar[\Pst@GeneralIParabolaLineInter{\Pst@GeneralIParabolaLineInter[]}}
\def\Pst@GeneralIParabolaLineInter[#1](#2)#3{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \def\pst@parabola@semifocalchord{#3}%
    \@ifnextchar[\Pst@GeneralIParabolaLineInter@i{\Pst@GeneralIParabolaLineInter@i[0]}}%
\def\Pst@GeneralIParabolaLineInter@i[#1]#2#3#4#5{%
    \pst@getcoor{#2}\pst@tempA%
    \pst@getcoor{#3}\pst@tempB%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempA \tx@UserCoor % x1,y1
      \pst@tempB \tx@UserCoor % x2,y2
      3 index 2 index sub abs 1E-5 lt { % if the line AB is vertical
        #1 dup cos exch sin % \cos\theta \sin\theta
        1 index abs 1E-5 lt { % like ZeroEq % if \cos\theta=0
          7 index 6 index sub % t=x0-x1
          7 index 1 index dup mul \pst@parabola@semifocalchord\space 2 mul div add % y=y_o+t^2/(2p)
          7 index exch 9 2 roll pop pop pop pop pop pop pop
        } {
          \pst@parabola@semifocalchord\space %p
          1 index 1 index mul % p\sin\theta
          dup dup mul 2 index 2 mul 9 index 12 index sub mul 5 index mul add % p^2\sin^2\theta+2p(x_1-x_o)\cos\theta
          dup 0 lt {
            pop pop pop pop pop
            pop pop pop pop pop
            pop 0 0
          } {
            sqrt 1 index exch sub 4 index div % t_1
            9 index 1 index 6 index mul add 1 index dup mul 4 index 2 mul div 5 index mul add % y_1
            9 index exch 11 2 roll pop pop pop pop
            pop pop pop pop pop
          } ifelse
        } ifelse
      } {
          0 index 3 index sub 2 index 5 index sub div % k
          2 index 4 index mul 2 index 6 index mul sub 3 index 6 index sub div % d
          \pst@parabola@semifocalchord\space %p
          2 index 9 index mul 8 index sub 2 index add % m=kx_o-y_o+d
          #1 dup cos exch sin % \cos\theta \sin\theta
          5 index 1 index mul 2 index add % e=k\sin\theta+\cos\theta
          6 index 3 index mul 2 index exch sub % f=\sin\theta-k\cos\theta
          dup abs 1E-5 lt { % like ZeroEq
            4 index 4 index mul % t=m\cos\theta
            14 index 1 index 5 index mul sub 1 index dup mul 8 index 2 mul div 6 index mul add % x_1
            14 index 2 index 7 index mul add 2 index dup mul 9 index 2 mul div 6 index mul add % y_1
            17 2 roll pop pop pop pop pop pop
            pop pop pop pop pop pop
            pop pop pop
          } {
            5 index 2 index mul % pe
            dup dup mul 2 index 7 index mul 8 index 2 mul mul add % (pe)^2+2fmp
            dup 0 lt {
              pop pop pop pop pop pop pop pop pop pop
              pop pop pop pop pop pop 0 0
            } {
              sqrt 1 index add neg 2 index div % t_1
              15 index 1 index 6 index mul sub 1 index dup mul 9 index 2 mul div 7 index mul add % x_1
              15 index 2 index 8 index mul add 2 index dup mul 10 index 2 mul div 7 index mul add % y_1
              18 2 roll pop pop pop pop pop pop
              pop pop pop pop pop pop
              pop pop pop pop
            } ifelse
          } ifelse
      } ifelse
    ){#4}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempA \tx@UserCoor % x1,y1
      \pst@tempB \tx@UserCoor % x2,y2
      3 index 2 index sub abs 1E-5 lt { % if the line AB is vertical
        #1 dup cos exch sin % \cos\theta \sin\theta
        1 index abs 1E-5 lt { % like ZeroEq % if \cos\theta=0
          pop pop pop pop pop pop pop pop 0 0
        } {
          \pst@parabola@semifocalchord\space %p
          1 index 1 index mul % p\sin\theta
          dup dup mul 2 index 2 mul 9 index 12 index sub mul 5 index mul add % p^2\sin^2\theta+2p(x_1-x_o)\cos\theta
          dup 0 lt {
            pop pop pop pop pop
            pop pop pop pop pop
            pop 0 0
          } {
            sqrt 1 index add 4 index div % t_2
            9 index 1 index 6 index mul add 1 index dup mul 4 index 2 mul div 5 index mul add % y_2
            9 index exch 11 2 roll pop pop pop pop
            pop pop pop pop pop
          } ifelse
        } ifelse
      } {
          0 index 3 index sub 2 index 5 index sub div % k
          2 index 4 index mul 2 index 6 index mul sub 3 index 6 index sub div % d
          \pst@parabola@semifocalchord\space %p
          2 index 9 index mul 8 index sub 2 index add % m=kx_o-y_o+t
          #1 dup cos exch sin % \cos\theta \sin\theta
          5 index 1 index mul 2 index add % e=k\sin\theta+\cos\theta
          6 index 3 index mul 2 index exch sub % f=\sin\theta-k\cos\theta
          dup abs 1E-5 lt { % like ZeroEq
            pop pop pop pop pop pop pop
            pop pop pop pop pop pop pop
            0 0
          } {
            5 index 2 index mul % pe
            dup dup mul 2 index 7 index mul 8 index 2 mul mul add % (pe)^2+2fmp
            dup 0 lt {
              pop pop pop pop pop pop pop pop pop pop
              pop pop pop pop pop pop 0 0
            } {
              sqrt 1 index sub 2 index div % t_2
              15 index 1 index 6 index mul sub 1 index dup mul 9 index 2 mul div 7 index mul add % x_2
              15 index 2 index 8 index mul add 2 index dup mul 10 index 2 mul div 7 index mul add % y_2
              18 2 roll pop pop pop pop pop pop
              pop pop pop pop pop pop
              pop pop pop pop
            } ifelse
          } ifelse
      } ifelse
    ){#5}
    \Pst@ManageParamList{#4}%
    \Pst@ManageParamList{#5}%
  \endgroup%
}%
%
%% \pstGeneralIParabolaPolarNode[Options](O){p}[rotation](F)[L1][L2]{A}{B}{T}
%% Find the polar point of chord AB on General Conjugate Parabola P.
%% If you not input the rotation angle, the default value is $0^\circ$.
%% We use the following proposition to find the polar point of chord AB:
%% Give any chord AB, drawing two focal chord AFC and BFD, where F is the focus, then drawing FX which is perpendicular to AFC at point F, and intersect with the directrix line at X; also drawing FY which is perpendicular to BFD at point F, and intersect with the directrix line at Y. Then the intersection T of AX and BY is the polar point of chord AB.
%% If you don't know the focus F, or the directrix line, we will find them automated, otherwise you can pass them to this macro.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] optional, the focus node/coordinate F of the parabola.
%% #6 -> [input] optional, the node/coordinate L1 on the directrix line of the parabola.
%% #7 -> [input] optional, the node/coordinate L2 on the directrix line of the parabola.
%% #8 -> [input] the node A on the parabola.
%% #9 -> [input] the node B on the parabola.
%% #10 -> [output] the polar node T of chord AB.
\def\pstGeneralIParabolaPolarNode{\@ifnextchar[\Pst@GeneralIParabolaPolarNode{\Pst@GeneralIParabolaPolarNode[]}}
\def\Pst@GeneralIParabolaPolarNode[#1](#2)#3{%
  \begingroup
    \psset{#1}%
    \def\pst@generalparabola@vertex{#2}%
    \def\pst@generalparabola@semifocalchord{#3}%
    \@ifnextchar[\Pst@GeneralIParabolaPolarNode@i{\Pst@GeneralIParabolaPolarNode@i[0]}}%
\def\Pst@GeneralIParabolaPolarNode@i[#1]{%
    \def\pst@generalparabola@gradientangle{#1}%
    \@ifnextchar(\Pst@GeneralIParabolaPolarNode@j{\Pst@GeneralIParabolaPolarNode@k}}%
\def\Pst@GeneralIParabolaPolarNode@j(#1){%
    \def\pst@generalparabola@focus{#1}%
    \@ifnextchar[\Pst@GeneralIParabolaPolarNode@jj{\Pst@GeneralIParabolaPolarNode@kk}}%
\def\Pst@GeneralIParabolaPolarNode@k{%
      \pstGeneralIParabolaFocusNode[PointName=none,PointSymbol=none](\pst@generalparabola@vertex){\pst@generalparabola@semifocalchord}[\pst@generalparabola@gradientangle]{@PST@GENERALIPARABOLA@FOCUS}
      \Pst@GeneralIParabolaPolarNode@j(@PST@GENERALIPARABOLA@FOCUS)}%
\def\Pst@GeneralIParabolaPolarNode@kk{%
      \pstGeneralIParabolaDirectrixLine[linestyle=none,PointName=none,PointSymbol=none](\pst@generalparabola@vertex){\pst@generalparabola@semifocalchord}[\pst@generalparabola@gradientangle]{@PST@GENERALIPARABOLA@DIRECTRIXLINEA}{@PST@GENERALIPARABOLA@DIRECTRIXLINEB}
      \Pst@GeneralIParabolaPolarNode@jj[@PST@GENERALIPARABOLA@DIRECTRIXLINEA][@PST@GENERALIPARABOLA@DIRECTRIXLINEB]}%
\def\Pst@GeneralIParabolaPolarNode@jj[#1][#2]#3#4#5{%
    \pstGeneralIParabolaLineInter[PointName=none,PointSymbol=none,linestyle=none](\pst@generalparabola@vertex){\pst@generalparabola@semifocalchord}[\pst@generalparabola@gradientangle]{#3}{\pst@generalparabola@focus}{@PST@GENERALIPARABOLA@FOCALCHORDAFC@A}{@PST@GENERALIPARABOLA@FOCALCHORDAFC@C}
    \pstGeneralIParabolaLineInter[PointName=none,PointSymbol=none,linestyle=none](\pst@generalparabola@vertex){\pst@generalparabola@semifocalchord}[\pst@generalparabola@gradientangle]{#4}{\pst@generalparabola@focus}{@PST@GENERALIPARABOLA@FOCALCHORDBFD@B}{@PST@GENERALIPARABOLA@FOCALCHORDBFD@D}
    \pstRotation[PointName=none,PointSymbol=none,RotAngle=90]{\pst@generalparabola@focus}{@PST@GENERALIPARABOLA@FOCALCHORDAFC@A}[@PST@GENERALIPARABOLA@FOCALCHORDAFC@AA]
    \pstRotation[PointName=none,PointSymbol=none,RotAngle=90]{\pst@generalparabola@focus}{@PST@GENERALIPARABOLA@FOCALCHORDBFD@B}[@PST@GENERALIPARABOLA@FOCALCHORDBFD@BB]
    \pstInterLL[PointName=none,PointSymbol=none]{#1}{#2}{\pst@generalparabola@focus}{@PST@GENERALIPARABOLA@FOCALCHORDAFC@AA}{@PST@GENERALIPARABOLA@FOCALCHORD@X}
    \pstInterLL[PointName=none,PointSymbol=none]{#1}{#2}{\pst@generalparabola@focus}{@PST@GENERALIPARABOLA@FOCALCHORDBFD@BB}{@PST@GENERALIPARABOLA@FOCALCHORD@Y}
    \pstInterLL{#3}{@PST@GENERALIPARABOLA@FOCALCHORD@X}{#4}{@PST@GENERALIPARABOLA@FOCALCHORD@Y}{#5}
    \Pst@geonodelabel{#5}%
    \pstLineAB{#3}{#5}
    \pstLineAB{#4}{#5}
    \endgroup
}%
%
%% \pstGeneralIParabolaTangentNode[Options](O){p}[rotation]{T}{A}{B}
%% Draw the two tangent lines through the point $T$ to the General Conjugate Parabola P and get the node A and B on the General Conjugate Parabola.
%% We use the following proposition to find the tangent node of T:
%% Give point T outside of the parabola, we draw any other two chords TPQ and TRS, PS and QR intersect at I, PR and QS intersect at X, XI and GeneralIParabola intersect at A and B, then TA is the tangent line through A and TB is the tangent line through B.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the given node T outside the parabola
%% #6 -> [output] the tangent node name A on the parabola
%% #7 -> [output] the tangent node name B on the parabola
\def\pstGeneralIParabolaTangentNode{\@ifnextchar[\Pst@GeneralIParabolaTangentNode{\Pst@GeneralIParabolaTangentNode[]}}
\def\Pst@GeneralIParabolaTangentNode[#1](#2)#3{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \def\pst@generalparabola@vertex{#2}%
    \def\pst@generalparabola@semifocalchord{#3}%
    \@ifnextchar[\Pst@GeneralIParabolaTangentNode@i{\Pst@GeneralIParabolaTangentNode@i[0]}}%
\def\Pst@GeneralIParabolaTangentNode@i[#1]#2#3#4{%
    \pstGeneralIParabolaAbsNode[PointName=none,PointSymbol=none](\pst@generalparabola@vertex){\pst@generalparabola@semifocalchord}[#1]{\pstAbscissa{#2} \pstAbscissa{\pst@generalparabola@vertex} le {\pstAbscissa{\pst@generalparabola@vertex} \pst@generalparabola@semifocalchord\space abs 2 div add}{\pstAbscissa{\pst@generalparabola@vertex} \pst@generalparabola@semifocalchord\space abs 2 div sub} ifelse}{@PST@GENERALIPARABOLA@TANGENTAUX@P0}{@PST@GENERALIPARABOLA@TANGENTAUX@P1}
    \pstGeneralIParabolaAbsNode[PointName=none,PointSymbol=none](\pst@generalparabola@vertex){\pst@generalparabola@semifocalchord}[#1]{\pstAbscissa{#2} \pstAbscissa{\pst@generalparabola@vertex} le {\pstAbscissa{\pst@generalparabola@vertex} \pst@generalparabola@semifocalchord\space abs 4 div add}{\pstAbscissa{\pst@generalparabola@vertex} \pst@generalparabola@semifocalchord\space abs 4 div sub} ifelse}{@PST@GENERALIPARABOLA@TANGENTAUX@R0}{@PST@GENERALIPARABOLA@TANGENTAUX@R1}
    \pstGeneralIParabolaLineInter[PointName=none,PointSymbol=none](\pst@generalparabola@vertex){\pst@generalparabola@semifocalchord}[#1]{#2}{@PST@GENERALIPARABOLA@TANGENTAUX@P0}{@PST@GENERALIPARABOLA@TANGENTAUX@P}{@PST@GENERALIPARABOLA@TANGENTAUX@Q}
    \pstGeneralIParabolaLineInter[PointName=none,PointSymbol=none](\pst@generalparabola@vertex){\pst@generalparabola@semifocalchord}[#1]{#2}{@PST@GENERALIPARABOLA@TANGENTAUX@R0}{@PST@GENERALIPARABOLA@TANGENTAUX@R}{@PST@GENERALIPARABOLA@TANGENTAUX@S}
    \pstInterLL[PointName=none,PointSymbol=none]{@PST@GENERALIPARABOLA@TANGENTAUX@P}{@PST@GENERALIPARABOLA@TANGENTAUX@S}{@PST@GENERALIPARABOLA@TANGENTAUX@Q}{@PST@GENERALIPARABOLA@TANGENTAUX@R}{@PST@GENERALIPARABOLA@TANGENTAUX@I}
    \pstInterLL[PointName=none,PointSymbol=none]{@PST@GENERALIPARABOLA@TANGENTAUX@P}{@PST@GENERALIPARABOLA@TANGENTAUX@R}{@PST@GENERALIPARABOLA@TANGENTAUX@Q}{@PST@GENERALIPARABOLA@TANGENTAUX@S}{@PST@GENERALIPARABOLA@TANGENTAUX@X}
    \pstGeneralIParabolaLineInter(\pst@generalparabola@vertex){\pst@generalparabola@semifocalchord}[#1]{@PST@GENERALIPARABOLA@TANGENTAUX@X}{@PST@GENERALIPARABOLA@TANGENTAUX@I}{#3}{#4}
    \Pst@ManageParamList{#3}%
    \Pst@ManageParamList{#4}%
    \pstLineAB{#2}{#3}
    \pstLineAB{#2}{#4}
  \endgroup%
}%
%
%
% 7. Standard Hyperbola with coordinate translation
%% ----------------------------------------------------------
%% The Standard Hyperbola H is defined by center O, the half of the real axis $a$, the half of the imaginary axis $b$.
%% The equation can be written as:
%% \begin{equation}\label{FunctionOfStandardHyperbola}
%% \dfrac{(x-x0)^2}{a^2}-\dfrac{(y-y0)^2}{b^2}=1
%% \end{equation}
%% and the parametric function can be written as:
%% \begin{equation}\label{ParametricFunctionOfStandardHyperbola}
%% \left\{\begin{array}{l}
%% x=a\sec\alpha+x_o\\
%% y=b\tan\alpha+y_o
%% \end{array}\right.
%% \end{equation}
%
%% \pstHyperbola[Options](O)(a,b)[maxAngleX]
%% Draw a Hyperbola with center O, the half of the real axis $abs(a)$, and the half of the imaginary axis $abs(b)$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the maximal angle to draw the branch.
\def\pstHyperbola{\@ifnextchar[\Pst@Hyperbola{\Pst@Hyperbola[]}}
\def\Pst@Hyperbola[#1](#2)(#3){%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@Hyperbola@i{\Pst@Hyperbola@i[85]}}%
\def\Pst@Hyperbola@i[#1]{%
    \pst@cnth=#1\pst@cntg=180\pst@cntm=180\pst@cntn=360
    \ifnum\pst@cnth<0
        \loop\advance\pst@cnth by 90
            \ifnum\pst@cnth<0
        \repeat
    \fi
    \ifnum\pst@cnth>90
        \loop\advance\pst@cnth by -90
            \ifnum\pst@cnth>90
        \repeat
    \fi
    \ifnum\pst@cnth>85
        \advance\pst@cnth by -5
    \fi
    \advance\pst@cntg by -\pst@cnth
    \advance\pst@cntm by \pst@cnth
    \advance\pst@cntn by -\pst@cnth
    \Pst@Hyperbola@ii[0][\number\pst@cnth]%
    \Pst@Hyperbola@ii[\number\pst@cntg][180]%
    \Pst@Hyperbola@ii[180][\number\pst@cntm]%
    \Pst@Hyperbola@ii[\number\pst@cntn][360]%
  \endgroup%
}%
\def\Pst@Hyperbola@ii[#1][#2]{%
    \parametricplot{#1}{#2}{%
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      t dup cos exch sin % cos{t} sin{t}
      1 index abs 1E-5 lt {
        pop pop pop pop
      } {
        5 index 4 index 3 index div add % x0+a\sec{t}
        5 index 4 index 3 index mul 4 index div add % y0+b\tan{t}
        8 2 roll pop pop pop pop pop pop
      } ifelse
    }%
}%
%
%% \pstHyperbolaNode[Options](O)(a,b){t}{P}
%% Create a new node P on the Hyperbola E whose parameter is the given value $t$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the parametric argument t.
%% #5 -> [output] the target node name.
\def\pstHyperbolaNode{\@ifnextchar[\Pst@HyperbolaNode{\Pst@HyperbolaNode[]}}
\def\Pst@HyperbolaNode[#1](#2)(#3)#4#5{%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #4 dup cos exch sin % cos{t} sin{t}
      1 index abs 1E-5 lt {
        pop pop pop pop
      }{
        5 index 4 index 3 index div add % x0+a\sec{t}
        5 index 4 index 3 index 5 index div mul add % y0+b\tan{t}
      } ifelse
      8 2 roll pop pop pop pop pop pop
    ){#5}%
    \Pst@geonodelabel{#5}%
  \endgroup%
}%
%
%% \pstHyperbolaAbsNode[Options](O)(a,b){x_1}{A}{B}
%% Create a new node P on the Hyperbola E whose abscissa is the given value $x_1$.
%% when $x=x_1$, we have
%% $$\dfrac{(x_1-x_0)^2}{a^2}-\dfrac{(y-y_0)^2}{b^2}=1$$
%% $$(y-y_0)^2=\dfrac{b^2(x_1-x_0)^2-a^2b^2}{a^2}$$
%% $$y=y_0\pm\dfrac{b}{a}\sqrt{(x_1-x_0)^2-a^2}$$
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the abbscissa value $x_1$.
%% #5 -> [output] the first target node name.
%% #6 -> [output] the first second node name.
\def\pstHyperbolaAbsNode{\@ifnextchar[\Pst@HyperbolaAbsNode{\Pst@HyperbolaAbsNode[]}}
\def\Pst@HyperbolaAbsNode[#1](#2)(#3)#4#5#6{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #4 4 index sub dup mul 2 index dup mul sub % (x_1-x_0)^2-a^2
      dup 0 lt {
        pop pop pop pop pop 0 0
      } {
        sqrt 1 index mul 2 index div 3 index exch sub % y1
        #4 exch 6 2 roll pop pop pop pop
      } ifelse
    ){#5}%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #4 4 index sub dup mul 2 index dup mul sub % (x_1-x_0)^2-a^2
      dup 0 lt {
        pop pop pop pop pop 0 0
      } {
        sqrt 1 index mul 2 index div 3 index add % y2
        #4 exch 6 2 roll pop pop pop pop
      } ifelse
    ){#6}%
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
  \endgroup%
}%
%
%% \pstHyperbolaOrdNode[Options](O)(a,b){y_1}{A}{B}
%% Create a new node P on the Hyperbola E whose ordinate is the given value $y_1$.
%% when $y=y_1$, we have
%% $$\dfrac{(x-x_0)^2}{a^2}-\dfrac{(y_1-y_0)^2}{b^2}=1$$
%% $$(x-x_0)^2=\dfrac{a^2(y_1-y_0)^2+a^2b^2}{b^2}$$
%% $$x=x_0\pm\dfrac{a}{b}\sqrt{(y_1-y_0)^2+b^2}$$
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the ordinate value $y_1$.
%% #5 -> [output] the first target node name.
%% #6 -> [output] the first second node name.
\def\pstHyperbolaOrdNode{\@ifnextchar[\Pst@HyperbolaOrdNode{\Pst@HyperbolaOrdNode[]}}
\def\Pst@HyperbolaOrdNode[#1](#2)(#3)#4#5#6{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #4 3 index sub dup mul 1 index dup mul add % (y_1-y_0)^2+b^2
      sqrt 2 index mul 1 index div 4 index exch sub % x1
      #4 6 2 roll pop pop pop pop
    ){#5}%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #4 3 index sub dup mul 1 index dup mul add % (y_1-y_0)^2+b^2
      sqrt 2 index mul 1 index div 4 index add % x2
      #4 6 2 roll pop pop pop pop
    ){#6}%
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
  \endgroup%
}%
%
%% \pstHyperbolaFocusNode[Options](O)(a,b){F1}{F2}
%% Create the two focus node F1 and F2 of the Hyperbola H.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [output] the first focus node name.
%% #5 -> [output] the first focus node name.
\def\pstHyperbolaFocusNode{\@ifnextchar[\Pst@HyperbolaFocusNode{\Pst@HyperbolaFocusNode[]}}
\def\Pst@HyperbolaFocusNode[#1](#2)(#3)#4#5{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      dup mul exch dup mul add sqrt % c
      2 index exch sub 1 index % x0-c,y0
      4 2 roll pop pop
    ){#4}%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      dup mul exch dup mul add sqrt % c
      2 index add 1 index % x0+c,y0
      4 2 roll pop pop
    ){#5}%
    \Pst@ManageParamList{#4}%
    \Pst@ManageParamList{#5}%
  \endgroup%
}%
%
%% \pstHyperbolaDirectrixLine[Options](O)(a,b){Lx}{Ly}{Rx}{Ry}
%% Draw the two directrix lines L1 and L2 of the Hyperbola H.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [output] the first node name on the first directrix line.
%% #5 -> [output] the second node name on the first directrix line.
%% #6 -> [output] the first node name on the second directrix line.
%% #7 -> [output] the second node name on the second directrix line.
\def\pstHyperbolaDirectrixLine{\@ifnextchar[\Pst@HyperbolaDirectrixLine{\Pst@HyperbolaDirectrixLine[]}}
\def\Pst@HyperbolaDirectrixLine[#1](#2)(#3)#4#5#6#7{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      1 index dup mul dup 2 index dup mul add sqrt div % a^2/c
      4 index exch sub 3 index % x0-a^2/c,y0
      6 2 roll pop pop pop pop
    ){#4}%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      1 index dup mul dup 2 index dup mul add sqrt div % a^2/c
      4 index exch sub 3 index 1 add % x0-a^2/c,y0+1
      6 2 roll pop pop pop pop
    ){#5}%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      1 index dup mul dup 2 index dup mul add sqrt div % a^2/c
      4 index add 3 index % x0+a^2/c,y0
      6 2 roll pop pop pop pop
    ){#6}%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      1 index dup mul dup 2 index dup mul add sqrt div % a^2/c
      4 index add 3 index 1 add % x0+a^2/c,y0+1
      6 2 roll pop pop pop pop
    ){#7}%
    \Pst@ManageParamList{#4}%
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
    \Pst@ManageParamList{#7}%
    \pstLineAB{#4}{#5}%
    \pstLineAB{#6}{#7}%
  \endgroup%
}%
%
%% \pstHyperbolaAsymptoteLine[Options](O)(a,b){L1}{L2}
%% Draw the two asymptote lines L1 and L2 of the Hyperbola H.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [output] the second node name on the first asymptote line, the first node is the center O.
%% #5 -> [output] the second node name on the second asymptote line, the first node is the center O.
\def\pstHyperbolaAsymptoteLine{\@ifnextchar[\Pst@HyperbolaAsymptoteLine{\Pst@HyperbolaAsymptoteLine[]}}
\def\Pst@HyperbolaAsymptoteLine[#1](#2)(#3)#4#5{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      0 index 2 index div % b/a
      4 index 1 add % x=x0+1
      4 index 2 index add % y=y0+b/a
      7 2 roll pop pop pop pop pop
    ){#4}%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      0 index 2 index div % b/a
      4 index 1 add % x=x0+1
      4 index 2 index sub % y=y0-b/a
      7 2 roll pop pop pop pop pop
    ){#5}%
    \Pst@ManageParamList{#4}%
    \Pst@ManageParamList{#5}%
    \pstLineAB{#2}{#4}%
    \pstLineAB{#2}{#5}%
  \endgroup%
}%
%
%% \pstHyperbolaLineInter[Options](O)(a,b){A}{B}{C}{D}
%% Find the two intersection nodes C and D of the Hyperbola H and line AB.
%%
%% Case 1. When line AB is vertical, i.e, $x_1=x_2$, we have
%% $$y=y_0\pm\dfrac{b}{a}\sqrt{(x_1-x_0)^2-a^2}$$
%%
%% Case 2. When line AB is not vertical, we can represent the line AB as the following function:
%% $$y=kx+d$$ where $$k=\dfrac{y_2-y_1}{x_2-x_1}, d=\dfrac{x_2y_1-x_1y_2}{x_2-x_1}$$
%% refer to equation (\ref{FunctionOfStandardHyperbola}), we have
%% $$(b^2-k^2a^2)X^2-2a^2kmX-a^2(m^2+b^2)=0$$
%% $$Y=kX+m$$
%% where
%% $$m=kx_o-y_o+d,X=x-x_0,Y=y-y_0$$
%%
%% Case 2.1 When $b^2-k^2a^2=0$, which gives $k=\pm\dfrac{b}{a}\neq0$,
%% at this time, when $m=0$, the line AB becomes the asymptote of the hyperbola,
%% so there is none intersection any more; else we have
%% $$x_{C}=x_o-\dfrac{m^2+b^2}{2km},y_{C}=kx_{C}+d$$
%% but D is not defined.
%%
%% Case 2.2 When $b^2-k^2a^2\neq0$, we have
%% $$x_{C,D}=x_0+\dfrac{a^2km\pm{}ab\sqrt{m^2+b^2-k^2a^2}}{b^2-k^2a^2},y_{C,D}=kx_{C,D}+d$$
%%
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the first node name on the given line AB.
%% #5 -> [input] the second node name on the given line AB.
%% #6 -> [output] the first intersection node.
%% #7 -> [output] the second intersection node.
\def\pstHyperbolaLineInter{\@ifnextchar[\Pst@HyperbolaLineInter{\Pst@HyperbolaLineInter[]}}
\def\Pst@HyperbolaLineInter[#1](#2)(#3)#4#5#6#7{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \pst@getcoor{#4}\pst@tempA%
    \pst@getcoor{#5}\pst@tempB%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      \pst@tempA \tx@UserCoor % x_1,y_1
      \pst@tempB \tx@UserCoor % x_2,y_2
      3 index 2 index sub abs 1E-5 lt { % if the line AB is vertical
        %% $$y=y_0\pm\dfrac{b}{a}\sqrt{(x_1-x_0)^2-a^2}$$
        3 index 8 index sub dup mul 6 index dup mul sub
        dup 0 lt {
          pop pop pop pop pop pop pop pop pop
          0 0
        } {
          sqrt 5 index mul 6 index div 7 index exch sub % y1
          4 index exch % x1
          10 2 roll pop pop pop pop pop pop pop pop
        } ifelse
      } {
        0 index 3 index sub 2 index 5 index sub div % k
        2 index 4 index mul 2 index 6 index mul sub 3 index 6 index sub div % d
        1 index 10 index mul 9 index sub 1 index add % m=kx_o-y_o+d
        7 index dup mul 9 index 4 index mul dup mul sub % b^2-k^2a^2
        0 index abs 1E-5 lt {
          1 index abs 1E-5 lt {
            pop pop pop pop pop pop
            pop pop pop pop pop pop
            0 0
          } {
            %% $$x_{C}=x_o-\dfrac{m^2+b^2}{2km},y_{C}=kx_{C}+d$$
            1 index dup mul 9 index dup mul add 2 index 5 index mul 2 mul div % (m^2+b^2)/2km
            12 index exch sub % x1
            4 index 1 index mul 4 index add % y1
            14 2 roll pop pop pop pop pop pop
            pop pop pop pop pop pop
          } ifelse
        } {
          1 index dup mul 1 index add % m^2+b^2-k^2a^2
          dup 0 lt {
            pop pop pop pop pop pop pop
            pop pop pop pop pop pop 0 0
          } {
            sqrt 10 index mul 9 index mul 10 index dup mul 5 index mul 3 index mul exch sub 1 index div 12 index add % x1
            4 index 1 index mul 4 index add % y1
            14 2 roll pop pop pop pop pop pop
            pop pop pop pop pop pop
          } ifelse
        } ifelse
      } ifelse
    ){#6}%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      \pst@tempA \tx@UserCoor % x_1,y_1
      \pst@tempB \tx@UserCoor % x_2,y_2
      3 index 2 index sub abs 1E-5 lt { % if the line AB is vertical
        %% $$y=y_0\pm\dfrac{b}{a}\sqrt{(x_1-x_0)^2-a^2}$$
        3 index 8 index sub dup mul 6 index dup mul sub
        dup 0 lt {
          pop pop pop pop pop pop pop pop
          0 0
        } {
          sqrt 5 index mul 6 index div 7 index add % y2
          4 index exch % x2
          10 2 roll pop pop pop pop pop pop pop pop
        } ifelse
      } {
        0 index 3 index sub 2 index 5 index sub div % k
        2 index 4 index mul 2 index 6 index mul sub 3 index 6 index sub div % d
        1 index 10 index mul 9 index sub 1 index add % m=kx_o-y_o+d
        7 index dup mul 9 index dup mul 4 index dup mul mul sub % b^2-k^2a^2
        dup abs 1E-5 lt {
          pop pop pop pop pop pop
          pop pop pop pop pop pop
          0 0
        } {
          1 index dup mul 1 index add % m^2+b^2-k^2a^2
          dup 0 lt {
            pop pop pop pop pop pop pop
            pop pop pop pop pop pop 0 0
          } {
            sqrt 10 index mul 9 index mul 10 index dup mul 5 index mul 3 index mul add 1 index div 12 index add % x2
            4 index 1 index mul 4 index add % y2
            14 2 roll pop pop pop pop pop pop
            pop pop pop pop pop pop
          } ifelse
        } ifelse
      } ifelse
    ){#7}%
    \Pst@ManageParamList{#6}%
    \Pst@ManageParamList{#7}%
  \endgroup%
}%
%
%% \pstHyperbolaPolarNode[Options](O)(a,b){A}{B}{T}
%% Find the polar point of chord AB on hyperbola H.
%% We use the following proposition to find the polar point of chord AB:
%% Let $P$, $Q$ are vertex points of the hyperbola, for any chord $AB$ of hyperbola, $PA$ and $BQ$ intersect at $E$, $PB$ and $AQ$ intersect at $F$, then the middle point $M$ of $EF$ is the polar point of chord $AB$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the node A on the hyperbola.
%% #5 -> [input] the node B on the hyperbola.
%% #6 -> [output] the polar node T of chord AB.
\def\pstHyperbolaPolarNode{\@ifnextchar[\Pst@HyperbolaPolarNode{\Pst@HyperbolaPolarNode[]}}
\def\Pst@HyperbolaPolarNode[#1](#2)(#3)#4#5#6{%
  \begingroup
    \psset{#1}%
    \pstHyperbolaOrdNode[PointName=none,PointSymbol=none](#2)(#3){\pstOrdinate{#2}}{@PST@HYPERBOLA@VERTEXA}{@PST@HYPERBOLA@VERTEXB}
    \pstInterLL[PointName=none,PointSymbol=none]{#4}{@PST@HYPERBOLA@VERTEXA}{#5}{@PST@HYPERBOLA@VERTEXB}{@PST@HYPERBOLA@INTER@X}
    \pstInterLL[PointName=none,PointSymbol=none]{#5}{@PST@HYPERBOLA@VERTEXA}{#4}{@PST@HYPERBOLA@VERTEXB}{@PST@HYPERBOLA@INTER@Y}
    \pstMiddleAB{@PST@HYPERBOLA@INTER@X}{@PST@HYPERBOLA@INTER@Y}{#6}
    \Pst@geonodelabel{#6}%
    \pstLineAB{#4}{#6}
    \pstLineAB{#5}{#6}
    \endgroup
}%
%
%% \pstHyperbolaTangentNode[Options](O)(a,b){T}{A}{B}
%% Draw the two tangent lines through the point $T$ to the Hyperbola H and get the node A and B on the Hyperbola.
%% We use the following proposition to find the tangent points $A$ and $B$ of $T$:
%% Let $T$ is a point out of the hyperbola, we give any two chords $TPQ$ and $TRS$ of the hyperbola, $PR$ and $QS$ intersect at $X$, $RQ$ and $PS$ intersect at $Y$,
%% then the intersection point $A$ and $B$ of $XY$ and the hyperbola are the tangent points from $T$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the given node T outside the hyperbola
%% #5 -> [output] the tangent node name A on the hyperbola
%% #6 -> [output] the tangent node name B on the hyperbola
\def\pstHyperbolaTangentNode{\@ifnextchar[\Pst@HyperbolaTangentNode{\Pst@HyperbolaTangentNode[]}}
\def\Pst@HyperbolaTangentNode[#1](#2)(#3)#4#5#6{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pstHyperbolaOrdNode[PointName=none,PointSymbol=none](#2)(#3){\pstOrdinate{#4} 0.3 add}{@PST@HYPERBOLA@TANGENTAUX@P0}{@PST@HYPERBOLA@TANGENTAUX@P1}
    \pstHyperbolaOrdNode[PointName=none,PointSymbol=none](#2)(#3){\pstOrdinate{#4} 0.3 sub}{@PST@HYPERBOLA@TANGENTAUX@R0}{@PST@HYPERBOLA@TANGENTAUX@R1}
    \pstHyperbolaLineInter[PointName=none,PointSymbol=none](#2)(#3){#4}{@PST@HYPERBOLA@TANGENTAUX@P0}{@PST@HYPERBOLA@TANGENTAUX@P}{@PST@HYPERBOLA@TANGENTAUX@Q}
    \pstHyperbolaLineInter[PointName=none,PointSymbol=none](#2)(#3){#4}{@PST@HYPERBOLA@TANGENTAUX@R0}{@PST@HYPERBOLA@TANGENTAUX@R}{@PST@HYPERBOLA@TANGENTAUX@S}
    \pstInterLL[PointName=none,PointSymbol=none]{@PST@HYPERBOLA@TANGENTAUX@P}{@PST@HYPERBOLA@TANGENTAUX@S}{@PST@HYPERBOLA@TANGENTAUX@Q}{@PST@HYPERBOLA@TANGENTAUX@R}{@PST@HYPERBOLA@TANGENTAUX@I}
    \pstInterLL[PointName=none,PointSymbol=none]{@PST@HYPERBOLA@TANGENTAUX@P}{@PST@HYPERBOLA@TANGENTAUX@R}{@PST@HYPERBOLA@TANGENTAUX@Q}{@PST@HYPERBOLA@TANGENTAUX@S}{@PST@HYPERBOLA@TANGENTAUX@X}
    \pstHyperbolaLineInter(#2)(#3){@PST@HYPERBOLA@TANGENTAUX@X}{@PST@HYPERBOLA@TANGENTAUX@I}{#5}{#6}
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
    \pstLineAB{#4}{#5}
    \pstLineAB{#4}{#6}
  \endgroup%
}%
%
% 8. Standard Conjugate Hyperbola with coordinate translation
%% ----------------------------------------------------------
%% The Standard Conjugate Hyperbola H is defined by center O, the half of the real axis $a$, the half of the imaginary axis $b$.
%% The equation can be written as:
%% \begin{equation}\label{FunctionOfStandardConjugateHyperbola}
%% \dfrac{(y-y0)^2}{a^2}-\dfrac{(x-x0)^2}{b^2}=1
%% \end{equation}
%% and the parametric function can be written as:
%% \begin{equation}\label{ParametricFunctionOfStandardConjugateHyperbola}
%% \left\{\begin{array}{l}
%% x=b\tan\alpha+x_o\\
%% y=a\sec\alpha+y_o
%% \end{array}\right.
%% \end{equation}
%
%% \pstIHyperbola[Options](O)(a,b)[maxAngleY]
%% Draw a Conjugate Hyperbola with center O, the half of the real axis $abs(a)$, and the half of the imaginary axis $abs(b)$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the maximal angle to draw the branch.
\def\pstIHyperbola{\@ifnextchar[\Pst@IHyperbola{\Pst@IHyperbola[]}}
\def\Pst@IHyperbola[#1](#2)(#3){%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@IHyperbola@i{\Pst@IHyperbola@i[85]}}%
\def\Pst@IHyperbola@i[#1]{%
    \pst@cnth=#1\pst@cntg=180\pst@cntm=180\pst@cntn=360
    \ifnum\pst@cnth<0
        \loop\advance\pst@cnth by 90
            \ifnum\pst@cnth<0
        \repeat
    \fi
    \ifnum\pst@cnth>90
        \loop\advance\pst@cnth by -90
            \ifnum\pst@cnth>90
        \repeat
    \fi
    \ifnum\pst@cnth>85
        \advance\pst@cnth by -5
    \fi
    \advance\pst@cntg by -\pst@cnth
    \advance\pst@cntm by \pst@cnth
    \advance\pst@cntn by -\pst@cnth
    \Pst@IHyperbola@ii[0][\number\pst@cnth]%
    \Pst@IHyperbola@ii[\number\pst@cntg][180]%
    \Pst@IHyperbola@ii[180][\number\pst@cntm]%
    \Pst@IHyperbola@ii[\number\pst@cntn][360]%
  \endgroup%
}%
\def\Pst@IHyperbola@ii[#1][#2]{%
    \parametricplot{#1}{#2}{%
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      t dup cos exch sin % cos{t} sin{t}
      1 index abs 1E-5 lt {
        pop pop pop pop
      } {
        5 index 3 index 2 index mul 3 index div add % x0+b\tan{t}
        5 index 5 index 4 index div add % y0+a\sec{t}
        8 2 roll pop pop pop pop pop pop
      } ifelse
    }%
}%
%
%% \pstIHyperbolaNode[Options](O)(a,b){t}{P}
%% Create a new node P on the Conjugate Hyperbola E whose parameter is the given value $t$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the parametric argument t.
%% #5 -> [output] the target node name.
\def\pstIHyperbolaNode{\@ifnextchar[\Pst@IHyperbolaNode{\Pst@IHyperbolaNode[]}}
\def\Pst@IHyperbolaNode[#1](#2)(#3)#4#5{%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #4 dup cos exch sin % cos{t} sin{t}
      1 index abs 1E-5 lt {
        pop pop pop pop
      }{
        5 index 3 index 2 index mul 3 index div add % x0+b\tan{t}
        5 index 5 index 4 index div add % y0+a\sec{t}
        8 2 roll pop pop pop pop pop pop
      } ifelse
    ){#5}%
    \Pst@geonodelabel{#5}%
  \endgroup%
}%
%
%% \pstIHyperbolaAbsNode[Options](O)(a,b){x_1}{A}{B}
%% Create a new node P on the Conjugate Hyperbola E whose abscissa is the given value $x_1$.
%% when $x=x_1$, we have
%% $$\dfrac{(y-y_0)^2}{a^2}-\dfrac{(x_1-x_0)^2}{b^2}=1$$
%% $$(y-y_0)^2=\dfrac{a^2(x_1-x_0)^2+a^2b^2}{b^2}$$
%% $$y=y_0\pm\dfrac{a}{b}\sqrt{(x_1-x_0)^2+b^2}$$
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the abbscissa value $x_1$.
%% #5 -> [output] the first target node name.
%% #6 -> [output] the first second node name.
\def\pstIHyperbolaAbsNode{\@ifnextchar[\Pst@IHyperbolaAbsNode{\Pst@IHyperbolaAbsNode[]}}
\def\Pst@IHyperbolaAbsNode[#1](#2)(#3)#4#5#6{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #4 4 index sub dup mul 1 index dup mul add % (x_1-x_0)^2+b^2
      sqrt 2 index mul 1 index div 3 index exch sub % y1
      #4 exch 6 2 roll pop pop pop pop
    ){#5}%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #4 4 index sub dup mul 1 index dup mul add % (x_1-x_0)^2+b^2
      sqrt 2 index mul 1 index div 3 index add % y1
      #4 exch 6 2 roll pop pop pop pop
    ){#6}%
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
  \endgroup%
}%
%
%% \pstIHyperbolaOrdNode[Options](O)(a,b){y_1}{A}{B}
%% Create a new node P on the Conjugate Hyperbola E whose ordinate is the given value $y_1$.
%% when $y=y_1$, we have
%% $$\dfrac{(y_1-y_0)^2}{a^2}-\dfrac{(x-x_0)^2}{b^2}=1$$
%% $$(x-x_0)^2=\dfrac{b^2(y_1-y_0)^2-a^2b^2}{a^2}$$
%% $$x=x_0\pm\dfrac{b}{a}\sqrt{(y_1-y_0)^2-a^2}$$
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the abbscissa value $x_1$.
%% #5 -> [output] the first target node name.
%% #6 -> [output] the first second node name.
\def\pstIHyperbolaOrdNode{\@ifnextchar[\Pst@IHyperbolaOrdNode{\Pst@IHyperbolaOrdNode[]}}
\def\Pst@IHyperbolaOrdNode[#1](#2)(#3)#4#5#6{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #4 3 index sub dup mul 2 index dup mul sub % (y_1-y_0)^2-a^2
      dup 0 lt {
        pop pop pop pop pop 0 0
      } {
        sqrt 1 index mul 2 index div 4 index exch sub % x1
        #4 6 2 roll pop pop pop pop
      } ifelse
    ){#5}%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #4 3 index sub dup mul 2 index dup mul sub % (y_1-y_0)^2-a^2
      dup 0 lt {
        pop pop pop pop pop 0 0
      } {
        sqrt 1 index mul 2 index div 4 index add % x2
        #4 6 2 roll pop pop pop pop
      } ifelse
    ){#6}%
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
  \endgroup%
}%
%
%% \pstIHyperbolaFocusNode[Options](O)(a,b){F1}{F2}
%% Create the two focus node F1 and F2 of the Conjugate Hyperbola H.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [output] the first focus node name.
%% #5 -> [output] the first focus node name.
\def\pstIHyperbolaFocusNode{\@ifnextchar[\Pst@IHyperbolaFocusNode{\Pst@IHyperbolaFocusNode[]}}
\def\Pst@IHyperbolaFocusNode[#1](#2)(#3)#4#5{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      dup mul exch dup mul add sqrt % c
      1 index exch sub 2 index exch % x0,y0-c
      4 2 roll pop pop
    ){#4}%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      dup mul exch dup mul add sqrt % c
      1 index add 2 index exch % x0,y0+c
      4 2 roll pop pop
    ){#5}%
    \Pst@ManageParamList{#4}%
    \Pst@ManageParamList{#5}%
  \endgroup%
}%
%
%% \pstIHyperbolaDirectrixLine[Options](O)(a,b){Lx}{Ly}{Rx}{Ry}
%% Draw the two directrix lines L1 and L2 of the Conjugate Hyperbola H.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [output] the first node name on the first directrix line.
%% #5 -> [output] the second node name on the first directrix line.
%% #6 -> [output] the first node name on the second directrix line.
%% #7 -> [output] the second node name on the second directrix line.
\def\pstIHyperbolaDirectrixLine{\@ifnextchar[\Pst@IHyperbolaDirectrixLine{\Pst@IHyperbolaDirectrixLine[]}}
\def\Pst@IHyperbolaDirectrixLine[#1](#2)(#3)#4#5#6#7{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      1 index dup mul dup 2 index dup mul add sqrt div % a^2/c
      3 index exch sub 4 index exch % x0,y0-a^2/c
      6 2 roll pop pop pop pop
    ){#4}%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      1 index dup mul dup 2 index dup mul add sqrt div % a^2/c
      3 index exch sub 4 index 1 add exch % x0+1,y0-a^2/c
      6 2 roll pop pop pop pop
    ){#5}%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      1 index dup mul dup 2 index dup mul add sqrt div % a^2/c
      3 index add 4 index exch % x0,y0+a^2/c
      6 2 roll pop pop pop pop
    ){#6}%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      1 index dup mul dup 2 index dup mul add sqrt div % a^2/c
      3 index add 4 index 1 add exch % x0+1,y0+a^2/c
      6 2 roll pop pop pop pop
    ){#7}%
    \Pst@ManageParamList{#4}%
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
    \Pst@ManageParamList{#7}%
    \pstLineAB{#4}{#5}%
    \pstLineAB{#6}{#7}%
  \endgroup%
}%
%
%% \pstIHyperbolaAsymptoteLine[Options](O)(a,b){L1}{L2}
%% Draw the two asymptote lines L1 and L2 of the Conjugate Hyperbola H.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [output] the second node name on the first asymptote line, the first node is the center O.
%% #5 -> [output] the second node name on the second asymptote line, the first node is the center O.
\def\pstIHyperbolaAsymptoteLine{\@ifnextchar[\Pst@IHyperbolaAsymptoteLine{\Pst@IHyperbolaAsymptoteLine[]}}
\def\Pst@IHyperbolaAsymptoteLine[#1](#2)(#3)#4#5{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      0 index 2 index div % b/a
      4 index 1 index sub % x=x0-b/a
      4 index 1 add % y=y0+1
      7 2 roll pop pop pop pop pop
    ){#4}%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      0 index 2 index div % b/a
      4 index 1 index add % x=x0+b/a
      4 index 1 add % y=y0+1
      7 2 roll pop pop pop pop pop
    ){#5}%
    \Pst@ManageParamList{#4}%
    \Pst@ManageParamList{#5}%
    \pstLineAB{#2}{#4}%
    \pstLineAB{#2}{#5}%
  \endgroup%
}%
%
%% \pstIHyperbolaLineInter[Options](O)(a,b){A}{B}{C}{D}
%% Find the two intersection nodes C and D of the Conjugate Hyperbola H and line AB.
%%
%% Case 1. When line AB is vertical, i.e, $x_1=x_2$, we have
%% $$y=y_0\pm\dfrac{a}{b}\sqrt{(x_1-x_0)^2+b^2}$$
%%
%% Case 2. When line AB is not vertical, we can represent the line AB as the following function:
%% $$y=kx+d$$ where $$k=\dfrac{y_2-y_1}{x_2-x_1}, d=\dfrac{x_2y_1-x_1y_2}{x_2-x_1}$$
%% refer to equation (\ref{FunctionOfStandardConjugateHyperbola}), we have
%% $$(b^2k^2-a^2)X^2+2b^2kmX+b^2(m^2-a^2)=0$$
%% $$Y=kX+m$$
%% where
%% $$m=kx_o-y_o+d,X=x-x_0,Y=y-y_0$$
%%
%% Case 2.1 When $b^2k^2-a^2=0$, which gives $k=\pm\dfrac{a}{b}\neq0$,
%% at this time, when $m=0$, the line AB becomes the asymptote of the hyperbola,
%% so there is none intersection any more; else we have
%% $$x_{C}=x_o-\dfrac{m^2-a^2}{2km},y_{C}=kx_{C}+d$$
%% but D is not defined.
%%
%% Case 2.2 When $b^2k^2-a^2\neq0$, we have
%% $$x_{C,D}=x_0+\dfrac{-b^2km\pm{}ab\sqrt{m^2+b^2k^2-a^2}}{b^2k^2-a^2},y_{C,D}=kx_{C,D}+d$$
%%
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the first node name on the given line AB.
%% #5 -> [input] the second node name on the given line AB.
%% #6 -> [output] the first intersection node.
%% #7 -> [output] the second intersection node.
\def\pstIHyperbolaLineInter{\@ifnextchar[\Pst@IHyperbolaLineInter{\Pst@IHyperbolaLineInter[]}}
\def\Pst@IHyperbolaLineInter[#1](#2)(#3)#4#5#6#7{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \pst@getcoor{#4}\pst@tempA%
    \pst@getcoor{#5}\pst@tempB%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      \pst@tempA \tx@UserCoor % x_1,y_1
      \pst@tempB \tx@UserCoor % x_2,y_2
      3 index 2 index sub abs 1E-5 lt { % if the line AB is vertical
        %% $$y=y_0\pm\dfrac{a}{b}\sqrt{(x_1-x_0)^2+b^2}$$
        3 index 8 index sub dup mul 5 index dup mul add
        sqrt 6 index mul 5 index div 7 index exch sub % y1
        4 index exch % x1
        10 2 roll pop pop pop pop pop pop pop pop
      } {
        0 index 3 index sub 2 index 5 index sub div % k
        2 index 4 index mul 2 index 6 index mul sub 3 index 6 index sub div % d
        1 index 10 index mul 9 index sub 1 index add % m=kx_o-y_o+d
        7 index dup mul 3 index dup mul mul 9 index dup mul sub % b^2k^2-a^2
        0 index abs 1E-5 lt {
          1 index abs 1E-5 lt {
            pop pop pop pop pop pop
            pop pop pop pop pop pop
            0 0
          } {
            %% $$x_{C}=x_o-\dfrac{m^2-a^2}{2km},y_{C}=kx_{C}+d$$
            1 index dup mul 10 index dup mul sub 2 index 5 index mul 2 mul div % (m^2-a^2)/2km
            12 index exch sub % x1
            4 index 1 index mul 4 index add % y1
            14 2 roll pop pop pop pop pop pop
            pop pop pop pop pop pop
          } ifelse
        } {
          1 index dup mul 1 index add % m^2+b^2k^2-a^2
          dup 0 lt {
            pop pop pop pop pop pop pop
            pop pop pop pop pop pop 0 0
          } {
            sqrt 10 index mul 9 index mul 9 index dup mul 5 index mul 3 index mul add neg 1 index div 12 index add % x1
            4 index 1 index mul 4 index add % y1
            14 2 roll pop pop pop pop pop pop
            pop pop pop pop pop pop
          } ifelse
        } ifelse
      } ifelse
    ){#6}%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      \pst@tempA \tx@UserCoor % x_1,y_1
      \pst@tempB \tx@UserCoor % x_2,y_2
      3 index 2 index sub abs 1E-5 lt { % if the line AB is vertical
        %% $$y=y_0\pm\dfrac{a}{b}\sqrt{(x_1-x_0)^2+b^2}$$
        3 index 8 index sub dup mul 5 index dup mul add
        sqrt 6 index mul 5 index div 7 index add % y2
        4 index exch % x2
        10 2 roll pop pop pop pop pop pop pop pop
      } {
        0 index 3 index sub 2 index 5 index sub div % k
        2 index 4 index mul 2 index 6 index mul sub 3 index 6 index sub div % d
        1 index 10 index mul 9 index sub 1 index add % m=kx_o-y_o+d
        7 index dup mul 3 index dup mul mul 9 index dup mul sub % b^2k^2-a^2
        dup abs 1E-5 lt {
          pop pop pop pop pop pop
          pop pop pop pop pop pop
          0 0
        } {
          1 index dup mul 1 index add % m^2+b^2k^2-a^2
          dup 0 lt {
            pop pop pop pop pop pop pop
            pop pop pop pop pop pop 0 0
          } {
            sqrt 10 index mul 9 index mul 9 index dup mul 5 index mul 3 index mul sub 1 index div 12 index add % x2
            4 index 1 index mul 4 index add % y2
            14 2 roll pop pop pop pop pop pop
            pop pop pop pop pop pop
          } ifelse
        } ifelse
      } ifelse
    ){#7}%
    \Pst@ManageParamList{#6}%
    \Pst@ManageParamList{#7}%
  \endgroup%
}%
%
%% \pstIHyperbolaPolarNode[Options](O)(a,b){A}{B}{T}
%% Find the polar point of chord AB on Conjugate Hyperbola H.
%% We use the following proposition to find the polar point of chord AB:
%% Let $P$, $Q$ are vertex points of the hyperbola, for any chord $AB$ of hyperbola, $PA$ and $BQ$ intersect at $E$, $PB$ and $AQ$ intersect at $F$, then the middle point $M$ of $EF$ is the polar point of chord $AB$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the node A on the hyperbola.
%% #5 -> [input] the node B on the hyperbola.
%% #6 -> [output] the polar node T of chord AB.
\def\pstIHyperbolaPolarNode{\@ifnextchar[\Pst@IHyperbolaPolarNode{\Pst@IHyperbolaPolarNode[]}}
\def\Pst@IHyperbolaPolarNode[#1](#2)(#3)#4#5#6{%
  \begingroup
    \psset{#1}%
    \pstIHyperbolaAbsNode[PointName=none,PointSymbol=none](#2)(#3){\pstAbscissa{#2}}{@PST@IHYPERBOLA@VERTEXA}{@PST@IHYPERBOLA@VERTEXB}
    \pstInterLL[PointName=none,PointSymbol=none]{#4}{@PST@IHYPERBOLA@VERTEXA}{#5}{@PST@IHYPERBOLA@VERTEXB}{@PST@IHYPERBOLA@INTER@X}
    \pstInterLL[PointName=none,PointSymbol=none]{#5}{@PST@IHYPERBOLA@VERTEXA}{#4}{@PST@IHYPERBOLA@VERTEXB}{@PST@IHYPERBOLA@INTER@Y}
    \pstMiddleAB{@PST@IHYPERBOLA@INTER@X}{@PST@IHYPERBOLA@INTER@Y}{#6}
    \Pst@geonodelabel{#6}%
    \pstLineAB{#4}{#6}
    \pstLineAB{#5}{#6}
    \endgroup
}%
%
%% \pstIHyperbolaTangentNode[Options](O)(a,b){T}{A}{B}
%% Draw the two tangent lines through the point $T$ to the Conjugate Hyperbola H and get the node A and B on the Conjugate Hyperbola.
%% We use the following proposition to find the tangent points $A$ and $B$ of $T$:
%% Let $T$ is a point out of the hyperbola, we give any two chords $TPQ$ and $TRS$ of the hyperbola, $PR$ and $QS$ intersect at $X$, $RQ$ and $PS$ intersect at $Y$,
%% then the intersection point $A$ and $B$ of $XY$ and the hyperbola are the tangent points from $T$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the given node T outside the hyperbola
%% #5 -> [output] the tangent node name A on the hyperbola
%% #6 -> [output] the tangent node name B on the hyperbola
\def\pstIHyperbolaTangentNode{\@ifnextchar[\Pst@IHyperbolaTangentNode{\Pst@IHyperbolaTangentNode[]}}
\def\Pst@IHyperbolaTangentNode[#1](#2)(#3)#4#5#6{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pstIHyperbolaAbsNode[PointName=none,PointSymbol=none](#2)(#3){\pstAbscissa{#4} 0.3 add}{@PST@IHYPERBOLA@TANGENTAUX@P0}{@PST@IHYPERBOLA@TANGENTAUX@P1}
    \pstIHyperbolaAbsNode[PointName=none,PointSymbol=none](#2)(#3){\pstAbscissa{#4} 0.3 sub}{@PST@IHYPERBOLA@TANGENTAUX@R0}{@PST@IHYPERBOLA@TANGENTAUX@R1}
    \pstIHyperbolaLineInter[PointName=none,PointSymbol=none](#2)(#3){#4}{@PST@IHYPERBOLA@TANGENTAUX@P0}{@PST@IHYPERBOLA@TANGENTAUX@P}{@PST@IHYPERBOLA@TANGENTAUX@Q}
    \pstIHyperbolaLineInter[PointName=none,PointSymbol=none](#2)(#3){#4}{@PST@IHYPERBOLA@TANGENTAUX@R0}{@PST@IHYPERBOLA@TANGENTAUX@R}{@PST@IHYPERBOLA@TANGENTAUX@S}
    \pstInterLL[PointName=none,PointSymbol=none]{@PST@IHYPERBOLA@TANGENTAUX@P}{@PST@IHYPERBOLA@TANGENTAUX@S}{@PST@IHYPERBOLA@TANGENTAUX@Q}{@PST@IHYPERBOLA@TANGENTAUX@R}{@PST@IHYPERBOLA@TANGENTAUX@I}
    \pstInterLL[PointName=none,PointSymbol=none]{@PST@IHYPERBOLA@TANGENTAUX@P}{@PST@IHYPERBOLA@TANGENTAUX@R}{@PST@IHYPERBOLA@TANGENTAUX@Q}{@PST@IHYPERBOLA@TANGENTAUX@S}{@PST@IHYPERBOLA@TANGENTAUX@X}
    \pstIHyperbolaLineInter(#2)(#3){@PST@IHYPERBOLA@TANGENTAUX@X}{@PST@IHYPERBOLA@TANGENTAUX@I}{#5}{#6}
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
    \pstLineAB{#4}{#5}
    \pstLineAB{#4}{#6}
  \endgroup%
}%
%
% 9. General Hyperbola with coordinate translation and rotation
%% ----------------------------------------------------------
%% The General Hyperbola H is defined by center O, the half of the real axis $a$, the half of the imaginary axis $b$,
%% and the rotation angle $\theta$ of the principal axis.
%% The equation can be got from the parametric function of the Standard Hyperbola \ref{ParametricFunctionOfStandardHyperbola},
%% using the rotation transform formula \ref{RotationTransformFormula}, then we have
%% \begin{equation}
%% \left\{\begin{array}{l}
%% x'=(a\sec\alpha+x_o)\cos\theta-(b\tan\alpha+y_o)\sin\theta=x_o'+a\sec\alpha\cos\theta-b\tan\alpha\sin\theta\\
%% y'=(a\sec\alpha+x_o)\sin\theta+(b\tan\alpha+y_o)\cos\theta=y_o'+a\sec\alpha\sin\theta+b\tan\alpha\cos\theta
%% \end{array}\right.
%% \end{equation}
%% where the $x_o'$ and $y_o'$ are the coordinate of the given center O after rotation.
%% So we get the parametric function of the General Hyperbola with coordinate translation and rotation as following:
%% \begin{equation}\label{ParametricFunctionOfGeneralHyperbola}
%% \left\{\begin{array}{l}
%% x=x_o+a\sec\alpha\cos\theta-b\tan\alpha\sin\theta\\
%% y=y_o+a\sec\alpha\sin\theta+b\tan\alpha\cos\theta
%% \end{array}\right.
%% \end{equation}
%
%% \pstGeneralHyperbola[Options](O)(a,b)[rotation][maxAngleX]
%% Draw a General Hyperbola with center O, the half of the real axis $abs(a)$, the half of the imaginary axis $abs(b)$,
%% and the rotation angle $\theta$ of the symmetrical axis.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the maximal angle to draw the branch.
\def\pstGeneralHyperbola{\@ifnextchar[\Pst@GeneralHyperbola{\Pst@GeneralHyperbola[]}}
\def\Pst@GeneralHyperbola[#1](#2)(#3){%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralHyperbola@i{\Pst@GeneralHyperbola@i[0]}}%
\def\Pst@GeneralHyperbola@i[#1]{%
    \def\pst@hyperbola@rotation{#1}%
    \@ifnextchar[\Pst@GeneralHyperbola@j{\Pst@GeneralHyperbola@j[85]}}%
\def\Pst@GeneralHyperbola@j[#1]{%
    \pst@cnth=#1\pst@cntg=180\pst@cntm=180\pst@cntn=360
    \ifnum\pst@cnth<0
        \loop\advance\pst@cnth by 90
            \ifnum\pst@cnth<0
        \repeat
    \fi
    \ifnum\pst@cnth>90
        \loop\advance\pst@cnth by -90
            \ifnum\pst@cnth>90
        \repeat
    \fi
    \ifnum\pst@cnth>85
        \advance\pst@cnth by -5
    \fi
    \advance\pst@cntg by -\pst@cnth
    \advance\pst@cntm by \pst@cnth
    \advance\pst@cntn by -\pst@cnth
    \Pst@GeneralHyperbola@k[0][\number\pst@cnth]%
    \Pst@GeneralHyperbola@k[\number\pst@cntg][180]%
    \Pst@GeneralHyperbola@k[180][\number\pst@cntm]%
    \Pst@GeneralHyperbola@k[\number\pst@cntn][360]%
  \endgroup%
}%
\def\Pst@GeneralHyperbola@k[#1][#2]{%
    \parametricplot{#1}{#2}{%
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      t dup cos exch sin % cos{t} sin{t}
      1 index abs 1E-5 lt {
        pop pop pop pop
      } {
        \pst@hyperbola@rotation\space dup cos exch sin % cos\theta sin\theta
        %% x=x_o+a\sec\alpha\cos\theta-b\tan\alpha\sin\theta
        7 index 6 index 5 index div 3 index mul add
        5 index 4 index mul 5 index div 2 index mul sub
        %% y=y_o+a\sec\alpha\sin\theta+b\tan\alpha\cos\theta
        7 index 7 index 6 index div 3 index mul add
        6 index 5 index mul 6 index div 4 index mul add
        10 2 roll pop pop pop pop pop pop pop pop
      } ifelse
    }%
}%
%
%% \pstGeneralHyperbolaFFN[Options]{F1}{F2}{N}{O}{R}{\theta}
%% Calculate the center and the radii of a General Hyperbola with two focus $F_1$, $F_2$, and one node $N$ on it,
%% then you can access the hyperbola with them.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the given focus F_1
%% #3 -> [input] the given focus F_2
%% #4 -> [input] the given node N on the hyperbola
%% #5 -> [output] the center of the hyperbola.
%% #6 -> [output] the pair of major and minor radius of the hyperbola.
%% #7 -> [output] the rotation of the hyperbola major axis.
\def\pstGeneralHyperbolaFFN{\@ifnextchar[\Pst@GeneralHyperbolaFFN{\Pst@GeneralHyperbolaFFN[]}}
\def\Pst@GeneralHyperbolaFFN[#1]#2#3#4#5#6#7{
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempFa%
    \pst@getcoor{#3}\pst@tempFb%
    \pst@getcoor{#4}\pst@tempN%
    \pnode(!
      \pst@tempFa \tx@UserCoor /Fay ED /Fax ED
      \pst@tempFb \tx@UserCoor /Fby ED /Fbx ED
      \pst@tempN \tx@UserCoor /Ny ED /Nx ED
      Fax Fbx add 2 div /HyperbolaOx ED
      Fay Fby add 2 div /HyperbolaOy ED
      Fax Fay Fbx Fby
      tx@EcldDict begin ABDist end
      2 div /HyperbolaC ED
      Nx Ny Fax Fay
      tx@EcldDict begin ABDist end
      Nx Ny Fbx Fby
      tx@EcldDict begin ABDist end
      sub 2 div abs /HyperbolaA ED
      HyperbolaC dup mul HyperbolaA dup mul sub sqrt /HyperbolaB ED
      Fay Fby lt {
        Fby Fay sub Fbx Fax sub atan /#7 ED
      } {
        Fay Fby sub Fax Fbx sub atan /#7 ED
      } ifelse
      HyperbolaOx HyperbolaOy
    ){#5}
    \Pst@geonodelabel{#5}%
    \pnode(! HyperbolaA HyperbolaB){#6}
    \ifPst@CodeFig
    \begingroup\psset{PointName=none,linecolor=\psk@CodeFigColor}
    \pstLineAB[nodesep=-0.6]{#2}{#3}
    \pstLineAA[nodesepA=-1.5,nodesepB=-0.5]{#5}{#7 90 add}{PST@HYPERBOLA@Y}
    \endgroup
    \fi
  \endgroup%
}%
%
%% \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 real 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\space 2 div /CurveCoefb ED
      \CurveCoefc /CurveCoefc ED
      \CurveCoefd\space 2 div /CurveCoefd ED
      \CurveCoefe\space 2 div /CurveCoefe ED
      \CurveCoeff /CurveCoeff ED
      % CurveCoefa = CurveCoefb = CurveCoefc = CurveCoefd = CurveCoefe = CurveCoeff =
      % I1=a+c
      CurveCoefa CurveCoefc add /DiscriminantI ED
      % I2=ac-b^2
      CurveCoefa CurveCoefc mul CurveCoefb dup mul sub /DiscriminantII ED
      % I3=|a b d,b c e,d e f|
      CurveCoefa CurveCoefb CurveCoefd
      CurveCoefb CurveCoefc CurveCoefe
      CurveCoefd CurveCoefe CurveCoeff
      tx@EcldDict begin DeterminantThree end /DiscriminantIII ED
      % DiscriminantI = DiscriminantII = DiscriminantIII =
      DiscriminantII 0 lt DiscriminantIII 0 ne and { % if I2<0 and I3!=0
        % Solve the Characteristic Equation: \lambda^2-I_1\lambda+I_2=0
        DiscriminantI dup mul 4 DiscriminantII mul sub 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 =
          % 20200726 Liaoxiongfei
          % fix how to get the rotation of the hyperbola real symmetrical axis.
          % since we can reduce the hyperbola to
          % \lambda_1x^2+\lambda_2y^2+I_3/I_2=0
          % and $I_2\leq0$, so the real symmetrical axis is determined by the characteristic root with the same sign as I3.
          % and the slope of real symmetrical axis is $(\lambda_1-a)/b$, or $(c-\lambda_2)/b$, where $\lambda_1*I_3>0$, or they have same sign.
          DiscriminantIII CharacteristicLambdaI mul 0 gt {
            DiscriminantIII CharacteristicLambdaI DiscriminantII mul div neg sqrt /MyHyperbolaA ED
            DiscriminantIII CharacteristicLambdaII DiscriminantII mul div sqrt /MyHyperbolaB ED
            CharacteristicLambdaI CurveCoefa lt {
              CharacteristicLambdaI CurveCoefa sub neg CurveCoefb neg atan /#5 ED
            } {
              CharacteristicLambdaI CurveCoefa sub CurveCoefb atan /#5 ED
            } ifelse
          } {
            DiscriminantIII CharacteristicLambdaII DiscriminantII mul div neg sqrt /MyHyperbolaA ED
            DiscriminantIII CharacteristicLambdaI DiscriminantII mul div sqrt /MyHyperbolaB ED
            CharacteristicLambdaII CurveCoefa lt {
              CharacteristicLambdaII CurveCoefa sub neg CurveCoefb neg atan /#5 ED
            } {
              CharacteristicLambdaII CurveCoefa sub CurveCoefb atan /#5 ED
            } ifelse
          } ifelse
          % MyHyperbolaA = MyHyperbolaB = #5 = (--------------) =
          % F_1(x,y)=ax+by+d=0
          % F_2(x,y)=bx+cy+e=0
          CurveCoefb CurveCoefe mul CurveCoefc CurveCoefd mul sub DiscriminantII div % x0
          CurveCoefb CurveCoefd mul CurveCoefa CurveCoefe 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, 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^2a
      % BxBy b + By^2 c + Bx d + By e + 1 f = -Bx^2a
      % CxCy b + Cy^2 c + Cx d + Cy e + 1 f = -Cx^2a
      % DxDy b + Dy^2 c + Dx d + Dy e + 1 f = -Dx^2a
      % ExEy b + Ey^2 c + Ex d + Ey e + 1 f = -Ex^2a
      % by Cramer's Rule, we have
      %    |Ax^2a Ay^2 Ax Ay 1| |AxAy Ay^2 Ax Ay 1|
      %    |Bx^2a By^2 Bx By 1| |BxBy By^2 Bx By 1|
      % b=-|Cx^2a Cy^2 Cx Cy 1|/|CxCy Cy^2 Cx Cy 1| etc.
      %    |Dx^2a Dy^2 Dx Dy 1| |DxDy Dy^2 Dx Dy 1|
      %    |Ex^2a Ey^2 Ex Ey 1| |ExEy Ey^2 Ex Ey 1|
      % if the denominator is zero, we can choose a = 0, else a = 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 /CurveCoefa ED
        % Ay^2 c + Ax d + Ay e + 1 f = -AxAyb
        % By^2 c + Bx d + By e + 1 f = -BxByb
        % Cy^2 c + Cx d + Cy e + 1 f = -CxCyb
        % Dy^2 c + Dx d + Dy e + 1 f = -DxDyb
        % by Cramer's Rule, we have
        %    |AxAyb Ax Ay 1| |Ay^2 Ax Ay 1|
        %    |BxByb Bx By 1| |By^2 Bx By 1|
        % c=-|CxCyb Cx Cy 1|/|Cy^2 Cx Cy 1| etc.
        %    |DxDyb Dx Dy 1| |Dy^2 Dx Dy 1|
        % if the denominator is zero, then b = 0, but I_2 is zero at this time,
        % and the equation is not a hyperbola. so we can choose b = 1.
        CurveNodeAY dup mul CurveNodeAX CurveNodeAY 1
        CurveNodeBY dup mul CurveNodeBX CurveNodeBY 1
        CurveNodeCY dup mul CurveNodeCX CurveNodeCY 1
        CurveNodeDY dup mul CurveNodeDX CurveNodeDY 1
        tx@EcldDict begin DeterminantFour end /LinearDiscriminant2nd ED
        LinearDiscriminant2nd abs 1E-5 lt { % D2=0
          0 /CurveCoefb ED
          0 /CurveCoefc ED
          0 /CurveCoefd ED
          0 /CurveCoefe ED
          0 /CurveCoeff ED
        } {
          1 2 div /CurveCoefb ED
          CurveNodeAX CurveNodeAY mul CurveNodeAX CurveNodeAY 1
          CurveNodeBX CurveNodeBY mul CurveNodeBX CurveNodeBY 1
          CurveNodeCX CurveNodeCY mul CurveNodeCX CurveNodeCY 1
          CurveNodeDX CurveNodeDY mul CurveNodeDX CurveNodeDY 1
          tx@EcldDict begin DeterminantFour end LinearDiscriminant2nd div neg /CurveCoefc ED
          CurveNodeAY dup mul CurveNodeAX CurveNodeAY mul CurveNodeAY 1
          CurveNodeBY dup mul CurveNodeBX CurveNodeBY mul CurveNodeBY 1
          CurveNodeCY dup mul CurveNodeCX CurveNodeCY mul CurveNodeCY 1
          CurveNodeDY dup mul CurveNodeDX CurveNodeDY mul CurveNodeDY 1
          tx@EcldDict begin DeterminantFour end LinearDiscriminant2nd div neg 2 div /CurveCoefd ED
          CurveNodeAY dup mul CurveNodeAX CurveNodeAX CurveNodeAY mul 1
          CurveNodeBY dup mul CurveNodeBX CurveNodeBX CurveNodeBY mul 1
          CurveNodeCY dup mul CurveNodeCX CurveNodeCX CurveNodeCY mul 1
          CurveNodeDY dup mul CurveNodeDX CurveNodeDX CurveNodeDY mul 1
          tx@EcldDict begin DeterminantFour end LinearDiscriminant2nd div neg 2 div /CurveCoefe ED
          CurveNodeAY dup mul CurveNodeAX CurveNodeAY CurveNodeAX CurveNodeAY mul
          CurveNodeBY dup mul CurveNodeBX CurveNodeBY CurveNodeBX CurveNodeBY mul
          CurveNodeCY dup mul CurveNodeCX CurveNodeCY CurveNodeCX CurveNodeCY mul
          CurveNodeDY dup mul CurveNodeDX CurveNodeDY CurveNodeDX CurveNodeDY mul
          tx@EcldDict begin DeterminantFour end LinearDiscriminant2nd div neg /CurveCoeff ED
        } ifelse
      } {
        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
      } ifelse
      % CurveCoefa = CurveCoefb = CurveCoefc = CurveCoefd = CurveCoefe = CurveCoeff =
      0 /CurveCoefMax ED 1E8 /CurveCoefMin ED
      CurveCoefa abs CurveCoefMax gt {CurveCoefa abs /CurveCoefMax ED} if
      CurveCoefb abs CurveCoefMax gt {CurveCoefb abs /CurveCoefMax ED} if
      CurveCoefc abs CurveCoefMax gt {CurveCoefc abs /CurveCoefMax ED} if
      CurveCoefd abs CurveCoefMax gt {CurveCoefd abs /CurveCoefMax ED} if
      CurveCoefe abs CurveCoefMax gt {CurveCoefe abs /CurveCoefMax ED} if
      CurveCoeff abs CurveCoefMax gt {CurveCoeff abs /CurveCoefMax ED} if
      CurveCoefa abs CurveCoefMin lt {CurveCoefa abs /CurveCoefMin ED} if
      CurveCoefb abs CurveCoefMin lt {CurveCoefb abs /CurveCoefMin ED} if
      CurveCoefc abs CurveCoefMin lt {CurveCoefc abs /CurveCoefMin ED} if
      CurveCoefd abs CurveCoefMin lt {CurveCoefd abs /CurveCoefMin ED} if
      CurveCoefe abs CurveCoefMin lt {CurveCoefe abs /CurveCoefMin ED} if
      CurveCoeff abs CurveCoefMin lt {CurveCoeff abs /CurveCoefMin ED} if
      % CurveCoefMin = CurveCoefMax =
      CurveCoefMin CurveCoefMax div 1E-5 lt {
        CurveCoefa CurveCoefMax div /CurveCoefa ED
        CurveCoefb CurveCoefMax div /CurveCoefb ED
        CurveCoefc CurveCoefMax div /CurveCoefc ED
        CurveCoefd CurveCoefMax div /CurveCoefd ED
        CurveCoefe CurveCoefMax div /CurveCoefe ED
        CurveCoeff CurveCoefMax div /CurveCoeff ED
      } if
      % CurveCoefa = CurveCoefb = CurveCoefc = CurveCoefd = CurveCoefe = CurveCoeff =
      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
      % the following is same with pstGeneralHyperbolaCoef.
      % CurveCoefa = CurveCoefb = CurveCoefc = CurveCoefd = CurveCoefe = CurveCoeff =
      % I1=a+c
      CurveCoefa CurveCoefc add /DiscriminantI ED
      % I2=ac-b^2
      CurveCoefa CurveCoefc mul CurveCoefb dup mul sub /DiscriminantII ED
      % I3=|a b d,b c e,d e f|
      CurveCoefa CurveCoefb CurveCoefd
      CurveCoefb CurveCoefc CurveCoefe
      CurveCoefd CurveCoefe CurveCoeff
      tx@EcldDict begin DeterminantThree end /DiscriminantIII ED
      % DiscriminantI = DiscriminantII = DiscriminantIII =
      DiscriminantII 0 lt DiscriminantIII 0 ne and { % if I2<0 and I3!=0
        % Solve the Characteristic Equation: \lambda^2-I_1\lambda+I_2=0
        DiscriminantI dup mul 4 DiscriminantII mul sub 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 =
          % 20200726 Liaoxiongfei
          % fix how to get the rotation of the hyperbola real symmetrical axis.
          % since we can reduce the hyperbola to
          % \lambda_1x^2+\lambda_2y^2+I_3/I_2=0
          % and $I_2\leq0$, so the real symmetrical axis is determined by the characteristic root with the same sign as I3.
          % and the slope of real symmetrical axis is $(\lambda_1-a)/b$, or $(c-\lambda_2)/b$, where $\lambda_1*I_3>0$, or they have same sign.
          DiscriminantIII CharacteristicLambdaI mul 0 gt {
            DiscriminantIII CharacteristicLambdaI DiscriminantII mul div neg sqrt /MyHyperbolaA ED
            DiscriminantIII CharacteristicLambdaII DiscriminantII mul div sqrt /MyHyperbolaB ED
            CharacteristicLambdaI CurveCoefa lt {
              CharacteristicLambdaI CurveCoefa sub neg CurveCoefb neg atan /#9 ED
            } {
              CharacteristicLambdaI CurveCoefa sub CurveCoefb atan /#9 ED
            } ifelse
          } {
            DiscriminantIII CharacteristicLambdaII DiscriminantII mul div neg sqrt /MyHyperbolaA ED
            DiscriminantIII CharacteristicLambdaI DiscriminantII mul div sqrt /MyHyperbolaB ED
            CharacteristicLambdaII CurveCoefa lt {
              CharacteristicLambdaII CurveCoefa sub neg CurveCoefb neg atan /#9 ED
            } {
              CharacteristicLambdaII CurveCoefa sub CurveCoefb atan /#9 ED
            } ifelse
          } ifelse
          % MyHyperbolaA = MyHyperbolaB = #9 = (--------------) =
          % F_1(x,y)=ax+by+d=0
          % F_2(x,y)=bx+cy+e=0
          CurveCoefb CurveCoefe mul CurveCoefc CurveCoefd mul sub DiscriminantII div % x0
          CurveCoefb CurveCoefd mul CurveCoefa CurveCoefe mul sub DiscriminantII div % y0
        } ifelse
      } {
        0 0
        0 /MyHyperbolaA ED
        0 /MyHyperbolaB ED
        0 /#9 ED
      } 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:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the parameter value t.
%% #6 -> [output] the target node name.
\def\pstGeneralHyperbolaNode{\@ifnextchar[\Pst@GeneralHyperbolaNode{\Pst@GeneralHyperbolaNode[]}}
\def\Pst@GeneralHyperbolaNode[#1](#2)(#3){%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralHyperbolaNode@i{\Pst@GeneralHyperbolaNode@i[0]}}%
\def\Pst@GeneralHyperbolaNode@i[#1]#2#3{%
    \pnode(!%
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #2 dup cos exch sin % cos{t} sin{t}
      1 index abs 1E-5 lt {
        pop pop pop pop
      } {
        #1 dup cos exch sin % cos\theta sin\theta
        %% x=x_o+a\sec\alpha\cos\theta-b\tan\alpha\sin\theta
        7 index 6 index 5 index div 3 index mul add
        5 index 4 index mul 5 index div 2 index mul sub
        %% y=y_o+a\sec\alpha\sin\theta+b\tan\alpha\cos\theta
        7 index 7 index 6 index div 3 index mul add
        6 index 5 index mul 6 index div 4 index mul add
        10 2 roll pop pop pop pop pop pop pop pop
      } ifelse
    ){#3}%
    \Pst@geonodelabel{#3}%
  \endgroup%
}%
%
%% \pstGeneralHyperbolaAbsNode[Options](O)(a,b)[rotation]{x_1}{A}{B}
%% Draw the nodes whose abscissa value are the given value x_1 on the General Hyperbola.
%%
%% set $e=a\cos\theta$, $f=b\sin\theta$, $g=a\sin\theta$, $h=b\cos\theta$, then we have
%% $$x=x_0+e\sec\alpha-f\tan\alpha, y=y_0+g\sec\alpha+h\tan\alpha$$
%% when $x=x_1$, we get
%% $$e\sec\alpha-f\tan\alpha=x_1-x_0$$
%% set $n=x_1-x_0$, we have
%% $$n\cos\alpha+f\sin\alpha=e$$
%% then
%% $$(n^2+f^2)\sin^2\alpha-2ef\sin\alpha+e^2-n^2=0$$
%% if $n^2+f^2=0$, we have $n=f=0$, i.e, $x_1=x_0$ and $\sin\theta=0$, but the last equation gives $e=0$, which is not possible.
%% so $n^2+f^2\neq0$, we get
%% $$\sin_{1,2}\alpha=\dfrac{ef\pm{}n\sqrt{n^2+f^2-e^2}}{n^2+f^2}$$
%% and
%% $$\cos_{1,2}\alpha=\dfrac{en\mp{}f\sqrt{n^2+f^2-e^2}}{n^2+f^2}$$
%% where $\cos\alpha$ can not be zero, but when $f=\pm{}e$, we have $\cos\alpha=0$, we should skip it.
%%
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the abscissa value x_1.
%% #6 -> [output] the first target node name.
%% #7 -> [output] the second target node name.
\def\pstGeneralHyperbolaAbsNode{\@ifnextchar[\Pst@GeneralHyperbolaAbsNode{\Pst@GeneralHyperbolaAbsNode[]}}
\def\Pst@GeneralHyperbolaAbsNode[#1](#2)(#3){%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralHyperbolaAbsNode@i{\Pst@GeneralHyperbolaAbsNode@i[0]}}%
\def\Pst@GeneralHyperbolaAbsNode@i[#1]#2#3#4{%
    \pnode(!%
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #1 dup cos exch sin % cos\theta sin\theta
      3 index 2 index mul % e=a\cos\theta
      3 index 2 index mul % f=b\sin\theta
      5 index 3 index mul % g=a\sin\theta
      5 index 5 index mul % h=b\cos\theta
      #2 10 index sub % n=x1-x0
      0 index dup mul 4 index dup mul add % n^2+f^2
      0 index abs 1E-5 lt {
        pop pop pop pop pop pop
        pop pop pop pop pop pop 0 0
      } {
        0 index 6 index dup mul sub dup 0 lt {
          pop pop pop pop pop pop pop
          pop pop pop pop pop pop 0 0
        } {
          sqrt % sqrt(n^2+f^2-e^2)
          %% \sin_{1,2}\alpha=\dfrac{ef\pm{}n\sqrt{n^2+f^2-e^2}}{n^2+f^2}
          2 index 1 index mul 7 index 7 index mul exch sub 2 index div % sin
          %% \cos_{1,2}\alpha=\dfrac{en\mp{}f\sqrt{n^2+f^2-e^2}}{n^2+f^2}
          6 index 2 index mul 8 index 5 index mul add 3 index div % cos
          dup abs 1E-5 lt {
            pop pop pop pop pop pop pop pop
            pop pop pop pop pop pop pop 0 0
          } {
            14 index 9 index 2 index div add 8 index 3 index mul 2 index div sub % x_1=x_0+e\sec\alpha-f\tan\alpha
            14 index 8 index 3 index div add 7 index 4 index mul 3 index div add % y_1=y_0+g\sec\alpha+h\tan\alpha
            17 2 roll pop pop pop pop pop pop pop pop
            pop pop pop pop pop pop pop
          } ifelse
        } ifelse
      } ifelse
    ){#3}%
    \pnode(!%
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #1 dup cos exch sin % cos\theta sin\theta
      3 index 2 index mul % e=a\cos\theta
      3 index 2 index mul % f=b\sin\theta
      5 index 3 index mul % g=a\sin\theta
      5 index 5 index mul % h=b\cos\theta
      #2 10 index sub % n=x1-x0
      0 index dup mul 4 index dup mul add % n^2+f^2
      0 index abs 1E-5 lt {
        pop pop pop pop pop pop
        pop pop pop pop pop pop 0 0
      } {
        0 index 6 index dup mul sub dup 0 lt {
          pop pop pop pop pop pop pop
          pop pop pop pop pop pop 0 0
        } {
          sqrt % sqrt(n^2+f^2-e^2)
          %% \sin_{1,2}\alpha=\dfrac{ef\pm{}n\sqrt{n^2+f^2-e^2}}{n^2+f^2}
          2 index 1 index mul 7 index 7 index mul add 2 index div % sin
          %% \cos_{1,2}\alpha=\dfrac{en\mp{}f\sqrt{n^2+f^2-e^2}}{n^2+f^2}
          6 index 2 index mul 8 index 5 index mul exch sub 3 index div % cos
          dup abs 1E-5 lt {
            pop pop pop pop pop pop pop pop
            pop pop pop pop pop pop pop 0 0
          } {
            14 index 9 index 2 index div add 8 index 3 index mul 2 index div sub % x_2=x_0+e\sec\alpha-f\tan\alpha
            14 index 8 index 3 index div add 7 index 4 index mul 3 index div add % y_2=y_0+g\sec\alpha+h\tan\alpha
            17 2 roll pop pop pop pop pop pop pop pop
            pop pop pop pop pop pop pop
          } ifelse
        } ifelse
      } ifelse
    ){#4}%
    \Pst@ManageParamList{#3}%
    \Pst@ManageParamList{#4}%
  \endgroup%
}%
%
%% \pstGeneralHyperbolaOrdNode[Options](O)(a,b)[rotation]{y_1}{A}{B}
%% Draw the nodes whose ordinate value are the given value y_1 on the General Hyperbola.
%%
%% set $e=a\cos\theta$, $f=b\sin\theta$, $g=a\sin\theta$, $h=b\cos\theta$, then we have
%% $$x=x_0+e\sec\alpha-f\tan\alpha, y=y_0+g\sec\alpha+h\tan\alpha$$
%% when $y=y_1$, we get
%% $$g\sec\alpha+h\tan\alpha=y_1-y_0$$
%% set $m=y_1-y_0$, we have
%% $$m\cos\alpha-h\sin\alpha=g$$
%% then
%% $$(m^2+h^2)\sin^2\alpha+2gh\sin\alpha+g^2-m^2=0$$
%% if $m^2+h^2=0$, we have $m=h=0$, i.e, $y_1=y_0$ and $\cos\theta=0$, but the last equation gives $e=0$, which is not possible.
%% so $m^2+h^2\neq0$, we get
%% $$\sin_{1,2}\alpha=\dfrac{-gh\pm{}m\sqrt{m^2+h^2-g^2}}{m^2+h^2}$$
%% and
%% $$\cos_{1,2}\alpha=\dfrac{gm\pm{}h\sqrt{m^2+h^2-g^2}}{m^2+h^2}$$
%% where $\cos\alpha$ can not be zero, but when $h=\pm{}g$, we have $\cos\alpha=0$, we should skip it.
%%
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the ordinate value y_1.
%% #6 -> [output] the first target node name.
%% #7 -> [output] the second target node name.
\def\pstGeneralHyperbolaOrdNode{\@ifnextchar[\Pst@GeneralHyperbolaOrdNode{\Pst@GeneralHyperbolaOrdNode[]}}
\def\Pst@GeneralHyperbolaOrdNode[#1](#2)(#3){%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralHyperbolaOrdNode@i{\Pst@GeneralHyperbolaOrdNode@i[0]}}%
\def\Pst@GeneralHyperbolaOrdNode@i[#1]#2#3#4{%
    \pnode(!%
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #1 dup cos exch sin % cos\theta sin\theta
      3 index 2 index mul % e=a\cos\theta
      3 index 2 index mul % f=b\sin\theta
      5 index 3 index mul % g=a\sin\theta
      5 index 5 index mul % h=b\cos\theta
      #2 9 index sub % m=y1-y0
      0 index dup mul 2 index dup mul add % m^2+h^2
      0 index abs 1E-5 lt {
        pop pop pop pop pop pop
        pop pop pop pop pop pop 0 0
      } {
        0 index 4 index dup mul sub dup 0 lt {
          pop pop pop pop pop pop pop
          pop pop pop pop pop pop 0 0
        } {
          sqrt % sqrt(m^2+h^2-g^2)
          %% \sin_{1,2}\alpha=\dfrac{-gh\pm{}m\sqrt{m^2+h^2-g^2}}{m^2+h^2}
          2 index 1 index mul 5 index 5 index mul add neg 2 index div % sin
          %% \cos_{1,2}\alpha=\dfrac{gm\pm{}h\sqrt{m^2+h^2-g^2}}{m^2+h^2}
          4 index 2 index mul 6 index 5 index mul exch sub 3 index div % cos
          dup abs 1E-5 lt {
            pop pop pop pop pop pop pop pop
            pop pop pop pop pop pop pop 0 0
          } {
            14 index 9 index 2 index div add 8 index 3 index mul 2 index div sub % x_1=x_0+e\sec\alpha-f\tan\alpha
            14 index 8 index 3 index div add 7 index 4 index mul 3 index div add % y_1=y_0+g\sec\alpha+h\tan\alpha
            17 2 roll pop pop pop pop pop pop pop pop
            pop pop pop pop pop pop pop
          } ifelse
        } ifelse
      } ifelse
    ){#3}%
    \pnode(!%
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #1 dup cos exch sin % cos\theta sin\theta
      3 index 2 index mul % e=a\cos\theta
      3 index 2 index mul % f=b\sin\theta
      5 index 3 index mul % g=a\sin\theta
      5 index 5 index mul % h=b\cos\theta
      #2 9 index sub % m=y1-y0
      0 index dup mul 2 index dup mul add % m^2+h^2
      0 index abs 1E-5 lt {
        pop pop pop pop pop pop
        pop pop pop pop pop pop 0 0
      } {
        0 index 4 index dup mul sub dup 0 lt {
          pop pop pop pop pop pop pop
          pop pop pop pop pop pop 0 0
        } {
          sqrt % sqrt(m^2+h^2-g^2)
          %% \sin_{1,2}\alpha=\dfrac{-gh\pm{}m\sqrt{m^2+h^2-g^2}}{m^2+h^2}
          2 index 1 index mul 5 index 5 index mul sub 2 index div % sin
          %% \cos_{1,2}\alpha=\dfrac{gm\pm{}h\sqrt{m^2+h^2-g^2}}{m^2+h^2}
          4 index 2 index mul 6 index 5 index mul add 3 index div % cos
          dup abs 1E-5 lt {
            pop pop pop pop pop pop pop pop
            pop pop pop pop pop pop pop 0 0
          } {
            14 index 9 index 2 index div add 8 index 3 index mul 2 index div sub % x_1=x_0+e\sec\alpha-f\tan\alpha
            14 index 8 index 3 index div add 7 index 4 index mul 3 index div add % y_1=y_0+g\sec\alpha+h\tan\alpha
            17 2 roll pop pop pop pop pop pop pop pop
            pop pop pop pop pop pop pop
          } ifelse
        } ifelse
      } ifelse
    ){#4}%
    \Pst@ManageParamList{#3}%
    \Pst@ManageParamList{#4}%
  \endgroup%
}%
%
%% \pstGeneralHyperbolaFocusNode[Options](O)(a,b)[rotation]{F1}{F2}
%% Draw the focus nodes of the General Hyperbola H.
%% If you not input the rotation angle, the default value is $0^\circ$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [output] the focus node F1 of the Hyperbola.
%% #6 -> [output] the focus node F2 of the Hyperbola.
\def\pstGeneralHyperbolaFocusNode{\@ifnextchar[\Pst@GeneralHyperbolaFocusNode{\Pst@GeneralHyperbolaFocusNode[]}}
\def\Pst@GeneralHyperbolaFocusNode[#1](#2)(#3){%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralHyperbolaFocusNode@i{\Pst@GeneralHyperbolaFocusNode@i[0]}}%
\def\Pst@GeneralHyperbolaFocusNode@i[#1]#2#3{%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #1 dup cos exch sin % cos\theta sin\theta
      3 index dup mul 3 index dup mul add sqrt % c=sqrt(a^2+b^2)
      6 index 1 index 4 index mul sub % x=x0-c\cos\theta
      6 index 2 index 4 index mul sub % y=y0-c\sin\theta
      9 2 roll pop pop pop pop pop pop pop
    ){#2}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #1 dup cos exch sin % cos\theta sin\theta
      3 index dup mul 3 index dup mul add sqrt % c=sqrt(a^2+b^2)
      6 index 1 index 4 index mul add % x=x0+c\cos\theta
      6 index 2 index 4 index mul add % y=y0+c\sin\theta
      9 2 roll pop pop pop pop pop pop pop
    ){#3}
    \Pst@ManageParamList{#2}%
    \Pst@ManageParamList{#3}%
  \endgroup%
}%
%
%% \pstGeneralHyperbolaVertexNode[Options](O)(a,b)[rotation]{V1}{V2}
%% Draw the vertex nodes of the General Hyperbola H.
%% If you not input the rotation angle, the default value is $0^\circ$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [output] the vertex node V1 of the Hyperbola.
%% #6 -> [output] the vertex node V2 of the Hyperbola.
\def\pstGeneralHyperbolaVertexNode{\@ifnextchar[\Pst@GeneralHyperbolaVertexNode{\Pst@GeneralHyperbolaVertexNode[]}}
\def\Pst@GeneralHyperbolaVertexNode[#1](#2)(#3){%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralHyperbolaVertexNode@i{\Pst@GeneralHyperbolaVertexNode@i[0]}}%
\def\Pst@GeneralHyperbolaVertexNode@i[#1]#2#3{%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #1 dup cos exch sin % cos\theta sin\theta
      5 index 4 index 3 index mul sub % x=x0-a\cos\theta
      5 index 5 index 3 index mul sub % y=y0-a\sin\theta
      8 2 roll pop pop pop pop pop pop
    ){#2}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #1 dup cos exch sin % cos\theta sin\theta
      5 index 4 index 3 index mul add % x=x0+a\cos\theta
      5 index 5 index 3 index mul add % y=y0+a\sin\theta
      8 2 roll pop pop pop pop pop pop
    ){#3}
    \Pst@ManageParamList{#2}%
    \Pst@ManageParamList{#3}%
  \endgroup%
}%
%
%% \pstGeneralHyperbolaDirectrixLine[Options](O)(a,b)[rotation]{Lx}{Ly}{Rx}{Ry}
%% Draw the two directrix lines of the General Hyperbola H.
%% If you not input the rotation angle, the default value is $0^\circ$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [output] the first node Lx on the first directrix line.
%% #6 -> [output] the second node Lx on the first directrix line.
%% #7 -> [output] the first node Lx on the second directrix line.
%% #8 -> [output] the second node Lx on the second directrix line.
\def\pstGeneralHyperbolaDirectrixLine{\@ifnextchar[\Pst@GeneralHyperbolaDirectrixLine{\Pst@GeneralHyperbolaDirectrixLine[]}}
\def\Pst@GeneralHyperbolaDirectrixLine[#1](#2)(#3){%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralHyperbolaDirectrixLine@i{\Pst@GeneralHyperbolaDirectrixLine@i[0]}}%
\def\Pst@GeneralHyperbolaDirectrixLine@i[#1]#2#3#4#5{%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      1 index dup mul 1 index dup mul add sqrt % c=sqrt(a^2+b^2)
      2 index dup mul 1 index div 5 index exch sub 4 index % x0-a^2/c,y0
      7 2 roll pop pop pop % x,y,x0,y0
      #1 dup cos exch sin % cos\theta sin\theta
      3 index 6 index 5 index sub 3 index mul add 5 index 4 index sub 2 index mul sub % x0+(x-x0)\cos\theta-(y-y0)\sin\theta
      3 index 7 index 6 index sub 3 index mul add 6 index 5 index sub 4 index mul add % y0+(x-x0)\sin\theta+(y-y0)\cos\theta
      8 2 roll pop pop pop pop pop pop
    ){#2}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      1 index dup mul 1 index dup mul add sqrt % c=sqrt(a^2+b^2)
      2 index dup mul 1 index div 5 index exch sub 4 index 1 add % x0-a^2/c,y0+1
      7 2 roll pop pop pop % x,y,x0,y0
      #1 dup cos exch sin % cos\theta sin\theta
      3 index 6 index 5 index sub 3 index mul add 5 index 4 index sub 2 index mul sub % x0+(x-x0)\cos\theta-(y-y0)\sin\theta
      3 index 7 index 6 index sub 3 index mul add 6 index 5 index sub 4 index mul add % y0+(x-x0)\sin\theta+(y-y0)\cos\theta
      8 2 roll pop pop pop pop pop pop
    ){#3}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      1 index dup mul 1 index dup mul add sqrt % c=sqrt(a^2+b^2)
      2 index dup mul 1 index div 5 index add 4 index % x0+a^2/c,y0
      7 2 roll pop pop pop % x,y,x0,y0
      #1 dup cos exch sin % cos\theta sin\theta
      3 index 6 index 5 index sub 3 index mul add 5 index 4 index sub 2 index mul sub % x0+(x-x0)\cos\theta-(y-y0)\sin\theta
      3 index 7 index 6 index sub 3 index mul add 6 index 5 index sub 4 index mul add % y0+(x-x0)\sin\theta+(y-y0)\cos\theta
      8 2 roll pop pop pop pop pop pop
    ){#4}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      1 index dup mul 1 index dup mul add sqrt % c=sqrt(a^2+b^2)
      2 index dup mul 1 index div 5 index add 4 index 1 add % x0+a^2/c,y0+1
      7 2 roll pop pop pop % x,y,x0,y0
      #1 dup cos exch sin % cos\theta sin\theta
      3 index 6 index 5 index sub 3 index mul add 5 index 4 index sub 2 index mul sub % x0+(x-x0)\cos\theta-(y-y0)\sin\theta
      3 index 7 index 6 index sub 3 index mul add 6 index 5 index sub 4 index mul add % y0+(x-x0)\sin\theta+(y-y0)\cos\theta
      8 2 roll pop pop pop pop pop pop
    ){#5}
    \Pst@ManageParamList{#2}%
    \Pst@ManageParamList{#3}%
    \Pst@ManageParamList{#4}%
    \Pst@ManageParamList{#5}%
    \pstLineAB{#2}{#3}%
    \pstLineAB{#4}{#5}%
  \endgroup%
}%
%
%% \pstGeneralHyperbolaAsymptoteLine[Options](O)(a,b)[rotation]{L1}{L2}
%% Draw the two asymptote lines L1 and L2 of the General Hyperbola H.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [output] the second node name on the first asymptote line, the first node is the center O.
%% #6 -> [output] the second node name on the second asymptote line, the first node is the center O.
\def\pstGeneralHyperbolaAsymptoteLine{\@ifnextchar[\Pst@GeneralHyperbolaAsymptoteLine{\Pst@GeneralHyperbolaAsymptoteLine[]}}
\def\Pst@GeneralHyperbolaAsymptoteLine[#1](#2)(#3){%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \def\pst@hyperbola@center{#2}
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralHyperbolaAsymptoteLine@i{\Pst@GeneralHyperbolaAsymptoteLine@i[0]}}%
\def\Pst@GeneralHyperbolaAsymptoteLine@i[#1]#2#3{%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      0 index 2 index div % b/a
      4 index 1 add % x=x0+1
      4 index 2 index add % y=y0+b/a
      7 2 roll pop pop pop % x y x_0 y_0
      #1 dup cos exch sin % cos\theta sin\theta
      3 index 6 index 5 index sub 3 index mul add 5 index 4 index sub 2 index mul sub % x0+(x-x0)\cos\theta-(y-y0)\sin\theta
      3 index 7 index 6 index sub 3 index mul add 6 index 5 index sub 4 index mul add % y0+(x-x0)\sin\theta+(y-y0)\cos\theta
      8 2 roll pop pop pop pop pop pop
    ){#2}%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      0 index 2 index div % b/a
      4 index 1 add % x=x0+1
      4 index 2 index sub % y=y0-b/a
      7 2 roll pop pop pop % x y x_0 y_0
      #1 dup cos exch sin % cos\theta sin\theta
      3 index 6 index 5 index sub 3 index mul add 5 index 4 index sub 2 index mul sub % x0+(x-x0)\cos\theta-(y-y0)\sin\theta
      3 index 7 index 6 index sub 3 index mul add 6 index 5 index sub 4 index mul add % y0+(x-x0)\sin\theta+(y-y0)\cos\theta
      8 2 roll pop pop pop pop pop pop
    ){#3}%
    \Pst@ManageParamList{#2}%
    \Pst@ManageParamList{#3}%
    \pstLineAB{\pst@hyperbola@center}{#2}%
    \pstLineAB{\pst@hyperbola@center}{#3}%
  \endgroup%
}%
%
%% \pstGeneralHyperbolaLineInter[Options](O)(a,b)[rotation]{A}{B}{C}{D}
%% Find the intersection nodes $C$ and $D$ of the given line AB with the General Hyperbola H.
%%
%% set $e=a\cos\theta$, $f=b\sin\theta$, $g=a\sin\theta$, $h=b\cos\theta$, then we have
%% $$x=x_0+e\sec\alpha-f\tan\alpha, y=y_0+g\sec\alpha+h\tan\alpha$$
%% when line AB is vertical, the solve is like as pstGeneralHyperbolaLineInter,
%% else we can represent the line AB as the following function:
%% $$y=kx+d$$ where $$k=\dfrac{y_2-y_1}{x_2-x_1}, d=\dfrac{x_2y_1-x_1y_2}{x_2-x_1}$$
%% Let $X=x-x_0$, $Y=y-y_0$, then we have $Y=kX+m$, where $m=kx_0-y_0+d$, then
%% $$g\sec\alpha+h\tan\alpha=k(e\sec\alpha-f\tan\alpha)+m$$
%% $$(kf+h)\sin\alpha=m\cos\alpha+ke-g$$
%% $$(kf+h)^2\sin^2\alpha=m^2\cos^2\alpha+2m(ke-g)\cos\alpha+(ke-g)^2$$
%% $$(m^2+(kf+h)^2)\cos^2\alpha-2m(g-ke)\cos\alpha+(g-ke)^2-(kf+h)^2=0$$
%% when $m^2+(kf+h)^2=0$, we have $m=kf+h=0$, at this time $ke-g=0$, we get
%% $$k=-\dfrac{\cos\theta}{\sin\theta}=\dfrac{\sin\theta}{\cos\theta}$$
%% which is not possible.
%% let $p=kf+h$, $q=g-ke$, so we have
%% $$(m^2+p^2)\cos^2\alpha-2mq\cos\alpha+q^2-p^2=0$$
%% then
%% $$\cos_{1,2}\alpha=\dfrac{mq\pm{}p\sqrt{m^2+p^2-q^2}}{m^2+p^2},\sin_{1,2}\alpha=\dfrac{-qp\pm{}m\sqrt{m^2+p^2-q^2}}{m^2+p^2}$$
%% where $\cos\alpha$ can not be zero, we should skip it.
%%
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the first node on the given line.
%% #6 -> [input] the second node on the given line.
%% #7 -> [output] the first intersection node name.
%% #8 -> [output] the second intersection node name.
\def\pstGeneralHyperbolaLineInter{\@ifnextchar[\Pst@GeneralHyperbolaLineInter{\Pst@GeneralHyperbolaLineInter[]}}
\def\Pst@GeneralHyperbolaLineInter[#1](#2)(#3){%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralHyperbolaLineInter@i{\Pst@GeneralHyperbolaLineInter@i[0]}}%
\def\Pst@GeneralHyperbolaLineInter@i[#1]#2#3#4#5{%
    \pst@getcoor{#2}\pst@tempA%
    \pst@getcoor{#3}\pst@tempB%
    \pnode(!%
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      \pst@tempA \tx@UserCoor % x1,y1
      \pst@tempB \tx@UserCoor % x2,y2
      3 index 2 index sub abs 1E-5 lt { % if the line AB is vertical
        #1 dup cos exch sin % cos\theta sin\theta
        7 index 2 index mul % e=a\cos\theta
        7 index 2 index mul % f=b\sin\theta
        9 index 3 index mul % g=a\sin\theta
        9 index 5 index mul % h=b\cos\theta
        7 index 14 index sub % n=x1-x0
        0 index dup mul 4 index dup mul add % n^2+f^2
        0 index abs 1E-5 lt {
          pop pop pop pop pop pop
          pop pop pop pop pop pop 0 0
        } {
          0 index 6 index dup mul sub dup 0 lt {
            pop pop pop pop pop pop pop
            pop pop pop pop pop pop 0 0
          } {
            sqrt % sqrt(n^2+f^2-e^2)
            %% \sin_{1,2}\alpha=\dfrac{ef\pm{}n\sqrt{n^2+f^2-e^2}}{n^2+f^2}
            2 index 1 index mul 7 index 7 index mul exch sub 2 index div % sin
            %% \cos_{1,2}\alpha=\dfrac{en\mp{}f\sqrt{n^2+f^2-e^2}}{n^2+f^2}
            6 index 2 index mul 8 index 5 index mul add 3 index div % cos
            dup abs 1E-5 lt {
              pop pop pop pop pop pop pop pop
              pop pop pop pop pop pop pop 0 0
            } {
              18 index 9 index 2 index div add 8 index 3 index mul 2 index div sub % x_1=x_0+e\sec\alpha-f\tan\alpha
              18 index 8 index 3 index div add 7 index 4 index mul 3 index div add % y_1=y_0+g\sec\alpha+h\tan\alpha
              21 2 roll pop pop pop pop pop pop pop pop
              pop pop pop pop pop pop pop pop pop pop pop
            } ifelse
          } ifelse
        } ifelse
      } {
        0 index 3 index sub 2 index 5 index sub div % k
        2 index 4 index mul 2 index 6 index mul sub 3 index 6 index sub div % d
        1 index 10 index mul 9 index sub 1 index add % m=kx_o-y_o+d
        #1 dup cos exch sin % cos\theta sin\theta
        10 index 2 index mul % e=a\cos\theta
        10 index 2 index mul % f=b\sin\theta
        12 index 3 index mul % g=a\sin\theta
        12 index 5 index mul % h=b\cos\theta
        0 index 9 index 4 index mul add % p=h+kf
        2 index 10 index 6 index mul sub % q=g-ke
        8 index dup mul 2 index dup mul add % m^2+p^2
        dup 1E-5 lt {
          pop pop pop pop pop pop pop pop pop pop
          pop pop pop pop pop pop pop pop pop pop
          0 0
        } {
          0 index 2 index dup mul sub dup 0 lt {
            pop pop pop pop pop pop pop pop pop pop
            pop pop pop pop pop pop pop pop pop pop
            pop 0 0
          } {
            sqrt % sqrt(m^2+p^2-q^2)
            % \sin_{1,2}\alpha=\dfrac{-qp\pm{}m\sqrt{m^2+p^2-q^2}}{m^2+p^2}
            10 index 1 index mul 4 index 4 index mul sub 2 index div % \sin\alpha
            % \cos_{1,2}\alpha=\dfrac{mq\pm{}p\sqrt{m^2+p^2-q^2}}{m^2+p^2}
            4 index 2 index mul 12 index 5 index mul add 3 index div % \cos\alpha
            dup abs 1E-5 lt {
              pop pop pop pop pop pop pop pop pop pop
              pop pop pop pop pop pop pop pop pop pop
              pop pop pop 0 0
            } {
              % x=x_0+e\sec\alpha-f\tan\alpha, y=y_0+g\sec\alpha+h\tan\alpha
              22 index 10 index 2 index div add 9 index 3 index mul 2 index div sub % x_1
              22 index 9 index 3 index div add 8 index 4 index mul 3 index div add % y_1
              25 2 roll
              pop pop pop pop pop pop pop pop pop pop
              pop pop pop pop pop pop pop pop pop pop
              pop pop pop
            } ifelse
          } ifelse
        } ifelse
      } ifelse
    ){#4}%
    \pnode(!%
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      \pst@tempA \tx@UserCoor % x1,y1
      \pst@tempB \tx@UserCoor % x2,y2
      3 index 2 index sub abs 1E-5 lt { % if the line AB is vertical
        #1 dup cos exch sin % cos\theta sin\theta
        7 index 2 index mul % e=a\cos\theta
        7 index 2 index mul % f=b\sin\theta
        9 index 3 index mul % g=a\sin\theta
        9 index 5 index mul % h=b\cos\theta
        7 index 14 index sub % n=x1-x0
        0 index dup mul 4 index dup mul add % n^2+f^2
        0 index abs 1E-5 lt {
          pop pop pop pop pop pop
          pop pop pop pop pop pop 0 0
        } {
          0 index 6 index dup mul sub dup 0 lt {
            pop pop pop pop pop pop pop
            pop pop pop pop pop pop 0 0
          } {
            sqrt % sqrt(n^2+f^2-e^2)
            %% \sin_{1,2}\alpha=\dfrac{ef\pm{}n\sqrt{n^2+f^2-e^2}}{n^2+f^2}
            2 index 1 index mul 7 index 7 index mul add 2 index div % sin
            %% \cos_{1,2}\alpha=\dfrac{en\mp{}f\sqrt{n^2+f^2-e^2}}{n^2+f^2}
            6 index 2 index mul 8 index 5 index mul exch sub 3 index div % cos
            dup abs 1E-5 lt {
              pop pop pop pop pop pop pop pop
              pop pop pop pop pop pop pop 0 0
            } {
              18 index 9 index 2 index div add 8 index 3 index mul 2 index div sub % x_2=x_0+e\sec\alpha-f\tan\alpha
              18 index 8 index 3 index div add 7 index 4 index mul 3 index div add % y_2=y_0+g\sec\alpha+h\tan\alpha
              21 2 roll pop pop pop pop pop pop pop pop
              pop pop pop pop pop pop pop pop pop pop pop
            } ifelse
          } ifelse
        } ifelse
      } {
        0 index 3 index sub 2 index 5 index sub div % k
        2 index 4 index mul 2 index 6 index mul sub 3 index 6 index sub div % d
        1 index 10 index mul 9 index sub 1 index add % m=kx_o-y_o+d
        #1 dup cos exch sin % cos\theta sin\theta
        10 index 2 index mul % e=a\cos\theta
        10 index 2 index mul % f=b\sin\theta
        12 index 3 index mul % g=a\sin\theta
        12 index 5 index mul % h=b\cos\theta
        0 index 9 index 4 index mul add % p=h+kf
        2 index 10 index 6 index mul sub % q=g-ke
        8 index dup mul 2 index dup mul add % m^2+p^2
        dup 1E-5 lt {
          pop pop pop pop pop pop pop pop pop pop
          pop pop pop pop pop pop pop pop pop pop
          0 0
        } {
          0 index 2 index dup mul sub dup 0 lt {
            pop pop pop pop pop pop pop pop pop pop
            pop pop pop pop pop pop pop pop pop pop
            pop 0 0
          } {
            sqrt % sqrt(m^2+p^2-q^2)
            % \sin_{1,2}\alpha=\dfrac{-qp\pm{}m\sqrt{m^2+p^2-q^2}}{m^2+p^2}
            10 index 1 index mul 4 index 4 index mul add neg 2 index div % \sin\alpha
            % \cos_{1,2}\alpha=\dfrac{mq\pm{}p\sqrt{m^2+p^2-q^2}}{m^2+p^2}
            4 index 2 index mul 12 index 5 index mul exch sub 3 index div % \cos\alpha
            dup abs 1E-5 lt {
              pop pop pop pop pop pop pop pop pop pop
              pop pop pop pop pop pop pop pop pop pop
              pop pop pop 0 0
            } {
              % x=x_0+e\sec\alpha-f\tan\alpha, y=y_0+g\sec\alpha+h\tan\alpha
              22 index 10 index 2 index div add 9 index 3 index mul 2 index div sub % x_1
              22 index 9 index 3 index div add 8 index 4 index mul 3 index div add % y_1
              25 2 roll
              pop pop pop pop pop pop pop pop pop pop
              pop pop pop pop pop pop pop pop pop pop
              pop pop pop
            } ifelse
          } ifelse
        } ifelse
      } ifelse
    ){#5}%
    \Pst@ManageParamList{#4}%
    \Pst@ManageParamList{#5}%
  \endgroup%
}%
%
%% \pstGeneralHyperbolaPolarNode[Options](O)(a,b)[rotation]{A}{B}{T}
%% Find the polar point of chord AB on General Hyperbola H.
%% We use the following proposition to find the polar point of chord AB:
%% Let $P$, $Q$ are vertex points of the hyperbola, for any chord $AB$ of hyperbola, $PA$ and $BQ$ intersect at $E$, $PB$ and $AQ$ intersect at $F$, then the middle point $M$ of $EF$ is the polar point of chord $AB$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the node A on the hyperbola.
%% #6 -> [input] the node B on the hyperbola.
%% #7 -> [output] the polar node T of chord AB.
\def\pstGeneralHyperbolaPolarNode{\@ifnextchar[\Pst@GeneralHyperbolaPolarNode{\Pst@GeneralHyperbolaPolarNode[]}}
\def\Pst@GeneralHyperbolaPolarNode[#1](#2)(#3){%
  \begingroup
    \psset{#1}%
    \def\pst@hyperbola@center{#2}
    \def\pst@hyperbola@radii{#3}
    \@ifnextchar[\Pst@GeneralHyperbolaPolarNode@i{\Pst@GeneralHyperbolaPolarNode@i[0]}}%
\def\Pst@GeneralHyperbolaPolarNode@i[#1]#2#3#4{%
    \pstGeneralHyperbolaVertexNode[PointName=none,PointSymbol=none](\pst@hyperbola@center)(\pst@hyperbola@radii)[#1]{@PST@GENERALHYPERBOLA@VERTEXA}{@PST@GENERALHYPERBOLA@VERTEXB}
    \pstInterLL[PointName=none,PointSymbol=none]{#2}{@PST@GENERALHYPERBOLA@VERTEXA}{#3}{@PST@GENERALHYPERBOLA@VERTEXB}{@PST@GENERALHYPERBOLA@INTER@X}
    \pstInterLL[PointName=none,PointSymbol=none]{#3}{@PST@GENERALHYPERBOLA@VERTEXA}{#2}{@PST@GENERALHYPERBOLA@VERTEXB}{@PST@GENERALHYPERBOLA@INTER@Y}
    \pstMiddleAB{@PST@GENERALHYPERBOLA@INTER@X}{@PST@GENERALHYPERBOLA@INTER@Y}{#4}
    \Pst@geonodelabel{#4}%
    \pstLineAB{#2}{#4}
    \pstLineAB{#3}{#4}
    \endgroup
}%
%
%% \pstGeneralHyperbolaTangentNode[Options](O)(a,b)[rotation]{T}{A}{B}
%% Draw the two tangent lines through the point $T$ to the General Hyperbola H and get the node A and B on the General Hyperbola.
%% We use the following proposition to find the tangent points $A$ and $B$ of $T$:
%% Let $T$ is a point out of the hyperbola, we give any two chords $TPQ$ and $TRS$ of the hyperbola, $PR$ and $QS$ intersect at $X$, $RQ$ and $PS$ intersect at $Y$,
%% then the intersection point $A$ and $B$ of $XY$ and the hyperbola are the tangent points from $T$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the given node T outside the hyperbola
%% #6 -> [output] the tangent node name A on the hyperbola
%% #7 -> [output] the tangent node name B on the hyperbola
\def\pstGeneralHyperbolaTangentNode{\@ifnextchar[\Pst@GeneralHyperbolaTangentNode{\Pst@GeneralHyperbolaTangentNode[]}}
\def\Pst@GeneralHyperbolaTangentNode[#1](#2)(#3){%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \def\pst@hyperbola@center{#2}
    \def\pst@hyperbola@radii{#3}
    \@ifnextchar[\Pst@GeneralHyperbolaTangentNode@i{\Pst@GeneralHyperbolaTangentNode@i[0]}}%
\def\Pst@GeneralHyperbolaTangentNode@i[#1]#2#3#4{%
    \pstGeneralHyperbolaNode[PointName=none,PointSymbol=none](\pst@hyperbola@center)(\pst@hyperbola@radii)[#1]{10}{@PST@GENERALHYPERBOLA@TANGENTAUX@P0}
    \pstGeneralHyperbolaNode[PointName=none,PointSymbol=none](\pst@hyperbola@center)(\pst@hyperbola@radii)[#1]{-10}{@PST@GENERALHYPERBOLA@TANGENTAUX@R0}
    \pstGeneralHyperbolaLineInter[PointName=none,PointSymbol=none](\pst@hyperbola@center)(\pst@hyperbola@radii)[#1]{#2}{@PST@GENERALHYPERBOLA@TANGENTAUX@P0}{@PST@GENERALHYPERBOLA@TANGENTAUX@P}{@PST@GENERALHYPERBOLA@TANGENTAUX@Q}
    \pstGeneralHyperbolaLineInter[PointName=none,PointSymbol=none](\pst@hyperbola@center)(\pst@hyperbola@radii)[#1]{#2}{@PST@GENERALHYPERBOLA@TANGENTAUX@R0}{@PST@GENERALHYPERBOLA@TANGENTAUX@R}{@PST@GENERALHYPERBOLA@TANGENTAUX@S}
    \pstInterLL[PointName=none,PointSymbol=none]{@PST@GENERALHYPERBOLA@TANGENTAUX@P}{@PST@GENERALHYPERBOLA@TANGENTAUX@S}{@PST@GENERALHYPERBOLA@TANGENTAUX@Q}{@PST@GENERALHYPERBOLA@TANGENTAUX@R}{@PST@GENERALHYPERBOLA@TANGENTAUX@I}
    \pstInterLL[PointName=none,PointSymbol=none]{@PST@GENERALHYPERBOLA@TANGENTAUX@P}{@PST@GENERALHYPERBOLA@TANGENTAUX@R}{@PST@GENERALHYPERBOLA@TANGENTAUX@Q}{@PST@GENERALHYPERBOLA@TANGENTAUX@S}{@PST@GENERALHYPERBOLA@TANGENTAUX@X}
    \pstGeneralHyperbolaLineInter(\pst@hyperbola@center)(\pst@hyperbola@radii)[#1]{@PST@GENERALHYPERBOLA@TANGENTAUX@X}{@PST@GENERALHYPERBOLA@TANGENTAUX@I}{#3}{#4}
    \Pst@ManageParamList{#3}%
    \Pst@ManageParamList{#4}%
    \pstLineAB{#2}{#3}
    \pstLineAB{#2}{#4}
  \endgroup%
}%
%
% 10. General Conjugate Hyperbola with coordinate translation and rotation
%% ----------------------------------------------------------
%% The General Conjugate Hyperbola H is defined by center O, the half of the real axis $a$, the half of the imaginary axis $b$,
%% and the rotation angle $\theta$ of the principal axis.
%% The equation can be got from the parametric function of the Standard Conjugate Hyperbola \ref{ParametricFunctionOfStandardConjugateHyperbola},
%% using the rotation transform formula \ref{RotationTransformFormula}, then we have
%% \begin{equation}
%% \left\{\begin{array}{l}
%% x'=(b\tan\alpha+x_o)\cos\theta-(a\sec\alpha+y_o)\sin\theta=x_o'+b\tan\alpha\cos\theta-a\sec\alpha\sin\theta\\
%% y'=(b\tan\alpha+x_o)\sin\theta+(a\sec\alpha+y_o)\cos\theta=y_o'+b\tan\alpha\sin\theta+a\sec\alpha\cos\theta
%% \end{array}\right.
%% \end{equation}
%% where the $x_o'$ and $y_o'$ are the coordinate of the given center O after rotation.
%% So we get the parametric function of the General Conjugate Hyperbola with coordinate translation and rotation as following:
%% \begin{equation}\label{ParametricFunctionOfGeneralConjugateHyperbola}
%% \left\{\begin{array}{l}
%% x=x_o+b\tan\alpha\cos\theta-a\sec\alpha\sin\theta\\
%% y=y_o+b\tan\alpha\sin\theta+a\sec\alpha\cos\theta
%% \end{array}\right.
%% \end{equation}
%
%% \pstGeneralIHyperbola[Options](O)(a,b)[rotation][maxAngleX]
%% Draw a General Conjugate Hyperbola with center O, the half of the real axis $abs(a)$, the half of the imaginary axis $abs(b)$,
%% and the rotation angle $\theta$ of the symmetrical axis.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the maximal angle to draw the branch.
\def\pstGeneralIHyperbola{\@ifnextchar[\Pst@GeneralIHyperbola{\Pst@GeneralIHyperbola[]}}
\def\Pst@GeneralIHyperbola[#1](#2)(#3){%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralIHyperbola@i{\Pst@GeneralIHyperbola@i[0]}}%
\def\Pst@GeneralIHyperbola@i[#1]{%
    \def\pst@hyperbola@rotation{#1}%
    \@ifnextchar[\Pst@GeneralIHyperbola@j{\Pst@GeneralIHyperbola@j[85]}}%
\def\Pst@GeneralIHyperbola@j[#1]{%
    \pst@cnth=#1\pst@cntg=180\pst@cntm=180\pst@cntn=360
    \ifnum\pst@cnth<0
        \loop\advance\pst@cnth by 90
            \ifnum\pst@cnth<0
        \repeat
    \fi
    \ifnum\pst@cnth>90
        \loop\advance\pst@cnth by -90
            \ifnum\pst@cnth>90
        \repeat
    \fi
    \ifnum\pst@cnth>85
        \advance\pst@cnth by -5
    \fi
    \advance\pst@cntg by -\pst@cnth
    \advance\pst@cntm by \pst@cnth
    \advance\pst@cntn by -\pst@cnth
    \Pst@GeneralIHyperbola@k[0][\number\pst@cnth]%
    \Pst@GeneralIHyperbola@k[\number\pst@cntg][180]%
    \Pst@GeneralIHyperbola@k[180][\number\pst@cntm]%
    \Pst@GeneralIHyperbola@k[\number\pst@cntn][360]%
  \endgroup%
}%
\def\Pst@GeneralIHyperbola@k[#1][#2]{%
    \parametricplot{#1}{#2}{%
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      t dup cos exch sin % cos{t} sin{t}
      1 index abs 1E-5 lt {
        pop pop pop pop
      } {
        \pst@hyperbola@rotation\space dup cos exch sin % cos\theta sin\theta
        %% x=x_o+b\tan\alpha\cos\theta-a\sec\alpha\sin\theta
        7 index 5 index 5 index div 4 index mul 3 index mul add
        6 index 5 index div 2 index mul sub
        %% y=y_o+b\tan\alpha\sin\theta+a\sec\alpha\cos\theta
        7 index 6 index 5 index mul 6 index div 3 index mul add
        7 index 6 index div 4 index mul add
        10 2 roll pop pop pop pop pop pop pop pop
      } ifelse
    }%
}%
%
%% \pstGeneralIHyperbolaNode[Options](O)(a,b)[rotation]{t}{A}
%% Draw a node whose parameter value is the given value t on the General Conjugate Hyperbola.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the parameter value t.
%% #6 -> [output] the target node name.
\def\pstGeneralIHyperbolaNode{\@ifnextchar[\Pst@GeneralIHyperbolaNode{\Pst@GeneralIHyperbolaNode[]}}
\def\Pst@GeneralIHyperbolaNode[#1](#2)(#3){%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralIHyperbolaNode@i{\Pst@GeneralIHyperbolaNode@i[0]}}%
\def\Pst@GeneralIHyperbolaNode@i[#1]#2#3{%
    \pnode(!%
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #2 dup cos exch sin % cos{t} sin{t}
      1 index abs 1E-5 lt {
        pop pop pop pop
      } {
        #1 dup cos exch sin % cos\theta sin\theta
        %% x=x_o+b\tan\alpha\cos\theta-a\sec\alpha\sin\theta
        7 index 5 index 5 index div 4 index mul 3 index mul add
        6 index 5 index div 2 index mul sub
        %% y=y_o+b\tan\alpha\sin\theta+a\sec\alpha\cos\theta
        7 index 6 index 5 index mul 6 index div 3 index mul add
        7 index 6 index div 4 index mul add
        10 2 roll pop pop pop pop pop pop pop pop
      } ifelse
    ){#3}%
    \Pst@geonodelabel{#3}%
  \endgroup%
}%
%
%% \pstGeneralIHyperbolaAbsNode[Options](O)(a,b)[rotation]{x_1}{A}{B}
%% Draw the nodes whose abscissa value are the given value x_1 on the General Conjugate Hyperbola.
%%
%% set $e=a\cos\theta$, $f=b\sin\theta$, $g=a\sin\theta$, $h=b\cos\theta$, then we have
%% $$x=x_0+h\tan\alpha-g\sec\alpha, y=y_0+f\tan\alpha+e\sec\alpha$$
%% when $x=x_1$, we get
%% $$h\tan\alpha-g\sec\alpha=x_1-x_0$$
%% set $n=x_1-x_0$, we have
%% $$h\sin\alpha-n\cos\alpha=g$$
%% then
%% $$(n^2+h^2)\cos^2\alpha+2ng\cos\alpha+g^2-h^2=0$$
%% if $n^2+h^2=0$, we have $n=h=0$, i.e, $x_1=x_0$ and $\cos\theta=0$, but the last equation gives $g=0$, which is not possible.
%% so $n^2+h^2\neq0$, we get
%% $$\cos_{1,2}\alpha=\dfrac{-ng\pm{}h\sqrt{n^2+h^2-g^2}}{n^2+h^2}$$
%% and
%% $$\sin_{1,2}\alpha=\dfrac{gh\pm{}n\sqrt{n^2+h^2-g^2}}{n^2+h^2}$$
%% where $\cos\alpha$ can not be zero, but when $h=\pm{}g$, we have $\cos\alpha=0$, we should skip it.
%%
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the abscissa value x_1.
%% #6 -> [output] the first target node name.
%% #7 -> [output] the second target node name.
\def\pstGeneralIHyperbolaAbsNode{\@ifnextchar[\Pst@GeneralIHyperbolaAbsNode{\Pst@GeneralIHyperbolaAbsNode[]}}
\def\Pst@GeneralIHyperbolaAbsNode[#1](#2)(#3){%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralIHyperbolaAbsNode@i{\Pst@GeneralIHyperbolaAbsNode@i[0]}}%
\def\Pst@GeneralIHyperbolaAbsNode@i[#1]#2#3#4{%
    \pnode(!%
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #1 dup cos exch sin % cos\theta sin\theta
      3 index 2 index mul % e=a\cos\theta
      3 index 2 index mul % f=b\sin\theta
      5 index 3 index mul % g=a\sin\theta
      5 index 5 index mul % h=b\cos\theta
      #2 10 index sub % n=x1-x0
      0 index dup mul 2 index dup mul add % n^2+h^2
      0 index abs 1E-5 lt {
        pop pop pop pop pop pop
        pop pop pop pop pop pop 0 0
      } {
        0 index 4 index dup mul sub dup 0 lt {
          pop pop pop pop pop pop pop
          pop pop pop pop pop pop 0 0
        } {
          sqrt % sqrt(n^2+h^2-g^2)
          %% \sin_{1,2}\alpha=\dfrac{gh\pm{}n\sqrt{n^2+h^2-g^2}}{n^2+h^2}
          2 index 1 index mul 5 index 5 index mul exch sub 2 index div % sin
          %% \cos_{1,2}\alpha=\dfrac{-ng\pm{}h\sqrt{n^2+h^2-g^2}}{n^2+h^2}
          4 index 2 index mul 4 index 7 index mul add neg 3 index div % cos
          dup abs 1E-5 lt {
            pop pop pop pop pop pop pop pop
            pop pop pop pop pop pop pop 0 0
          } {
            14 index 6 index 3 index mul 2 index div add 7 index 2 index div sub % x_1=x_0+h\tan\alpha-g\sec\alpha
            14 index 9 index 4 index mul 3 index div add 10 index 3 index div add % y_1=y_0+f\tan\alpha+e\sec\alpha
            17 2 roll pop pop pop pop pop pop pop pop
            pop pop pop pop pop pop pop
          } ifelse
        } ifelse
      } ifelse
    ){#3}%
    \pnode(!%
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #1 dup cos exch sin % cos\theta sin\theta
      3 index 2 index mul % e=a\cos\theta
      3 index 2 index mul % f=b\sin\theta
      5 index 3 index mul % g=a\sin\theta
      5 index 5 index mul % h=b\cos\theta
      #2 10 index sub % n=x1-x0
      0 index dup mul 2 index dup mul add % n^2+h^2
      0 index abs 1E-5 lt {
        pop pop pop pop pop pop
        pop pop pop pop pop pop 0 0
      } {
        0 index 4 index dup mul sub dup 0 lt {
          pop pop pop pop pop pop pop
          pop pop pop pop pop pop 0 0
        } {
          sqrt % sqrt(n^2+h^2-g^2)
          %% \sin_{1,2}\alpha=\dfrac{gh\pm{}n\sqrt{n^2+h^2-g^2}}{n^2+h^2}
          2 index 1 index mul 5 index 5 index mul add 2 index div % sin
          %% \cos_{1,2}\alpha=\dfrac{-ng\pm{}h\sqrt{n^2+h^2-g^2}}{n^2+h^2}
          4 index 2 index mul 4 index 7 index mul sub 3 index div % cos
          dup abs 1E-5 lt {
            pop pop pop pop pop pop pop pop
            pop pop pop pop pop pop pop 0 0
          } {
            14 index 6 index 3 index mul 2 index div add 7 index 2 index div sub % x_2=x_0+h\tan\alpha-g\sec\alpha
            14 index 9 index 4 index mul 3 index div add 10 index 3 index div add % y_2=y_0+f\tan\alpha+e\sec\alpha
            17 2 roll pop pop pop pop pop pop pop pop
            pop pop pop pop pop pop pop
          } ifelse
        } ifelse
      } ifelse
    ){#4}%
    \Pst@ManageParamList{#3}%
    \Pst@ManageParamList{#4}%
  \endgroup%
}%
%
%% \pstGeneralIHyperbolaOrdNode[Options](O)(a,b)[rotation]{y_1}{A}{B}
%% Draw the nodes whose ordinate value are the given value y_1 on the General Conjugate Hyperbola.
%%
%% set $e=a\cos\theta$, $f=b\sin\theta$, $g=a\sin\theta$, $h=b\cos\theta$, then we have
%% $$x=x_0+h\tan\alpha-g\sec\alpha, y=y_0+f\tan\alpha+e\sec\alpha$$
%% when $y=y_1$, we get
%% $$f\tan\alpha+e\sec\alpha=y_1-y_0$$
%% set $m=y_1-y_0$, we have
%% $$m\cos\alpha-f\sin\alpha=e$$
%% then
%% $$(m^2+f^2)\sin^2\alpha+2fe\sin\alpha+e^2-m^2=0$$
%% if $m^2+f^2=0$, we have $m=f=0$, i.e, $y_1=y_0$ and $\sin\theta=0$, but the last equation gives $e=0$, which is not possible.
%% so $m^2+f^2\neq0$, we get
%% $$\sin_{1,2}\alpha=\dfrac{-fe\pm{}m\sqrt{m^2+f^2-e^2}}{m^2+f^2}$$
%% and
%% $$\cos_{1,2}\alpha=\dfrac{em\pm{}f\sqrt{m^2+f^2-e^2}}{m^2+f^2}$$
%% where $\cos\alpha$ can not be zero, but when $f=\pm{}e$, we have $\cos\alpha=0$, we should skip it.
%%
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the ordinate value y_1.
%% #6 -> [output] the first target node name.
%% #7 -> [output] the second target node name.
\def\pstGeneralIHyperbolaOrdNode{\@ifnextchar[\Pst@GeneralIHyperbolaOrdNode{\Pst@GeneralIHyperbolaOrdNode[]}}
\def\Pst@GeneralIHyperbolaOrdNode[#1](#2)(#3){%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralIHyperbolaOrdNode@i{\Pst@GeneralIHyperbolaOrdNode@i[0]}}%
\def\Pst@GeneralIHyperbolaOrdNode@i[#1]#2#3#4{%
    \pnode(!%
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #1 dup cos exch sin % cos\theta sin\theta
      3 index 2 index mul % e=a\cos\theta
      3 index 2 index mul % f=b\sin\theta
      5 index 3 index mul % g=a\sin\theta
      5 index 5 index mul % h=b\cos\theta
      #2 9 index sub % m=y1-y0
      0 index dup mul 4 index dup mul add % m^2+f^2
      0 index abs 1E-5 lt {
        pop pop pop pop pop pop
        pop pop pop pop pop pop 0 0
      } {
        0 index 6 index dup mul sub dup 0 lt {
          pop pop pop pop pop pop pop
          pop pop pop pop pop pop 0 0
        } {
          sqrt % sqrt(m^2+f^2-e^2)
          %% \sin_{1,2}\alpha=\dfrac{-fe\pm{}m\sqrt{m^2+f^2-e^2}}{m^2+f^2}
          2 index 1 index mul 7 index 7 index mul add neg 2 index div % sin
          %% \cos_{1,2}\alpha=\dfrac{em\pm{}f\sqrt{m^2+f^2-e^2}}{m^2+f^2}
          6 index 2 index mul 8 index 5 index mul exch sub 3 index div % cos
          dup abs 1E-5 lt {
            pop pop pop pop pop pop pop pop
            pop pop pop pop pop pop pop 0 0
          } {
            14 index 6 index 3 index mul 2 index div add 7 index 2 index div sub % x_1=x_0+h\tan\alpha-g\sec\alpha
            14 index 9 index 4 index mul 3 index div add 10 index 3 index div add % y_1=y_0+f\tan\alpha+e\sec\alpha
            17 2 roll pop pop pop pop pop pop pop pop
            pop pop pop pop pop pop pop
          } ifelse
        } ifelse
      } ifelse
    ){#3}%
    \pnode(!%
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #1 dup cos exch sin % cos\theta sin\theta
      3 index 2 index mul % e=a\cos\theta
      3 index 2 index mul % f=b\sin\theta
      5 index 3 index mul % g=a\sin\theta
      5 index 5 index mul % h=b\cos\theta
      #2 9 index sub % m=y1-y0
      0 index dup mul 4 index dup mul add % m^2+f^2
      0 index abs 1E-5 lt {
        pop pop pop pop pop pop
        pop pop pop pop pop pop 0 0
      } {
        0 index 6 index dup mul sub dup 0 lt {
          pop pop pop pop pop pop pop
          pop pop pop pop pop pop 0 0
        } {
          sqrt % sqrt(m^2+f^2-e^2)
          %% \sin_{1,2}\alpha=\dfrac{-fe\pm{}m\sqrt{m^2+f^2-e^2}}{m^2+f^2}
          2 index 1 index mul 7 index 7 index mul sub 2 index div % sin
          %% \cos_{1,2}\alpha=\dfrac{em\pm{}f\sqrt{m^2+f^2-e^2}}{m^2+f^2}
          6 index 2 index mul 8 index 5 index mul add 3 index div % cos
          dup abs 1E-5 lt {
            pop pop pop pop pop pop pop pop
            pop pop pop pop pop pop pop 0 0
          } {
            14 index 6 index 3 index mul 2 index div add 7 index 2 index div sub % x_2=x_0+h\tan\alpha-g\sec\alpha
            14 index 9 index 4 index mul 3 index div add 10 index 3 index div add % y_2=y_0+f\tan\alpha+e\sec\alpha
            17 2 roll pop pop pop pop pop pop pop pop
            pop pop pop pop pop pop pop
          } ifelse
        } ifelse
      } ifelse
    ){#4}%
    \Pst@ManageParamList{#3}%
    \Pst@ManageParamList{#4}%
  \endgroup%
}%
%
%% \pstGeneralIHyperbolaFocusNode[Options](O)(a,b)[rotation]{F1}{F2}
%% Draw the focus nodes of the General Conjugate Hyperbola H.
%% If you not input the rotation angle, the default value is $0^\circ$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [output] the focus node F1 of the Hyperbola.
%% #6 -> [output] the focus node F2 of the Hyperbola.
\def\pstGeneralIHyperbolaFocusNode{\@ifnextchar[\Pst@GeneralIHyperbolaFocusNode{\Pst@GeneralIHyperbolaFocusNode[]}}
\def\Pst@GeneralIHyperbolaFocusNode[#1](#2)(#3){%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralIHyperbolaFocusNode@i{\Pst@GeneralIHyperbolaFocusNode@i[0]}}%
\def\Pst@GeneralIHyperbolaFocusNode@i[#1]#2#3{%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #1 dup cos exch sin % cos\theta sin\theta
      3 index dup mul 3 index dup mul add sqrt % c=sqrt(a^2+b^2)
      6 index 1 index 3 index mul sub % x=x0-c\sin\theta
      6 index 2 index 5 index mul add % y=y0+c\cos\theta
      9 2 roll pop pop pop pop pop pop pop
    ){#2}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #1 dup cos exch sin % cos\theta sin\theta
      3 index dup mul 3 index dup mul add sqrt % c=sqrt(a^2+b^2)
      6 index 1 index 3 index mul add % x=x0+c\sin\theta
      6 index 2 index 5 index mul sub % y=y0-c\cos\theta
      9 2 roll pop pop pop pop pop pop pop
    ){#3}
    \Pst@ManageParamList{#2}%
    \Pst@ManageParamList{#3}%
  \endgroup%
}%
%
%% \pstGeneralIHyperbolaVertexNode[Options](O)(a,b)[rotation]{V1}{V2}
%% Draw the vertex nodes of the General Conjugate Hyperbola H.
%% If you not input the rotation angle, the default value is $0^\circ$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [output] the vertex node V1 of the Hyperbola.
%% #6 -> [output] the vertex node V2 of the Hyperbola.
\def\pstGeneralIHyperbolaVertexNode{\@ifnextchar[\Pst@GeneralIHyperbolaVertexNode{\Pst@GeneralIHyperbolaVertexNode[]}}
\def\Pst@GeneralIHyperbolaVertexNode[#1](#2)(#3){%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralIHyperbolaVertexNode@i{\Pst@GeneralIHyperbolaVertexNode@i[0]}}%
\def\Pst@GeneralIHyperbolaVertexNode@i[#1]#2#3{%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #1 dup cos exch sin % cos\theta sin\theta
      5 index 4 index 2 index mul sub % x=x0-a\sin\theta
      5 index 5 index 4 index mul add % y=y0+a\cos\theta
      8 2 roll pop pop pop pop pop pop
    ){#2}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      #1 dup cos exch sin % cos\theta sin\theta
      5 index 4 index 2 index mul add % x=x0+a\sin\theta
      5 index 5 index 4 index mul sub % y=y0-a\cos\theta
      8 2 roll pop pop pop pop pop pop
    ){#3}
    \Pst@ManageParamList{#2}%
    \Pst@ManageParamList{#3}%
  \endgroup%
}%
%
%% \pstGeneralIHyperbolaDirectrixLine[Options](O)(a,b)[rotation]{Lx}{Ly}{Rx}{Ry}
%% Draw the two directrix lines of the General Conjugate Hyperbola H.
%% If you not input the rotation angle, the default value is $0^\circ$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [output] the first node Lx on the first directrix line.
%% #6 -> [output] the second node Lx on the first directrix line.
%% #7 -> [output] the first node Lx on the second directrix line.
%% #8 -> [output] the second node Lx on the second directrix line.
\def\pstGeneralIHyperbolaDirectrixLine{\@ifnextchar[\Pst@GeneralIHyperbolaDirectrixLine{\Pst@GeneralIHyperbolaDirectrixLine[]}}
\def\Pst@GeneralIHyperbolaDirectrixLine[#1](#2)(#3){%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralIHyperbolaDirectrixLine@i{\Pst@GeneralIHyperbolaDirectrixLine@i[0]}}%
\def\Pst@GeneralIHyperbolaDirectrixLine@i[#1]#2#3#4#5{%
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      1 index dup mul 1 index dup mul add sqrt % c=sqrt(a^2+b^2)
      2 index dup mul 1 index div 4 index exch sub 5 index exch % x0,y0-a^2/c
      7 2 roll pop pop pop % x,y,x0,y0
      #1 dup cos exch sin % cos\theta sin\theta
      3 index 6 index 5 index sub 3 index mul add 5 index 4 index sub 2 index mul sub % x0+(x-x0)\cos\theta-(y-y0)\sin\theta
      3 index 7 index 6 index sub 3 index mul add 6 index 5 index sub 4 index mul add % y0+(x-x0)\sin\theta+(y-y0)\cos\theta
      8 2 roll pop pop pop pop pop pop
    ){#2}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      1 index dup mul 1 index dup mul add sqrt % c=sqrt(a^2+b^2)
      2 index dup mul 1 index div 4 index exch sub 5 index 1 add exch % x0+1,y0-a^2/c
      7 2 roll pop pop pop % x,y,x0,y0
      #1 dup cos exch sin % cos\theta sin\theta
      3 index 6 index 5 index sub 3 index mul add 5 index 4 index sub 2 index mul sub % x0+(x-x0)\cos\theta-(y-y0)\sin\theta
      3 index 7 index 6 index sub 3 index mul add 6 index 5 index sub 4 index mul add % y0+(x-x0)\sin\theta+(y-y0)\cos\theta
      8 2 roll pop pop pop pop pop pop
    ){#3}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      1 index dup mul 1 index dup mul add sqrt % c=sqrt(a^2+b^2)
      2 index dup mul 1 index div 4 index add 5 index exch % x0,y0+a^2/c
      7 2 roll pop pop pop % x,y,x0,y0
      #1 dup cos exch sin % cos\theta sin\theta
      3 index 6 index 5 index sub 3 index mul add 5 index 4 index sub 2 index mul sub % x0+(x-x0)\cos\theta-(y-y0)\sin\theta
      3 index 7 index 6 index sub 3 index mul add 6 index 5 index sub 4 index mul add % y0+(x-x0)\sin\theta+(y-y0)\cos\theta
      8 2 roll pop pop pop pop pop pop
    ){#4}
    \pnode(!
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      1 index dup mul 1 index dup mul add sqrt % c=sqrt(a^2+b^2)
      2 index dup mul 1 index div 4 index add 5 index 1 add exch % x0+1,y0+a^2/c
      7 2 roll pop pop pop % x,y,x0,y0
      #1 dup cos exch sin % cos\theta sin\theta
      3 index 6 index 5 index sub 3 index mul add 5 index 4 index sub 2 index mul sub % x0+(x-x0)\cos\theta-(y-y0)\sin\theta
      3 index 7 index 6 index sub 3 index mul add 6 index 5 index sub 4 index mul add % y0+(x-x0)\sin\theta+(y-y0)\cos\theta
      8 2 roll pop pop pop pop pop pop
    ){#5}
    \Pst@ManageParamList{#2}%
    \Pst@ManageParamList{#3}%
    \Pst@ManageParamList{#4}%
    \Pst@ManageParamList{#5}%
    \pstLineAB{#2}{#3}%
    \pstLineAB{#4}{#5}%
  \endgroup%
}%
%
%% \pstGeneralIHyperbolaAsymptoteLine[Options](O)(a,b)[rotation]{L1}{L2}
%% Draw the two asymptote lines L1 and L2 of the General Conjugate Hyperbola H.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [output] the second node name on the first asymptote line, the first node is the center O.
%% #6 -> [output] the second node name on the second asymptote line, the first node is the center O.
\def\pstGeneralIHyperbolaAsymptoteLine{\@ifnextchar[\Pst@GeneralIHyperbolaAsymptoteLine{\Pst@GeneralIHyperbolaAsymptoteLine[]}}
\def\Pst@GeneralIHyperbolaAsymptoteLine[#1](#2)(#3){%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \def\pst@hyperbola@center{#2}
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralIHyperbolaAsymptoteLine@i{\Pst@GeneralIHyperbolaAsymptoteLine@i[0]}}%
\def\Pst@GeneralIHyperbolaAsymptoteLine@i[#1]#2#3{%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      0 index 2 index div % b/a
      4 index 1 index sub % x=x0-b/a
      4 index 1 add % y=y0+1
      7 2 roll pop pop pop % x y x_0 y_0
      #1 dup cos exch sin % cos\theta sin\theta
      3 index 6 index 5 index sub 3 index mul add 5 index 4 index sub 2 index mul sub % x0+(x-x0)\cos\theta-(y-y0)\sin\theta
      3 index 7 index 6 index sub 3 index mul add 6 index 5 index sub 4 index mul add % y0+(x-x0)\sin\theta+(y-y0)\cos\theta
      8 2 roll pop pop pop pop pop pop
    ){#2}%
    \pnode(!
      \pst@tempO \tx@UserCoor % x_o,y_o
      \pst@tempR \tx@UserCoor % a,b
      0 index 2 index div % b/a
      4 index 1 index add % x=x0+b/a
      4 index 1 add % y=y0+1
      7 2 roll pop pop pop % x y x_0 y_0
      #1 dup cos exch sin % cos\theta sin\theta
      3 index 6 index 5 index sub 3 index mul add 5 index 4 index sub 2 index mul sub % x0+(x-x0)\cos\theta-(y-y0)\sin\theta
      3 index 7 index 6 index sub 3 index mul add 6 index 5 index sub 4 index mul add % y0+(x-x0)\sin\theta+(y-y0)\cos\theta
      8 2 roll pop pop pop pop pop pop
    ){#3}%
    \Pst@ManageParamList{#2}%
    \Pst@ManageParamList{#3}%
    \pstLineAB{\pst@hyperbola@center}{#2}%
    \pstLineAB{\pst@hyperbola@center}{#3}%
  \endgroup%
}%
%
%
%% \pstGeneralIHyperbolaLineInter[Options](O)(a,b)[rotation]{A}{B}{C}{D}
%% Find the intersection nodes $C$ and $D$ of the given line AB with the General Conjugate Hyperbola H.
%%
%% set $e=a\cos\theta$, $f=b\sin\theta$, $g=a\sin\theta$, $h=b\cos\theta$, then we have
%% $$x=x_0+h\tan\alpha-g\sec\alpha, y=y_0+f\tan\alpha+e\sec\alpha$$
%% when line AB is vertical, the solve is like as pstGeneralIHyperbolaAbsNode,
%% else we can represent the line AB as the following function:
%% $$y=kx+d$$ where $$k=\dfrac{y_2-y_1}{x_2-x_1}, d=\dfrac{x_2y_1-x_1y_2}{x_2-x_1}$$
%% Let $X=x-x_0$, $Y=y-y_0$, then we have $Y=kX+m$, where $m=kx_0-y_0+d$, then
%% $$f\tan\alpha+e\sec\alpha=k(h\tan\alpha-g\sec\alpha)+m$$
%% $$(kh-f)\sin\alpha+m\cos\alpha=kg+e$$
%% $$(kh-f)^2\sin^2\alpha=m^2\cos^2\alpha-2m(kg+e)\cos\alpha+(kg+e)^2$$
%% $$(m^2+(kh-f)^2)\cos^2\alpha-2m(kg+e)\cos\alpha+(kg+e)^2-(kh-f)^2=0$$
%% when $m^2+(kh-f)^2=0$, we have $m=kh-f=0$, at this time $kg+e=0$, we get
%% $$k=\dfrac{\sin\theta}{\cos\theta}=-\dfrac{\cos\theta}{\sin\theta}$$
%% which is not possible.
%%
%% let $p=kh-f$, $q=kg+e$, so we have
%% $$(m^2+p^2)\cos^2\alpha-2mq\cos\alpha+q^2-p^2=0$$
%% then
%% $$\cos_{1,2}\alpha=\dfrac{mq\pm{}p\sqrt{m^2+p^2-q^2}}{m^2+p^2},\sin_{1,2}\alpha=\dfrac{qp\mp{}m\sqrt{m^2+p^2-q^2}}{m^2+p^2}$$
%% where $\cos\alpha$ can not be zero, we should skip it.
%%
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the first node on the given line.
%% #6 -> [input] the second node on the given line.
%% #7 -> [output] the first intersection node name.
%% #8 -> [output] the second intersection node name.
\def\pstGeneralIHyperbolaLineInter{\@ifnextchar[\Pst@GeneralIHyperbolaLineInter{\Pst@GeneralIHyperbolaLineInter[]}}
\def\Pst@GeneralIHyperbolaLineInter[#1](#2)(#3){%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \@ifnextchar[\Pst@GeneralIHyperbolaLineInter@i{\Pst@GeneralIHyperbolaLineInter@i[0]}}%
\def\Pst@GeneralIHyperbolaLineInter@i[#1]#2#3#4#5{%
    \pst@getcoor{#2}\pst@tempA%
    \pst@getcoor{#3}\pst@tempB%
    \pnode(!%
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      \pst@tempA \tx@UserCoor % x1,y1
      \pst@tempB \tx@UserCoor % x2,y2
      3 index 2 index sub abs 1E-5 lt { % if the line AB is vertical
        #1 dup cos exch sin % cos\theta sin\theta
        7 index 2 index mul % e=a\cos\theta
        7 index 2 index mul % f=b\sin\theta
        9 index 3 index mul % g=a\sin\theta
        9 index 5 index mul % h=b\cos\theta
        7 index 14 index sub % n=x1-x0
        0 index dup mul 2 index dup mul add % n^2+h^2
        0 index abs 1E-5 lt {
          pop pop pop pop pop pop
          pop pop pop pop pop pop 0 0
        } {
          0 index 4 index dup mul sub dup 0 lt {
            pop pop pop pop pop pop pop
            pop pop pop pop pop pop 0 0
          } {
            sqrt % sqrt(n^2+h^2-g^2)
            %% \sin_{1,2}\alpha=\dfrac{gh\pm{}n\sqrt{n^2+h^2-g^2}}{n^2+h^2}
            2 index 1 index mul 5 index 5 index mul exch sub 2 index div % sin
            %% \cos_{1,2}\alpha=\dfrac{-ng\pm{}h\sqrt{n^2+h^2-g^2}}{n^2+h^2}
            4 index 2 index mul 4 index 7 index mul add neg 3 index div % cos
            dup abs 1E-5 lt {
              pop pop pop pop pop pop pop pop
              pop pop pop pop pop pop pop 0 0
            } {
              18 index 6 index 3 index mul 2 index div add 7 index 2 index div sub % x_1=x_0+h\tan\alpha-g\sec\alpha
              18 index 9 index 4 index mul 3 index div add 10 index 3 index div add % y_1=y_0+f\tan\alpha+e\sec\alpha
              21 2 roll pop pop pop pop pop pop pop pop
              pop pop pop pop pop pop pop pop pop pop pop
            } ifelse
          } ifelse
        } ifelse
      } {
        0 index 3 index sub 2 index 5 index sub div % k
        2 index 4 index mul 2 index 6 index mul sub 3 index 6 index sub div % d
        1 index 10 index mul 9 index sub 1 index add % m=kx_o-y_o+d
        #1 dup cos exch sin % cos\theta sin\theta
        10 index 2 index mul % e=a\cos\theta
        10 index 2 index mul % f=b\sin\theta
        12 index 3 index mul % g=a\sin\theta
        12 index 5 index mul % h=b\cos\theta
        8 index 1 index mul 3 index sub % p=kh-f
        9 index 3 index mul 5 index add % q=kg+e
        8 index dup mul 2 index dup mul add % m^2+p^2
        dup 1E-5 lt {
          pop pop pop pop pop pop pop pop pop pop
          pop pop pop pop pop pop pop pop pop pop
          0 0
        } {
          0 index 2 index dup mul sub dup 0 lt {
            pop pop pop pop pop pop pop pop pop pop
            pop pop pop pop pop pop pop pop pop pop
            pop 0 0
          } {
            sqrt % sqrt(m^2+p^2-q^2)
            % \sin_{1,2}\alpha=\dfrac{qp\mp{}m\sqrt{m^2+p^2-q^2}}{m^2+p^2}
            10 index 1 index mul 4 index 4 index mul add 2 index div % \sin\alpha
            % \cos_{1,2}\alpha=\dfrac{mq\pm{}p\sqrt{m^2+p^2-q^2}}{m^2+p^2}
            4 index 2 index mul 12 index 5 index mul exch sub 3 index div % \cos\alpha
            dup abs 1E-5 lt {
              pop pop pop pop pop pop pop pop pop pop
              pop pop pop pop pop pop pop pop pop pop
              pop pop pop 0 0
            } {
              % x=x_0+h\tan\alpha-g\sec\alpha, y=y_0+f\tan\alpha+e\sec\alpha
              22 index 8 index 2 index div sub 7 index 3 index mul 2 index div add % x_1
              22 index 11 index 3 index div add 10 index 4 index mul 3 index div add % y_1
              25 2 roll
              pop pop pop pop pop pop pop pop pop pop
              pop pop pop pop pop pop pop pop pop pop
              pop pop pop
            } ifelse
          } ifelse
        } ifelse
      } ifelse
    ){#4}%
    \pnode(!%
      \pst@tempO \tx@UserCoor % x0,y0
      \pst@tempR \tx@UserCoor abs exch abs exch % |a|,|b|
      \pst@tempA \tx@UserCoor % x1,y1
      \pst@tempB \tx@UserCoor % x2,y2
      3 index 2 index sub abs 1E-5 lt { % if the line AB is vertical
        #1 dup cos exch sin % cos\theta sin\theta
        7 index 2 index mul % e=a\cos\theta
        7 index 2 index mul % f=b\sin\theta
        9 index 3 index mul % g=a\sin\theta
        9 index 5 index mul % h=b\cos\theta
        7 index 14 index sub % n=x1-x0
        0 index dup mul 2 index dup mul add % n^2+h^2
        0 index abs 1E-5 lt {
          pop pop pop pop pop pop
          pop pop pop pop pop pop 0 0
        } {
          0 index 4 index dup mul sub dup 0 lt {
            pop pop pop pop pop pop pop
            pop pop pop pop pop pop 0 0
          } {
            sqrt % sqrt(n^2+h^2-g^2)
            %% \sin_{1,2}\alpha=\dfrac{gh\pm{}n\sqrt{n^2+h^2-g^2}}{n^2+h^2}
            2 index 1 index mul 5 index 5 index mul add 2 index div % sin
            %% \cos_{1,2}\alpha=\dfrac{-ng\pm{}h\sqrt{n^2+h^2-g^2}}{n^2+h^2}
            4 index 2 index mul 4 index 7 index mul sub 3 index div % cos
            dup abs 1E-5 lt {
              pop pop pop pop pop pop pop pop
              pop pop pop pop pop pop pop 0 0
            } {
              18 index 6 index 3 index mul 2 index div add 7 index 2 index div sub % x_2=x_0+h\tan\alpha-g\sec\alpha
              18 index 9 index 4 index mul 3 index div add 10 index 3 index div add % y_2=y_0+f\tan\alpha+e\sec\alpha
              21 2 roll pop pop pop pop pop pop pop pop
              pop pop pop pop pop pop pop pop pop pop pop
            } ifelse
          } ifelse
        } ifelse
      } {
        0 index 3 index sub 2 index 5 index sub div % k
        2 index 4 index mul 2 index 6 index mul sub 3 index 6 index sub div % d
        1 index 10 index mul 9 index sub 1 index add % m=kx_o-y_o+d
        #1 dup cos exch sin % cos\theta sin\theta
        10 index 2 index mul % e=a\cos\theta
        10 index 2 index mul % f=b\sin\theta
        12 index 3 index mul % g=a\sin\theta
        12 index 5 index mul % h=b\cos\theta
        8 index 1 index mul 3 index sub % p=kh-f
        9 index 3 index mul 5 index add % q=kg+e
        8 index dup mul 2 index dup mul add % m^2+p^2
        dup 1E-5 lt {
          pop pop pop pop pop pop pop pop pop pop
          pop pop pop pop pop pop pop pop pop pop
          0 0
        } {
          0 index 2 index dup mul sub dup 0 lt {
            pop pop pop pop pop pop pop pop pop pop
            pop pop pop pop pop pop pop pop pop pop
            pop 0 0
          } {
            sqrt % sqrt(m^2+p^2-q^2)
            % \sin_{1,2}\alpha=\dfrac{qp\mp{}m\sqrt{m^2+p^2-q^2}}{m^2+p^2}
            10 index 1 index mul 4 index 4 index mul exch sub 2 index div % \sin\alpha
            % \cos_{1,2}\alpha=\dfrac{mq\pm{}p\sqrt{m^2+p^2-q^2}}{m^2+p^2}
            4 index 2 index mul 12 index 5 index mul add 3 index div % \cos\alpha
            dup abs 1E-5 lt {
              pop pop pop pop pop pop pop pop pop pop
              pop pop pop pop pop pop pop pop pop pop
              pop pop pop 0 0
            } {
              % x=x_0+h\tan\alpha-g\sec\alpha, y=y_0+f\tan\alpha+e\sec\alpha
              22 index 8 index 2 index div sub 7 index 3 index mul 2 index div add % x_2
              22 index 11 index 3 index div add 10 index 4 index mul 3 index div add % y_2
              25 2 roll
              pop pop pop pop pop pop pop pop pop pop
              pop pop pop pop pop pop pop pop pop pop
              pop pop pop
            } ifelse
          } ifelse
        } ifelse
      } ifelse
    ){#5}%
    \Pst@ManageParamList{#4}%
    \Pst@ManageParamList{#5}%
  \endgroup%
}%
%
%% \pstGeneralIHyperbolaPolarNode[Options](O)(a,b)[rotation]{A}{B}{T}
%% Find the polar point of chord AB on General Conjugate Hyperbola H.
%% We use the following proposition to find the polar point of chord AB:
%% Let $P$, $Q$ are vertex points of the hyperbola, for any chord $AB$ of hyperbola, $PA$ and $BQ$ intersect at $E$, $PB$ and $AQ$ intersect at $F$, then the middle point $M$ of $EF$ is the polar point of chord $AB$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the node A on the hyperbola.
%% #6 -> [input] the node B on the hyperbola.
%% #7 -> [output] the polar node T of chord AB.
\def\pstGeneralIHyperbolaPolarNode{\@ifnextchar[\Pst@GeneralIHyperbolaPolarNode{\Pst@GeneralIHyperbolaPolarNode[]}}
\def\Pst@GeneralIHyperbolaPolarNode[#1](#2)(#3){%
  \begingroup
    \psset{#1}%
    \def\pst@hyperbola@center{#2}
    \def\pst@hyperbola@radii{#3}
    \@ifnextchar[\Pst@GeneralIHyperbolaPolarNode@i{\Pst@GeneralIHyperbolaPolarNode@i[0]}}%
\def\Pst@GeneralIHyperbolaPolarNode@i[#1]#2#3#4{%
    \pstGeneralIHyperbolaVertexNode[PointName=none,PointSymbol=none](\pst@hyperbola@center)(\pst@hyperbola@radii)[#1]{@PST@GENERALIHYPERBOLA@VERTEXA}{@PST@GENERALIHYPERBOLA@VERTEXB}
    \pstInterLL[PointName=none,PointSymbol=none]{#2}{@PST@GENERALIHYPERBOLA@VERTEXA}{#3}{@PST@GENERALIHYPERBOLA@VERTEXB}{@PST@GENERALIHYPERBOLA@INTER@X}
    \pstInterLL[PointName=none,PointSymbol=none]{#3}{@PST@GENERALIHYPERBOLA@VERTEXA}{#2}{@PST@GENERALIHYPERBOLA@VERTEXB}{@PST@GENERALIHYPERBOLA@INTER@Y}
    \pstMiddleAB{@PST@GENERALIHYPERBOLA@INTER@X}{@PST@GENERALIHYPERBOLA@INTER@Y}{#4}
    \Pst@geonodelabel{#4}%
    \pstLineAB{#2}{#4}
    \pstLineAB{#3}{#4}
    \endgroup
}%
%
%% \pstGeneralIHyperbolaTangentNode[Options](O)(a,b)[rotation]{T}{A}{B}
%% Draw the two tangent lines through the point $T$ to the General Conjugate Hyperbola H and get the node A and B on the General Conjugate Hyperbola.
%% We use the following proposition to find the tangent points $A$ and $B$ of $T$:
%% Let $T$ is a point out of the hyperbola, we give any two chords $TPQ$ and $TRS$ of the hyperbola, $PR$ and $QS$ intersect at $X$, $RQ$ and $PS$ intersect at $Y$,
%% then the intersection point $A$ and $B$ of $XY$ and the hyperbola are the tangent points from $T$.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola center O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [input] the given node T outside the hyperbola
%% #6 -> [output] the tangent node name A on the hyperbola
%% #7 -> [output] the tangent node name B on the hyperbola
\def\pstGeneralIHyperbolaTangentNode{\@ifnextchar[\Pst@GeneralIHyperbolaTangentNode{\Pst@GeneralIHyperbolaTangentNode[]}}
\def\Pst@GeneralIHyperbolaTangentNode[#1](#2)(#3){%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \def\pst@hyperbola@center{#2}
    \def\pst@hyperbola@radii{#3}
    \@ifnextchar[\Pst@GeneralIHyperbolaTangentNode@i{\Pst@GeneralIHyperbolaTangentNode@i[0]}}%
\def\Pst@GeneralIHyperbolaTangentNode@i[#1]#2#3#4{%
    \pstGeneralIHyperbolaNode[PointName=none,PointSymbol=none](\pst@hyperbola@center)(\pst@hyperbola@radii)[#1]{10}{@PST@GENERALIHYPERBOLA@TANGENTAUX@P0}
    \pstGeneralIHyperbolaNode[PointName=none,PointSymbol=none](\pst@hyperbola@center)(\pst@hyperbola@radii)[#1]{-10}{@PST@GENERALIHYPERBOLA@TANGENTAUX@R0}
    \pstGeneralIHyperbolaLineInter[PointName=none,PointSymbol=none](\pst@hyperbola@center)(\pst@hyperbola@radii)[#1]{#2}{@PST@GENERALIHYPERBOLA@TANGENTAUX@P0}{@PST@GENERALIHYPERBOLA@TANGENTAUX@P}{@PST@GENERALIHYPERBOLA@TANGENTAUX@Q}
    \pstGeneralIHyperbolaLineInter[PointName=none,PointSymbol=none](\pst@hyperbola@center)(\pst@hyperbola@radii)[#1]{#2}{@PST@GENERALIHYPERBOLA@TANGENTAUX@R0}{@PST@GENERALIHYPERBOLA@TANGENTAUX@R}{@PST@GENERALIHYPERBOLA@TANGENTAUX@S}
    \pstInterLL[PointName=none,PointSymbol=none]{@PST@GENERALIHYPERBOLA@TANGENTAUX@P}{@PST@GENERALIHYPERBOLA@TANGENTAUX@S}{@PST@GENERALIHYPERBOLA@TANGENTAUX@Q}{@PST@GENERALIHYPERBOLA@TANGENTAUX@R}{@PST@GENERALIHYPERBOLA@TANGENTAUX@I}
    \pstInterLL[PointName=none,PointSymbol=none]{@PST@GENERALIHYPERBOLA@TANGENTAUX@P}{@PST@GENERALIHYPERBOLA@TANGENTAUX@R}{@PST@GENERALIHYPERBOLA@TANGENTAUX@Q}{@PST@GENERALIHYPERBOLA@TANGENTAUX@S}{@PST@GENERALIHYPERBOLA@TANGENTAUX@X}
    \pstGeneralIHyperbolaLineInter(\pst@hyperbola@center)(\pst@hyperbola@radii)[#1]{@PST@GENERALIHYPERBOLA@TANGENTAUX@X}{@PST@GENERALIHYPERBOLA@TANGENTAUX@I}{#3}{#4}
    \Pst@ManageParamList{#3}%
    \Pst@ManageParamList{#4}%
    \pstLineAB{#2}{#3}
    \pstLineAB{#2}{#4}
  \endgroup%
}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 11. General Conic Equation ax^2+bxy+cy^2+dx+ey+f=0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%% \pstGeneralConicEquation[Options]{A}{B}{C}{D}{E}{a,b,c,d,e,f}
%% Calculate the quadratic curve equation $ax^2+bxy+cy^2+dx+ey+f=0$ which through five different points A,B,C,D,E.
%% 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 output coefficents name a,b,c,d,e,f of quadratic equation.
\def\pstGeneralConicEquation{\@ifnextchar[\Pst@GeneralConicEquation{\Pst@GeneralConicEquation[]}}
\def\Pst@GeneralConicEquation[#1]#2#3#4#5#6#7{
  \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%
    \pstParseArg{OutCurveCoef}{a,b,c,d,e,f}{#7}
    \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, 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^2a
      % BxBy b + By^2 c + Bx d + By e + 1 f = -Bx^2a
      % CxCy b + Cy^2 c + Cx d + Cy e + 1 f = -Cx^2a
      % DxDy b + Dy^2 c + Dx d + Dy e + 1 f = -Dx^2a
      % ExEy b + Ey^2 c + Ex d + Ey e + 1 f = -Ex^2a
      % by Cramer's Rule, we have
      %    |Ax^2a Ay^2 Ax Ay 1| |AxAy Ay^2 Ax Ay 1|
      %    |Bx^2a By^2 Bx By 1| |BxBy By^2 Bx By 1|
      % b=-|Cx^2a Cy^2 Cx Cy 1|/|CxCy Cy^2 Cx Cy 1| etc.
      %    |Dx^2a Dy^2 Dx Dy 1| |DxDy Dy^2 Dx Dy 1|
      %    |Ex^2a Ey^2 Ex Ey 1| |ExEy Ey^2 Ex Ey 1|
      % if the denominator is zero, we can choose a = 0, else a = 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 /CurveCoefa ED
        % Ay^2 c + Ax d + Ay e + 1 f = -AxAyb
        % By^2 c + Bx d + By e + 1 f = -BxByb
        % Cy^2 c + Cx d + Cy e + 1 f = -CxCyb
        % Dy^2 c + Dx d + Dy e + 1 f = -DxDyb
        % by Cramer's Rule, we have
        %    |AxAyb Ax Ay 1| |Ay^2 Ax Ay 1|
        %    |BxByb Bx By 1| |By^2 Bx By 1|
        % c=-|CxCyb Cx Cy 1|/|Cy^2 Cx Cy 1| etc.
        %    |DxDyb Dx Dy 1| |Dy^2 Dx Dy 1|
        CurveNodeAY dup mul CurveNodeAX CurveNodeAY 1
        CurveNodeBY dup mul CurveNodeBX CurveNodeBY 1
        CurveNodeCY dup mul CurveNodeCX CurveNodeCY 1
        CurveNodeDY dup mul CurveNodeDX CurveNodeDY 1
        tx@EcldDict begin DeterminantFour end /LinearDiscriminant2nd ED
        LinearDiscriminant2nd abs 1E-5 lt { % D2=0
          0 /CurveCoefb ED
          % Ax d + Ay e + 1 f = -Ay^2c
          % Bx d + By e + 1 f = -By^2c
          % Cx d + Cy e + 1 f = -Cy^2c
          % by Cramer's Rule, we have
          % d=-|Ay^2c Ay 1| |Ax Ay 1|
          %    |By^2c By 1| |Bx By 1|
          %    |Cy^2c Cy 1|/|Cx Cy 1| etc.
          CurveNodeAX CurveNodeAY 1
          CurveNodeBX CurveNodeBY 1
          CurveNodeCX CurveNodeCY 1
          tx@EcldDict begin DeterminantThree end /LinearDiscriminant3rd ED
          LinearDiscriminant3rd abs 1E-5 lt { % D3=0
            0 /CurveCoefc ED
            % Ay e + 1 f = -Axd
            % By e + 1 f = -Bxd
            CurveNodeAY 1
            CurveNodeBY 1
            tx@EcldDict begin DeterminantTwo end /LinearDiscriminant4th ED
            LinearDiscriminant4th abs 1E-5 lt { % D4=0
              0 /CurveCoefd ED
              1 /CurveCoefe ED
              CurveNodeAY neg /CurveCoeff ED
            } {
              1 /CurveCoefd ED
              CurveNodeAX 1
              CurveNodeBX 1
              tx@EcldDict begin DeterminantTwo end LinearDiscriminant4th div neg /CurveCoefe ED
              CurveNodeAY CurveNodeAX
              CurveNodeBY CurveNodeBX
              tx@EcldDict begin DeterminantTwo end LinearDiscriminant4th div neg /CurveCoeff ED
            } ifelse
          } {
            1 /CurveCoefc ED
            CurveNodeAY dup mul CurveNodeAY 1
            CurveNodeBY dup mul CurveNodeBY 1
            CurveNodeCY dup mul CurveNodeCY 1
            tx@EcldDict begin DeterminantThree end LinearDiscriminant3rd div neg /CurveCoefd ED
            CurveNodeAX CurveNodeAY dup mul 1
            CurveNodeBX CurveNodeBY dup mul 1
            CurveNodeCX CurveNodeCY dup mul 1
            tx@EcldDict begin DeterminantThree end LinearDiscriminant3rd div neg /CurveCoefe ED
            CurveNodeAX CurveNodeAY CurveNodeAY dup mul
            CurveNodeBX CurveNodeBY CurveNodeBY dup mul
            CurveNodeCX CurveNodeCY CurveNodeCY dup mul
            tx@EcldDict begin DeterminantThree end LinearDiscriminant3rd div neg /CurveCoeff ED
          } ifelse
        } {
          1 /CurveCoefb ED
          CurveNodeAX CurveNodeAY mul CurveNodeAX CurveNodeAY 1
          CurveNodeBX CurveNodeBY mul CurveNodeBX CurveNodeBY 1
          CurveNodeCX CurveNodeCY mul CurveNodeCX CurveNodeCY 1
          CurveNodeDX CurveNodeDY mul CurveNodeDX CurveNodeDY 1
          tx@EcldDict begin DeterminantFour end LinearDiscriminant2nd div neg /CurveCoefc ED
          CurveNodeAY dup mul CurveNodeAX CurveNodeAY mul CurveNodeAY 1
          CurveNodeBY dup mul CurveNodeBX CurveNodeBY mul CurveNodeBY 1
          CurveNodeCY dup mul CurveNodeCX CurveNodeCY mul CurveNodeCY 1
          CurveNodeDY dup mul CurveNodeDX CurveNodeDY mul CurveNodeDY 1
          tx@EcldDict begin DeterminantFour end LinearDiscriminant2nd div neg /CurveCoefd ED
          CurveNodeAY dup mul CurveNodeAX CurveNodeAX CurveNodeAY mul 1
          CurveNodeBY dup mul CurveNodeBX CurveNodeBX CurveNodeBY mul 1
          CurveNodeCY dup mul CurveNodeCX CurveNodeCX CurveNodeCY mul 1
          CurveNodeDY dup mul CurveNodeDX CurveNodeDX CurveNodeDY mul 1
          tx@EcldDict begin DeterminantFour end LinearDiscriminant2nd div neg /CurveCoefe ED
          CurveNodeAY dup mul CurveNodeAX CurveNodeAY CurveNodeAX CurveNodeAY mul
          CurveNodeBY dup mul CurveNodeBX CurveNodeBY CurveNodeBX CurveNodeBY mul
          CurveNodeCY dup mul CurveNodeCX CurveNodeCY CurveNodeCX CurveNodeCY mul
          CurveNodeDY dup mul CurveNodeDX CurveNodeDY CurveNodeDX CurveNodeDY mul
          tx@EcldDict begin DeterminantFour end LinearDiscriminant2nd div neg /CurveCoeff ED
        } ifelse
      } {
        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
      } ifelse
      % CurveCoefa = CurveCoefb = CurveCoefc = CurveCoefd = CurveCoefe = CurveCoeff =
      0 /CurveCoefMax ED 1E8 /CurveCoefMin ED
      CurveCoefa abs CurveCoefMax gt {CurveCoefa abs /CurveCoefMax ED} if
      CurveCoefb abs CurveCoefMax gt {CurveCoefb abs /CurveCoefMax ED} if
      CurveCoefc abs CurveCoefMax gt {CurveCoefc abs /CurveCoefMax ED} if
      CurveCoefd abs CurveCoefMax gt {CurveCoefd abs /CurveCoefMax ED} if
      CurveCoefe abs CurveCoefMax gt {CurveCoefe abs /CurveCoefMax ED} if
      CurveCoeff abs CurveCoefMax gt {CurveCoeff abs /CurveCoefMax ED} if
      CurveCoefa abs CurveCoefMin lt {CurveCoefa abs /CurveCoefMin ED} if
      CurveCoefb abs CurveCoefMin lt {CurveCoefb abs /CurveCoefMin ED} if
      CurveCoefc abs CurveCoefMin lt {CurveCoefc abs /CurveCoefMin ED} if
      CurveCoefd abs CurveCoefMin lt {CurveCoefd abs /CurveCoefMin ED} if
      CurveCoefe abs CurveCoefMin lt {CurveCoefe abs /CurveCoefMin ED} if
      CurveCoeff abs CurveCoefMin lt {CurveCoeff abs /CurveCoefMin ED} if
      % CurveCoefMin = CurveCoefMax =
      CurveCoefMin CurveCoefMax div 1E-5 lt {
        CurveCoefa CurveCoefMax div /CurveCoefa ED
        CurveCoefb CurveCoefMax div /CurveCoefb ED
        CurveCoefc CurveCoefMax div /CurveCoefc ED
        CurveCoefd CurveCoefMax div /CurveCoefd ED
        CurveCoefe CurveCoefMax div /CurveCoefe ED
        CurveCoeff CurveCoefMax div /CurveCoeff ED
      } if
      % CurveCoefa = CurveCoefb = CurveCoefc = CurveCoefd = CurveCoefe = CurveCoeff =
      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
      % CurveCoefa = CurveCoefb = CurveCoefc = CurveCoefd = CurveCoefe = CurveCoeff =
      CurveCoefa /\OutCurveCoefa\space ED
      CurveCoefb /\OutCurveCoefb\space ED
      CurveCoefc /\OutCurveCoefc\space ED
      CurveCoefd /\OutCurveCoefd\space ED
      CurveCoefe /\OutCurveCoefe\space ED
      CurveCoeff /\OutCurveCoeff\space ED
      \ifPst@CodeFig
        [\OutCurveCoefa\space \OutCurveCoefb\space \OutCurveCoefc\space \OutCurveCoefd\space \OutCurveCoefe\space \OutCurveCoeff\space] ==
      \fi
      0 0
    ){@Pst@GeneralConicEquationDummyNode}
  \endgroup%
}%
%
%% \pstGeneralEllipseEquation[Options](O)(a,b)[rotation]{a,b,c,d,e,f}
%% Calculate the quadratic curve equation $ax^2+bxy+cy^2+dx+ey+f=0$ for the given general ellipse.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the ellipse center O
%% #3 -> [input] the horizontal and vertical radii
%% #4 -> [input] the rotation angle $\theta$ of the major axis.
%% #5 -> [output] the output coefficents name a,b,c,d,e,f of quadratic equation.
\def\pstGeneralEllipseEquation{\@ifnextchar[\Pst@GeneralEllipseEquation{\Pst@GeneralEllipseEquation[]}}
\def\Pst@GeneralEllipseEquation[#1](#2)(#3){%
  \begingroup
    \psset{#1}%
    \def\PST@EllipseCenter{#2}%
    \def\PST@EllipseRadii{#3}%
    \@ifnextchar[\Pst@GeneralEllipseEquation@i{\Pst@GeneralEllipseEquation@i[0]}}%
\def\Pst@GeneralEllipseEquation@i[#1]#2{%
    \pstGeneralEllipseNode[PointName=none,PointSymbol=none](\PST@EllipseCenter)(\PST@EllipseRadii)[#1]{0}{@PST@EllipseTmpNodeA}
    \pstGeneralEllipseNode[PointName=none,PointSymbol=none](\PST@EllipseCenter)(\PST@EllipseRadii)[#1]{90}{@PST@EllipseTmpNodeB}
    \pstGeneralEllipseNode[PointName=none,PointSymbol=none](\PST@EllipseCenter)(\PST@EllipseRadii)[#1]{180}{@PST@EllipseTmpNodeC}
    \pstGeneralEllipseNode[PointName=none,PointSymbol=none](\PST@EllipseCenter)(\PST@EllipseRadii)[#1]{270}{@PST@EllipseTmpNodeD}
    \pstGeneralEllipseNode[PointName=none,PointSymbol=none](\PST@EllipseCenter)(\PST@EllipseRadii)[#1]{45}{@PST@EllipseTmpNodeE}
    \pstGeneralConicEquation{@PST@EllipseTmpNodeA}{@PST@EllipseTmpNodeB}{@PST@EllipseTmpNodeC}{@PST@EllipseTmpNodeD}{@PST@EllipseTmpNodeE}{#2}
  \endgroup%
}%
%
%% \pstGeneralHyperbolaEquation[Options](O)(a,b)[rotation]{a,b,c,d,e,f}
%% Calculate the quadratic curve equation $ax^2+bxy+cy^2+dx+ey+f=0$ for the given general hyperbola.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the hyperbola vertex O
%% #3 -> [input] the radii of real and imaginary axis
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [output] the output coefficents name a,b,c,d,e,f of quadratic equation.
\def\pstGeneralHyperbolaEquation{\@ifnextchar[\Pst@GeneralHyperbolaEquation{\Pst@GeneralHyperbolaEquation[]}}
\def\Pst@GeneralHyperbolaEquation[#1](#2)(#3){%
  \begingroup
    \psset{#1}%
    \def\PST@HyperbolaCenter{#2}%
    \def\PST@HyperbolaRadii{#3}%
    \@ifnextchar[\Pst@GeneralHyperbolaEquation@i{\Pst@GeneralHyperbolaEquation@i[0]}}%
\def\Pst@GeneralHyperbolaEquation@i[#1]#2{%
    \pstGeneralHyperbolaVertexNode[PointName=none,PointSymbol=none](\PST@HyperbolaCenter)(\PST@HyperbolaRadii)[#1]{@PST@HyperbolaTmpNodeA}{@PST@HyperbolaTmpNodeB}
    \pstGeneralHyperbolaNode[PointName=none,PointSymbol=none](\PST@HyperbolaCenter)(\PST@HyperbolaRadii)[#1]{10}{@PST@HyperbolaTmpNodeC}
    \pstGeneralHyperbolaNode[PointName=none,PointSymbol=none](\PST@HyperbolaCenter)(\PST@HyperbolaRadii)[#1]{-10}{@PST@HyperbolaTmpNodeD}
    \pstGeneralHyperbolaNode[PointName=none,PointSymbol=none](\PST@HyperbolaCenter)(\PST@HyperbolaRadii)[#1]{100}{@PST@HyperbolaTmpNodeE}
    \pstGeneralConicEquation{@PST@HyperbolaTmpNodeA}{@PST@HyperbolaTmpNodeB}{@PST@HyperbolaTmpNodeC}{@PST@HyperbolaTmpNodeD}{@PST@HyperbolaTmpNodeE}{#2}
  \endgroup%
}%
%
%% \pstGeneralParabolaEquation[Options](O){p}[rotation]{a,b,c,d,e,f}
%% Calculate the quadratic curve equation $ax^2+bxy+cy^2+dx+ey+f=0$ for the given general Parabola.
%% Parameters:
%% #1 -> options
%% #2 -> [input] the Parabola vertex O
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the rotation angle $\theta$ of the symmetrical axis.
%% #5 -> [output] the output coefficents name a,b,c,d,e,f of quadratic equation.
\def\pstGeneralParabolaEquation{\@ifnextchar[\Pst@GeneralParabolaEquation{\Pst@GeneralParabolaEquation[]}}
\def\Pst@GeneralParabolaEquation[#1](#2)#3{%
  \begingroup
    \psset{#1}%
    \def\PST@ParabolaVertex{#2}%
    \def\PST@ParabolaSemiFocalChord{#3}%
    \@ifnextchar[\Pst@GeneralParabolaEquation@i{\Pst@GeneralParabolaEquation@i[0]}}%
\def\Pst@GeneralParabolaEquation@i[#1]#2{%
    \pstGeneralParabolaNode[PointName=none,PointSymbol=none](\PST@ParabolaVertex){\PST@ParabolaSemiFocalChord}[#1]{0}{@PST@ParabolaTmpNodeA}
    \pstGeneralParabolaNode[PointName=none,PointSymbol=none](\PST@ParabolaVertex){\PST@ParabolaSemiFocalChord}[#1]{90}{@PST@ParabolaTmpNodeB}
    \pstGeneralParabolaNode[PointName=none,PointSymbol=none](\PST@ParabolaVertex){\PST@ParabolaSemiFocalChord}[#1]{180}{@PST@ParabolaTmpNodeC}
    \pstGeneralParabolaNode[PointName=none,PointSymbol=none](\PST@ParabolaVertex){\PST@ParabolaSemiFocalChord}[#1]{270}{@PST@ParabolaTmpNodeD}
    \pstGeneralParabolaNode[PointName=none,PointSymbol=none](\PST@ParabolaVertex){\PST@ParabolaSemiFocalChord}[#1]{45}{@PST@ParabolaTmpNodeE}
    \pstGeneralConicEquation{@PST@ParabolaTmpNodeA}{@PST@ParabolaTmpNodeB}{@PST@ParabolaTmpNodeC}{@PST@ParabolaTmpNodeD}{@PST@ParabolaTmpNodeE}{#2}
  \endgroup%
}%
%
%% \pstGeneralConicLineInter[Options]{A}{B}{a,b,c,d,e,f}{C}{D}
%% Get the two intersections $C$ and $D$ of the General Conic $ax^2+bxy+cy^2+dx+ey+f=0$ with the given line $AB$.
%
%% Parameters:
%% #1 -> options
%% #2 -> [input] the node name A on the given line
%% #3 -> [input] the node name B on the given line
%% #4 -> [input] the coefficents of the quadratic curve equation, with six numbers $a,b,c,d,e,f$ joined with comma.
%% #5 -> [output] the first intersection node name
%% #6 -> [output] the second intersection node name
\def\pstGeneralConicLineInter{\@ifnextchar[\Pst@GeneralConicLineInter{\Pst@GeneralConicLineInter[]}}
\def\Pst@GeneralConicLineInter[#1]#2#3#4#5#6{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempA%
    \pst@getcoor{#3}\pst@tempB%
    \pstParseArg{CurveCoef}{a,b,c,d,e,f}{#4}
    \pnode(!
      % Conic ax^2+bxy+cy^2+dx+ey+f=0
      \CurveCoefa /Ca ED
      \CurveCoefb /Cb ED
      \CurveCoefc /Cc ED
      \CurveCoefd /Cd ED
      \CurveCoefe /Ce ED
      \CurveCoeff /Cf ED
      % Line ax+by+c=0
      \pst@tempA \tx@UserCoor /Ay ED /Ax ED
      \pst@tempB \tx@UserCoor /By ED /Bx ED
      By Ay sub /La ED
      Ax Bx sub /Lb ED
      Ay Bx mul Ax By mul sub /Lc ED
      La abs 1E-5 lt { % La==0
        Lb abs 1E-5 lt { % Lb==0
          0 0
          0 /Dx ED 0 /Dy ED
        } {
          % Quadratic equation ax^2+bx+c=0
          Ca Lb mul /Qa ED % Qa = Ca.Lb
          Cd Lb mul Cb Lc mul sub /Qb ED % Qb = Cd.Lb-Cb.Lc
          Cf Lb mul Ce Lc mul sub Cc Lc mul Lc mul Lb div add /Qc ED % Qc = Cf.Lb-Ce.Lc+Cc.Lc.Lc/Lb
          Qa abs 1E-5 lt { % Qa==0
            Qb abs 1E-5 lt { % Qb==0
              0 0
              0 /Dx ED 0 /Dy ED
            } {
              Qc Qb div neg % Cx
              Lc Lb div neg % Cy
              0 /Dx ED 0 /Dy ED
            } ifelse
          } {
            Qb dup mul Qa Qc mul 4 mul sub dup 0 lt { % Delta < 0
              0 0
              0 /Dx ED 0 /Dy ED
            } {
              sqrt dup Qb neg add Qa 2 mul div /Dx ED
              Lc Lb div neg /Dy ED
              Qb neg exch sub Qa 2 mul div % Cx
              Lc Lb div neg % Cy
            } ifelse
          } ifelse
        } ifelse
      } {
        % Quadratic equation ay^2+by+c=0
        Ca Lb mul Lb mul La div Cc La mul add Cb Lb mul sub /Qa ED % Qa = Ca.Lb.Lb/La+Cc.La-Cb.Lb
        Ca Lb mul Lc mul 2 mul La div Ce La mul add Cb Lc mul sub Cd Lb mul sub /Qb ED % Qb = 2.Ca.Lb.Lc/La+Ce.La-Cb.Lc-Cd.Lb
        Ca Lc mul Lc mul La div Cf La mul add Cd Lc mul sub /Qc ED % Qc = Ca.Lc.Lc/La+Cf.La-Cd.LC
        % Ca = Cb = Cc = Cd = Ce = Cf =
        % La = Lb = Lc = Qa = Qb = Qc =
        Qa abs 1E-5 lt { % Qa==0
          Qb abs 1E-5 lt { % Qb==0
            0 0
            0 /Dx ED 0 /Dy ED
          } {
              Qc Qb div neg % Cy
              dup Lb mul Lc add La div neg % Cx
              exch % Cx Cy
              0 /Dx ED 0 /Dy ED
          } ifelse
        } {
          Qb dup mul Qa Qc mul 4 mul sub dup 0 lt { % Delta < 0
            0 0
            0 /Dx ED 0 /Dy ED
          } {
            sqrt dup Qb neg add Qa 2 mul div /Dy ED
            Dy Lb mul Lc add La div neg /Dx ED
            Qb neg exch sub Qa 2 mul div % Cy
            dup Lb mul Lc add La div neg % Cx
            exch % Cx Cy
          } ifelse
        } ifelse
      } ifelse
    ){#5}
    \pnode(! Dx Dy){#6}
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
  \endgroup%
}%
%
%% \pstGeneralConicCircleInter[Options]{O}{A}{a,b,c,d,e,f}{C}{D}{E}{F}
%% Get the most four intersections $C$, $D$, $E$ and $F$ of the General Conic $ax^2+bxy+cy^2+dx+ey+f=0$ and the given circle $O$ with radius $OA$.
%
%% Parameters:
%% #1 -> options
%% #2 -> [input] the center O of the given circle
%% #3 -> [input] the node A on the given circle
%% #4 -> [input] the coefficents of the quadratic curve equation, with six numbers $a,b,c,d,e,f$ joined with comma.
%% #5 -> [output] the first intersection node name
%% #6 -> [output] the second intersection node name
%% #7 -> [output] the third intersection node name
%% #8 -> [output] the fourth intersection node name
\def\pstGeneralConicCircleInter{\@ifnextchar[\Pst@GeneralConicCircleInter{\Pst@GeneralConicCircleInter[]}}
\def\Pst@GeneralConicCircleInter[#1]#2#3#4#5#6#7#8{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempA%
    \pstParseArg{CurveCoef}{a,b,c,d,e,f}{#4}
    \pnode(!
      % Conic ax^2+bxy+cy^2+dx+ey+f=0
      \CurveCoefa /Ca ED
      \CurveCoefb /Cb ED
      \CurveCoefc /Cc ED
      \CurveCoefd /Cd ED
      \CurveCoefe /Ce ED
      \CurveCoeff /Cf ED
      % Circle
      \pst@tempO \tx@UserCoor /Oy ED /Ox ED
      \pst@tempA \tx@UserCoor /Ay ED /Ax ED
      /Rc Ax Ox sub dup mul Ay Oy sub dup mul add sqrt def
      tx@EcldDict begin Ca Cb Cc Cd Ce Cf Ox Oy Rc ConicCircleInter end
      /nInters ED /Inters ED
      nInters 0 gt {
        /XYPair Inters 0 get def
        XYPair 0 get XYPair 1 get
      } {
        0 0
      } ifelse
      /Dx 0 def /Dy 0 def
      /Ex 0 def /Ey 0 def
      /Fx 0 def /Fy 0 def
      nInters 1 gt {
        /XYPair Inters 1 get def
        /Dx XYPair 0 get def
        /Dy XYPair 1 get def
      } if
      nInters 2 gt {
        /XYPair Inters 2 get def
        /Ex XYPair 0 get def
        /Ey XYPair 1 get def
      } if
      nInters 3 gt {
        /XYPair Inters 3 get def
        /Fx XYPair 0 get def
        /Fy XYPair 1 get def
      } if
    ){#5}
    \pnode(! Dx Dy){#6}
    \pnode(! Ex Ey){#7}
    \pnode(! Fx Fy){#8}
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
    \Pst@ManageParamList{#7}%
    \Pst@ManageParamList{#8}%
  \endgroup%
}%
%
%% \pstGeneralConicEllipseInter[Options](O)(m,n){a,b,c,d,e,f}{C}{D}{E}{F}
%% Get the most four intersections $C$, $D$, $E$ and $F$ of the General Conic $ax^2+bxy+cy^2+dx+ey+f=0$ and the given ellipse $(x-O_x)^2/m^2+(y-O_y)^2/n^2=1$.
%
%% Parameters:
%% #1 -> options
%% #2 -> [input] the center O of the given ellipse
%% #3 -> [input] the radius (m,n) of the given ellipse
%% #4 -> [input] the coefficents of the quadratic curve equation, with six numbers $a,b,c,d,e,f$ joined with comma.
%% #5 -> [output] the first intersection node name
%% #6 -> [output] the second intersection node name
%% #7 -> [output] the third intersection node name
%% #8 -> [output] the fourth intersection node name
\def\pstGeneralConicEllipseInter{\@ifnextchar[\Pst@GeneralConicEllipseInter{\Pst@GeneralConicEllipseInter[]}}
\def\Pst@GeneralConicEllipseInter[#1](#2)(#3)#4#5#6#7#8{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \pstParseArg{CurveCoef}{a,b,c,d,e,f}{#4}
    \pnode(!
      % Conic ax^2+bxy+cy^2+dx+ey+f=0
      \CurveCoefa /Ca ED
      \CurveCoefb /Cb ED
      \CurveCoefc /Cc ED
      \CurveCoefd /Cd ED
      \CurveCoefe /Ce ED
      \CurveCoeff /Cf ED
      % Ellipse
      \pst@tempO \tx@UserCoor /Oy ED /Ox ED
      \pst@tempR \tx@UserCoor /Ry ED /Rx ED
      tx@EcldDict begin Ca Cb Cc Cd Ce Cf Ox Oy Rx Ry ConicEllipseInter end
      /nInters ED /Inters ED
      nInters 0 gt {
        /XYPair Inters 0 get def
        XYPair 0 get XYPair 1 get
      } {
        0 0
      } ifelse
      /Dx 0 def /Dy 0 def
      /Ex 0 def /Ey 0 def
      /Fx 0 def /Fy 0 def
      nInters 1 gt {
        /XYPair Inters 1 get def
        /Dx XYPair 0 get def
        /Dy XYPair 1 get def
      } if
      nInters 2 gt {
        /XYPair Inters 2 get def
        /Ex XYPair 0 get def
        /Ey XYPair 1 get def
      } if
      nInters 3 gt {
        /XYPair Inters 3 get def
        /Fx XYPair 0 get def
        /Fy XYPair 1 get def
      } if
    ){#5}
    \pnode(! Dx Dy){#6}
    \pnode(! Ex Ey){#7}
    \pnode(! Fx Fy){#8}
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
    \Pst@ManageParamList{#7}%
    \Pst@ManageParamList{#8}%
  \endgroup%
}%
%
%% \pstGeneralConicHyperbolaInter[Options](O)(m,n){a,b,c,d,e,f}{C}{D}{E}{F}
%% Get the most four intersections $C$, $D$, $E$ and $F$ of the General Conic $ax^2+bxy+cy^2+dx+ey+f=0$ and the given hyperbola $(x-O_x)^2/m^2-(y-O_y)^2/n^2=1$.
%
%% Parameters:
%% #1 -> options
%% #2 -> [input] the center O of the given hyperbola
%% #3 -> [input] the radius (m,n) of the given hyperbola
%% #4 -> [input] the coefficents of the quadratic curve equation, with six numbers $a,b,c,d,e,f$ joined with comma.
%% #5 -> [output] the first intersection node name
%% #6 -> [output] the second intersection node name
%% #7 -> [output] the third intersection node name
%% #8 -> [output] the fourth intersection node name
\def\pstGeneralConicHyperbolaInter{\@ifnextchar[\Pst@GeneralConicHyperbolaInter{\Pst@GeneralConicHyperbolaInter[]}}
\def\Pst@GeneralConicHyperbolaInter[#1](#2)(#3)#4#5#6#7#8{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \pstParseArg{CurveCoef}{a,b,c,d,e,f}{#4}
    \pnode(!
      % Conic ax^2+bxy+cy^2+dx+ey+f=0
      \CurveCoefa /Ca ED
      \CurveCoefb /Cb ED
      \CurveCoefc /Cc ED
      \CurveCoefd /Cd ED
      \CurveCoefe /Ce ED
      \CurveCoeff /Cf ED
      % Hyperbola
      \pst@tempO \tx@UserCoor /Oy ED /Ox ED
      \pst@tempR \tx@UserCoor /Ry ED /Rx ED
      tx@EcldDict begin Ca Cb Cc Cd Ce Cf Ox Oy Rx Ry ConicHyperbolaInter end
      /nInters ED /Inters ED
      nInters 0 gt {
        /XYPair Inters 0 get def
        XYPair 0 get XYPair 1 get
      } {
        0 0
      } ifelse
      /Dx 0 def /Dy 0 def
      /Ex 0 def /Ey 0 def
      /Fx 0 def /Fy 0 def
      nInters 1 gt {
        /XYPair Inters 1 get def
        /Dx XYPair 0 get def
        /Dy XYPair 1 get def
      } if
      nInters 2 gt {
        /XYPair Inters 2 get def
        /Ex XYPair 0 get def
        /Ey XYPair 1 get def
      } if
      nInters 3 gt {
        /XYPair Inters 3 get def
        /Fx XYPair 0 get def
        /Fy XYPair 1 get def
      } if
    ){#5}
    \pnode(! Dx Dy){#6}
    \pnode(! Ex Ey){#7}
    \pnode(! Fx Fy){#8}
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
    \Pst@ManageParamList{#7}%
    \Pst@ManageParamList{#8}%
  \endgroup%
}%
%
%% \pstGeneralConicIHyperbolaInter[Options](O)(m,n){a,b,c,d,e,f}{C}{D}{E}{F}
%% Get the most four intersections $C$, $D$, $E$ and $F$ of the General Conic $ax^2+bxy+cy^2+dx+ey+f=0$ and the given conjugate hyperbola $(y-O_y)^2/m^2-(x-O_x)^2/n^2=1$.
%
%% Parameters:
%% #1 -> options
%% #2 -> [input] the center O of the given conjugate hyperbola
%% #3 -> [input] the radius (m,n) of the given conjugate hyperbola
%% #4 -> [input] the coefficents of the quadratic curve equation, with six numbers $a,b,c,d,e,f$ joined with comma.
%% #5 -> [output] the first intersection node name
%% #6 -> [output] the second intersection node name
%% #7 -> [output] the third intersection node name
%% #8 -> [output] the fourth intersection node name
\def\pstGeneralConicIHyperbolaInter{\@ifnextchar[\Pst@GeneralConicIHyperbolaInter{\Pst@GeneralConicIHyperbolaInter[]}}
\def\Pst@GeneralConicIHyperbolaInter[#1](#2)(#3)#4#5#6#7#8{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pst@getcoor{#3}\pst@tempR%
    \pstParseArg{CurveCoef}{a,b,c,d,e,f}{#4}
    \pnode(!
      % Conic ax^2+bxy+cy^2+dx+ey+f=0
      \CurveCoefa /Ca ED
      \CurveCoefb /Cb ED
      \CurveCoefc /Cc ED
      \CurveCoefd /Cd ED
      \CurveCoefe /Ce ED
      \CurveCoeff /Cf ED
      % Hyperbola
      \pst@tempO \tx@UserCoor /Oy ED /Ox ED
      \pst@tempR \tx@UserCoor /Ry ED /Rx ED
      tx@EcldDict begin Ca Cb Cc Cd Ce Cf Ox Oy Rx Ry ConicIHyperbolaInter end
      /nInters ED /Inters ED
      nInters 0 gt {
        /XYPair Inters 0 get def
        XYPair 0 get XYPair 1 get
      } {
        0 0
      } ifelse
      /Dx 0 def /Dy 0 def
      /Ex 0 def /Ey 0 def
      /Fx 0 def /Fy 0 def
      nInters 1 gt {
        /XYPair Inters 1 get def
        /Dx XYPair 0 get def
        /Dy XYPair 1 get def
      } if
      nInters 2 gt {
        /XYPair Inters 2 get def
        /Ex XYPair 0 get def
        /Ey XYPair 1 get def
      } if
      nInters 3 gt {
        /XYPair Inters 3 get def
        /Fx XYPair 0 get def
        /Fy XYPair 1 get def
      } if
    ){#5}
    \pnode(! Dx Dy){#6}
    \pnode(! Ex Ey){#7}
    \pnode(! Fx Fy){#8}
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
    \Pst@ManageParamList{#7}%
    \Pst@ManageParamList{#8}%
  \endgroup%
}%
%
%% \pstGeneralConicParabolaInter[Options](O){p}{a,b,c,d,e,f}{C}{D}{E}{F}
%% Get the most four intersections $C$, $D$, $E$ and $F$ of the General Conic $ax^2+bxy+cy^2+dx+ey+f=0$ and the given parabola $(x-x0)^2=2p(y-y0)$.
%
%% Parameters:
%% #1 -> options
%% #2 -> [input] the vertex O of the given parabola
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the coefficents of the quadratic curve equation, with six numbers $a,b,c,d,e,f$ joined with comma.
%% #5 -> [output] the first intersection node name
%% #6 -> [output] the second intersection node name
%% #7 -> [output] the third intersection node name
%% #8 -> [output] the fourth intersection node name
\def\pstGeneralConicParabolaInter{\@ifnextchar[\Pst@GeneralConicParabolaInter{\Pst@GeneralConicParabolaInter[]}}
\def\Pst@GeneralConicParabolaInter[#1](#2)#3#4#5#6#7#8{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pstParseArg{CurveCoef}{a,b,c,d,e,f}{#4}
    \pnode(!
      % Conic ax^2+bxy+cy^2+dx+ey+f=0
      \CurveCoefa /Ca ED
      \CurveCoefb /Cb ED
      \CurveCoefc /Cc ED
      \CurveCoefd /Cd ED
      \CurveCoefe /Ce ED
      \CurveCoeff /Cf ED
      % Parabola
      \pst@tempO \tx@UserCoor /Oy ED /Ox ED
      tx@EcldDict begin Ca Cb Cc Cd Ce Cf Ox Oy #3 ConicParabolaInter end
      /nInters ED /Inters ED
      nInters 0 gt {
        /XYPair Inters 0 get def
        XYPair 0 get XYPair 1 get
      } {
        0 0
      } ifelse
      /Dx 0 def /Dy 0 def
      /Ex 0 def /Ey 0 def
      /Fx 0 def /Fy 0 def
      nInters 1 gt {
        /XYPair Inters 1 get def
        /Dx XYPair 0 get def
        /Dy XYPair 1 get def
      } if
      nInters 2 gt {
        /XYPair Inters 2 get def
        /Ex XYPair 0 get def
        /Ey XYPair 1 get def
      } if
      nInters 3 gt {
        /XYPair Inters 3 get def
        /Fx XYPair 0 get def
        /Fy XYPair 1 get def
      } if
    ){#5}
    \pnode(! Dx Dy){#6}
    \pnode(! Ex Ey){#7}
    \pnode(! Fx Fy){#8}
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
    \Pst@ManageParamList{#7}%
    \Pst@ManageParamList{#8}%
  \endgroup%
}%
%
%% \pstGeneralConicIParabolaInter[Options](O){p}{a,b,c,d,e,f}{C}{D}{E}{F}
%% Get the most four intersections $C$, $D$, $E$ and $F$ of the General Conic $ax^2+bxy+cy^2+dx+ey+f=0$ and the given conjugate parabola $(y-y0)^2=2p(x-x0)$.
%
%% Parameters:
%% #1 -> options
%% #2 -> [input] the vertex O of the given conjugate parabola
%% #3 -> [input] the half of focal chord $p$
%% #4 -> [input] the coefficents of the quadratic curve equation, with six numbers $a,b,c,d,e,f$ joined with comma.
%% #5 -> [output] the first intersection node name
%% #6 -> [output] the second intersection node name
%% #7 -> [output] the third intersection node name
%% #8 -> [output] the fourth intersection node name
\def\pstGeneralConicIParabolaInter{\@ifnextchar[\Pst@GeneralConicIParabolaInter{\Pst@GeneralConicIParabolaInter[]}}
\def\Pst@GeneralConicIParabolaInter[#1](#2)#3#4#5#6#7#8{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempO%
    \pstParseArg{CurveCoef}{a,b,c,d,e,f}{#4}
    \pnode(!
      % Conic ax^2+bxy+cy^2+dx+ey+f=0
      \CurveCoefa /Ca ED
      \CurveCoefb /Cb ED
      \CurveCoefc /Cc ED
      \CurveCoefd /Cd ED
      \CurveCoefe /Ce ED
      \CurveCoeff /Cf ED
      % Parabola
      \pst@tempO \tx@UserCoor /Oy ED /Ox ED
      tx@EcldDict begin Ca Cb Cc Cd Ce Cf Ox Oy #3 ConicIParabolaInter end
      /nInters ED /Inters ED
      nInters 0 gt {
        /XYPair Inters 0 get def
        XYPair 0 get XYPair 1 get
      } {
        0 0
      } ifelse
      /Dx 0 def /Dy 0 def
      /Ex 0 def /Ey 0 def
      /Fx 0 def /Fy 0 def
      nInters 1 gt {
        /XYPair Inters 1 get def
        /Dx XYPair 0 get def
        /Dy XYPair 1 get def
      } if
      nInters 2 gt {
        /XYPair Inters 2 get def
        /Ex XYPair 0 get def
        /Ey XYPair 1 get def
      } if
      nInters 3 gt {
        /XYPair Inters 3 get def
        /Fx XYPair 0 get def
        /Fy XYPair 1 get def
      } if
    ){#5}
    \pnode(! Dx Dy){#6}
    \pnode(! Ex Ey){#7}
    \pnode(! Fx Fy){#8}
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
    \Pst@ManageParamList{#7}%
    \Pst@ManageParamList{#8}%
  \endgroup%
}%
%
%% \pstGeneralConicInter[Options]{a,b,c,d,e,f}{a',b',c',d',e',f'}{C}{D}{E}{F}
%% Get the most four intersections $C$, $D$, $E$ and $F$ of the General Conic $ax^2+bxy+cy^2+dx+ey+f=0$ and $a'x^2+b'xy+c'y^2+d'x+e'y+f'=0$.
%
%% 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 -> [input] the coefficents of the quadratic curve equation, with six numbers $a',b',c',d',e',f'$ joined with comma.
%% #4 -> [output] the first intersection node name
%% #5 -> [output] the second intersection node name
%% #6 -> [output] the third intersection node name
%% #7 -> [output] the fourth intersection node name
\def\pstGeneralConicInter{\@ifnextchar[\Pst@GeneralConicInter{\Pst@GeneralConicInter[]}}
\def\Pst@GeneralConicInter[#1]#2#3#4#5#6#7{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pstParseArg{CurveCoef}{a,b,c,d,e,f}{#2}
    \pstParseArg{CurveCoef}{A,B,C,D,E,F}{#3}
    \pnode(!
      % Conic ax^2+bxy+cy^2+dx+ey+f=0
      \CurveCoefa /Ca ED
      \CurveCoefb /Cb ED
      \CurveCoefc /Cc ED
      \CurveCoefd /Cd ED
      \CurveCoefe /Ce ED
      \CurveCoeff /Cf ED
      % Conic a'x^2+b'xy+c'y^2+d'x+e'y+f'=0
      \CurveCoefA /CA ED
      \CurveCoefB /CB ED
      \CurveCoefC /CC ED
      \CurveCoefD /CD ED
      \CurveCoefE /CE ED
      \CurveCoefF /CF ED
      tx@EcldDict begin Ca Cb Cc Cd Ce Cf CA CB CC CD CE CF ConicInter end
      /nInters ED /Inters ED
      nInters 0 gt {
        /XYPair Inters 0 get def
        XYPair 0 get XYPair 1 get
      } {
        0 0
      } ifelse
      /Dx 0 def /Dy 0 def
      /Ex 0 def /Ey 0 def
      /Fx 0 def /Fy 0 def
      nInters 1 gt {
        /XYPair Inters 1 get def
        /Dx XYPair 0 get def
        /Dy XYPair 1 get def
      } if
      nInters 2 gt {
        /XYPair Inters 2 get def
        /Ex XYPair 0 get def
        /Ey XYPair 1 get def
      } if
      nInters 3 gt {
        /XYPair Inters 3 get def
        /Fx XYPair 0 get def
        /Fy XYPair 1 get def
      } if
    ){#4}
    \pnode(! Dx Dy){#5}
    \pnode(! Ex Ey){#6}
    \pnode(! Fx Fy){#7}
    \Pst@ManageParamList{#4}%
    \Pst@ManageParamList{#5}%
    \Pst@ManageParamList{#6}%
    \Pst@ManageParamList{#7}%
  \endgroup%
}%
%
%% \pstGeneralConicTangentLine[Options]{A}{a,b,c,d,e,f}{B}
%% Get the tangent line through point $A% on the General Conic $ax^2+bxy+cy^2+dx+ey+f=0$.
%
%% Parameters:
%% #1 -> options
%% #2 -> [input] the point $A$ on the conic.
%% #3 -> [input] the coefficents of the quadratic curve equation, with six numbers $a,b,c,d,e,f$ joined with comma.
%% #4 -> [output] the node name $B$ on the tangent line.
\def\pstGeneralConicTangentLine{\@ifnextchar[\Pst@GeneralConicTangentLine{\Pst@GeneralConicTangentLine[]}}
\def\Pst@GeneralConicTangentLine[#1]#2#3#4{%
  \begingroup
    \@InitListMng %
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempA%
    \pstParseArg{CurveCoef}{a,b,c,d,e,f}{#3}
    \pnode(!
      % Conic ax^2+bxy+cy^2+dx+ey+f=0
      \CurveCoefa /Ca ED
      \CurveCoefb /Cb ED
      \CurveCoefc /Cc ED
      \CurveCoefd /Cd ED
      \CurveCoefe /Ce ED
      \CurveCoeff /Cf ED
      \pst@tempA \tx@UserCoor /Ay ED /Ax ED
      Ca Ax mul Ax mul
      Cb Ax mul Ay mul add
      Cc Ay mul Ay mul add
      Cd Ax mul add
      Ce Ay mul add
      Cf add abs 1E-5 lt {
        % axx_A+b(x_Ay+xy_A)/2+cy_Ay+d(x_A+x)/2+e(y_A+y)/2+f=0
        /LA Ca Ax mul Cb Ay mul 2 div add Cd 2 div add def
        /LB Cc Ay mul Cb Ax mul 2 div add Ce 2 div add def
        /LC Cd Ax mul 2 div Ce Ay mul 2 div add Cf add def
        LB abs 1E-5 lt {
          Ax Ay 1 add
        } {
          Ax 1 add
          LA Ax 1 add mul LC add LB div neg
        } ifelse
      } {
        0 0
      } ifelse
    ){#4}
    \Pst@ManageParamList{#4}%
  \endgroup%
}%
%
%% \pstGeneralConicTangentChord[Options]{T}{a,b,c,d,e,f}{A}{B}
%% Get the tangent line through point $T% out of the General Conic $ax^2+bxy+cy^2+dx+ey+f=0$,
%% and output the tangent nodes A and B.
%
%% Parameters:
%% #1 -> options
%% #2 -> [input] the point $A$ on the conic.
%% #3 -> [input] the coefficents of the quadratic curve equation, with six numbers $a,b,c,d,e,f$ joined with comma.
%% #4 -> [output] the node name $A$ on the tangent chord.
%% #5 -> [output] the node name $B$ on the tangent chord.
\def\pstGeneralConicTangentChord{\@ifnextchar[\Pst@GeneralConicTangentChord{\Pst@GeneralConicTangentChord[]}}
\def\Pst@GeneralConicTangentChord[#1]#2#3#4#5{%
  \begingroup
    \psset{#1}%
    \pst@getcoor{#2}\pst@tempT%
    \pstParseArg{CurveCoef}{a,b,c,d,e,f}{#3}
    \pnode(!
      % Conic ax^2+bxy+cy^2+dx+ey+f=0
      \CurveCoefa /Ca ED
      \CurveCoefb /Cb ED
      \CurveCoefc /Cc ED
      \CurveCoefd /Cd ED
      \CurveCoefe /Ce ED
      \CurveCoeff /Cf ED
      \pst@tempT \tx@UserCoor /Ty ED /Tx ED
      Ca Tx mul Tx mul
      Cb Tx mul Ty mul add
      Cc Ty mul Ty mul add
      Cd Tx mul add
      Ce Ty mul add
      Cf add abs 1E-5 gt {
        % axx_T+b(x_Ty+xy_T)/2+cy_Ty+d(x_T+x)/2+e(y_T+y)/2+f=0
        /LA Ca Tx mul Cb Ty mul 2 div add Cd 2 div add def
        /LB Cc Ty mul Cb Tx mul 2 div add Ce 2 div add def
        /LC Cd Tx mul 2 div Ce Ty mul 2 div add Cf add def
        LB abs 1E-5 lt {
          LC LA div neg Ty 1 add
          LC LA div neg Ty 1 sub /By ED /Bx ED
        } {
          Tx 1 add LA Tx 1 add mul LC add LB div neg
          Tx 1 sub LA Tx 1 sub mul LC add LB div neg /By ED /Bx ED
        } ifelse
      } {
        0 0 0 0 /By ED /Bx ED
      } ifelse
    ){Pst@GeneralConicTCA}
    \pnode(! Bx By){Pst@GeneralConicTCB}
    \pstGeneralConicLineInter{Pst@GeneralConicTCA}{Pst@GeneralConicTCB}{#3}{#4}{#5}
  \endgroup%
}%
%
\catcode`\@=\PstAtCode\relax
%
\endinput
%% END: pst-euclide.tex
%
