tikz 坐标可以导出到文本文件吗?

tikz 坐标可以导出到文本文件吗?

在呈现文档时,可以将 tikz 坐标导出到文本文件吗?让文档为:

\documentclass{scrartcl}
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document} 
  \begin{tikzpicture}
    \coordinate(vertexA) at (0, 10);
    \coordinate(vertexB) at (5, 8);
    \coordinate(vertexC) at (2.5, 0);
  \end{tikzpicture}
\end{document}

我很高兴有一个文本文件,其中包含 tikz 中每个命名点的页码和绝对坐标。它可能看起来像这样:(表格格式仅用于说明,但并不重要。)

label   | page | top | left | unit
--------+------+-----+------+------
vertexA |    1 | 128 |   54 | pt
--------+------+-----+------+------
vertexB |    1 | ... |  ... | pt
--------+------+-----+------+------
vertexC |    1 | ... |  ... | pt

最后,我想为我的学生创建测试表。他们应该通过填写小圆圈来回答多项选择题。通过了解圆圈的位置,我可以借助计算机程序扫描和检查结果表。(我知道如何进行机器视觉,但不知道如何在 tikz 中导出坐标。)

答案1

这会将缩放点(65536 sp = 1 pt)中的坐标保留在文件中.pos

\documentclass{scrartcl}
\usepackage{tikz}
\usetikzlibrary{calc}

