5

I am drawing some diagrams of mechanical systems which have many rotated components. For each of these components I am attaching a coordinate system, which is often rotated with the component. I am drawing the coordinates using the draw command and adding labels (x and y) using the node command. I would like the axis label to be in line with the axis (i.e., the arrow points directly at it) regardless of how the coordinate system is rotated. Currently I have done:

\documentclass{standalone}
    \usepackage{tikz}
\begin{document}
    \begin{tikzpicture}
        \draw[<->,rotate around={22.5:(0,0)}](0,1)node[above]{$y$}--(0,0.2)--(1,0.2)node[right]{$x$};
    \end{tikzpicture}
\end{document}

This code results in the following output:

enter image description here

TikZ seems to be interpreting node[above] to mean above using the standard coordinates, instead of "rotating" what it means for the node to be above the end of the line. I would ideally like to be able to write something like node[angle=22.5] to correctly position the label. Is there a way to do this where I can specify the angle instead of just above, right, etc.?

  • Welcome to TeX.SX! Next time, please make your MWE compilable so that answerers don't have to add this text to test. – Matthew Leingang Jan 17 '15 at 20:40
  • 1
    Edited the MSE to be compilable – Isaac Vandermeulen Jan 17 '15 at 21:06
2

Have you tried something like node[pos=xx]?

\documentclass{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
    \draw[<->,rotate around={22.5:(0,0)}] 
        (0,1) --(0,0.2) node[pos=-0.2] {$y$}
        -- (1,0.2) node[pos=1.2] {$x$};
\end{tikzpicture}
\end{document}

sample output

The pos key of a node places it that position along the segment. pos=0 is the beginning, and pos=1 is the end. pos=0.5 is the middle, sometimes useful, but not here.

We need to place the nodes a little bit before the beginning of the segment and a little bit after. So we subtract a little bit from 0 and add a little bit to 1.

The disadvantage here is that the separation you get is as a fraction of the segment length. So if you want a fixed distance from the end you may need to find another way.

  • Thanks! This is a decent work around considering there doesn't seem to be a nice angle based solution anyone can provide – Isaac Vandermeulen Jan 20 '15 at 21:13
2

If I were you, PSTricks would be my first resort.

\rput has angular parameter for rotation. If we prefix the angle with *, the rotation will be absolute. For example, consider \rput{60}(0,0){\rput{*45}(0,0){Object}}. The object will be rotated 45 degrees rather 105 degrees.

\documentclass[pstricks,border=12pt,12pt]{standalone}

\def\Axes{%
\pspicture(-3.5,-3.5)(3.5,3.5)
    \psline{<->}(3;0)(0,0)(3;90)
    \rput{*0}(3.3;0){$x$}
    \rput{*0}(3.3;90){$y$}
\endpspicture}

\begin{document}
\foreach \a in {0,30,...,330}{%
\pspicture(-4,-4)(4,4)
\rput{\a}(0,0){\Axes}
\rput(0,4){Rotation $\a^\circ$}
\endpspicture}
\end{document}

enter image description here

  • Is there a way to use this inside of a TikZ environment? It doesn't seem worth learning PSTricks and converting diagrams into it just so that I can use one nice command which seems absent from TikZ. – Isaac Vandermeulen Jan 20 '15 at 21:19
1

You don't need to specify the angles; TikZ can do the calculations for you! Here's an option that guarantees that the labels are placed at the same distance from the end of the segments and in the appropriate direction (that of each of the segments):

enter image description here

The code:

\documentclass[border=5pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{xparse}

\newlength\mylena
\newlength\mylenb

\NewDocumentCommand\Rotcs{mmmmmO{x}O{y}}{
\draw[<->,rotate around={#1:(0,0)}] 
  #2 coordinate (rotcs#5a) -- 
  #3 coordinate (rotcs#5b) -- 
  #4 coordinate (rotcs#5c);
\path let
  \p1=( $ (rotcs#5b) - (rotcs#5a) $ ), 
  \p2=( $ (rotcs#5b) - (rotcs#5c) $ ) in 
  \pgfextra{\pgfmathsetlength\mylena{veclen(\x1,\y1)}}
  \pgfextra{\pgfmathsetlength\mylenb{veclen(\x2,\y2)}}
  node at ($ (rotcs#5b)!\mylena+6pt!(rotcs#5a) $ ) {$#6$}
  node at ($ (rotcs#5b)!\mylenb+6pt!(rotcs#5c) $ ) {$#7$};
}

\begin{document}
\begin{tikzpicture}
\Rotcs{22.5}{(0,1)}{(0,0.2)}{(0.5,0.2)}{w}
\begin{scope}[xshift=1.5cm]
\Rotcs{22.5}{(0,1)}{(0,0.2)}{(3,0.2)}{z}
\end{scope}
\begin{scope}[xshift=5cm]
\Rotcs{60}{(0,1)}{(0,0.2)}{(3,0.2)}{z}
\end{scope}
\begin{scope}[xshift=8cm]
\Rotcs{160}{(0,3)}{(0,0)}{(1,0)}{z}
\end{scope}
\end{tikzpicture}

\end{document}

Remarks

  • The idea behind this solution is simple; lets asume we have two coordinates (A) and (B); we use a distance modifier (A)!<length>!(B) to place the label in the line from (A) to (B) at a distance <length> from (A). The trick is to calculate the appropriate value for <length> which is the length of the segment from (A) to (B) plus 6pt.

  • The \Rotcs command has 5 mandatory arguments:

    \Rotcs{<angle>}{<point1>}{<point2>}{<point3>}{<prefix>}
    

    the first one is the rotation angle; arguments two, three and four are used to specify the three points for the coordinate system and the fifth argument is used to set a prefix used internally for the coordinates in the command. Two additional optional arguments allow to change the labels used (see example code).

  • While I like the idea of defining a coordinate system object, this solution doesn't really answer my question. I was using coordinate systems mostly as an example. I was hoping for something where I can just type in the angle as it would be a much more general solution which I could also use in other places. For example if I want to place a length label on the midpoint of an angled line, it'd be nice to be able to enter an angle as an option into node[<options>]{label} so that the label is a fixed distance from the midpoint of the line in the direction orthogonal to the line at that point – Isaac Vandermeulen Jan 20 '15 at 21:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.