View Javadoc
1   package org.opentrafficsim.core.math;
2   
3   import java.io.Serializable;
4   import java.util.Locale;
5   
6   import org.djunits.unit.DirectionUnit;
7   import org.djunits.value.ValueRuntimeException;
8   import org.djunits.value.vdouble.scalar.Direction;
9   import org.djunits.value.vdouble.vector.DirectionVector;
10  
11  /**
12   * 3D-rotation, RPY coded (longitudinal roll along the x-axis, lateral pitch along the y-axis and vertical yaw along the
13   * z-axis), also called Tait–Bryan angles or Cardan angles. Angles are absolute and relate to the absolute XYZ-frame of the
14   * world.
15   * <p>
16   * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
17   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
18   * </p>
19   * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
20   * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
21   */
22  public class Direction3d implements Serializable
23  {
24      /** */
25      private static final long serialVersionUID = 20160000L;
26  
27      /** The angles of the rotation in 3D (RPY coded). */
28      private final DirectionVector rotation;
29  
30      /**
31       * @param rotation DirectionVector; the angles in 3D (RPY coded)
32       * @throws ValueRuntimeException in case the vector does not have exactly three elements
33       */
34      public Direction3d(final DirectionVector rotation) throws ValueRuntimeException
35      {
36          if (rotation.size() != 3)
37          {
38              throw new ValueRuntimeException("Size of an RPY-rotation vector should be exactly 3. Got: " + rotation);
39          }
40          this.rotation = rotation;
41      }
42  
43      /**
44       * @param roll Direction; (phi) the rotation around the x-axis
45       * @param pitch Direction; (theta) the rotation around the y-axis
46       * @param yaw Direction; (psi) the rotation around the z-axis
47       * @throws ValueRuntimeException in case the units are incorrect
48       */
49      public Direction3d(final Direction roll, final Direction pitch, final Direction yaw) throws ValueRuntimeException
50      {
51          this.rotation = new DirectionVector(new Direction[] {roll, pitch, yaw}, roll.getDisplayUnit());
52      }
53  
54      /**
55       * @param roll double; (phi) the rotation around the x-axis
56       * @param pitch double; (theta) the rotation around the y-axis
57       * @param yaw double; (psi) the rotation around the z-axis
58       * @param unit DirectionUnit; the unit of the RPY parameters
59       * @throws ValueRuntimeException in case the units are incorrect
60       */
61      public Direction3d(final double roll, final double pitch, final double yaw, final DirectionUnit unit)
62              throws ValueRuntimeException
63      {
64          this.rotation = new DirectionVector(new double[] {roll, pitch, yaw}, unit);
65      }
66  
67      /**
68       * @return the roll.
69       */
70      public final Direction getRoll()
71      {
72          try
73          {
74              return this.rotation.get(0);
75          }
76          catch (ValueRuntimeException exception)
77          {
78              // should be impossible as we constructed the vector always with three elements
79              throw new RuntimeException(
80                      "getRoll() gave an exception; apparently vector " + this.rotation + " was not constructed right",
81                      exception);
82          }
83      }
84  
85      /**
86       * @return the pitch.
87       */
88      public final Direction getPitch()
89      {
90          try
91          {
92              return this.rotation.get(1);
93          }
94          catch (ValueRuntimeException exception)
95          {
96              // should be impossible as we constructed the vector always with three elements
97              throw new RuntimeException(
98                      "getPitch() gave an exception; apparently vector " + this.rotation + " was not constructed right",
99                      exception);
100         }
101     }
102 
103     /**
104      * @return the yaw.
105      */
106     public final Direction getYaw()
107     {
108         try
109         {
110             return this.rotation.get(2);
111         }
112         catch (ValueRuntimeException exception)
113         {
114             // should be impossible as we constructed the vector always with three elements
115             throw new RuntimeException(
116                     "getYaw() gave an exception; apparently vector " + this.rotation + " was not constructed right", exception);
117         }
118     }
119 
120     /** {@inheritDoc} */
121     @Override
122     public final String toString()
123     {
124         return String.format(Locale.US, "Rotation3d.Abs roll %s, pitch %s, yaw %s", getRoll(), getPitch(), getYaw());
125     }
126 }