3

The initial code is as follows: the idea is to avoid the "dimension too large" error by temporarily modifying the veclen macro

\documentclass{standalone} 
\usepackage{tkz-euclide}

\begin{document} % Schrodinger's cat idea 03/01/20 \makeatletter \tikzset{xfp/.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% }}}% \makeatother

\begin{tikzpicture}[scale=1] \tkzDefPoint(0,0){O} \tkzDefPoint(2.5,0){N} \tkzDefPoint(-4.2,0.5){M} \tkzDefPointByrotation=center O angle 30 \tkzGetPoint{B} \tkzDefPointByrotation=center O angle -50 \tkzGetPoint{A} \tkzInterLCcommon=B(O,B) \tkzGetFirstPoint{C} \tkzInterLCcommon=A(O,A) \tkzGetFirstPoint{A'} \tkzDrawSegments(A,C M,A M,B A,B) \tkzDrawCircle(O,N) % \tkzMarkAnglemkpos=.2, size=1.2 % Latex Error: ./testlua2.tex:32 Dimension too large. \begin{scope}[xfp] \tkzMarkAnglemkpos=.2, size=1.2 \end{scope} \tkzDrawPoints(O, A, B, M, B, C, A') \tkzLabelPointsright \tkzLabelPointsabove left \tkzLabelPointbelow left{$A'$} \end{tikzpicture} \end{document}

enter image description here

Now I try to use lua like this:

\documentclass{standalone} 
\usepackage{tkz-euclide}

\begin{document} % Schrodinger's cat idea 03/01/20 \makeatletter \tikzset{lua/.code={% \pgfmathdeclarefunction*{veclen}{2}{% \begingroup% \pgfmath@x##1pt\relax% \pgfmath@y##2pt\relax% \pgf@xa=\pgf@x% \pgf@ya=\pgf@y% \edef\tkz@temp@xa{\pgfmath@tonumber{\pgf@xa}}% \strip@pt ?? \edef\tkz@temp@ya{\pgfmath@tonumber{\pgf@ya}}% \edef\tkz@xfpMathLen{\directlua{tex.print(math.sqrt((\tkz@temp@xa)^2+(\tkz@temp@ya)^2))}} % \edef\tkz@xfpMathLen{\fpeval{round(\tkz@xfpMathLen,6)}} % with this line I get a result \pgfmath@returnone\tkz@xfpMathLen pt% \endgroup% }}}% \makeatother

\begin{tikzpicture}[scale=1] \tkzDefPoint(0,0){O} \tkzDefPoint(2.5,0){N} \tkzDefPoint(-4.2,0.5){M} \tkzDefPointByrotation=center O angle 30 \tkzGetPoint{B} \tkzDefPointByrotation=center O angle -50 \tkzGetPoint{A} \tkzInterLCcommon=B(O,B) \tkzGetFirstPoint{C} \tkzInterLCcommon=A(O,A) \tkzGetFirstPoint{A'} \tkzDrawSegments(A,C M,A M,B A,B) \tkzDrawCircle(O,N) % \tkzMarkAnglemkpos=.2, size=1.2 % Latex Error: ./testlua2.tex:32 Dimension too large. \begin{scope}[lua] \tkzMarkAnglemkpos=.2, size=1.2 \end{scope} \tkzDrawPoints(O, A, B, M, B, C, A') \tkzLabelPointsright \tkzLabelPointsabove left \tkzLabelPointbelow left{$A'$} \end{tikzpicture} \end{document}

but I get the following error: ! Illegal unit of measure (pt inserted). This error disappears if I use:

\edef\tkz@xfpMathLen{\fpeval{round(\tkz@xfpMathLen,6)}}

I must admit that I don't understand what is going on. How to avoid this mistake properly?

In order to convert a dimension into a number I know two methods: \pgfmath@tonumber \strip@pt. I have tried both without success. I don't know if that's the problem.

Alain Matthes
  • 95,075
  • The last computation returns 9.4868329805051e-05. You have to tell Lua to return a number not in exponential form. – egreg Jan 09 '23 at 22:17
  • 2
    something like tex.print(string.format('\@percentchar.12f',math.sqrt(... should work (increase the 12 if you need more digits.) – Ulrike Fischer Jan 09 '23 at 23:03
  • @egreg Thanks. I had asked how to do it herei link but it is very heavy to use. tex.print(string.format("\csstring\%f", r)) – Alain Matthes Jan 09 '23 at 23:06
  • You can always make a wrapper function in Lua. Something like function print_float(x) tex.print(string.format(...) end -- side note, to understand what's going on just print out things with e.g. \typeout which is sufficient in this case. – user202729 Jan 10 '23 at 02:12
  • @egreg What is the most effective way to find that the last computation returns 9.4868329805051e-05. i work with the package trace but I get too much informations. – Alain Matthes Jan 10 '23 at 10:33
  • 2
    @AlainMatthes I just added \show\tkz@xfpMathLen after the \edef and kept hitting return until the error showed. – egreg Jan 10 '23 at 10:36

2 Answers2

3

One of the computations returns 9.4868329805051e-05.

You have to tell Lua to always return numbers not in exponential form (I'm sure there's a way).

In the meantime doing

\edef\tkz@xfpMathLen{\fpeval{\directlua{tex.print(math.sqrt((\tkz@temp@xa)^2+(\tkz@temp@ya)^2))}}}

works around the issue, because \fpeval normalizes the output.

enter image description here

A possibly better way is to define a macro for “Pythagorean addition”:

\documentclass[border=4]{standalone} 
\usepackage{tkz-euclide}
\usepackage{iftex}

\begin{document} % Schrodinger's cat idea 03/01/20 \makeatletter

\ifluatex \newcommand{\tkz@pythadd}[2]{% \directlua{% tex.print(string.format('@percentchar.12f',math.sqrt((#1)^2+(#2)^2)))% }% } \else \newcommand{\tkz@pythadd}[2]{% \fpeval{(#1)^2+(#2)^2}% } \fi

\tikzset{lua/.code={% \pgfmathdeclarefunction*{veclen}{2}{% \begingroup% \pgfmath@x##1pt\relax% \pgfmath@y##2pt\relax% \pgf@xa=\pgf@x% \pgf@ya=\pgf@y% \edef\tkz@temp@xa{\pgfmath@tonumber{\pgf@xa}}% \strip@pt ?? \edef\tkz@temp@ya{\pgfmath@tonumber{\pgf@ya}}% \edef\tkz@xfpMathLen{\tkz@pythadd{\tkz@temp@xa}{\tkz@temp@ya}}% % \edef\tkz@xfpMathLen{\fpeval{round(\tkz@xfpMathLen,6)}} % with this line I get a result \pgfmath@returnone\tkz@xfpMathLen pt% \endgroup% }}}% \makeatother

\begin{tikzpicture}[scale=1] \tkzDefPoint(0,0){O} \tkzDefPoint(2.5,0){N} \tkzDefPoint(-4.2,0.5){M} \tkzDefPointByrotation=center O angle 30 \tkzGetPoint{B} \tkzDefPointByrotation=center O angle -50 \tkzGetPoint{A} \tkzInterLCcommon=B(O,B) \tkzGetFirstPoint{C} \tkzInterLCcommon=A(O,A) \tkzGetFirstPoint{A'} \tkzDrawSegments(A,C M,A M,B A,B) \tkzDrawCircle(O,N) % \tkzMarkAnglemkpos=.2, size=1.2 % Latex Error: ./testlua2.tex:32 Dimension too large. \begin{scope}[lua] \tkzMarkAnglemkpos=.2, size=1.2 \end{scope} \tkzDrawPoints(O, A, B, M, B, C, A') \tkzLabelPointsright \tkzLabelPointsabove left \tkzLabelPointbelow left{$A'$} \end{tikzpicture} \end{document}

egreg
  • 1,121,712
  • Tanks the code is very clear like this. I have a lua option for my package and if it is used then compiling with lualatex is required and I load only the modules written for lua. – Alain Matthes Jan 10 '23 at 15:52
1

Here is a small summary of the different ideas that have been proposed

A) egreg found out where the problem was coming from and a solution based on my workaround

\edef\tkz@xfpMathLen{\fpeval{\directlua{tex.print(math.sqrt((\tkz@temp@xa)^2+(\tkz@temp@ya)^2))}}}

B) The wrapper function is a nice idea from user202729

 \RequirePackage{luacode}

\begin{luacode} function print_decimal(num) return tex.print(string.format("\csstring%f", num)) end \end{luacode}

then

\tikzset{lua/.code={%
 \pgfmathdeclarefunction*{veclen}{2}{%
 \begingroup%
  \pgfmath@x##1pt\relax%
  \pgfmath@y##2pt\relax%
  \pgf@xa=\pgf@x%
  \pgf@ya=\pgf@y%
  \edef\tkz@temp@xa{\pgfmath@tonumber{\pgf@xa}}% \strip@pt ??
  \edef\tkz@temp@ya{\pgfmath@tonumber{\pgf@ya}}%
  \edef\tkz@tmp{math.sqrt((\tkz@temp@xa)^2+(\tkz@temp@ya)^2)}
  \edef\tkz@xfpMathLen{\directlua{print_decimal(\tkz@tmp)}}
  \pgfmath@returnone\tkz@xfpMathLen pt%
\endgroup%
}}}%

and

\begin{scope}[lua]
     \tkzMarkAngle[mkpos=.2, size=1.2](C,A,M)
 \end{scope}

C) There are several possibilities to convert a number with an exponential writing to a decimal writing.
Ulrike Fischer proposed

tex.print(string.format('\@percentchar.12f',math.sqrt(...

I proposed an idea of Henri Menke with

   tex.print(string.format("\csstring\%f",...))

Here is !

Alain Matthes
  • 95,075