Line segments with text in the middle in TikZ

Another exam, another image. I am trying to create the following image in TikZ Now. I am looking for some feedback on my code. I am trying to learn TikZ as fast as I can, but still I feel I am doing things in an overly complicated or hugely inefficient way.

My main problem is finding the best way to create the line segments on the left. How do I do this? Breaking them up and placing text in between just is meh.

My attempt is below. Please pay little attention to it as it really sucks.

\documentclass[10pt,a4paper]{article}
\usepackage[dvipsnames*,svgnames]{xcolor}
\usepackage{tkz-euclide}
\usetkzobj{all}
\usepackage{mathtools}

\begin{document}

\begin{tikzpicture}[scale=5]
\tkzDefPoint(-0.1,0){P}
\tkzDefPoint(0,0){O}
\tkzDefPoint(1.2,0){A}
\tkzDefPoint(0,0.8){B}
\tkzDefPoint(0,1.6){C}
\tkzDefPoint(1.2,0){G}
\tkzDefPoint(1.2,.83){U}
\tkzDefPointBy[rotation= center B angle 110](C) \tkzGetPoint{D}
\tkzDefPointBy[rotation= center O angle  35](G) \tkzGetPoint{E}
\tkzDefMidPoint(B,E) \tkzGetPoint{M1}
\tkzDefMidPoint(C,E) \tkzGetPoint{M2}
\tkzMarkAngle[thick,scale=0.5,fill=black!20!white](A,O,E)
\tkzMarkAngle[thick,scale=0.4,fill=black!20!white](E,B,C)
\tkzDrawSegment[thick](P,A)
\draw[thick](-0.6,0)--(-0.4,0);\draw[thick](-0.6,1.6)--(-0.4,1.6);
\draw[thick](-0.1,0.8)--(-0.3,0.8);\draw[thick](-0.1,1.6)--(-0.3,1.6);
\draw[thick](-0.2,1.6)--(-0.2,1.3);\draw[thick](-0.2,0.8)--(-0.2,1.1);
\draw[thick](-0.5,0.0)--(-0.5,0.6);\draw[thick](-0.5,0.8)--(-0.5,1.6);
\tkzDrawSegment[ultra thick,Goldenrod,dashed](O,U)
\tkzDrawSegments[ultra thick](O,C B,E)
\tkzDrawSegment[ultra thick,Magenta](C,E)
\tkzLabelPoint[left=-.55](-0.2,1.2){$0.8$ m} ;
\tkzLabelPoint[left=-.65](-0.5,0.7){$\stackrel{\text{\large Vindu}}{1.6 \text{m}}$} ;
\tkzLabelPoint[above=0.2](M1){Arm} ;
\tkzLabelPoint[below left](M1){$0.8$m} ;
\tkzLabelPoint[above=0.2,right, Magenta](M2){$\mathit{\mathbf{L}}$} ;
\tkzLabelPoint[above=1,Magenta](M2){\bfseries Markiseduk} ;
\tkzLabelPoint[below=1.75,left,Goldenrod](E){\bfseries Solstr\aa le} ;
\tkzLabelAngle[pos=0.3](A,O,E){$u$}
\tkzLabelAngle[pos=0.225](E,B,C){$v$}
\end{tikzpicture}

\end{document}

My result... • Aren't you afraid your students might read this? Nice exam preparation! ;-) – gerrit Nov 26 '11 at 18:14
• Its an old exam, I am just clening them up and adding solutions for them! ^^ – N3buchadnezzar Nov 26 '11 at 18:21
• I have the feeling that this would be a lot simpler in plain TikZ. For example, the yellow line could be drawn along with the label with a simple command like \draw[ultra thick,Goldenrod,dashed] (O) -- (U) node[midway,below right] {\bfseries Solstr\aa le};. – qubyte Nov 26 '11 at 18:52
• It's a lot simpler if you have studied Tikz but for someone who does not to know all about tikz' but who wants to draw only geometric pictures, perhaps it's a fine way. With this package, I hope that the user tries to study tikzbecause a lot of "styles" (options) are the same. It will be easy to work with tikz after that. Its also easy to pass from pst-eucl to tkz-euclidewithout to know all the pgfmanual. – Alain Matthes Nov 26 '11 at 20:01

With tkz-euclide but I remark a bug because I need to use pos=0.4 to place the label vertically (??)

version 2 with option |-|

\documentclass[10pt,a4paper]{article}
\usepackage[dvipsnames*,svgnames]{xcolor}
\usepackage{tkz-euclide}
\usetkzobj{all}
\usepackage{mathtools}

\begin{document}

