% tkz-tools-eu-math.tex
% Copyright 2011-2026  Alain Matthes
% SPDX-License-Identifier: LPPL-1.3c
% Maintainer: Alain Matthes

\typeout{2026/01/25 5.13c tkz-tools-eu-math.tex}
\makeatletter
%<-------------------------------------------------------------------------->
% \tkzpointnormalised#
% tkzCalcLength
% \tkzGetLength
% \tkzpttocm
% \tkzcmtopt
% \tkzFindSlope
% option xfp

%  \tkzpointnormalised    normalise un point A-->A' tq ||v(OA')=1||
% Ã©quivalent de \pgfpointnormalised avec fp
% example
% \tkzpointnormalised{%
% \pgfpointdiff{\pgfpointanchor{A}{center}}
%              {\pgfpointanchor{B}{center}}}

% or
% \pgf@x=1 cm
% \pgf@y=12 cm
% \tkzpointnormalised{}
%<--------------------------------------------------------------------------
\def\tkzpointnormalised#1{%
\pgf@process{#1}%
\edef\tkz@den{\fpeval{sqrt((\pgf@x)^2+(\pgf@y)^2)}}
\edef\tkz@coordx{\fpeval{\pgf@x/\tkz@den}}
\edef\tkz@coordx{\fpeval{round(\tkz@coordx,5)}}
\edef\tkz@coordy{\fpeval{\pgf@y/\tkz@den}}
\edef\tkz@coordy{\fpeval{round(\tkz@coordy,5)}}
\pgf@x = \tkz@coordx pt
\pgf@y = \tkz@coordy pt
}
%<-------------------------------------------------------------------------->
% restaure and save length
\def\tkz@save@length{\global\let\tkz@temp@length\tkzLengthResult}%
\def\tkz@restore@length{\global\let\tkzLengthResult\tkz@temp@length }%
%<-------------------------------------------------------------------------->
%    \tkzCalcLength      Distance entre deux points en pt ou en cm  avec xfp
% \veclen mais avec fp
%  option cm le résultat est en cm sinon en pt with cm=false
%<-------------------------------------------------------------------------->
\pgfkeys{tkzcalclen/.cd,
       cm/.is if         = tkzLengthIncm,
       cm/.default       = true,
       cm                = true}

