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 trying to create several anchors equally spaced on the edge of my shape. The way I've tried to do this is to pass a key value in the node that would then define the anchors.

The following code is trying to achieve that by using a loop in the main pgfdeclareshape part. Although the loop works and creates an anchor ( in the wrong position for now ) it will only create one as the key still has the initial value.

\documentclass[a4paper]{article}
\usepackage{tikz}

\makeatletter
\tikzset{anchorpoints/.initial = 1}

\pgfdeclareshape{hat}{
    \inheritsavedanchors[from=rectangle]
    \inheritanchorborder[from=rectangle]
    \inheritanchor[from=rectangle]{center}
    \inheritanchor[from=rectangle]{north}

    % This loop will go through once for each anchorpoints and create an anchor
    \c@pgf@counta=0
    \pgfkeysgetvalue{/tikz/anchorpoints}{\anchorpoints}
    \c@pgf@countb\anchorpoints\relax
    \pgfmathloop
        \ifnum\c@pgf@counta<\c@pgf@countb\relax
            \pgfmathtruncatemacro{\anchorname}{\c@pgf@counta}\relax
            \xdef\doanchor{
                \noexpand\anchor{o\anchorname}{
                    \noexpand\northeast
                    \noexpand\pgf@y=1\noexpand\pgf@y%
                }
            }\doanchor
            \advance\c@pgf@counta 1\relax
    \repeatpgfmathloop  

    \backgroundpath{
        \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y
        \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y
        \pgfmathsetlength{\pgf@xc}{\pgf@xa + (\pgf@xb - \pgf@xa)/2}

        \pgfpathmoveto{\pgfpoint{\pgf@xc}{\pgf@ya}}
        \pgfpathlineto{\pgfpoint{\pgf@xa}{\pgf@yb}}
        \pgfpathlineto{\pgfpoint{\pgf@xb}{\pgf@yb}}
        \pgfpathclose
    }
}
\makeatother

\begin{document}
\begin{tikzpicture}
    \node [shape=hat,draw=black,scale=0.75,anchorpoints=3] (1) at (0, 0) {};
\end{tikzpicture}
\end{document}

Is there any way to wait with creating the anchor until after the key has been set? If I try to put some .code to the key then it will execute at change but it seems that at that point it is too late to create the anchors.

share|improve this question
    
I don't know if this just for exercise but this shape is already defined in shapes.geometric library. Also you are inheriting the anchors of a rectangle for a triangle. Lastly, (anynodename.numberindegrees) is much easier to define the anchors. Otherwise you have to calculate the point on the border manually too. –  percusse Jan 11 '13 at 18:29
1  
I do this in the TQFT package. There's a note in my code saying that I "borrowed" the idea from the regular polygon shape. I think the code for that will be more illuminating than my TQFT code. –  Loop Space Jan 11 '13 at 23:04
    
@percusse I'm not sure which shape you are referring to, but the end shape I have in mind is certainly different from isosceles triangle or regular polygon. I toyed around with the idea of using the degree anchors as a shorthand for the anchor points I really wanted, but I couldn't find any way to define my own coordinates based on angle input. –  Johan Paulsson Jan 12 '13 at 17:23
    
@AndrewStacey Thank you for that pointer. It turns out that \expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@hat\endcsname{...} was precisely what I was looking for. The code both in your TQFT package and for the regular polygon was very helpful. I suppose posting that as some answer so I can mark the question as answered is the custom here? –  Johan Paulsson Jan 12 '13 at 17:27
    
You should feel free to answer your own question. I put a comment rather than an answer because I'm not on a device where I can test a solution but I thought I could help with a pointer. You, or anyone else, should feel free to flesh it out into a full answer to help others. If no-one does before I'm next in a position to do so then I could answer it but that might be a day or so away. –  Loop Space Jan 12 '13 at 18:07
add comment

1 Answer

This is done in the regular polygon shape that is part of the shapes.geometric library. The number of sides is not known until the shape is declared but the anchors are meant to be declared in the shape definition. The declaration gets round this limitation by adding code to declare additional anchors at call time.

When a node shape is used, a certain macro is called which sets up loads of stuff (the saved macros, the saved anchors, paths, and so forth). The various parts of the \pgfdeclarefunction macro add code to this, but they add it in specific ways. What the regular polygon declaration does is add some extra code to this macro. This extra code sets up the necessary extra anchors. In the shape declaration, it is the part which starts:

\expandafter\pgfutil@g@addto@macro\csname pgf@sh@s@regular polygon\endcsname{%

the actual code then adds the necessary anchor definitions. It loops through the number of sides, adding the anchor definition if it isn't already there. The code looks a bit horrible, but that's only because of the enormous number of \noexpands as it's done in an \xdef.

One important side effect is that these extra anchors are then available to all subsequent regular polygons, no matter what their number of sides. So if you draw a heptagon, and then later draw a pentagon, you can still refer to anchors on sides 6 and 7 on the pentagon.

I use this technique in my TQFT package which I adapted from this regular polygon code.

share|improve this answer
add comment

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.