Tight fit in horizontal diagram generated with forest
To be honest, I'm not sure this is much of an improvement. However, it is a lot clearer what is going on and the code is considerably less cluttered. It is also slightly more compact (both width and height/depth are smaller than in the OP's solution). Whether any of this is of any importance is, of course, another matter.
\documentclass[border=10pt]{standalone}
\usepackage{forest}
\usetikzlibrary{matrix}
\tikzset{
fixedBase/.style={draw, circle, fill=black, text=white},
prismaticJoint/.style={draw},
revoluteJoint/.style={draw, rounded corners=2mm},
rigidLink/.style={draw, color=blue, fill=blue, text=white},
fixedTranslation/.style={draw, fill=gray},
fixedRotation/.style={draw, fill=gray, rounded corners=2mm},
springDamperElement/.style={draw, circle, color=blue, fill=blue, text=white},
fork/.style={draw, circle, color=red, fill=red, text=white},
endpoint/.style={draw, fill=black, text=white},
}
\newsavebox\treelegend
\setbox0=\hbox{% solution from Steven B. Segletes: https://tex.stackexchange.com/a/366710/
\begin{tikzpicture}
\matrix [matrix of nodes, column 2/.style={text height=3.5mm, text depth=3.5mm, text width=40mm}]
{%
|[fixedBase]| F8 & Fixed base \\
|[prismaticJoint]| PJ & Prismatic joint \\
|[revoluteJoint]| RJ & Revolute joint \\
|[rigidLink]| RL & Rigid link \\
|[fixedTranslation]| FT & Fixed translation \\
|[springDamperElement]| SD & Spring-damper element \\
|[fork]| F & Fork \\
|[endpoint]| EP & Endpoint \\
};
\end{tikzpicture}%
}
\savebox\treelegend{\copy0}
\begin{document}
\begin{forest}
fork/.style={
/tikz/fork,
before computing xy={for children={l'+=8mm}},
},
for tree={
anchor=center
},
before computing xy={
for tree={l'=9mm},
}
[FB, fixedBase, grow'=east, anchor=east
[BJ$_X$, prismaticJoint, for tree={grow=north}
[BJ$_Y$, prismaticJoint
[BJ$_Z$, prismaticJoint
[BJ$_X$, revoluteJoint
[BJ$_Y$, revoluteJoint
[BJ$_Z$, revoluteJoint, grow'=east
[F, fork, grow'=east, before computing xy={for children={l'+=5mm}}
[LLJ$_X$, revoluteJoint, for tree={grow=north}
[LLJ$_Z$, revoluteJoint
[F, fork, grow=east
[FT, fixedTranslation, for tree={grow=south}
[WMJ$_{ABD}$, prismaticJoint
[SD, springDamperElement, before computing xy={l'=0pt, s'=15mm}]
[EP, endpoint, before computing xy={l=10mm, s'=0pt}]
]
]
[ABD, rigidLink, for tree={grow=north}
[ULJ$_X$, revoluteJoint
[ULJ$_Y$, revoluteJoint
[ULJ$_Z$, revoluteJoint
[F, fork, grow=east
[FT, fixedTranslation, for tree={grow=south}
[WMJ$_{THO}$, prismaticJoint
[SD, springDamperElement, before computing xy={l'=0pt, s'=15mm}]
[EP, endpoint, before computing xy={l=10mm, s'=0pt}]
]
]
[THO, rigidLink, for tree={grow=north}
[F, fork, grow'=east, before computing xy={for children={l'+=10mm}}
[F, fork, grow'=east
[LNJ$_X$, revoluteJoint
[LNJ$_Y$, revoluteJoint
[LNJ$_Z$, revoluteJoint
[HEA, rigidLink, for tree={grow=north}
[EP, endpoint]
]
]
]
]
[SJ$_{L,X}$, revoluteJoint, for tree={grow=south}
[SJ$_{L,Y}$, revoluteJoint
[SJ$_{L,Z}$, revoluteJoint
[UPA$_L$, rigidLink
[EJ$_{L,Z}$, revoluteJoint
[LOA$_L$, rigidLink
[EP, endpoint]
]
]
]
]
]
]
]
[SJ$_{R,X}$, revoluteJoint, for tree={grow=south}
[SJ$_{R,Y}$, revoluteJoint
[SJ$_{R,Z}$, revoluteJoint
[UPA$_R$, rigidLink
[EJ$_{R,Z}$, revoluteJoint
[LOA$_R$, rigidLink
[EP, endpoint]
]
]
]
]
]
]
]]]]]]]]]
]
[PEL, rigidLink, for tree={grow=south}
[F, fork, grow=south, before packing={s sep'+=5mm}, before computing xy={for children={l'-=5mm}}
[HJ$_{L,X}$, revoluteJoint
[HJ$_{L,Y}$, revoluteJoint
[HJ$_{L,Z}$, revoluteJoint
[THI$_L$, rigidLink
[KJ$_{L,Z}$, revoluteJoint
[SHA$_L$, rigidLink
[AJ$_{L,X}$, revoluteJoint
[AJ$_{L,Y}$, revoluteJoint
[AJ$_{L,Z}$, revoluteJoint
[F, fork, grow'=east
[COPJ$_{L,X}$, prismaticJoint, for tree={grow=north}
[COPJ$_{L,Y}$, prismaticJoint
[COPJ$_{L,Z}$, prismaticJoint
[EP, endpoint]
]
]
]
[FOO$_L$, rigidLink
[EP, endpoint]
]
]
]
]
]
]
]
]
]
]
]
[HJ$_{R,X}$, revoluteJoint
[HJ$_{R,Y}$, revoluteJoint
[HJ$_{R,Z}$, revoluteJoint
[THI$_R$, rigidLink
[KJ$_{R,Z}$, revoluteJoint
[SHA$_R$, rigidLink
[AJ$_{R,X}$, revoluteJoint
[AJ$_{R,Y}$, revoluteJoint
[AJ$_{R,Z}$, revoluteJoint
[F, fork, grow'=east
[COPJ$_{R,X}$, prismaticJoint, for tree={grow=north}
[COPJ$_{R,Y}$, prismaticJoint
[COPJ$_{R,Z}$, prismaticJoint
[EP, endpoint]
]
]
]
[FOO$_R$, rigidLink
[EP, endpoint]
]
]
]
]
]
]
]
]
]
]
]
]
]]]]]]]]
]
\node [anchor=north west] at (current bounding box.north west) {\usebox{\treelegend}};
\end{forest}
\end{document}
Ok, thank you Bobyandbob and Tina for providing the initial hint. The option l sep
was the key. Here is the code and diagram I finally came up with. I had to use some before computing xy
, but I like the result.
\documentclass{standalone}
\usepackage{forest}
\begin{document}
\forestset{
fixedBase/.style={draw, circle, fill=black, text=white},
prismaticJoint/.style={draw},
revoluteJoint/.style={draw, rounded corners=2mm},
rigidLink/.style={draw, color=blue, fill=blue, text=white},
fixedTranslation/.style={draw, fill=gray},
fixedRotation/.style={draw, fill=gray, rounded corners=2mm},
springDamperElement/.style={draw, circle, color=blue, fill=blue, text=white},
fork/.style={draw, circle, color=red, fill=red, text=white},
endpoint/.style={draw, fill=black, text=white},
}
\begin{forest}
for tree={anchor=center}
[FB, fixedBase, l sep=-300mm, grow'=east,
[FB, fixedBase, edge'={}, grow'=east, before computing xy={l=5mm, s=160mm}, [Fixed base, edge'={}, anchor=west, before computing xy={l=5mm, s=0}]],
[PJ, prismaticJoint, edge'={}, grow'=east, before computing xy={l=5mm, s=150mm}, [Prismatic joint, edge'={}, anchor=west, before computing xy={l=5mm, s=0}]],
[RJ, revoluteJoint, edge'={}, grow'=east, before computing xy={l=5mm, s=140mm}, [Revolute joint, edge'={}, anchor=west, before computing xy={l=5mm, s=0}]],
[RL, rigidLink, edge'={}, grow'=east, before computing xy={l=5mm, s=130mm}, [Rigid link, edge'={}, anchor=west, before computing xy={l=5mm, s=0}]],
[FT, fixedTranslation, edge'={}, grow'=east, before computing xy={l=5mm, s=120mm}, [Fixed translation, edge'={}, anchor=west, before computing xy={l=5mm, s=0}]],
[SD, springDamperElement, edge'={}, grow'=east, before computing xy={l=5mm, s=110mm}, [Spring-damper element, edge'={}, anchor=west, before computing xy={l=5mm, s=0}]],
[F, fork, edge'={}, grow'=east, before computing xy={l=5mm, s=100mm}, [Fork, edge'={}, anchor=west, before computing xy={l=5mm, s=0}]],
[EP, endpoint, edge'={}, grow'=east, before computing xy={l=5mm, s=90mm}, [Endpoint, edge'={}, anchor=west, before computing xy={l=5mm, s=0}]],
[BJ$_X$, prismaticJoint, l sep=-300mm, for tree={grow=north}, before computing xy={l=12mm, s=0},
[BJ$_Y$, prismaticJoint, l sep=-300mm,
[BJ$_Z$, prismaticJoint, l sep=-300mm,
[BJ$_X$, revoluteJoint, l sep=-300mm,
[BJ$_Y$, revoluteJoint, l sep=-300mm,
[BJ$_Z$, revoluteJoint, l sep=-300mm, grow'=east,
[F, fork, grow'=east,
[LLJ$_X$, revoluteJoint, l sep=-300mm, for tree={grow=north},
[LLJ$_Z$, revoluteJoint, l sep=-300mm,
[F, fork, grow=east,
[FT, fixedTranslation, for tree={grow=south}, [WMJ$_{ABD}$, prismaticJoint, [SD, springDamperElement, before computing xy={l=0, s=15mm}], [EP, endpoint, before computing xy={l=10mm, s=0}]]],
[ABD, rigidLink, l sep=-300mm, for tree={grow=north},
[ULJ$_X$, revoluteJoint, l sep=-300mm,
[ULJ$_Y$, revoluteJoint, l sep=-300mm,
[ULJ$_Z$, revoluteJoint, l sep=-300mm,
[F, fork, grow=east,
[FT, fixedTranslation, for tree={grow=south}, [WMJ$_{THO}$, prismaticJoint, [SD, springDamperElement, before computing xy={l=0, s=15mm}], [EP, endpoint, before computing xy={l=10mm, s=0}]]],
[THO, rigidLink, l sep=-300mm, for tree={grow=north},
[F, fork, l sep+=15mm, grow'=east,
[F, fork, l sep+=5mm, grow'=east,
[LNJ$_X$, revoluteJoint, [LNJ$_Y$, revoluteJoint, [LNJ$_Z$, revoluteJoint, [HEA, rigidLink, for tree={grow=north}, [EP, endpoint]]]]],
[SJ$_{L,X}$, revoluteJoint, for tree={grow=south}, [SJ$_{L,Y}$, revoluteJoint, [SJ$_{L,Z}$, revoluteJoint, [UPA$_L$, rigidLink, [EJ$_{L,Z}$, revoluteJoint, [LOA$_L$, rigidLink, [EP, endpoint]]]]]]],
],
[SJ$_{R,X}$, revoluteJoint, for tree={grow=south}, [SJ$_{R,Y}$, revoluteJoint, [SJ$_{R,Z}$, revoluteJoint, [UPA$_R$, rigidLink, [EJ$_{R,Z}$, revoluteJoint, [LOA$_R$, rigidLink, [EP, endpoint]]]]]]],
]]]]]]]]]],
[PEL, rigidLink, for tree={grow=south},
[F, fork, grow=south,
[HJ$_{L,X}$, revoluteJoint, l sep=-300mm, [HJ$_{L,Y}$, revoluteJoint, l sep=-300mm, [HJ$_{L,Z}$, revoluteJoint, l sep=-300mm, [THI$_L$, rigidLink, l sep=-300mm, [KJ$_{L,Z}$, revoluteJoint, l sep=-300mm, [SHA$_L$, rigidLink, l sep=-300mm, [AJ$_{L,X}$, revoluteJoint, l sep=-300mm, [AJ$_{L,Y}$, revoluteJoint, l sep=-300mm, [AJ$_{L,Z}$, revoluteJoint, l sep=-300mm, [F, fork, grow'=east, [COPJ$_{L,X}$, prismaticJoint, for tree={grow=north}, [COPJ$_{L,Y}$, prismaticJoint, [COPJ$_{L,Z}$, prismaticJoint, [EP, endpoint]]]], [FOO$_L$, rigidLink, [EP, endpoint]]]]]]]]]]]],
[HJ$_{R,X}$, revoluteJoint, l sep=-300mm, [HJ$_{R,Y}$, revoluteJoint, l sep=-300mm, [HJ$_{R,Z}$, revoluteJoint, l sep=-300mm, [THI$_R$, rigidLink, l sep=-300mm, [KJ$_{R,Z}$, revoluteJoint, l sep=-300mm, [SHA$_R$, rigidLink, l sep=-300mm, [AJ$_{R,X}$, revoluteJoint, l sep=-300mm, [AJ$_{R,Y}$, revoluteJoint, l sep=-300mm, [AJ$_{R,Z}$, revoluteJoint, l sep=-300mm, [F, fork, grow'=east, [COPJ$_{R,X}$, prismaticJoint, for tree={grow=north}, [COPJ$_{R,Y}$, prismaticJoint, [COPJ$_{R,Z}$, prismaticJoint, [EP, endpoint]]]], [FOO$_R$, rigidLink, [EP, endpoint]]]]]]]]]]]],
]]]]]]]]]]
\end{forest}
\end{document}