我不确定标题是否正确,但我会尝试正确解释我的问题。
我一直在研究 pgfvectorian 包,并尝试添加一些有用的宏。其中一个宏是在两个节点之间放置一个矢量装饰。
下一个代码为您提供了一个名为的矢量对象,\myobject
我定义了一个宏\pgfobj
来绘制该对象。在这个例子中,我添加了 3 个选项:scale
,width
和anchor
。
width
用于绘制具有预定义宽度的对象,并anchor
用于放置对象。
我还定义了一种样式object
,以便轻松地将对象放置在两点之间。我计算两点之间的距离,然后使用sloped
和放置对象pos
。
我的问题:我想扩展样式object
。例如,我想更改的值pos
和的值,anchor
但我找不到解决方案。
我想要一个类似的语法\draw [black] (A) to [object,pos=.2,anchor=north] (B);
,但应用这些值node [anchor=south,pos=.5,sloped,allow upside down,inner sep=0pt]
抱歉,代码太长了,但我认为有必要理解这个问题:
\documentclass[landscape]{scrartcl}
\usepackage{fullpage,tikz}
\usetikzlibrary{shapes.geometric,calc}
%8<------8<------8<------8<------8<------8<------8<------8<------8<------
\def\myobject{%
\pgfpathmoveto{\pgfqpoint{0bp}{0bp}}
\pgfpathcurveto{\pgfqpoint{50bp}{0bp}}
{\pgfqpoint{150bp}{0bp}}
{\pgfqpoint{200bp}{16bp}}
\pgfpathcurveto{\pgfqpoint{250bp}{0bp}}
{\pgfqpoint{350bp}{0bp}}
{\pgfqpoint{400bp}{0bp}}
\pgfpathlineto{\pgfqpoint{400bp}{1bp}}
\pgfpathcurveto{\pgfqpoint{350bp}{0bp}}
{\pgfqpoint{250bp}{0bp}}
{\pgfqpoint{200bp}{22bp}}
\pgfpathcurveto{\pgfqpoint{150bp}{0bp}}
{\pgfqpoint{50bp}{0bp}}
{\pgfqpoint{0bp}{1bp}}
\pgfpathlineto{\pgfqpoint{0bp}{0bp}}
\pgfusepath{fill,stroke}}
%8<------8<------8<------8<------8<------8<------8<------8<------8<------
\makeatletter
\pgfkeys{
/obj/.cd,
scale/.code = {\def\pgfogjscale{#1}},
width/.code = {\def\pgfogjwidth{#1}},
anchor/.code = {\def\pgfobjanchor{#1}}
}
%8<------8<------8<------8<------8<------8<------8<------8<------8<------
\def\pgfobj{\pgfutil@ifnextchar[{\pgf@obj}{\pgf@obj[]}}
\def\pgf@obj[#1]{%
\pgfkeys{%
/obj/.cd,
scale = 1,
width = {},
anchor = south
}%
\pgfqkeys{/obj}{#1}%
\begin{tikzpicture}[baseline=(current bounding box.\pgfobjanchor)]
\ifx\pgfogjwidth\empty \else
\pgfmathsetmacro{\pgfogjscale}{\pgfogjwidth /400 bp}%
\fi
\pgftransformscale{\pgfogjscale}%
\myobject
\end{tikzpicture}%
}%
%8<------8<------8<------8<------8<------8<------8<------8<------8<------
\tikzset{%
object/.style={to path={%
\pgfextra{%
\tikz@scan@one@point\pgfutil@firstofone(\tikztostart)\relax
\pgf@xa=\pgf@x
\pgf@ya=\pgf@y
\tikz@scan@one@point\pgfutil@firstofone(\tikztotarget)\relax
\pgf@xb=\pgf@x
\pgf@yb=\pgf@y
\advance\pgf@xa by-\pgf@xb
\advance\pgf@ya by-\pgf@yb
\pgfmathveclen{\pgf@xa}{\pgf@ya}
\global\let\objlen\pgfmathresult
\path (\tikztostart) -- node [anchor=south,pos=.5,
sloped,allow upside down,inner sep=0pt]%
{\pgfobj[width=\objlen]} (\tikztotarget) ;
}%end pgfextra
}% end to path
}% end style
}
%8<------8<------8<------8<------8<------8<------8<------8<------8<------
\makeatother
\begin{document}
vector ornament with \texttt{scale=.5}: \pgfobj[scale=.5]
vector ornament between 2 nodes :
\begin{tikzpicture}
\node (A) at (0,0) {}; \node (B) at (7,5) {};
\draw [help lines] (0,0) grid (7,5);
\draw [fill=black] (A) circle (2pt)
(B) circle (2pt);
\draw [black] (A) to [object] (B);
\end{tikzpicture}
Ornaments with a pentagon :
\begin{tikzpicture}
\node[regular polygon, regular polygon sides=5,
minimum size=8cm,inner sep=0pt](h) {};
\foreach \i [count=\next from 2] in {1,...,5}
{%
\draw (h.corner \i) to [object] (h.corner \next);
\pgfmathtruncatemacro{\next}{mod(\next,5)} }
\end{tikzpicture}
\end{document}
备注 1)我可以使用另一个代码来绘制对象,如下:
\pgfmathsetmacro{\objangle}{atan2(\pgf@xa,\pgf@ya)}
\node[anchor=south,rotate=\objangle,inner sep=0pt] at
($(\tikztostart)!.5!(\tikztotarget)$){\pgfobj[width=\objlen]} ;
2)事实上我也使用了几个对象,语法如下:
\draw [black] (A) to [object = integer] (B); % integer = numero of the object
3)也许我走错了路,如果你有更好的想法,我会听的!
答案1
(这确实是一条很长的评论,但我想发布一张图片。你还对这个问题感兴趣吗?)
我不确定你想用这个实现什么效果。下面是对你的代码的一个小改动,我添加了一些键,这些键会传递给绘图代码,但我脑子里没有你想要的输出是什么样子的图片。我定义了几个新的键,/tikz/obj/anchor
和/tikz/obj/pos
,它们设置了宏,然后在构造中使用。为了让[object,pos=.2,anchor=south]
工作照原样然后我使用object
样式偷偷更改目录到,/tikz/obj
以便/tikz/obj/anchor
和/tikz/obj/pos
用于pos
和anchor
。为了正确执行此操作,我应该放入一个.unknown
处理程序以确保任何其他键都传递给/tikz/
。或者可以明确使用obj/pos
和而obj/anchor
无需偷偷更改目录。
代码如下:
\documentclass[landscape]{scrartcl}
\usepackage{fullpage,tikz}
\usetikzlibrary{shapes.geometric,calc}
%8<------8<------8<------8<------8<------8<------8<------8<------8<------
\def\myobject{%
\pgfpathmoveto{\pgfqpoint{0bp}{0bp}}
\pgfpathcurveto{\pgfqpoint{50bp}{0bp}}
{\pgfqpoint{150bp}{0bp}}
{\pgfqpoint{200bp}{16bp}}
\pgfpathcurveto{\pgfqpoint{250bp}{0bp}}
{\pgfqpoint{350bp}{0bp}}
{\pgfqpoint{400bp}{0bp}}
\pgfpathlineto{\pgfqpoint{400bp}{1bp}}
\pgfpathcurveto{\pgfqpoint{350bp}{0bp}}
{\pgfqpoint{250bp}{0bp}}
{\pgfqpoint{200bp}{22bp}}
\pgfpathcurveto{\pgfqpoint{150bp}{0bp}}
{\pgfqpoint{50bp}{0bp}}
{\pgfqpoint{0bp}{1bp}}
\pgfpathlineto{\pgfqpoint{0bp}{0bp}}
\pgfusepath{fill,stroke}}
%8<------8<------8<------8<------8<------8<------8<------8<------8<------
\makeatletter
\pgfkeys{
/obj/.cd,
scale/.code = {\def\pgfogjscale{#1}},
width/.code = {\def\pgfogjwidth{#1}},
anchor/.code = {\def\pgfobjanchor{#1}},
}
\tikzset{
obj/.cd,
anchor/.code = {\def\pgfobjnodeanchor{#1}},
pos/.code = {\def\pgfobjnodepos{#1}},
anchor = north,
pos = .5
}
%8<------8<------8<------8<------8<------8<------8<------8<------8<------
\def\pgfobj{\pgfutil@ifnextchar[{\pgf@obj}{\pgf@obj[]}}
\def\pgf@obj[#1]{%
\pgfkeys{%
/obj/.cd,
scale = 1,
width = {},
anchor = south,
}%
\pgfqkeys{/obj}{#1}%
\begin{tikzpicture}[baseline=(current bounding box.\pgfobjanchor)]
\ifx\pgfogjwidth\empty \else
\pgfmathsetmacro{\pgfogjscale}{\pgfogjwidth /400 bp}%
\fi
\pgftransformscale{\pgfogjscale}%
\myobject
\end{tikzpicture}%
}%
%8<------8<------8<------8<------8<------8<------8<------8<------8<------
\tikzset{%
object/.style={to path={%
\pgfextra{%
\tikz@scan@one@point\pgfutil@firstofone(\tikztostart)\relax
\pgf@xa=\pgf@x
\pgf@ya=\pgf@y
\tikz@scan@one@point\pgfutil@firstofone(\tikztotarget)\relax
\pgf@xb=\pgf@x
\pgf@yb=\pgf@y
\advance\pgf@xa by-\pgf@xb
\advance\pgf@ya by-\pgf@yb
\pgfmathveclen{\pgf@xa}{\pgf@ya}
\global\let\objlen\pgfmathresult
\path (\tikztostart) -- node [anchor=\pgfobjnodeanchor,pos=\pgfobjnodepos,
sloped,allow upside down,inner sep=0pt]%
{\pgfobj[width=\objlen]} (\tikztotarget) ;
}%end pgfextra
},% end to path
obj/.cd,
}% end style
}
%8<------8<------8<------8<------8<------8<------8<------8<------8<------
\makeatother
\begin{document}
vector ornament with \texttt{scale=.5}: \pgfobj[scale=.5]
vector ornament between 2 nodes :
\begin{tikzpicture}
\node (A) at (0,0) {}; \node (B) at (7,5) {};
\draw [help lines] (0,0) grid (7,5);
\draw [fill=black] (A) circle (2pt)
(B) circle (2pt);
\draw [black] (A) to [object] (B);
\end{tikzpicture}
vector ornament between 2 nodes :
\begin{tikzpicture}
\node (A) at (0,0) {}; \node (B) at (7,5) {};
\draw [help lines] (0,0) grid (7,5);
\draw [fill=black] (A) circle (2pt)
(B) circle (2pt);
\draw [black] (A) to [object,pos=.2,anchor=north] (B);
\end{tikzpicture}
Ornaments with a pentagon :
\begin{tikzpicture}
\node[regular polygon, regular polygon sides=5,
minimum size=8cm,inner sep=0pt](h) {};
\foreach \i [count=\next from 2] in {1,...,5}
{%
\draw (h.corner \i) to [object] (h.corner \next);
\pgfmathtruncatemacro{\next}{mod(\next,5)} }
\end{tikzpicture}
\end{document}
这是结果,但正如我所说:我不确定这是否是你想要的。