Acceleration3d.java

  1. package org.opentrafficsim.core.math;

  2. import java.io.Serializable;
  3. import java.util.Locale;

  4. import org.djunits.unit.AccelerationUnit;
  5. import org.djunits.unit.DirectionUnit;
  6. import org.djunits.value.ValueRuntimeException;
  7. import org.djunits.value.vdouble.scalar.Acceleration;
  8. import org.djunits.value.vdouble.scalar.Direction;
  9. import org.djunits.value.vdouble.vector.AccelerationVector;

  10. /**
  11.  * A 3D acceleration vector, decomposed in X, Y, and Z-acceleration with easy conversion from and to a spherical coordinate
  12.  * system. <br>
  13.  * <a href="https://en.wikipedia.org/wiki/Spherical_coordinate_system">Physicists and mathematicians <strong>do not</strong>
  14.  * agree on the meaning of theta and phi.</a> In this class the convention in the physics domain is used:
  15.  * <ul>
  16.  * <li>theta is the angle from the z direction.</li>
  17.  * <li>phi is the projected angle in the xy-plane from the x direction.</li>
  18.  * </ul>
  19.  * N.B. In the geography domain yet another convention is used. <br>
  20.  * <p>
  21.  * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  22.  * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  23.  * </p>
  24.  * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
  25.  * @author <a href="https://github.com/peter-knoppers">Peter Knoppers</a>
  26.  */
  27. public class Acceleration3d implements Serializable
  28. {
  29.     /** */
  30.     private static final long serialVersionUID = 20150000L;

  31.     /** The acceleration in 3D (XYZ coded). */
  32.     private final AccelerationVector acceleration;

  33.     /**
  34.      * Construct a new Acceleration3d from vector of strongly typed Cartesian coordinates.
  35.      * @param acceleration the accelerations in 3D (YPR coded)
  36.      * @throws ValueRuntimeException in case the vector does not have exactly three elements
  37.      */
  38.     public Acceleration3d(final AccelerationVector acceleration) throws ValueRuntimeException
  39.     {
  40.         if (acceleration.size() != 3)
  41.         {
  42.             throw new ValueRuntimeException("Size of an RPY-acceleration vector should be exactly 3. Got: " + acceleration);
  43.         }
  44.         this.acceleration = acceleration;
  45.     }

  46.     /**
  47.      * Construct a new Acceleration3d from three strongly typed Cartesian coordinates.
  48.      * @param x the acceleration in the x-direction
  49.      * @param y the acceleration in the y-direction
  50.      * @param z the acceleration in the z-direction
  51.      * @throws ValueRuntimeException in case the units are incorrect
  52.      */
  53.     public Acceleration3d(final Acceleration x, final Acceleration y, final Acceleration z) throws ValueRuntimeException
  54.     {
  55.         this.acceleration = new AccelerationVector(new Acceleration[] {x, y, z}, AccelerationUnit.SI);
  56.     }

  57.     /**
  58.      * Construct a new Acceleration3d from three double Cartesian coordinates and a acceleration unit.
  59.      * @param x the acceleration in the x-direction
  60.      * @param y the acceleration in the y-direction
  61.      * @param z the acceleration in the z-direction
  62.      * @param unit the unit of the xyz parameters
  63.      * @throws ValueRuntimeException in case the units are incorrect
  64.      */
  65.     public Acceleration3d(final double x, final double y, final double z, final AccelerationUnit unit)
  66.             throws ValueRuntimeException
  67.     {
  68.         this.acceleration = new AccelerationVector(new double[] {x, y, z}, AccelerationUnit.SI);
  69.     }

  70.     /**
  71.      * Construct a new Acceleration3d from a strongly typed acceleration and polar coordinates.
  72.      * @param acceleration the acceleration in the direction of the angle along the vector
  73.      * @param theta the angle from the z direction
  74.      * @param phi the projected angle in the xy-plane from the x direction
  75.      * @throws ValueRuntimeException in case the vector does not have exactly three elements
  76.      */
  77.     public Acceleration3d(final Acceleration acceleration, final Direction theta, final Direction phi)
  78.             throws ValueRuntimeException
  79.     {
  80.         double[] xyz = Scalar3d.polarToCartesian(acceleration.getInUnit(), theta.si, phi.si);
  81.         this.acceleration = new AccelerationVector(xyz, acceleration.getDisplayUnit());
  82.     }

  83.     /**
  84.      * Retrieve the x-component of this Acceleration3d.
  85.      * @return the acceleration in the x-direction.
  86.      */
  87.     public final Acceleration getX()
  88.     {
  89.         try
  90.         {
  91.             return this.acceleration.get(0);
  92.         }
  93.         catch (ValueRuntimeException exception)
  94.         {
  95.             // should be impossible as we constructed the vector always with three elements
  96.             throw new RuntimeException(
  97.                     "getX() gave an exception; apparently vector " + this.acceleration + " was not constructed right",
  98.                     exception);
  99.         }
  100.     }

  101.     /**
  102.      * Retrieve the y-component of this Acceleration3d.
  103.      * @return the acceleration in the y-direction.
  104.      */
  105.     public final Acceleration getY()
  106.     {
  107.         try
  108.         {
  109.             return this.acceleration.get(1);
  110.         }
  111.         catch (ValueRuntimeException exception)
  112.         {
  113.             // should be impossible as we constructed the vector always with three elements
  114.             throw new RuntimeException(
  115.                     "getY() gave an exception; apparently vector " + this.acceleration + " was not constructed right",
  116.                     exception);
  117.         }
  118.     }

  119.     /**
  120.      * Retrieve the z-component of this Acceleration3d.
  121.      * @return the acceleration in the z-direction.
  122.      */
  123.     public final Acceleration getZ()
  124.     {
  125.         try
  126.         {
  127.             return this.acceleration.get(2);
  128.         }
  129.         catch (ValueRuntimeException exception)
  130.         {
  131.             // should be impossible as we constructed the vector always with three elements
  132.             throw new RuntimeException(
  133.                     "getZ() gave an exception; apparently vector " + this.acceleration + " was not constructed right",
  134.                     exception);
  135.         }
  136.     }

  137.     /**
  138.      * Retrieve the theta of this Acceleration3d.
  139.      * @return the angle of direction perpendicular to the xy-plane
  140.      */
  141.     public final Direction getTheta()
  142.     {
  143.         return Scalar3d.cartesianToTheta(getX().si, getY().si, getZ().si);
  144.     }

  145.     /**
  146.      * Retrieve the phi of this Acceleration3d.
  147.      * @return the projected angle of direction in the xy-plane
  148.      */
  149.     public final Direction getPhi()
  150.     {
  151.         return Scalar3d.cartesianToPhi(getX().si, getY().si);
  152.     }

  153.     /**
  154.      * Retrieve the norm of this Acceleration3d.
  155.      * @return the combined acceleration in the direction of the angle
  156.      */
  157.     public final Acceleration getAcceleration()
  158.     {
  159.         return new Acceleration(Scalar3d.cartesianToRadius(getX().si, getY().si, getZ().si), AccelerationUnit.SI);
  160.     }

  161.     @Override
  162.     public final String toString()
  163.     {
  164.         return String.format(Locale.US, "Acceleration3d %s (%s, theta %s, phi %s)", this.acceleration, getAcceleration(),
  165.                 new Direction(getTheta().getInUnit(DirectionUnit.EAST_DEGREE), DirectionUnit.EAST_DEGREE),
  166.                 new Direction(getPhi().getInUnit(DirectionUnit.EAST_DEGREE), DirectionUnit.EAST_DEGREE));
  167.     }

  168. }