Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I'm not sure if the title is correct but I'll try to explain my problem correctly.

I always work on the pgfvectorian package and I try to add some useful macros. One of these macros is to place an vector ornament between two nodes.

The next code give you a vector object named \myobject the I define a macro \pgfobj to draw this object. In this example I added 3 options : scale , width and anchor. width is to draw the object with a predefined width and anchor is used to place the object.

I also defined a style object to easily place the object between two points. I calculate the distance between the 2 points and then I place the object with sloped and pos.

My problem : I would like to extend the style object. I would like for example change the value of pos and the value of anchor but I can't find a solution to this.

I would like a syntax like \draw [black] (A) to [object,pos=.2,anchor=north] (B); but apply these values at node [anchor=south,pos=.5,sloped,allow upside down,inner sep=0pt]

Sorry fot the long code but I think it's necessary to understand the question :

\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} 

enter image description here

Remark 1) I can use another code to draw the object like :

        \pgfmathsetmacro{\objangle}{atan2(\pgf@xa,\pgf@ya)} 
        \node[anchor=south,rotate=\objangle,inner sep=0pt] at    
        ($(\tikztostart)!.5!(\tikztotarget)$){\pgfobj[width=\objlen]} ; 

2) In fact I work with several objects also the syntax is something like :

   \draw [black]   (A) to [object = integer]  (B); % integer = numero of the object

3) Perhaps I may have taken a wrong way also if you have a better idea, I'm listening !

share|improve this question

1 Answer 1

up vote 6 down vote accepted

(This is really a long comment, but I want to post a picture. Are you still interested in this question?)

I'm not sure what effect you are trying to achieve with this. Here's a small adaptation of your code where I've added some keys which get passed on to the drawing code, but I don't have a picture in my head of what you want the output to look like. I define a couple of new keys, /tikz/obj/anchor and /tikz/obj/pos, which set macros that then get used in the construction. To make [object,pos=.2,anchor=south] work as is then I have the object style sneakily change directory to /tikz/obj so that /tikz/obj/anchor and /tikz/obj/pos are used for pos and anchor. To do this properly, I ought to put in an .unknown handler to ensure that any other key gets passed on to /tikz/. Or one could use obj/pos and obj/anchor explicitly without the sneaky change of directory.

Here's the code:

\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} 

Here's the result, but as I say: I'm not sure if it is what you want or not.

vectorian with options

share|improve this answer
    
Yes it's fine. Your answer is interesting because I can analyze how you work with pgfkeys. Sometimes it's not easy, for example, I had never thought of using obj/.cd ! –  Alain Matthes Apr 13 '12 at 9:29
    
Glad it's helpful. I'll be curious to see what the end result is. (I'm no expert on pgfkeys - we need Ryan Reich for that!) –  Loop Space Apr 13 '12 at 9:30

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.