\begin{tikzpicture}[scale=5]
\tkzDefPoint(-0.1,0){P}
\tkzDefPoint(0,0){O}
\tkzDefPoint(1.2,0){A}
\tkzDefPoint(0,0.8){B}
\tkzDefPoint(0,1.6){C}
\tkzDefPoint(1.2,0){G}
\tkzDefPoint(1.2,.83){U}
\tkzDefPointBy[rotation= center B angle 110](C) \tkzGetPoint{D}
\tkzDefPointBy[rotation= center O angle  35](G) \tkzGetPoint{E}
\tkzDefShiftPoint[B](-0.2,0){B'}
\tkzDefShiftPoint[C](-0.2,0){C'}
\tkzDefShiftPoint[O](-0.6,0){O''}
\tkzDefShiftPoint[C](-0.6,0){C''}

\tkzMarkAngle[thick,scale=0.5,fill=black!20!white](A,O,E)
\tkzMarkAngle[thick,scale=0.4,fill=black!20!white](E,B,C)
\tkzDrawSegment[thick](P,A)
\tkzDrawSegment[ultra thick,Goldenrod,dashed](O,U)
\tkzDrawSegments[ultra thick](O,C B,E)
\tkzDrawSegment[ultra thick,Magenta](C,E)
\tkzDrawSegments[|-|](B',C' O'',C'')

\tkzLabelSegment[above=0.2](B,E){Arm}
\tkzLabelSegment[below left](B,E){$0.8$m}
\tkzLabelSegment[above=0.2,right, Magenta](C,E){$\mathit{\mathbf{L}}$}
\tkzLabelSegment[above=1,Magenta](C,E){\bfseries Markiseduk}
\tkzLabelSegment[pos=.4,fill=white,inner sep=10pt](B',C'){$0.8$ m}
\tkzLabelSegment[pos=.4,fill=white,inner sep=10pt,align=center](O'',C''){\large Vindu\\$1.6$ m}
\tkzLabelPoint[below=1.75,left,Goldenrod](E){\bfseries Solstr\aa le}
\tkzLabelAngle[pos=0.3](A,O,E){$u$}
\tkzLabelAngle[pos=0.225](E,B,C){$v$}
\end{tikzpicture}

\end{document} • I found the bug in \tkzLabelSegment. I need to remove above in the code below \def\tkz@LabelSegment[#1](#2,#3)#4{% \begingroup \path (#2) to node[above,#1]{#4} (#3) ; \endgroup } – Alain Matthes Nov 26 '11 at 20:04

Another way to break the line is to draw it after the node and make it go via the node. When you do that, then TikZ breaks the line to "hop" over the node. As a simple example:

\node (a) at (0,0) {a};
\draw (-3,0) -- (a) -- (3,0);

will produce:

---- a ----

(okay, it'll look a bit nice than that!)

• I'm trying to find something shorter (same idea occurred). Do you reckon anything can be done with a decoration? Probably overkill! Obviously this would entail a lot more code somewhere. I guess this will be the shortest in practical terms. – qubyte Nov 26 '11 at 18:57
• @MarkS.Everitt I guess that by "shorter" you would want it all done in a single command. You still need the node to be actually placed first so that the path knows where to break itself, but as it's placed at a certain location on the path then it should be possible. Not sure how much hacking would be involved, though. Possibly decorations, or pre/post actions. I'm not sure. – Loop Space Nov 26 '11 at 19:18

This is how I would have done it, but it is definitely a matter of taste. You can also play around with the angle -105 to get different outputs for your needs.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,arrows}
\begin{document}
\begin{tikzpicture}[every node/.style={inner sep=0cm,outer sep=0cm},scale=5]
\draw[thick]  (0,0) node (O) {} --  (0,0.8cm) node(M) {} -- (0,1.6cm) node (T) {} (0,0.8cm) -- ($(M)!1!-105:(T)$) node (tip){};
\draw (-2mm,0) -- node (justanode) {} (1.2cm,0);
\draw[magenta] (T) --node[near start,above right=2mm] {{\bfseries Markiseduk}} node[midway,above right=1mm] {L} (tip);
\draw[yellow!80!black,densely dashed] (O) -- node[midway,below right=1mm] {{\bfseries Solstr\aa le}} ($(O)!1.1!(tip)$);
\draw[|-|] ($(T) + (-2mm,0)$) -- node[fill=white,inner sep=1mm,midway] {0.8 m}($(M) + (-2mm,0)$);
\draw[|-|] ($(T) + (-4mm,0)$) -- node[fill=white,inner sep=1mm,text width=1cm,midway] {Vindu 1.6 m}($(O) + (-4mm,0)$);
\end{tikzpicture}
\end{document}

The output: A very crude way of making those lines with labels is with the following macro

\newcommand{\midlabelline}{
\node (midlabel) at ($(#1)!.5!(#2)$) {#3};
\draw[|-,thick] (#1) --  (midlabel);
\draw[-|,thick] (midlabel) -- (#2);
}

which requires the calc library, i.e. \usetikzlibrary{calc}. This can obviously be improved, but it will do what you want with a command like:

\midlabelline{-20,80}{-20,160}{0.8\,m}

You can simply add the node with a white background. The line you are trying to create would be generated by:

\tikz\path[draw] (0,0) -- ++(1,0) ++(-0.5,0) -- ++(0,-5) node[pos=0.5,fill=white] {Vindu} ++(.5,0) -- ++(-1,0);

To get it to two lines, you need to add text alignment and width. If you want the white space to be a little greater, increase the inner sep with inner sep=6pt, for instance, on the node.

• Or \tikz \draw[|-|] (0,0) to node [fill=white]{text} (0,5) ; by default you have pos=.5 – Alain Matthes Nov 26 '11 at 20:14