\def\tkzCalcLength{\pgfutil@ifnextchar[{\tkz@CalcLength}{\tkz@CalcLength[]}}
\def\tkz@CalcLength[#1](#2,#3){%
%\pgfkeys{tkzcalclen/.cd, cm = true}
\pgfqkeys{/tkzcalclen}{#1}%
\begingroup
\tkz@@CalcLength(#2,#3){tkzLengthResult}
\iftkzLengthIncm
   \pgfmathparse{\tkzLengthResult pt/1cm}
   \edef\tkz@xfpMathLen{\fpeval{round(\pgfmathresult,6)}}
   \global\let\tkzLengthResult\tkz@xfpMathLen
\fi
\endgroup
}%
\def\tkz@@CalcLength(#1,#2)#3{%
\pgfpointdiff{\pgfpointanchor{#1}{center}}%
             {\pgfpointanchor{#2}{center}}%
\edef\tkz@xfpMathLen{\fpeval{sqrt((\pgf@x)^2+(\pgf@y)^2)}}
\edef\tkz@xfpMathLen{\fpeval{round(\tkz@xfpMathLen,6)}}
\global\expandafter\edef\csname #3\endcsname{\tkz@xfpMathLen}
}
\def\tkz@@CalcLengthcm(#1,#2)#3{%
\pgfpointdiff{\pgfpointanchor{#1}{center}}%
             {\pgfpointanchor{#2}{center}}%
\edef\tkz@xfpMathLen{\fpeval{sqrt((\pgf@x)^2+(\pgf@y)^2)}}
\edef\tkz@xfpMathLen{\fpeval{round(\tkz@xfpMathLen/28.45274,6)}}
\global\expandafter\edef\csname #3\endcsname{\tkz@xfpMathLen}
}
%<-------------------------------------------------------------------------->
\def\tkzGetLength#1{%
\global\expandafter\edef\csname #1\endcsname{\tkzLengthResult}}
%<-------------------------------------------------------------------------->
%     \tkzpttocm  passage de pt   cm div par 28.45274
%<-------------------------------------------------------------------------->
\def\tkzpttocm(#1)#2{%
\begingroup
  \pgfmathparse{#1/1cm}
  \edef\tkz@mathresult{\fpeval{round(\pgfmathresult,5)}}
  \global\let\tkz@mathresult\tkz@mathresult
  \global\expandafter\edef\csname #2\endcsname{\tkz@mathresult}%
\endgroup
}%
%<-------------------------------------------------------------------------->
%     \tkzcmtopt  passage de cm   pt mul par 28.45274
%<--------------------------------------------------------------------------
\def\tkzcmtopt(#1)#2{%
\begingroup
   \pgfmathparse{#1*1cm}
  \edef\tkz@mathresult{\fpeval{round(\pgfmathresult,5)}}
  \global\let\tkz@mathresult\tkz@mathresult
  \global\expandafter\edef\csname #2\endcsname{\tkz@mathresult}%
\endgroup
}%

%  Schrodinger's cat idea 03/01/20
\tikzset{veclen/.code={%
\pgfmathdeclarefunction*{veclen}{2}{%
\begingroup%
    \pgfmath@x##1pt\relax%
    \pgfmath@y##2pt\relax%
    \edef\tkz@xfpMathLen{\fpeval{sqrt((\pgf@x)^2+(\pgf@y)^2)}}
    \pgfmath@returnone\tkz@xfpMathLen pt%
\endgroup%
}}}%
%<---------------------------------------------------------–>
\def\tkzSwapPoints(#1,#2){
  \pgfnodealias{tkzPointTmp}{#2}
   \pgfnodealias{#2}{#1}
  \pgfnodealias{#1}{tkzPointTmp}}
%<---------------------------------------------------------–>
\def\tkzPermute(#1,#2,#3){
\tkzURotateWithNodes(#1,#3,#2)(#3)  \tkzGetPoint{tkzpt}
\tkzURotateWithNodes(#1,#2,#3)(#2) \tkzGetPoint{#2}
\tkzSwapPoints(tkzpt,#3)}
%<---------------------------------------------------------–>
\def\tkzDotProduct(#1,#2,#3){%
\begingroup
\pgfextractx{\pgf@x}{\pgfpointanchor{#1}{center}}%
\pgfextracty{\pgf@y}{\pgfpointanchor{#1}{center}}%
\tkz@ax\pgf@x%
\tkz@ay\pgf@y%
\pgfextractx{\pgf@x}{\pgfpointanchor{#2}{center}}%
\pgfextracty{\pgf@y}{\pgfpointanchor{#2}{center}}
\tkz@bx\pgf@x%
\tkz@by\pgf@y%
\pgfextractx{\pgf@x}{\pgfpointanchor{#3}{center}}%
\pgfextracty{\pgf@y}{\pgfpointanchor{#3}{center}}%
\tkz@cx\pgf@x%
\tkz@cy\pgf@y%
\edef\tkz@@dotprod{\fpeval{round(((\tkz@bx-\tkz@ax)*(\tkz@cx-\tkz@ax)+(\tkz@by-\tkz@ay)*(\tkz@cy-\tkz@ay))/(809.55841),5)}}
\global\let\tkzMathResult\tkz@@dotprod
\endgroup}
%<---------------------------------------------------------–>
 \def\tkzGetResult#1{%
   \global\expandafter\edef\csname #1\endcsname{\tkzMathResult}}
%<---------------------------------------------------------–>
% #1,#2 and #3 aligned
\def\tkzIsLinear(#1,#2,#3){%
\begingroup
\tkz@@CalcLengthcm(#1,#2){tkz@la}
\tkz@@CalcLengthcm(#1,#3){tkz@lb}
\tkzDotProduct(#1,#2,#3)
\edef\tkzResult{\fpeval{abs(\tkzMathResult)-(\tkz@la)*(\tkz@lb)}}
\ifdim \tkzResult pt < 0.01 pt\relax%
\global\tkzLineartrue
\else
\global\tkzLinearfalse
\fi
\endgroup
}
%<---------------------------------------------------------–>
% syntax : vec(#2,#1) ortho vec(#3,#1)
\def\tkzIsOrtho(#1,#2,#3){%
\begingroup
\tkzDotProduct(#1,#2,#3)
\edef\tkzResult{\fpeval{abs(\tkzMathResult)}}
\ifdim \tkzResult pt < 1 pt\relax%
\global\tkzOrthotrue
\else
\global\tkzOrthofalse
\fi
\endgroup
}
%<---------------------------------------------------------–>
%<---------------------------------------------------------–>
% \tkzPowerCircle(M)(O,A) --> OM^2-OA^2
\def\tkzPowerCircle(#1)(#2,#3){%
\begingroup
\tkz@@CalcLengthcm(#2,#3){tkz@ra}
\tkz@@CalcLengthcm(#1,#2){tkz@om}
\gdef\tkzMathResult{\fpeval{round(\tkz@om*\tkz@om -\tkz@ra*\tkz@ra,5)}}
\endgroup
}
%<---------------------------------------------------------–>
\def\tkzDefRadicalAxis(#1,#2)(#3,#4){%
\begingroup
\tkz@@CalcLengthcm(#1,#3){tkz@d}
\tkz@@CalcLengthcm(#1,#2){tkz@ra}
\tkz@@CalcLengthcm(#3,#4){tkz@rb}
\edef\tkzMathResult{\fpeval{\tkz@d-(\tkz@ra+\tkz@rb)}}
\edef\tkzMathResultb{\fpeval{abs(\tkz@d-(\tkz@ra+\tkz@rb))}}
\edef\tkzMathResultc{\fpeval{abs(\tkz@d-abs(\tkz@ra-\tkz@rb))}}
\ifdim \tkzMathResultc pt < 0.1 pt\relax%
 \tkzURotateAngle(#2,90)(#3) \tkzGetPoint{tkzFirstPointResult}
  \tkzURotateAngle(#2,-90)(#3) \tkzGetPoint{tkzSecondPointResult}
\else
\ifdim \tkzMathResultb pt < 0.1 pt\relax%
 \tkzURotateAngle(#2,90)(#3) \tkzGetPoint{tkzFirstPointResult}
  \tkzURotateAngle(#2,-90)(#3) \tkzGetPoint{tkzSecondPointResult}
  \else
\ifdim \tkzMathResult pt > 1 pt\relax%
  \tkzURotateAngle(#1,60)(#3)    \tkzGetPoint{tkz@aux}
  \tkzInterCC(#1,#2)(tkz@aux,#1) \tkzGetPoints{tkz@pta}{tkz@ptb}
  \tkzInterCC(#3,#4)(tkz@aux,#1) \tkzGetPoints{tkz@ptc}{tkz@ptd}
  \tkzInterLL(tkz@pta,tkz@ptb)(tkz@ptc,tkz@ptd) \tkzGetPoint{tkz@pta}
  \tkzUProjection(#1,#3)(tkz@pta)  \tkzGetPoint{tkz@ptb}
  \pgfnodealias{tkzSecondPointResult}{tkz@ptb}
  \pgfnodealias{tkzFirstPointResult}{tkz@pta}
\else
\tkzInterCCR(#1,\tkz@ra)(#3,\tkz@rb){tkzFirstPointResult}{tkzSecondPointResult}
\fi
\fi
\fi
\endgroup
}
\def\tkzmathrotatepointaround#1#2#3{%
  \pgf@process{%
    \pgf@process{#1}%
    \pgf@xc=\pgf@x%
    \pgf@yc=\pgf@y%
    \pgf@process{#2}%
    \pgf@xa\pgf@x%
    \pgf@ya\pgf@y%
    \pgf@xb\pgf@x%
    \pgf@yb\pgf@y%
    \pgf@x=\pgf@xc%
    \pgf@y=\pgf@yc%
    \advance\pgf@x-\pgf@xa%
    \advance\pgf@y-\pgf@ya%
    \pgfmathsetmacro\angle{#3}%
    \mathSin{\mathRad{\angle}}%
    \let\sineangle\pgfmathresult%
    \mathCos{\mathRad{\angle}}%
    \let\cosineangle\pgfmathresult%
    \pgf@xa\cosineangle\pgf@x%
    \advance\pgf@xa-\sineangle\pgf@y%
    \pgf@ya\sineangle\pgf@x%
    \advance\pgf@ya\cosineangle\pgf@y%
    \pgf@x\pgf@xb%
    \pgf@y\pgf@yb%
    \advance\pgf@x\pgf@xa%
    \advance\pgf@y\pgf@ya%
  }%
}
\makeatother
\endinput