1

I'm trying to declare a new tikz shape to draw a 3d coordinate axis. I finally worked through the basics but still have some details I can't figure out

enter image description here

  1. Why is the scale so large? In the above picture the axis length was defined as 0.5mm but is actually more than an order of magnitude larger.

  2. How can I position the x,y,z labels so the they are centered over the respective anchors?

\documentclass{letter}
\usepackage{tikz}
\usetikzlibrary{3d}

\tikzset{length/.initial=1mm} \tikzset{sep/.initial=0mm}

\makeatletter \newbox\pgfnodepartxbox \newbox\pgfnodepartybox \newbox\pgfnodepartzbox \pgfdeclareshape{axis}{ \nodeparts{x,y,z}

\saveddimen{\length} {\pgf@x=\pgfkeysvalueof{/tikz/length}} \saveddimen{\sep} {\pgf@x=\pgfkeysvalueof{/tikz/sep}}

\anchor{center}{\pgfpointorigin} \anchor{text}{\pgfpointxyz{\sep}{\sep}{0}} \anchor{x}{\pgfpointxyz{\length + \sep}{0}{0}} \anchor{y}{\pgfpointxyz{0}{\length + \sep}{0}} \anchor{z}{\pgfpointxyz{0}{0}{\length + \sep}}

\backgroundpath{% \pgfsetarrowsend{to}

\pgfpathmoveto{\pgfpointorigin}
\pgfpathlineto{\pgfpointxyz{\length}{0}{0}}
\pgfusepath{stroke}

\pgfpathmoveto{\pgfpointorigin}
\pgfpathlineto{\pgfpointxyz{0}{\length}{0}}
\pgfusepath{stroke}

\pgfpathmoveto{\pgfpointorigin}
\pgfpathlineto{\pgfpointxyz{0}{0}{\length}}
\pgfusepath{stroke}

} } \makeatother

\begin{document} \begin{tikzpicture} \node [shape=axis, length=0.5mm, sep=0.1mm] (p0) at (0,0,0) { \nodepart{x} (x) \nodepart{y} (y) \nodepart{z} (z) };

\draw[|-|] (0,-2mm) -- node[below] {14mm} ++(14mm, 0); \end{tikzpicture} \end{document}

Update: What I'm trying to do is get reusable axis I can easily manipulate with offsets and rotations. This is common when writing about rigid body motions, e.g. this picture from a text book enter image description here

ryan0270
  • 235
  • The anchors for the node parts specify the left side of the baseline. You need to use the dimensions of the boxes to figure out the placement. I wonder if a shape is the right tool for what you're trying to achieve. It might be better to use a pic than a shape. What are you going to do with that shape? – Qrrbrbirlbel Jun 16 '23 at 23:02
  • 1
    You're mixing lengths with the xyz coordinate system. The 0.5mm are converted to pt and that value in pt is then used to multiply the x vector (default 1cm). The xyz cs is just a coordinate transformation from 3d (but often just 2d as well) w/o units to 2d on the page (with units). Use \pgfsetxvec to set the length and then use \pgfpointxyz just with 1. (Or just use the length directly with the right direction.) – Qrrbrbirlbel Jun 16 '23 at 23:06
  • @Qrrbrbirlbel Thanks, I'll look into the correct usage of pgfsetxvec and pgfpointxyz.

    How do I account for the text box sizes? The manual explicitly advises against using \pgfnodepartxbox https://tikz.dev/base-nodes#\anchor

    – ryan0270 Jun 16 '23 at 23:39
  • You should only use saved dimen, saved anchors or saved macros in the definition of \anchors since they are evaluated after the creation of the node. That's why you can't use the boxes anymore. The same actually applies to the XYZ coordinate system as well. The vectors might be set up totally different then as well. I still think a pic would be much easier to implement and also be mich was owe to use. They work very similar to nodes but you can use normal TikZ code. – Qrrbrbirlbel Jun 17 '23 at 00:08
  • Can you point me to an example of how to make a reusable pic like that? Would it rotate correctly? Since it's a 3d projection onto 2d space, rotating the axes is a bit more work than just rotating a 2d picture – ryan0270 Jun 17 '23 at 01:01

0 Answers0