越来越少
越来越少
这家伙很懒,什么也没写!

注册于 4年前

回答
27
文章
0
关注者
1

\coordinate ["$P1$"] (P1) at ($(O1)!\length cm!\pgfmathresult:(O2)$);

\coordinate ["$P1$"] (P1) at ($(O1)!\length cm!\length cm:(O2)$);

是一样的.

\pgfmathparse 解析 \length cm, 得到 \pgfmathresult, 然后再解析 \pgfmathresult:(O2)这一部分.

多数 pgf 的数学函数都会把结果保存到 \pgfmathresult, 命令 \pgfmathparse 总会把结果保存到 \pgfmathresult.

如果需要某个 \pgfmathresult, 最好及时转存它的值.

具体原因见 tikz 的 calc 库.

参考这里提及的文章

或者使用 tikz 的 to 路径.

%\usetikzlibrary{topaths}
\begin{tikzpicture}
\draw [->] (-4,0) -- (4,0);
\draw [->] (0,-4) -- (0,4);
\def\rightpart{
    (0,0) to[out=-60,in=180,in looseness=0.5] (0.5,-0.5)
          to[out=0,in=180,out looseness=0.5,in looseness=0.5] (2,3)
          to[out=0,in=180,out looseness=0.5,in looseness=0.5] (2.5,2.5)
          to[out=0,in=-100,out looseness=0.5,in looseness=0.5] (3,3.5)
}
\draw \rightpart ;
\draw[rotate=180]\rightpart ;
\end{tikzpicture}

dc0a17a512da9e48ee2839868bb52fcd.png

电脑的计算几乎都是近似计算, 只要近似地还行, 不是切线也是切线.

\documentclass[tikz]{standalone}
\begin{document}

\begin{tikzpicture}[scale=1.5]

\tikzset{
  temp/.cd,
    s opt/.store in=\solidlineopt, s opt={draw=green},
    s path/.store in=\solidlinepath, s path=,
    s end opt/.store in=\solidlineendopt, s end opt={below},
    s end text/.store in=\solidlineendtext, s end text=,
    d opt/.store in=\dashedlineopt, d opt={draw=red,dashed},
    d path/.store in=\dashedlinepath, d path=,
    d end opt/.store in=\dashedlineendopt, d end opt={below},
    d end text/.store in=\dashedlineendtext, d end text=,
}
\def\linesdraw#1{
  \begingroup
    \tikzset{temp/.cd,#1}
    \edef\tempcmd{
      \noexpand\begin{scope}
        \noexpand\draw[\solidlineopt]\solidlinepath node[\solidlineendopt]{\solidlineendtext};
      \noexpand\end{scope}
      \noexpand\begin{scope}
        \noexpand\draw[yscale=-1,rotate=-90,\dashedlineopt]
          \dashedlinepath
          node[\dashedlineendopt]{\dashedlineendtext};
      \noexpand\end{scope}
    }
    \tempcmd
  \endgroup
}

\begin{scope}[rotate=-135]
\foreach \i/\j/\k in {
{(4,4)--(4,0)arc(0:-180:1.5)--(1,5)}/{$+a_{12}a_{23}a_{31}$}/{$-a_{12}a_{21}a_{33}$},
{(3,3)--(3,0)arc(0:-180:1.5)--(0,5)}/{$+a_{13}a_{21}a_{32}$}/{$-a_{11}a_{23}a_{32}$},
{(2,0)--(2,5)}/{$+a_{11}a_{22}a_{33}$}/{$-a_{13}a_{22}a_{31}$}
}{
\linesdraw{
%  s opt=,
  s path={\i},
%  s end opt={},
  s end text={\j},
%  d opt=,
  d path={\i},
%  d end opt={},
  d end text={\k},
}}
\end{scope}

\begin{scope}[yscale={-sqrt(2)},xscale={sqrt(2)},shift={(-2,0)}]
\foreach \i in {1,2,3}{
\foreach \j in {1,2,3}{
  \node [fill=white] at(\i,\j){$a_{\j\i}$};
}}
\end{scope}

\end{tikzpicture}

\end{document}

d6d10b231447de91db2afa74bae60696.png

试试下面的代码。

\documentclass{article}
\usepackage{geometry}
\geometry{papersize={16cm,9cm}, hmargin=2cm,vmargin=1.5cm}
\usepackage{tikz}

\begin{document}

XXXXX XXXXX XXXXX XXXXX 
XXXXX XXXXX XXXXX XXXXX 
XXXXX XXXXX XXXXX XXXXX 

\begin{tikzpicture}[remember picture]
  \node[draw=red](A)at(1,1){something};%
  \path (A.south west);%
  \pgfgetlastxy{\Ax}{\Ay}%
  \path [overlay] (current page.south west);%
  \pgfgetlastxy{\Px}{\Py}%
  \pgfmathparse{\Ax-\Px}%
  \edef\APx{\pgfmathresult pt}
  \pgfmathparse{\Ay-\Py}%
  \edef\APy{\pgfmathresult pt}
  \edef\APcoord{\APx,\APy}%
  \draw [overlay] (current page.south west) -- node[sloped,align=left]{\APx,\\ \APy} ++(\APcoord);%
\end{tikzpicture}

XXXXX XXXXX XXXXX XXXXX 
XXXXX XXXXX XXXXX XXXXX 
XXXXX XXXXX XXXXX XXXXX 

\end{document}

结果如图:
result.png

不能。一个路径只能有一个颜色。似乎pdf格式就是这样的,记不准确了。

你需要重新定义 \tdplotdefinepoints.

你可能需要了解 \tikz@scan@one@point, 以及 TikZ 的代表 xyz 坐标系的矩阵, 代表 canvas 坐标系的矩阵.

简单说, TikZ 会把 (1,2,3) 这样的坐标通过矩阵乘法, 转换为 canvas 坐标系中的二维坐标数据. 像 (A) 这样的坐标位置实际上也是二维的. 你想要的就是这个过程的逆过程, 也就是把二维的数据再变成对应的三维坐标数据, 这需要计算 canvas 坐标系矩阵的逆矩阵(参考 \pgftransforminvert). 另外 TikZ 的 xyz 坐标系的矩阵实际是利用 3 个二维向量模拟三维标架(可以认为是2行3列的矩阵), 所以这个逆过程似乎比较困难.

可以用其他办法, 例如, 直接把 (A)(1,2,3) 联系起来,

