I have two nodes (A) and (B), and I want to only draw a central segment of the straight line between them, of a certain given length (say 2cm, but will vary). Is there some way I can do this? I am guaranteed that (A) and (B) are at least 2cm apart.

I know about shorten < and shorten >, but the problem is that I don't know the exact amount to shorten by, and I don't want to have to do the calculation myself each time.

4 Answers 4


I didn't read the question very carefully and thought you want to draw the middle part of of any kind of path. So I created a (meta-)decoration to do just that. For straight lines the other solutions given here are of course a lot simpler.


% A simple empty decoration, that is used to ignore the last bit of the path

% Declare the actual decoration.
        width={(\pgfmetadecoratedpathlength - \the\pgfdecorationsegmentlength)/2},
        next state=middle

        next state=final


% Create a key for easy access to the decoration (as suggested by Jake).
\tikzset{middle segment/.style={decoration={middle},decorate, segment length=#1}}

    \fill (0,0) circle;
    \fill (4,0) circle;
    \draw[middle segment=2cm,double,red,->] (0,0) to[out=30,in=150] (4,0);


  • 3
    Excellent! Adding to that: If you define a style \tikzset{middle segment/.style={decoration={middle},decorate, segment length=#1}}, you can easily draw line segments with different lengths using \draw [middle segment=<length>] (a) -- (b);
    – Jake
    May 19, 2011 at 18:04
  • @Jake: Good idea!
    – Caramdir
    May 19, 2011 at 18:22
  • Hi Caramdir. I like your solution, it seems really flexible! I tried modify it so that the line segment would have an arrow at the end, but without any luck. Can someone give me a hand? May 19, 2011 at 19:20
  • @Jamie: Add \afterdecoration { \pgfsetarrowsend{to} \pgfusepath{stroke} } to the middle state (right after ...curveto}, before the second }). You can replace to by the arrow type you want. See also the example on page 601 of the (v2.10) manual.
    – Caramdir
    May 19, 2011 at 19:30
  • That's great! I actually just found that myself. But now I've also noticed that my [double] option is getting ignored, if I want make the line into two parallel lines ... how can I add that in? May 19, 2011 at 19:32

The calc library eats this sort of thing for breakfast.


\node (a) at (0,0) {A};
\node (b) at (3,3) {B};
\draw ($($(a)!.5!(b)$)!1cm!(a)$) --  ($($(a)!.5!(b)$)!1cm!(b)$);

The syntax works as follows: $...$ is interpreted as a "coordinate calculation" and it returns a coordinate. We start with $(a)!.5!(b)$ which is halfway between (a) and (b). Then we move 1cm from this point towards (a). That's our starting point. We draw a line from that to the same but with (b) in place of (a).


centre path

  • 2
    Thanks Andrew, I don't really know much about the calc package, this is a good advertisement for it. May 19, 2011 at 19:20

Along the same line as the other answers, but also using the intersections library.





\coordinate (A) at (0,0) ;
\coordinate (B) at (4,4);

\coordinate (mid) at ($(A)!0.5!(B)$);

\path[name path=line,draw=lightgray] (A) node[left] {$A$} -- (B)  node[right] {$B$};
\path[name path=circle,draw=lightgray] (mid) circle[radius=0.5*\length];

\draw [red, blue,ultra thick, name intersections={of=line and circle}]
(intersection-1) -- (intersection-2);


The output is


The length of the blue segment is determined by the value of the macro \length.

Another option is to clip the path :


\coordinate[label=left:$A$] (A) at (0,0) ;
\coordinate[label=right:$B$] (B) at (4,4);

\coordinate (mid) at ($(A)!0.5!(B)$);

\clip (mid) circle[radius=0.5*\length];
\draw[blue,ultra thick] (A) -- (B);
  • This is a great illustration of named paths. Thanks! May 19, 2011 at 17:47
  • @Jamie : I just realized that the length of the line segment is the diameter of the circle !! I must divide the radius of the circle by 2. I fixed the code, but not the picture.
    – Frédéric
    May 19, 2011 at 17:53
  • Thanks Frédéric. It's funny that the first three solutions manage to do it in four different ways! May 19, 2011 at 19:21

How about that?


    % def Points
    \fill (0,0) coordinate (A) circle (1pt) (5,2) coordinate (B) circle (1pt); 
    % two nodes A and B
    \node [below] at (A) {Node A};
    \node [above] at (B) {Node B};
    % line between
    \draw ($(A)!1cm!(B)$) -- ($(A)!3cm!(B)$);

First I define two corrdinates, draw them and add two nodes. The I the ⟨p⟩!⟨factor/dimension⟩!⟨q⟩ syntax to get specified points between A and B.
Unfortunately in my solution you have to use two dimes to get a defined length. In ths case 3cm - 1cm = 2cm segment length.

See PGF manual, section “4.2.1 Using Partway Calculations for the Construction of D” in the Euclid Tutorial


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .