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 have N points on a circle, I want to draw the intersection of the convex hulls of all sets of N-k consecutive points.

The points are not evenly spaced. The values of N and k (and the actual angles of each point) will change, so I'd rather not have a hard-coded solution.

Here is the best I've come up with. The silly way does exactly what I want, but it involves a lot of cut-and-paste every time. I don't understand why the second way fails; I've read that variables in \foreach loops don't quite behave as variables (I think), but I can't figure out a way around this.

\documentclass{article}
\usepackage{tikz}


\begin{document}

\begin{tikzpicture}[every node/.style={draw,inner sep=0mm}]

  \def\rad{5cm}
  \def\k{2}
  \def\N{6}


  \node (x1) at (15:\rad) {} ;
  \node (x2) at (45:\rad) {} ;
  \node (x3) at (90:\rad) {} ;
  \node (x4) at (120:\rad) {} ;
  \node (x5) at (210:\rad) {} ;
  \node (x6) at (270:\rad) {} ;


  %%% draw all the lines from xi to x(i+k)
  \foreach \i in {1,2,3,4,5,6} {
    \pgfmathtruncatemacro{\j}{1+mod(\i-1+\k,6)}
    \draw (x\i) -- (x\j) ;
  }


  %%% draw the intersection of all convex hulls of 5 consecutive points among the six
  %%% this is a silly way
  \clip (x1.center) -- (x2.center) -- (x3.center) -- (x4.center) -- (x5.center) -- cycle ;
  \clip (x2.center) -- (x3.center) -- (x4.center) -- (x5.center) -- (x6.center) -- cycle ;
  \clip (x3.center) -- (x4.center) -- (x5.center) -- (x6.center) -- (x1.center) -- cycle ;
  \clip (x4.center) -- (x5.center) -- (x6.center) -- (x1.center) -- (x2.center) -- cycle ;
  \clip (x5.center) -- (x6.center) -- (x1.center) -- (x2.center) -- (x3.center) -- cycle ;
  \fill (x6.center) -- (x1.center) -- (x2.center) -- (x3.center) -- (x4.center) -- cycle ;



  %%% draw the intersection of all convex hulls of N-k+1 consecutive points among the N
  %%% this is the code I think should work but doesn't
  %%% error message: ! Package tikz Error: Giving up on this path. Did you forget a semicolon?.
  \foreach \a in {1,...,\N}{
    \pgfmathsetmacro{\b}{1+mod(\a+\k,\N)}
    \draw (x\a) -- (x\b)
    \foreach \x in {\k,...,\N} {
      \pgfmathtruncatemacro{\xp}{1+mod(\a+\x-1,\N)}
      \pgfmathtruncatemacro{\xq}{1+mod(\a+\x,\N)}
      (x-\xp) -- (x-\xq)
    } ;
  }

\end{tikzpicture}


\end{document}
share|improve this question

1 Answer 1

up vote 5 down vote accepted

You need to complete a full, valid-syntax path at each spin of foreach. Also you can't simply do calculations right away when it is parsing the path commands. You need to bury them inside \pgfextra{} to pause the parsing and do other things.

So only change required here is below;

  \foreach \a in {1,...,\N}{
    \draw\pgfextra{\pgfmathsetmacro{\b}{1+mod(\a+\k,\N)}}
     (x\a) -- (x\b)
    \foreach \x in {\k,...,\N} {
      \pgfextra{\pgfmathtruncatemacro{\xp}{1+mod(\a+\x-1,\N)}
      \pgfmathtruncatemacro{\xq}{1+mod(\a+\x,\N)}}
      (x\xp) -- (x\xq)
    };
  }

enter image description here

I don't know if this is the intended result though.

share|improve this answer
    
The \pgfextra{} did the trick. (My indexing was wrong, and I needed to \clip and \fill, but that's my bad.) –  mike newman Aug 10 at 7:39
    
I guess \pgfextra{} isn't completely ignored when parsing for the path... For instance, \pgfextra{...}\draw (x\a) -- (x\b) does not seem to work. This isn't really a problem, but strikes me as odd. –  mike newman Aug 10 at 7:42

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.