\makeatletter
\def\savemycoord(#1)(#2){
    \expandafter\def\csname my@coord@(1)\endcsname{(#2)}
}
\def\readmycoord(#1){
    \edef\tempsave{\csname my@coord@(#1)\endcsname}
}

这样定义后,

\savemycoord(A)(1,2,3)
\readmycoord(A)

就会把 (1,2,3) 保存到 \tempsave.

编译下面的代码

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{plotmarks}
\usepackage{tikz-3dplot}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\begin{document}
\begin{tikzpicture}
  \begin{axis}
    \addplot3 [
      domain=0:1,
      samples=10,
      contour/number=5,
      contour gnuplot,
    ]
      {sin(deg(2*pi*x))* exp(-10*(y-0.5)^2) + exp(-(x-0.5)^2*10 - (y-0.25)^2 - (x-0.5)*(y-0.25))};
  \end{axis}

  \begin{axis}
    \addplot3 [
      domain=0:1,
      samples=10,
      contour gnuplot={contour dir=y,levels=0.5},
    ]
      {sin(deg(2*pi*x))* exp(-10*(y-0.5)^2) + exp(-(x-0.5)^2*10 - (y-0.25)^2 - (x-0.5)*(y-0.25))};
  \end{axis}
\end{tikzpicture}
\end{document}

后, 在主文件目录下会有两个 .table 文件, 其中就是绘制等高线的数据, 如果不嫌麻烦的话, 可以利用这些数据绘制需要的图形. 问题中的图形是平面图形, 只用到 .table 文件中的第一, 第二列数据.

如果觉得图形不够精确, 可以尝试增加 sample 的数量.

703b4040c3947db007d0b90a80599d06.jpg

这个图就是下面的代码. 使用 LuaLaTeX 编译, 如果觉得编译太慢, 请事先修改选项 samples 的值.

各个选项的用法可以参考 pgfplots 手册.

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{plotmarks}
\usepackage{tikz-3dplot}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\begin{document}
\begin{tikzpicture}
  \begin{axis}[
    samples=100,
    width=30cm,
    xmin=-1,xmax=2,
    ymin=-1,ymax=2,
    zmin=-2,zmax=2,
    contour/number=10
  ]
    \addplot3 [
      domain=0:1,
      contour lua,
      z filter/.code={\def\pgfmathresult{-2}},
    ]
      {sin(deg(2*pi*x))* exp(-10*(y-0.5)^2) + exp(-(x-0.5)^2*10 - (y-0.25)^2 - (x-0.5)*(y-0.25))};

    \addplot3 [
      domain=0:1,
      contour lua={contour dir=x},
      x filter/.code={\edef\pgfmathresult{-1}},
    ]
      {sin(deg(2*pi*x))* exp(-10*(y-0.5)^2) + exp(-(x-0.5)^2*10 - (y-0.25)^2 - (x-0.5)*(y-0.25))};

    \addplot3 [
      domain=0:1,
      contour lua={contour dir=y},
      y filter/.code={\edef\pgfmathresult{2}},
    ]
      {sin(deg(2*pi*x))* exp(-10*(y-0.5)^2) + exp(-(x-0.5)^2*10 - (y-0.25)^2 - (x-0.5)*(y-0.25))};

    \addplot3 [
      surf,
      mesh/interior colormap={blueblack}{color=(black) color=(white)},
      colormap/blackwhite, samples=30,
      domain=0:1,
    ]
      {sin(deg(2*pi*x))* exp(-10*(y-0.5)^2) + exp(-(x-0.5)^2*10 - (y-0.25)^2 - (x-0.5)*(y-0.25))};
  \end{axis}
\end{tikzpicture}
\end{document}

你没有用具体例子来详细表达问题,我也不好猜测你具体需要什么。还是建议你先去读一下手册。

我对 graph 库的理解是这样的。

用户可以用一些变量(参数,其实就是 pgf 的 key),来定义一种计算 node 位置的方法,这些变量例如

\tikzgraphsset{
  placement/.cd,
  element count/.initial=0,
  chain count/.initial=0,
  depth/.initial=0,
  width/.initial=0,
  level/.initial=0,
  logical node depth/.code=\def\pgfmathresult{1},
  logical node width/.code=\def\pgfmathresult{1},
}%

Graph 库的作者利用这些变量定义了几种计算方式,默认的是 /tikz/graphs/Cartesian placement 这个计算方式。对于这个计算方式来说,用户可以通过调整某些 key 的值(如 /tikz/graphs/chain shift)来影响这个计算方式的计算结果,但计算方式的框架是不容易修改的。

详细情况请参考手册。

也可以使用 graphdrawing 库引入其他的计算方式,这个库借助 lua 来计算,我不懂 lua。熟悉 lua 的用户可以自己编写一种计算方式。

总之 graph 库以及 graphdrawing 库强调的是“自动计算,自动排布”,非常依赖算法,而不是强调人工干预。如果总是期望用户来控制各个 node 的位置,那就背离了这个思想。所以这个思想主要针对有很多 node 的情况。当然用户也可以根据情况来调整个别 node 的位置,但这不是重点。

在 node 比较多的情况下,并没有绝对的标准来判断一种排布方式是否足够美观,减少用户的干预也未必不是一个好的选择。当然这对算法的设计也就有相当的要求,不是那么轻易就能设计好。例如命令 \usegdlibrary{force} 引入的算法就参考了数篇论文。你可以搜索相关的资料,例如 胡一凡 的作品

如果你想知道如何用参数调整算法的计算结果,应该先去阅读手册,或者手册中给出的参考论文。如果你觉得英文手册不好读,倒是也有关于 graph 库的中文介绍,也不太好读。不过,只要静心读,总能读明白。

d68f2e551f87045462c7bedfeff9f5bb.png

导言区使用:

\usepackage{tikz}
\usetikzlibrary{fadings,shadings,intersections}
\usepackage{pgfplots}
\usepgfplotslibrary{fillbetween}

下面是绘图的命令:

\begin{tikzfadingfrompicture}[name=pl]
\shade[inner color=transparent!0,outer color=transparent!100](0,0) rectangle (6,2);
\end{tikzfadingfrompicture}

\begin{tikzpicture}
\path [clip] (-2,-2) rectangle (6,8);
\fill [color=black!50!white,] (-2,2.5) rectangle (6,10);
%注意坐标 (-1,3), (1,3), 与下文的坐标 (0,3) 对应
\draw [name path=p1,white,rotate=-15] (-1,10)  {[rounded corners=15pt]-- (-1,3)}{[rounded corners=20pt]--(0,0)}{[rounded corners=15pt]--(1,3) -- (1,10)};
\path [name path=h] (-2,2.5)--(4,2.5);
%用到 pgfplots 的 fillbetween 库来计算下面命令中的 L2, 即下面命令画出的红色线条
\draw [draw=red,intersection segments={of=p1 and h,sequence=L2},line width=2pt];
%scale around={0.8:(0,3)}, 注意坐标 (0,3), 与上文的坐标 (-1,3), (1,3) 对应
\draw [name path=p2,white,rotate=-15,scale around={0.8:(0,3)}] (-1,10)  {[rounded corners=15pt]-- (-1,3)}{[rounded corners=20pt]--(0,0)}{[rounded corners=15pt]--(1,3) -- (1,10)} ;
%再次用到 pgfplots 的 fillbetween 库
\draw [draw=orange,intersection segments={of=p2 and h,sequence=L2},line width=2pt];
%利用前文定义的 pl 做 fading 效果
\draw [line width=2pt,path fading=pl]
(0,0)..controls ++(5,0.5) and ++(2,0)..(3,1)..controls ++(-2,0) and ++(-2,0)..(3,1.5)..controls ++(2,0) and ++(-1,-0.5)..(6,2);
\end{tikzpicture}

以上只是一个简单的尝试,只是说明能用 TikZ 画,仅供参考。

\tikz{%r^2=a^2*cos(2*i)
  \def\a{2}
  \def\tempsave{}
  \foreach \i in {-45,-44.5,...,45,135,135.5,...,225}
  {
    \pgfmathparse{sqrt(\a^2*cos(2*\i))}
    \xdef\tempsave{\tempsave(\i:\pgfmathresult)}
  }
  \draw plot[smooth] coordinates {\tempsave};
}

cb3e54f03f9a696c85cc4ab5325dbe78.png

\begin{tikzpicture}
\begin{scope}[xslant=0.5]%y=(60:1)???
  \foreach \i in {0,...,6}
  {
    \foreach \j in {0,...,5}
    {
      \pgfmathparse{\j>-\i+6}
      \ifnum \pgfmathresult=1
      \else
        \node [
%          fill,
           draw,
           circle,inner sep=0pt,minimum size=3mm](n-\i-\j) at(\i,\j) {%
%        n-\i-\j
        };
      \fi
    }
  }
\end{scope}
\draw ($(n-1-5.north)+(90:1.5)$)--($(n-1-5.north)+(90:1)$)--($(n-6-0)+(0:1)$)--++(-90:5)-|($(n-0-0)+(180:1)$)--($(n-0-5.north)+(90:1)$)--($(n-0-5.north)+(90:1.5)$);
\end{tikzpicture}

得到
5585798563121045a23b8f558bfa152f.png
其余的线可以参考其他回答。

发布
问题