Sagittarius Rover
Sagittarius Rover
这家伙很懒,什么也没写!

注册于 3年前

回答
417
文章
0
关注者
15

Thanks to Jasper Habicht!


最初的尝试 version1

一个可能的答案如下:

\documentclass{article}
\usepackage{libertinus-otf}
\usepackage[landscape]{geometry}
\usepackage{tabularray}
\UseTblrLibrary{functional, tikz}
\IgnoreSpacesOn
\tlNew \gTikzPathsTlpositive
\tlNew \gTikzPathsTlnegative
\clistNew \lCurrentRowDataClist
\prgNewFunction \RowMax {m} {%
    \prgReturn {\fpEval {max(#1)}}
}
\prgNewFunction \RowMin {m} {%
    \prgReturn {\fpEval {min(#1)}}
}
\prgNewFunction \DrawDataBar { m m } {%
    \tlClear \gTikzPathsTl%
    \intStepOneInline {#1} {\arabic{rowcount}} {%
        \clistSet \lCurrentRowDataClist {}
        \intStepOneInline {#2} {\arabic{colcount}} {%
            \clistPutRight \lCurrentRowDataClist {\cellGetText {##1} {####1} }
        }
        \intStepOneInline {#2} {\arabic{colcount}} {%
            \fpSet \lTmpaFp {\RowMax{\expValue \lCurrentRowDataClist}}
            \fpSet \lTmpbFp {\RowMin{\expValue \lCurrentRowDataClist}}
            \fpSet \lTmpcFp {\cellGetText {##1} {####1} }
            \fpSet \lTmpiFp {%
                \fpMathDiv {\fpUse \lTmpcFp} {\fpUse \lTmpaFp}
            }%
            \fpSet \lTmpjFp {%
                \fpMathDiv {\fpUse \lTmpcFp} {\fpUse \lTmpbFp}
            }%
            \fpCompareTF {\lTmpaFp} > {\cZeroFp}{
                \tlPutRight \gTikzPathsTlpositive {%
                    \evalWhole {%
                        ([shift={(.5pt,.5pt)}]##1-####1.south~west) rectangle 
                        ([shift={(-.5pt,-.5pt)}]$(##1-####1.north~west)!{\fpUse \lTmpiFp}!(##1-####1.north~east)$)
                    }%
                }%
            }{%
                \tlPutRight \gTikzPathsTlnegative {%
                    \evalWhole {%
                        ([shift={(-.5pt,-.5pt)}]##1-####1.north~east) rectangle 
                        ([shift={(.5pt,.5pt)}]$(##1-####1.south~east)!{\fpUse \lTmpjFp}!(##1-####1.south~west)$)
                    }%
                }%
            }
        }
    }
}
\IgnoreSpacesOff
\begin{document}

\begin{tblrtikzbelow}
   \fill [violet!80] \gTikzPathsTlpositive;
   \fill [magenta!80] \gTikzPathsTlnegative;
\end{tblrtikzbelow}
\begin{tblr}{
    colspec={*{5}{Q[c,3cm]}},
    hlines, vlines,
    row{1} = {bg=lightgray},
    process=\DrawDataBar{2}{1}
}
    Item1 & Item2 & Item3 & Item4 & Item5 \\
    1 & 2 & 3 & 4 & 5 \\
    6.5 & 5.4 & 4.3 & 3.2 & 2.1 \\
    -1 & -2 & -3 & -4 & -5 \\
    -6.5 & -5.4 & -4.3 & -3.2 & -2.1 \\
    0.5 & 1.5 & 2.5 & 3.5 & 4.5 \\
    -0.5 & -1.5 & -2.5 & -3.5 & -4.5 \\
    -5.5 & -6.5 & -7.5 & -8.5 & -9.5 \\
    -3.1 & -2.1 & -1.1 & -0.1 & -1.1 \\
    1 & 4 & 2 & 8 & 5 \\
    5.5 & 6.5 & 7.5 & 8.5 & 9.5 \\
\end{tblr}

\end{document}

image.png

由于我没想好关于「同一行内既有正数也有负数」应该如何绘制,因此\fpCompareTF的判断应该也有一定的修改空间...目前只支持全正/全负的同一行数字,且个人认为用户接口并不太友好...


Edit: 直接增加功能version2

增加了对于行内数字有正有负形式的支持:

\documentclass{article}
\usepackage{libertinus-otf}
\usepackage[landscape]{geometry}
\usepackage{tabularray}
\UseTblrLibrary{functional, tikz}
\IgnoreSpacesOn
\tlNew \gTikzPathsTlpositive
\tlNew \gTikzPathsTlnegative
\tlNew \gTikzPathsTlcrosspositive
\tlNew \gTikzPathsTlcrossnegative

\clistNew \lCurrentRowDataClist
\prgNewFunction \RowMax {m} {%
    \prgReturn {\fpEval {max(#1)}}
}
\prgNewFunction \RowMin {m} {%
    \prgReturn {\fpEval {min(#1)}}
}
\prgNewFunction \DrawDataBar { m m } {%
    \tlClear \gTikzPathsTl%
    \intStepOneInline {#1} {\arabic{rowcount}} {%
        \clistSet \lCurrentRowDataClist {}
        \intStepOneInline {#2} {\arabic{colcount}} {%
            \clistPutRight \lCurrentRowDataClist {\cellGetText {##1} {####1} }
        }
        \intStepOneInline {#2} {\arabic{colcount}} {%
            \fpSet \lTmpaFp {\RowMax{\expValue \lCurrentRowDataClist}}
            \fpSet \lTmpbFp {\RowMin{\expValue \lCurrentRowDataClist}}
            \fpSet \lTmpcFp {\cellGetText {##1} {####1} }
            \fpSet \lTmpiFp {%
                \fpMathDiv {\fpUse \lTmpcFp} {\fpUse \lTmpaFp}
            }%
            \fpSet \lTmpjFp {%
                \fpMathDiv {\fpUse \lTmpcFp} {\fpUse \lTmpbFp}
            }%
            \fpSet \lTmpkFp {%
                \fpEval {( 0 - \fpUse \lTmpbFp) / (\fpUse \lTmpaFp - \fpUse \lTmpbFp)}
            }%
            \fpSet \lTmppFp {%
                \fpEval {(\fpUse \lTmpcFp - \fpUse \lTmpbFp) / (\fpUse \lTmpaFp - \fpUse \lTmpbFp)}
            }%
            \fpCompareTF {\lTmpaFp} > {\cZeroFp}{
                \fpCompareTF {\lTmpbFp} > {\cZeroFp}{%
                    % case1: max>0 min>0
                    \tlPutRight \gTikzPathsTlpositive {%
                        \evalWhole {%
                            ([shift={(.5pt,.5pt)}]##1-####1.south~west) rectangle 
                            ([shift={(-.5pt,-.5pt)}]$(##1-####1.north~west)!{\fpUse \lTmpiFp}!(##1-####1.north~east)$)
                        }%
                    }%
                }{
                    % case2: max>0 min<0
                    \fpCompareTF {\lTmpcFp} < {\cZeroFp}{%
                    % 如果当前值比0小,则从「\lTmppFp到\lTmpkFp」
                        \tlPutRight \gTikzPathsTlcrossnegative {%
                            \evalWhole {%
                                ([shift={(.5pt,.5pt)}]$(##1-####1.south~west)!{\fpUse \lTmppFp}!(##1-####1.south~east)$) 
                                rectangle 
                                ([shift={(-.5pt,-.5pt)}]$(##1-####1.north~west)!{\fpUse \lTmpkFp}!(##1-####1.north~east)$)
                            }
                        }
                    }{%% 如果当前值比0大,则从「\lTmpkFp到\lTmppFp」
                        \tlPutRight \gTikzPathsTlcrosspositive {%
                        \evalWhole {%
                                ([shift={(.5pt,.5pt)}]$(##1-####1.south~west)!{\fpUse \lTmpkFp}!(##1-####1.south~east)$) 
                                rectangle 
                                ([shift={(-.5pt,.5pt)}]$(##1-####1.north~west)!{\fpUse \lTmppFp}!(##1-####1.north~east)$)
                            }
                        }
                    }
                }
            }{%
                % case3: max<0 min<0
                \tlPutRight \gTikzPathsTlnegative {%
                    \evalWhole {%
                        ([shift={(-.5pt,-.5pt)}]##1-####1.north~east) rectangle 
                        ([shift={(.5pt,.5pt)}]$(##1-####1.south~east)!{\fpUse \lTmpjFp}!(##1-####1.south~west)$)
                    }%
                }%
            }
        }
    }
}
\IgnoreSpacesOff
\begin{document}

\begin{tblrtikzbelow}
   \fill [violet!80] \gTikzPathsTlpositive;
   \fill [magenta!80] \gTikzPathsTlnegative;
   \fill [green!80] \gTikzPathsTlcrosspositive;
   \fill [cyan!80] \gTikzPathsTlcrossnegative;
\end{tblrtikzbelow}
\begin{tblr}{
    colspec={*{5}{Q[c,3cm]}},
    hlines, vlines,
    row{1} = {bg=lightgray},
    process=\DrawDataBar{2}{1}
}
    Item1 & Item2 & Item3 & Item4 & Item5 \\
    0.5 & 1.5 & 2.5 & 3.5 & 4.5 \\
    -1 & -2 & -3 & -4 & -5 \\
    -6.5 & -5.4 & -4.3 & -3.2 & -2.1 \\
    6.5 & -5.4 & 4.3 & -3.2 & 2.1 \\
    -0.5 & -1.5 & -2.5 & -3.5 & -4.5 \\
    -5.5 & -6.5 & -7.5 & -8.5 & -9.5 \\
    -1 & 2 & -3 & 4 & -5 \\
    -3.1 & -2.1 & -1.1 & 1 & -1.1 \\
    1 & 4 & 2 & 8 & 5 \\
    5.5 & 6.5 & 7.5 & 8.5 & 9.5 \\
\end{tblr}

\end{document}

image.png

嗯...但他目前也有缺点,似乎暂时缺少对填充的数字为「0」时的支持,同时个人觉得条件判断的逻辑写复杂了,代码仍然有很大的改进空间...

Re-Edit:version3

完善了条件逻辑...但好像也并不完善,优化了坐标点位的命名,补充对「0」这一边界点的支持:

\documentclass{article}
\usepackage{libertinus-otf}
\usepackage[landscape]{geometry}
\usepackage{tabularray}
\UseTblrLibrary{functional, tikz}
\IgnoreSpacesOn
\tlNew \gTikzPathsTlpositive
\tlNew \gTikzPathsTlnegative
\tlNew \gTikzPathsTlcrosspositive
\tlNew \gTikzPathsTlcrossnegative

\clistNew \lCurrentRowDataClist
\prgNewFunction \RowMax {m} {%
    \prgReturn {\fpEval {max(#1)}}
}
\prgNewFunction \RowMin {m} {%
    \prgReturn {\fpEval {min(#1)}}
}
\prgNewFunction \DrawDataBar { m m } {%
    \tlClear \gTikzPathsTl%
    \intStepOneInline {#1} {\arabic{rowcount}} {%
        \clistSet \lCurrentRowDataClist {}
        \intStepOneInline {#2} {\arabic{colcount}} {%
            \clistPutRight \lCurrentRowDataClist {\cellGetText {##1} {####1} }
        }
        \fpSet \lTmpmaxFp {\RowMax{\expValue \lCurrentRowDataClist}}
        \fpSet \lTmpminFp {\RowMin{\expValue \lCurrentRowDataClist}}
        \intStepOneInline {#2} {\arabic{colcount}} {%
            \fpSet \lTmpnowFp {\cellGetText {##1} {####1} }
            % cond1: min>0
            \fpCompareT {\lTmpminFp} > {\cZeroFp} {
                \fpSet \lTmpstartFp { \cZeroFp}
                \fpSet \lTmpendFp { \fpEval {( \lTmpnowFp - \cZeroFp  ) / ( \lTmpmaxFp - \cZeroFp ) }}
                \tlPutRight \gTikzPathsTlpositive {%
                    \evalWhole {%
                        ([shift={(.5pt,.5pt)}]$(##1-####1.south~west)!{\fpUse \lTmpstartFp}!(##1-####1.south~east)$) 
                        rectangle 
                        ([shift={(-.5pt,-.5pt)}]$(##1-####1.north~west)!{\fpUse \lTmpendFp}!(##1-####1.north~east)$)
                    }
                }
            }
            % cond2: max<0
            \fpCompareT {\lTmpmaxFp} < {\cZeroFp} {
                % \fpSet \lTmpstartFp {\fpEval {( \cZeroFp - \lTmpnowFp ) / ( \cZeroFp - \lTmpminFp ) }}% 好像有点不对称...
                \fpSet \lTmpstartFp {\fpEval {\cOneFp - ( \lTmpnowFp - \cZeroFp ) / ( \lTmpminFp - \cZeroFp ) }}
                \fpSet \lTmpendFp {\cOneFp}
                \tlPutRight \gTikzPathsTlnegative {%
                    \evalWhole {%
                        ([shift={(.5pt,.5pt)}]$(##1-####1.south~west)!{\fpUse \lTmpstartFp}!(##1-####1.south~east)$) 
                        rectangle 
                        ([shift={(-.5pt,-.5pt)}]$(##1-####1.north~west)!{\fpUse \lTmpendFp}!(##1-####1.north~east)$)
                    }
                }
            }
            % cond3: min < 0 < max 
            \fpCompareT {\lTmpminFp} < {\cZeroFp} {
                \fpCompareT {\lTmpmaxFp} > {\cZeroFp} {
                    %% cond3进入判断
                    \fpSet \lTmpzeroFp { \fpEval {( \cZeroFp - \lTmpminFp ) / ( \lTmpmaxFp - \lTmpminFp )}}
                    \fpSet \lTmppointFp {
                        \fpEval { ( \lTmpnowFp - \lTmpminFp ) / ( \lTmpmaxFp - \lTmpminFp ) }
                    }
                    \fpCompareTF {\lTmpnowFp} < {\cZeroFp} {
                        % 分类绘制
                            \tlPutRight \gTikzPathsTlcrossnegative {%
                            \evalWhole {%
                                ([shift={(.5pt,.5pt)}]$(##1-####1.south~west)!{\fpUse \lTmppointFp}!(##1-####1.south~east)$) 
                                rectangle 
                                ([shift={(-.5pt,-.5pt)}]$(##1-####1.north~west)!{\fpUse \lTmpzeroFp}!(##1-####1.north~east)$)
                            }
                        }
                    } {
                        \tlPutRight \gTikzPathsTlcrosspositive {%
                            \evalWhole {%
                                ([shift={(.5pt,.5pt)}]$(##1-####1.south~west)!{\fpUse \lTmpzeroFp}!(##1-####1.south~east)$) 
                                rectangle 
                                ([shift={(-.5pt,-.5pt)}]$(##1-####1.north~west)!{\fpUse \lTmppointFp}!(##1-####1.north~east)$)
                            }
                        }
                    }
                }
            }
        }
    }
}
\IgnoreSpacesOff
\begin{document}

\begin{tblrtikzbelow}
   \fill [violet!80] \gTikzPathsTlpositive;
   \fill [magenta!80] \gTikzPathsTlnegative;
   \fill [green!80] \gTikzPathsTlcrosspositive;
   \fill [cyan!80] \gTikzPathsTlcrossnegative;
\end{tblrtikzbelow}
\begin{tblr}{
    colspec={*{5}{Q[c,3cm]}},
    hlines, vlines, %stretch = 0,
    row{1} = {bg=lightgray,font=\bfseries\large},
    process=\DrawDataBar{2}{1}
}
    Item1 & Item2 & Item3 & Item4 & Item5 \\
    0.5 & 1.5 & 2.5 & 3.5 & 4.5 \\
    -1 & -2 & -3 & -4 & -5 \\
    -6.5 & -5.4 & -4.3 & -3.2 & -2.1 \\
    6.5 & -5.4 & 0 & -3.2 & 2.1 \\
    -0.5 & -1.5 & -8.5 & -3.5 & -4.5 \\
    -5.5 & -9.5 & -2.5 & -7.5 & -6.5\\
    -1 & 2 & -3 & 4 & -5 \\
    -3.1 & -2.1 & -1.1 & 1 & -1.1 \\
    1 & 4 & 2 & 8 & 5 \\
    5.5 & 6.5 & 7.5 & 8.5 & 9.5 \\
\end{tblr}

\end{document}

image.png

搜题找到答案

首先做题不在本提问的范围内,所以搜了下题:

搜题答案.pdf

在B站上面看到有些大佬们用画板来画。向请问下我们在 LaTeX 能比较容易地通过计算来画出来这些答案所对应的精确图形么?就比如下面题目中的第二问。

我更倾向于LaTeX更主要是用来「绘图」而非进行「遍历直线上的点、判断是否有交点」一类精确计算的;所以要想「画出来这些答案所对应的精确图形」,不妨 先画靶子再射箭 ,从答案入手。

问题2中对「点D」是没有任何显式限制的,所以由▲ADE确定的「点E」也是自由的,换言之,直线「BE/BN」也是自由的。考虑最后再画直线「BN」。

答案中有三个相关的可能情况,需要一一做排除

image.png

情况一:不存在这样的三角形,进而不存在「精确图形」

要绘制「大概成立的图2-1」,找个差不多的「M」点即可,此时▲FMN必定不是准确的等腰直角三角形。因此这里没必要画,略去。

情况二:考虑当「M(4,0)」的图2-2的情况:

\documentclass[border=5pt]{standalone}
\usepackage{tkz-base}
\usepackage{tkz-euclide}
\begin{document}
\begin{tikzpicture}
\tkzInit[xmin=-5,xmax=5,ymin=-3,ymax=4]
\tkzDrawX[noticks,thick]\tkzDrawY[noticks,right=2pt,thick]
\tkzDefPoints{0/0/O,-4/0/B,4/0/C,0/4/A,0/3/F}
\tkzDrawPolygon[thick](B,C,A)
\tkzDefPoint(4,0){M}
% 这里用▲FMN为等腰直角,用利用\tkzDefPointWith[orthogonal,K=-1]实现FM顺时针旋转90度来定位N点
\tkzDefPointWith[orthogonal,K=-1](F,M)
\tkzGetPoint{N}
\tkzDrawPolygon[thick](M,N,F)

\tkzDrawLine[add=1.2 and 1.5,thick](B,N)

\tkzDefPointBy[projection= onto O--F](N)
\tkzGetPoint{P}
\tkzDrawSegment[dashed,thick](N,P)

\tkzDrawPoints(O,F,M,N,B,C,A,P)
\tkzLabelPoints[above left](O)
\tkzLabelPoints[above right](C)
\tkzLabelPoints[below](B,N,M)
\tkzLabelPoints[right](P)
\tkzLabelPoints[left](A,F)
\end{tikzpicture}
\end{document}

image.png

情况三:考虑当「M(-7,0)」的图2-3的情况:

\documentclass[border=5pt]{standalone}
\usepackage{tkz-base}
\usepackage{tkz-euclide}
\begin{document}
\begin{tikzpicture}
\tkzInit[xmin=-8,xmax=5,ymin=-3,ymax=4]
\tkzDrawX[noticks,thick]\tkzDrawY[noticks,right=2pt,thick]
\tkzDefPoints{0/0/O,-4/0/B,4/0/C,0/4/A,0/3/F}
\tkzDrawPolygon[thick](B,C,A)
\tkzDefPoint(-7,0){M}
% 这里用▲FMN为等腰直角,用斜边FM以及\tkzDefTriangle[isosceles right]来定义等腰直角三角形确定点N
\tkzDefTriangle[isosceles right](F,M)
\tkzGetPoint{N}
\tkzDrawPolygon[thick](M,N,F)

\tkzDrawLine[add=1.2 and .5,thick](B,N)

\tkzDefPointBy[projection= onto O--F](N)
\tkzGetPoint{T}
\tkzDefPointBy[projection= onto O--B](N)
\tkzGetPoint{S}
\tkzDrawSegments[dashed,thick](N,T N,S)

\tkzDrawPoints(O,F,M,N,B,C,A,T,S)
\tkzLabelPoints[above left](O)
\tkzLabelPoints[above right](C)
\tkzLabelPoints[below](B,N,M)
\tkzLabelPoints[right](T,F)
\tkzLabelPoints[above](S)
\tkzLabelPoints[left](A)
\end{tikzpicture}
\end{document}

image.png

供参考。

不做解释了,最后一种是我认为的最佳实践

\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}
\usepackage{nicematrix}
\begin{document}
\begin{equation*}
\begin{bNiceArray}{ccc}[first-row,first-col]
   & \text{Col 1} & \text{Col 2} & \text{Col 3} \\
  \text{Row 1} & 1 & 2 & 3 \\
  \text{Row 2} & 4 & 5 & 6 \\
  \Hline
  \text{Row 3} & 7 & 8 & 9 \\
\end{bNiceArray}
\end{equation*}

\begin{equation*}
\begin{bNiceArray}{cc|[tikz=dashed,color=red]c}[first-row,first-col,margin]
   & \text{Col 1} & \text{Col 2} & \text{Col 3} \\
  \text{Row 1} & 1 & 2 & 3 \\
  \text{Row 2} & 4 & 5 & 6 \\
  \Hline
  \text{Row 3} & 7 & 8 & 9 \\
\end{bNiceArray}
\end{equation*}

\begin{equation*}
\begin{bNiceArray}{cc|[tikz=dashed]c}[first-row,first-col,margin]
   & \text{Col 1} & \text{Col 2} & \text{Col 3} \\
  \text{Row 1} & \Block[borders={bottom,right,tikz=dashed}]{2-2}{}
  1 & 2 & 3 \\
  \text{Row 2} & 4 & 5 & 6 \\
  \text{Row 3} & 7 & 8 &\Block[borders={left,top,tikz=dashed}]{1-1}{} 9 \\
\end{bNiceArray}
\end{equation*}

\begin{equation*}
\begin{bNiceArray}{cc|[tikz=dashed,color=violet]c}[first-row,first-col,margin]
   & \text{Col 1} & \text{Col 2} & \text{Col 3} \\
  \text{Row 1} & 1 & 2 & 3 \\
  \text{Row 2} & 4 & 5 & 6 \\
  \Hline[tikz=dashed,color=orange]
  \text{Row 3} & 7 & 8 & 9 \\
\end{bNiceArray}
\end{equation*}
\end{document}

image.png

代码要给完整,不要给别人增加负担。

\documentclass[fontset=fandol]{ctexart}
\usepackage{amsmath,amsfonts}
\usepackage{lipsum}
\begin{document}
\lipsum[1][1-3]
\begin{equation*}
       \text{单品加成率} =  (\text{销售单价} - \text{批发价}) / \text{批发价} \times 100\%
\end{equation*}
\lipsum[1][1-3]
\end{document}

image.png

  1. 请提供完整的可编译代码(从\documentclass开始到\end{document}结束)。
  2. 请补充当前代码的编译效果截图。如果有错误,请贴报错信息。
  3. 提供一个预期效果图示,仅有「排版图片 排版格式问题 图片」几个字谁能弄明白呢,并解释上面的「Excel页面」和「图表」具体是什么,与你的问题有何关系。

Claim:我不是太确定这样会不会有什么bug...

能够自动保持参数中的字母(a-z)为正体(即 \mathrm{a} 等)同时能够正确解释其他 LaTeX 指令(至少能够保证上下标以及 \bar 命令被正确解释)

但是对于\mathup吞的参数,只要没有过于神秘的希腊字母、花体字母一类的在ams框架下缺少的字体。这 似乎 是可行的。

\documentclass[fontset=fandol]{ctexart}
\usepackage{amsmath,amsfonts,amssymb}
\DeclareMathAlphabet{\mathup}{OT1}{\familydefault}{m}{n}
\begin{document}
\begin{tabular}{*{3}{c}}
\hline\hline
默认的效果 & 期望的结果 & 实际结果 \\
\hline
$p2_1/b11$ & $\mathrm{p}2_{1}/\mathrm{b}11$ & $\mathup{p2_1/b11}$ \\
\hline
$p\bar{6}m2$ & $\mathrm{p}\bar{6}\mathrm{m}2$ & $\mathup{p\bar{6}m2}$ \\
\hline
$x_1^n + \hat{y} - \sqrt{z}$ & $\mathrm{x}_1^{\mathrm{n}} + \hat{\mathrm{y}} - \sqrt{\mathrm{z}}$ & $\mathup{x_1^n + \hat{y} - \sqrt{z}}$ \\
\hline
$\sum_{n=1}^\infty \frac{1}{n^2}=\frac{\pi^2}{6}$ & $\mathrm{\sum_{n=1}^\infty \frac{1}{n^2}=\frac{\pi^2}{6}}$ & $\mathup{\sum_{n=1}^\infty \frac{1}{n^2}=\frac{\pi^2}{6}}$ \\
\hline\hline
\end{tabular}
\end{document}

image.png

先解决原始问题

image.png

注意

\tkzGetAngle(angleADG)

\tkzGetAngle{angleADG}

看文档的例子:

image.png

所以,你只要把\tkzGetAngle(angleADG)替换为\tkzGetAngle{angleADG}即可

\documentclass[border=5pt]{standalone}
\usepackage{tkz-euclide}

\begin{document}
    \begin{tikzpicture}
        
        % ===== 定义点 =====
        \tkzDefPoints{0/0/C, 4/0/E}
        \tkzDefTriangle[two angles=23 and 37](C,E)
        \tkzGetPoint{B}
        
        \tkzDefPointBy[rotation=center B angle -90](C)
        \tkzGetPoint{A}
        \tkzDefPointBy[rotation=center B angle 90](E)
        \tkzGetPoint{D}
        
        \tkzCalcLength(B,D)
        \tkzGetLength{BDlen} 
        \tkzDefPointWith[linear normed, K=\BDlen](B,A) 
        \tkzGetPoint{G}
        
        \tkzFindAngle(A,D,G)
        \tkzGetAngle{angleADG}%<-注意花括号
        \tkzDefPointBy[rotation=center B angle \angleADG](A)
        \tkzGetPoint{f}
        \tkzInterLL(B,f)(A,D)
        \tkzGetPoint{F}
        

        % ===== 绘制图形 =====
        \tkzDrawPolygon[thick](B,C,E)
        \tkzDrawSegments[thick](A,B D,B A,C D,E A,D D,G B,F G,F)
        
    \end{tikzpicture}
\end{document}

一个workaround:

如果只要用一次,那么也可以直接用\tkzAngleResult,这样可以不用再\tkzGetAngle多写一行...

image.png

\documentclass[border=5pt]{standalone}
\usepackage{tkz-euclide}
\begin{document}
    \begin{tikzpicture}[font=\small]
        % ===== 定义点 =====
        \tkzDefPoints{0/0/C, 4/0/E}
        \tkzDefTriangle[two angles=23 and 37](C,E)
        \tkzGetPoint{B}
        
        \tkzDefPointBy[rotation=center B angle -90](C)
        \tkzGetPoint{A}
        \tkzDefPointBy[rotation=center B angle 90](E)
        \tkzGetPoint{D}
        
        \tkzCalcLength(B,D)
        \tkzGetLength{BDlen} 
        \tkzDefPointWith[linear normed, K=\BDlen](B,A) 
        \tkzGetPoint{G}
        
        \tkzFindAngle(A,D,G)
        % \tkzGetAngle(angleADG)
        \tkzDefPointBy[rotation=center B angle \tkzAngleResult](A)
        \tkzGetPoint{f}
        \tkzInterLL(B,f)(A,D)
        \tkzGetPoint{F}
        

        % ===== 绘制图形 =====
        \tkzDrawPolygon[thick](B,C,E)
        \tkzDrawSegments[thick](A,B D,B A,C D,E A,D D,G B,F G,F)
    \end{tikzpicture}
\end{document}

image.png

差不多就是小学生找规律问题((^_^))

07 -> (7,0)
23 -> (3,2)
152 -> (2,5)

使用取模和向下取整的函数即可,规律是显然的。

第一步:

先把「10-99」缩为一重循环;再把「100-199」也缩为一重循环即可

\documentclass[tikz,border=2pt]{standalone}
\usepackage{ctex}
\usepackage{circledtext}
\begin{document}
\tikz{
    \foreach \x in {0,...,9} {
        \node[scale=2.75]  at (\x,0) {\circledtext{\x}};
    }
    \foreach \x in {10,...,99}{%
        \pgfmathtruncatemacro{\xx}{mod(\x,10)}
        \pgfmathtruncatemacro{\yy}{floor(\x/10)}
        \node[scale=2.75] at (\xx,\yy) {\circledtext{\scalebox{1.25}[2]{\x}}};
    }%
}
\tikz{
    \foreach \x in {100,...,199}{%
        \pgfmathtruncatemacro{\xx}{mod(\x-100,10)}
        \pgfmathtruncatemacro{\yy}{floor((\x-100)/10)}
        \node[scale=2.75] at (\xx,\yy) {\circledtext{\scalebox{1}[2]{\x}}};
    }%
}
\end{document}

第二步:

根据数字的位数使用一个分支判断。这样可以把三个循环再缩为一个。

这里我不希望把0-199的数字拆分为两个tikzpicture,所以我稍微修改了一下逻辑和目标效果。

\documentclass[tikz,border=2pt]{standalone}
\usepackage{ctex}
\usepackage{circledtext}
\begin{document}
\tikz{
    \foreach \x in {0,...,299} {
        \pgfmathtruncatemacro{\xx}{mod(\x,10)}
        \pgfmathtruncatemacro{\yy}{floor(\x/10)}
        \ifnum\yy<1\relax
           \def\content{\x}
        \else%
            \ifnum\yy<10\relax
               \def\content{\scalebox{1.25}[2]{\x}}
            \else
               \def\content{\scalebox{1}[2]{\x}}
            \fi
        \fi
        \node[scale=2.75] at (\xx,\yy) {\circledtext{\content}};
    }%
}
\end{document}

image.png

我也来贡献一个可能的答案吧...

我其实见过Qrrbrbirlbel在这里的一个神级操作

\documentclass[tikz,border=8pt]{standalone}
\begin{document}
  \begin{tikzpicture}
    \path[draw]
    foreach \x[
        evaluate = \x as \angle using {360/12*(\x+1/2)}
    ] in {0,...,11} {
        node[
            shape=circle, color=black, draw, fill,
            inner sep=+0pt, minimum size=+2pt,
            label = {[anchor=\angle+180]{\angle}:$\x$},
            ] (a\x) at (\angle:1) {}
        }
    plot [sharp cycle, samples at = {0,...,11}] (a\x.center);
  \end{tikzpicture}
\end{document}

出于一些我比较菜的原因...我不知道是否有办法对plot加上-latex...

image.png

可以用on background layer来避免第二个循环

\documentclass[border=6pt]{standalone}
\usepackage{tkz-euclide}
\usetikzlibrary{backgrounds}
\pgfmathsetseed{42}
\begin{document}
\begin{tikzpicture}
\tkzDefPoint(0,-.5){b0}\tkzDrawPoints[size=3pt](b0)
\foreach \x[remember=\x as \lastx (initially 0)] in {1,...,16}{
    \begin{scope}[on background layer]
        \pgfmathrandominteger{\yy}{-2}{2}
        \tkzDefPoint(\x*0.5,\yy pt){b\x}
        \tkzDrawSegments(b\lastx,b\x)
    \end{scope}
    \tkzDrawPoints[size=3pt](b\x)
}
\end{tikzpicture}
\end{document}

上面的例子中的\pgfmathrandominteger是我刻意构造的,就是为了避免被「抖机灵」(是我的 恶意 ,我希望 直面 这种 17个点16根连线的 「循环」不方便的情况)

image.png

虽然点和线的绘制次序改变了,但「17个点16根连线」的问题还是会出现「冗余」的:

\tkzDefPoint(0,-.5){b0}\tkzDrawPoints[size=3pt](b0)

我再蹲一蹲。

首先,在对「CJK文字」进行下划线时,建议使用xeCJKfntef宏包来实现,否则会出现无法正确换行的情况。

原生的xeCJKfntef的功能

image.png

\documentclass[fontset=fandol,12pt]{ctexart}
\usepackage{xeCJKfntef}
\setlength{\parindent}{0pt}
\begin{document}

\CJKunderline{史记赵世家}

\CJKunderline*{史记赵世家}
    
\CJKunderwave{史记赵世家}

\CJKunderwave*{史记赵世家}

\CJKunderline{史记,赵世家}

\CJKunderline*{史记,赵世家}

\CJKunderline-{史}%
\CJKunderline-{记}%
,%
\CJKunderline-{赵}%
\CJKunderline-{世}%
\CJKunderline-{家}%

\CJKunderwave{史记,赵世家}

\CJKunderwave*{史记,赵世家}

\CJKunderwave-{史}%
\CJKunderwave-{记}%
,%
\CJKunderwave-{赵}%
\CJKunderwave-{世}%
\CJKunderwave-{家}%

\end{document}

image.png

另外,这种「逐字」需要下划线和下划波浪线的实际用途是什么(?)一般波浪线和下划线很少需要逐字添加绘制(?)

一个不成功的探索

最后,要想调好不借助现有功能是比较困难的:

  • 标点压缩
  • 标点禁则
  • 字符压缩

每个CJK字符最终呈现的宽度是并不统一的,我在xeCJkfntef的框架下做了如下修改,也有瑕疵...

\documentclass[fontset=fandol,12pt]{ctexart}
\usepackage{xeCJKfntef}
\usepackage{zhlipsum}
\setlength{\parindent}{0pt}
\ExplSyntaxOn
%Line 5716~5733
% \NewDocumentCommand \CJKunderline { s t- s o }
% {
%     \xeCJK_ulem_group_begin:
%     \xeCJK_fntef_boot:nnNNNn { underline } { uline } #1#2#3 {#4} 
%     \xeCJK_fntef_initial:nnn
%         { \l__xeCJK_uline_depth_tl }
%         { \l__xeCJK_uline_sep_tl }
%         {
%             \l__xeCJK_uline_format_tl
%             \tex_vrule:D
%             height \dim_eval:n { \l__xeCJK_uline_thickness_tl } 
%             depth \c_zero_dim
%             width .2em
%         }
%     \xeCJK_ulem_on:n
% }
\RenewDocumentCommand \CJKunderline { s t- s o }
{
    \xeCJK_ulem_group_begin:
    \xeCJK_fntef_boot:nnNNNn { underline } { uline } #1#2#3 {#4} 
    \xeCJK_fntef_initial:nnn{ \l__xeCJK_uline_depth_tl }{ \l__xeCJK_uline_sep_tl }{%
        \l__xeCJK_uline_format_tl
        \tex_vrule:D height \dim_eval:n { \l__xeCJK_uline_thickness_tl }  depth \c_zero_dim width .95em\hskip1pt}%
 \xeCJK_ulem_on:n
}
\ExplSyntaxOff

\xeCJKsetup{ underwave = { symbol = \sixly \hskip1pt plus 1fill minus 1fill\char 58\hskip0pt plus 1fill minus 1fill\char 58\hskip1pt plus 1fill minus 1fill\relax } }
\begin{document}

\CJKunderline{史记赵世家}

\CJKunderline*{史记赵世家}
    
\CJKunderwave{史记赵世家}

\CJKunderwave*{史记赵世家}

\CJKunderline{史记,赵世家}

\CJKunderline*{史记,赵世家}
    
\CJKunderwave{史记,赵世家}

\CJKunderwave*{史记,赵世家}

\end{document}

image.png

这里的刚性宽度控制在字更多的时候很容易「歪」,同时如果遇到压缩的标点符号/换行等特殊情况,也是难以正常工作的....

该问题的mwe可以更短

emotion或者emoji宏包只是使用lualatex编译的理由

% lualatex
\documentclass{ctexart}
\begin{document}
你好
\end{document}

可能有关:

其实关键问题点并没有解决

感觉是varwidth的基线和stretch的功能互相作用导致...

just a workaround

如果想要「每一行的高度至少有“3行那么高”,当然不一定必须是3行,也可以是3cm,5cm等」,似乎用ht会更方便(?)

\documentclass[border=2pt]{standalone}
\usepackage{ctex,tabularray,xcolor,varwidth}
\begin{document}
\begin{tblr}{
    colspec={Q[l,m]Q[l,m]},
    hlines={dashed},
    column{1}={fg=red,rightsep+=.2em},
    column{2}={font=\scriptsize,leftsep+=.2em},
    % stretch=3.5,
    rows = {ht = 3\baselineskip},
}
    \begin{varwidth}{4em}
        四个个字
    \end{varwidth}&
    \begin{varwidth}{50em}
        六个个个个字\texttt{Sixxxx}四个个字,六个个个个字
    \end{varwidth}\\
    \begin{varwidth}{4em}
        四个个字
    \end{varwidth}&
    \begin{varwidth}{50em}
        十二个个个个个个个个个字,五个个个字
    \end{varwidth}\\
    \begin{varwidth}{4em}
        四个个字
    \end{varwidth}&
    \begin{varwidth}{50em}
        八个个个个个个字,九个个个个个个个字
    \end{varwidth}\\
\end{tblr}
\end{document}

image.png

P.S 上述的7点需求似乎只有「2」与问题核心有关....为了让潜在的回答者少看文字,其他的内容或许可以更加省略...

如何延长线段长度

通过比例确定

\documentclass[border=4pt]{standalone}
\usepackage{tkz-euclide}
\begin{document}
\begin{tikzpicture}
    \tkzDefPoints{0/0/A, 2/0/B} 
    \tkzDrawPoints(A,B)
    \tkzDrawSegment[-Stealth](A,B)
    \tkzDefPointWith[linear,K=1.5](A,B)
    \tkzGetPoint{C}
    \tkzDefPointWith[linear,K=.75](A,B)
    \tkzGetPoint{D}
    \tkzDefPointWith[linear,K=-.5](A,B)
    \tkzGetPoint{E}
    \tkzDrawPoints[violet](C) % 1.5
    \tkzDrawPoints[cyan](D) % .75
    \tkzDrawPoints[olive](E)% -.5
    \tkzLabelPoints[above](A,B,C,D,E)
    \tkzDrawLine[gray,dashed,add=1 and 1](A,B)
\end{tikzpicture}
\end{document}

image.png

通过长度确定

读文档,不难发现...

image.png

对于linear normed,参数K为「绝对距离」。

\documentclass[border=4pt]{standalone}
\usepackage{tkz-euclide}
\begin{document}
\begin{tikzpicture}
    \tkzDefPoints{0/0/A, 2/0/B} 
    \tkzDrawPoints(A,B)
    \tkzDrawSegment[-Stealth](A,B)
    \tkzDefPointWith[linear normed,K=1.5](A,B)
    \tkzGetPoint{C}
    \tkzDefPointWith[linear normed,K=2.5](A,B)
    \tkzGetPoint{D}
    \tkzDefPointWith[linear normed,K=-1](A,B)
    \tkzGetPoint{E}
    \tkzDrawPoints[violet](C) % K=1.5 |AC|=1.5,|BD|=0.5
    \tkzDrawPoints[cyan](D) % K=2.5 |AD|=2.5,|BD|=0.5
    \tkzDrawPoints[olive](E)% K=-1 |EA|=1
    \tkzLabelPoints[above](A,B,C,D,E)
    \tkzDrawLine[gray,dashed,add=1 and 1](A,B)
\end{tikzpicture}
\end{document}

image.png

至此,假如已知BD=4.2的情况下,如何延长BA到点E,并且使AE = BD = 4.2,也就是延长绝对的数量;

应该是可以解决了...

如何获取线段的长度

假如BD长度未知,如何得到它的长度,并且延长BA到点E,并且使AE = BD的长度

在文档中也有类似的功能\tkzCalcLength

image.png

下面把|AB|设置为倾斜的,因此|AB|长度需要通过勾股定理,较难计算。同时我们预期在|AC|上延长这段长度...
\documentclass[border=4pt]{standalone}
\usepackage{tkz-euclide}
\begin{document}
\begin{tikzpicture}
    \tkzDefPoints{0/0/A, 1.5/0.25/B, 1/1/C}
    \tkzDrawPoints(A,B,C)
    \tkzLabelPoints(A,B,C) 
    \tkzDrawSegments[thick](A,B A,C)
    %计算|AB|的长度
    \tkzCalcLength(A,B)
    \tkzGetLength{dAB}
    %从C点反向延长距离为\dAB的长度
    \tkzDefPointWith[linear normed,K=-\dAB](C,A)
    \tkzGetPoint{D}
    \tkzDrawSegment[magenta,semithick](A,D)
    \tkzDrawPoints[magenta](D)
    \tkzLabelPoints[magenta](D) 
    \tkzDrawSegment[dim={\pgfmathprintnumber\dAB,6pt,}](C,D)
\end{tikzpicture}
\end{document}

image.png

挑个软柿子:

可以看到,以上代码高亮也有问题,我希望(原环境)可以高亮命令,比如 \begin, \end, \draw等,但现在只能高亮命令名,反斜杠不支持。如果使用 minted 库,一定程度上可以改进,但 minted 库需要调用 Pygments,编译速度很慢,我希望能规避

这个问题应该与tcolorboxexample无关,可以参考这个链接.

发布
问题