\newwrite\posfile
\immediate\openout\posfile=\jobname .pos
\newcommand\coordpos[1]{%
\node at (#1) {\pdfsavepos\write\posfile{#1: \the\pdflastxpos, \the\pdflastypos}}
}
\begin{document} 
  \begin{tikzpicture}
    \coordinate(vertexA) at (0, 10);
    \coordinate(vertexB) at (5, 8);
    \coordinate(vertexC) at (2.5, 0);
    \coordpos{vertexA};
    \coordpos{vertexB};
    \coordpos{vertexC};
  \end{tikzpicture}
\end{document}

导致

vertexA: 6830544, 49603716
vertexB: 16153939, 45874358
vertexC: 11492241, 30956926

答案2

与 David 的典型机智黑客相比,这是我的超级冗余答案(尽管只有我们努力才能打破他的计划)。但它不使用写入处理程序,而是.txt通过以下方式更新文件pgfplotstable

我做了什么?

我开始更新 TikZ 图片计数器(虽然\pgfpictureid也这样做,但我不想碰它)并且我还计算 TikZ 图片中的节点数以供以后使用。

在每个 TikZ 图片的末尾,我都会获取页码、节点原始名称及其顶部和左侧位置,并将其写入临时表。然后我将vertcat上一个表写入pointlist.txt。然后我用更新后的表重写该文件。我重置节点计数器并等待下一张图片。

如何使用

relevant将要启用录制的 TikZ 图片添加到相关图片中,并将atl节点和坐标添加到其中。这样会在同一文件夹中生成一个 txt 文件,pointlist.txt您也可以将其排版到 TeX 文件中,如下所示。

代码

\documentclass{scrartcl}
\usepackage{tikz,lipsum,pgfplotstable}
\usepackage[user]{zref}
\pgfplotsset{compat=1.8}

%======================= Here we go ==============================
\newcounter{mypiccount}\setcounter{mypiccount}{0}
\newcounter{mypointcount}\setcounter{mypointcount}{0}
\makeatletter
\tikzset{
    relevant/.prefix style={
        remember picture,
        execute at begin picture={\zlabel{\pgfpictureid}},
        execute at end picture={%
            \pgfplotstableset{
                 create on use/label/.style={create col/assign/.code={
                     \edef\myentry{\expandafter\csname nnn\themypiccount\number\numexpr\pgfplotstablerow+1\relax\endcsname}
                     \pgfkeyslet{/pgfplots/table/create col/next content}{\myentry}
                    }
                }, 
                 create on use/top/.style={create col/assign/.code={
                     \pgfpointdiff{\pgfpointanchor{current page}{north west}}%
                         {\pgfpointanchor{nnn-\themypiccount-\number\numexpr\pgfplotstablerow+1\relax}{center}}
                     \edef\myentry{\the\pgf@y}
                     \pgfkeyslet{/pgfplots/table/create col/next content}{\myentry}
                     }
                 },
                 create on use/left/.style={create col/assign/.code={
                     \pgfpointdiff{\pgfpointanchor{current page}{north west}}%
                         {\pgfpointanchor{nnn-\themypiccount-\number\numexpr\pgfplotstablerow+1\relax}{center}}
                     \edef\myentry{\the\pgf@x}
                     \pgfkeyslet{/pgfplots/table/create col/next content}{\myentry}
                     }
                 },                
                 create on use/page/.estyle={create col/set={\zpageref{\pgfpictureid}}},
            }%
            \pgfplotstablenew[columns={label,page,top,left}]{\themypointcount}{\mytemptable}%
            \ifnum\themypiccount>1\pgfplotstablevertcat{\mytemptable}{pointlist.txt}\else\fi%
            \pgfplotstablesave[columns={label,page,top,left}]{\mytemptable}{pointlist.txt}
            \pgfplotstableclear{\mytemptable}%
            \setcounter{mypointcount}{0}%
        },
        execute at begin picture={%
            \stepcounter{mypiccount}\setcounter{mypointcount}{0}%
        }
    },
    atl/.style={/utils/exec={\stepcounter{mypointcount}},
                alias={nnn-\themypiccount-\themypointcount},
                append after command={\pgfextra{\expandafter\xdef\csname nnn\themypiccount\themypointcount\endcsname{\tikz@last@fig@name}}}
    }
}
\makeatother
%======================= That was weird ==============================


\begin{document}

  \begin{tikzpicture}[relevant]
    \node[atl] (vertexA) at (0, 10) {A};
    \node[atl] (vertexB) at (5, 8) {B};
    \node (vertexC) at (2.5, 0) {C};
  \end{tikzpicture}

\lipsum[1-6]

  \begin{tikzpicture}[relevant]
    \node[atl] (vertexA) at (0, 10) {A};
    \node[atl] (vertexB) at (5, 8) {B};
    \node[atl] (vertexD) at (2, 8) {D};
    \node (vertexC) at (2.5, 0) {C};
  \end{tikzpicture}
  \begin{tikzpicture}[relevant]
    \node[atl,circle] (vertexA) at (0, 10) {A};
    \node[atl] (vertexB) at (5, 8) {B};
    \node[atl] (vertexD) at (2, 8) {D};
    \node (vertexC) at (2.5, 0) {C};
  \end{tikzpicture}

\lipsum[1-3]

  \begin{tikzpicture}[relevant]
    \node[atl] (vertexB) at (5, 8) {B};
    \node (vertexD) at (2, 8) {D};
    \node[atl] (vertexC) at (2.5, 0) {C};
  \end{tikzpicture}

\pgfplotstabletypeset[string type]{pointlist.txt}
\tikz[overlay,remember picture]{
\draw[thick,red] (current page.north west) -- ++(193.76636pt,-160.42473pt);
\draw[thick,blue] (current page.north west) -- ++(122.63449pt,-388.04668pt);
}
\end{document}

这给出

在此处输入图片描述

需要考虑的几点:

  • 我已经删除了单位列,因为维度列的条目已经pt涉及(很好地尝试让坏事看起来很好:P)
  • 我做了一些糟糕的事情,比如在宏中使用数字等。但获取节点的原始名称总是无聊而糟糕。这可能是我真正不喜欢 TikZ 的少数事情之一。但这是一种设计选择,允许在节点名称中使用大量非字母字符。
  • 由于某种原因,当我想初始化一个单行表时,它总是产生两行,我不知道为什么。不再相关。
  • \thepage正如 MWE 中所述,如果 TeX 认为图片太大并将其推到下一页,则有可能欺骗计数器。计数器仍然是 2,但图片在第 3 页。我记得用某个zref模块修复了它,但我找不到它。
  • 如果您缩放图片,距离不会更新,因为我没有考虑转换,所以存在一些(更多)脆弱性。

要做的事情

  • 删除包含条目的初始表格行-。然后可以按页列进行排序。现在可以对表格进行排序。
  • 找到那个zref东西 固定的

答案3

这是一个解决方案,它创建了一个表格

<coordinate name> <picture id> <page> <x_pic> <y_pic> <x_cipic> <y_cipic> <x> <y>

在哪里

  • <coordinate name>是坐标的名称;
  • <picture id>是图片的ID(随着每一个\pgfpicture而增加的​​值,因此\tikzpicture);
  • <page>是页码;
  • <x_pic><y_pic>分别是图片原点的坐标<picture id>
  • <x_cipic><y_cipic>分别是图片内部坐标的坐标;
  • <x><y>分别是页面左下角坐标的坐标。

这需要remember picture您想要保存坐标的图片。

此解决方案可以在任何图片之外使用。

代码

\documentclass{scrartcl}
\usepackage{tikz,etoolbox}
\makeatletter
\patchcmd\pgfpicture{\edef\pgfpictureid{pgfid\the\pgf@picture@serial@count}}{\edef\pgfpictureid{pgfid\the\pgf@picture@serial@count:\the\c@page}}{}{}
\tikzset{
  export coordinates/.style 2 args={%
    /utils/exec={\begingroup
          \pgftransformreset
          \immediate\openout\w@pgf@writea=#2\relax},
    @export coordinates/.list={#1},
    /utils/exec={\immediate\closeout\w@pgf@writea
        \endgroup}},
  @export coordinates/.code=\tikz@expc@export{#1}%
}
\def\tikz@expc@export#1{%
  \expandafter\let\expandafter\pgf@temp\csname pgf@sh@pi@#1\endcsname
  \expandafter\tikz@expc@split\pgf@temp\pgf@stop
  \pgfsys@getposition{\csname pgf@sh@pi@#1\endcsname}\tikz@expc@original@picture%
  \pgfextract@process\tikz@expc@original@picture{\tikz@expc@original@picture}%
  \pgfextract@process\tikz@expc@coordinpic{\let\pgf@shape@interpictureshift\pgfutil@gobble\pgfpointanchor{#1}{center}}%
  \tikz@expc@original@picture \pgf@xa\pgf@x \pgf@ya\pgf@y
  \tikz@expc@coordinpic
  \pgf@xb\pgf@x \pgf@yb\pgf@y \pgf@xc\pgf@x \pgf@yc\pgf@y
  \advance\pgf@xc\pgf@xa \advance\pgf@yc\pgf@ya
  %
  \immediate\write\w@pgf@writea{#1 \tikz@expc@pid\space\tikz@expc@page\space
    \the\pgf@xa\space\the\pgf@ya\space
    \the\pgf@xb\space\the\pgf@yb\space
    \the\pgf@xc\space\the\pgf@yc}}%
\def\tikz@expc@split pgfid#1:#2\pgf@stop{%
  \def\tikz@expc@pid{#1}%
  \def\tikz@expc@page{#2}}
\makeatother
\begin{document} 
  \begin{tikzpicture}[remember picture]
    \coordinate[label=A](vertexA) at (0, 10);
    \coordinate[label=B](vertexB) at (5, 8);
    \coordinate[label=C](vertexC) at (2.5, 0);
  \end{tikzpicture}
  \tikzset{export coordinates={vertexA,vertexB,vertexC}{coordsA.dat}}

  \pagebreak

  \begin{tikzpicture}[remember picture]
    \coordinate[label=A](vertexA') at (0, 10);
    \coordinate[label=B](vertexB') at (5, 8);
    \coordinate[label=C](vertexC') at (2.5, 0);
  \end{tikzpicture}
  \tikzset{export coordinates={vertexA,vertexB,vertexC,vertexA',vertexB',vertexC'}{coordsB.dat}}
\end{document}

输出coordsB.dat

vertexA 1 1 108.33208pt 461.03311pt 0.0pt 284.52744pt 108.33208pt 745.56055pt
vertexB 1 1 108.33208pt 461.03311pt 142.26372pt 227.62195pt 250.5958pt 688.65506pt
vertexC 1 1 108.33208pt 461.03311pt 71.13185pt 0.0pt 179.46393pt 461.03311pt
vertexA' 2 2 108.33208pt 461.03311pt 0.0pt 284.52744pt 108.33208pt 745.56055pt
vertexB' 2 2 108.33208pt 461.03311pt 142.26372pt 227.62195pt 250.5958pt 688.65506pt
vertexC' 2 2 108.33208pt 461.03311pt 71.13185pt 0.0pt 179.46393pt 461.03311pt

答案4

该方法\pdfsavepos也已用于自动多项选择项目。也许你可以看看它的网站,并考虑加入该项目?它允许对问题和答案进行打乱,从扫描中获取结果,并生成带注释的完整答题纸。

相关内容